Showing
22 changed files
with
486 additions
and
112 deletions
... | ... | @@ -15,8 +15,11 @@ |
15 | 15 | */ |
16 | 16 | package org.thingsboard.server.controller; |
17 | 17 | |
18 | +import io.swagger.annotations.ApiOperation; | |
19 | +import io.swagger.annotations.ApiParam; | |
18 | 20 | import org.apache.commons.lang3.StringUtils; |
19 | 21 | import org.springframework.http.HttpStatus; |
22 | +import org.springframework.http.MediaType; | |
20 | 23 | import org.springframework.security.access.prepost.PreAuthorize; |
21 | 24 | import org.springframework.web.bind.annotation.PathVariable; |
22 | 25 | import org.springframework.web.bind.annotation.RequestBody; |
... | ... | @@ -55,11 +58,25 @@ import java.util.List; |
55 | 58 | public class AlarmController extends BaseController { |
56 | 59 | |
57 | 60 | public static final String ALARM_ID = "alarmId"; |
61 | + private static final String ALARM_SECURITY_CHECK = "If the user has the authority of 'Tenant Administrator', the server checks that the originator of alarm is owned by the same tenant. " + | |
62 | + "If the user has the authority of 'Customer User', the server checks that the originator of alarm belongs to the customer. "; | |
63 | + private static final String ALARM_QUERY_SEARCH_STATUS_DESCRIPTION = "A string value representing one of the AlarmSearchStatus enumeration value"; | |
64 | + private static final String ALARM_QUERY_SEARCH_STATUS_ALLOWABLE_VALUES = "ANY, ACTIVE, CLEARED, ACK, UNACK"; | |
65 | + private static final String ALARM_QUERY_STATUS_DESCRIPTION = "A string value representing one of the AlarmStatus enumeration value"; | |
66 | + private static final String ALARM_QUERY_STATUS_ALLOWABLE_VALUES = "ACTIVE_UNACK, ACTIVE_ACK, CLEARED_UNACK, CLEARED_ACK"; | |
67 | + private static final String ALARM_QUERY_TEXT_SEARCH_DESCRIPTION = "The case insensitive 'startsWith' filter based on of next alarm fields: type, severity or status"; | |
68 | + private static final String ALARM_QUERY_START_TIME_DESCRIPTION = "The start timestamp(milliseconds) of the search time range over the alarm object field: 'createdTime'."; | |
69 | + private static final String ALARM_QUERY_END_TIME_DESCRIPTION = "The end timestamp(milliseconds) of the search time range over the alarm object field: 'createdTime'."; | |
70 | + private static final String ALARM_QUERY_FETCH_ORIGINATOR_DESCRIPTION = "A boolean value to specify if the alarm originator name will be " + | |
71 | + "filled in the AlarmInfo object field: 'originatorName' or will returns as null."; | |
58 | 72 | |
59 | - @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") | |
73 | + @ApiOperation(value = "Get Alarm (getAlarmById)", | |
74 | + notes = "Fetch the Alarm object based on the provided Alarm Id. " + ALARM_SECURITY_CHECK, produces = MediaType.APPLICATION_JSON_VALUE) | |
75 | + @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") | |
60 | 76 | @RequestMapping(value = "/alarm/{alarmId}", method = RequestMethod.GET) |
61 | 77 | @ResponseBody |
62 | - public Alarm getAlarmById(@PathVariable(ALARM_ID) String strAlarmId) throws ThingsboardException { | |
78 | + public Alarm getAlarmById(@ApiParam(value = ALARM_ID_PARAM_DESCRIPTION) | |
79 | + @PathVariable(ALARM_ID) String strAlarmId) throws ThingsboardException { | |
63 | 80 | checkParameter(ALARM_ID, strAlarmId); |
64 | 81 | try { |
65 | 82 | AlarmId alarmId = new AlarmId(toUUID(strAlarmId)); |
... | ... | @@ -69,10 +86,14 @@ public class AlarmController extends BaseController { |
69 | 86 | } |
70 | 87 | } |
71 | 88 | |
72 | - @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") | |
89 | + @ApiOperation(value = "Get Alarm Info (getAlarmInfoById)", | |
90 | + notes = "Fetch the Alarm Info object based on the provided Alarm Id. " + | |
91 | + ALARM_SECURITY_CHECK + ALARM_INFO_DESCRIPTION, produces = MediaType.APPLICATION_JSON_VALUE) | |
92 | + @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") | |
73 | 93 | @RequestMapping(value = "/alarm/info/{alarmId}", method = RequestMethod.GET) |
74 | 94 | @ResponseBody |
75 | - public AlarmInfo getAlarmInfoById(@PathVariable(ALARM_ID) String strAlarmId) throws ThingsboardException { | |
95 | + public AlarmInfo getAlarmInfoById(@ApiParam(value = ALARM_ID_PARAM_DESCRIPTION) | |
96 | + @PathVariable(ALARM_ID) String strAlarmId) throws ThingsboardException { | |
76 | 97 | checkParameter(ALARM_ID, strAlarmId); |
77 | 98 | try { |
78 | 99 | AlarmId alarmId = new AlarmId(toUUID(strAlarmId)); |
... | ... | @@ -82,10 +103,20 @@ public class AlarmController extends BaseController { |
82 | 103 | } |
83 | 104 | } |
84 | 105 | |
85 | - @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") | |
106 | + @ApiOperation(value = "Create or update Alarm (saveAlarm)", | |
107 | + notes = "Creates or Updates the Alarm. " + | |
108 | + "When creating alarm, platform generates Alarm Id as [time-based UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_1_(date-time_and_MAC_address). " + | |
109 | + "The newly created Alarm id will be present in the response. Specify existing Alarm id to update the alarm. " + | |
110 | + "Referencing non-existing Alarm Id will cause 'Not Found' error. " + | |
111 | + "\n\nPlatform also deduplicate the alarms based on the entity id of originator and alarm 'type'. " + | |
112 | + "For example, if the user or system component create the alarm with the type 'HighTemperature' for device 'Device A' the new active alarm is created. " + | |
113 | + "If the user tries to create 'HighTemperature' alarm for the same device again, the previous alarm will be updated (the 'end_ts' will be set to current timestamp). " + | |
114 | + "If the user clears the alarm (see 'Clear Alarm(clearAlarm)'), than new alarm with the same type and same device may be created. " | |
115 | + , produces = MediaType.APPLICATION_JSON_VALUE) | |
116 | + @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") | |
86 | 117 | @RequestMapping(value = "/alarm", method = RequestMethod.POST) |
87 | 118 | @ResponseBody |
88 | - public Alarm saveAlarm(@RequestBody Alarm alarm) throws ThingsboardException { | |
119 | + public Alarm saveAlarm(@ApiParam(value = "A JSON value representing the alarm.") @RequestBody Alarm alarm) throws ThingsboardException { | |
89 | 120 | try { |
90 | 121 | alarm.setTenantId(getCurrentUser().getTenantId()); |
91 | 122 | |
... | ... | @@ -106,10 +137,12 @@ public class AlarmController extends BaseController { |
106 | 137 | } |
107 | 138 | } |
108 | 139 | |
109 | - @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") | |
140 | + @ApiOperation(value = "Delete Alarm (deleteAlarm)", | |
141 | + notes = "Deletes the Alarm. Referencing non-existing Alarm Id will cause an error.", produces = MediaType.APPLICATION_JSON_VALUE) | |
142 | + @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") | |
110 | 143 | @RequestMapping(value = "/alarm/{alarmId}", method = RequestMethod.DELETE) |
111 | 144 | @ResponseBody |
112 | - public Boolean deleteAlarm(@PathVariable(ALARM_ID) String strAlarmId) throws ThingsboardException { | |
145 | + public Boolean deleteAlarm(@ApiParam(value = ALARM_ID_PARAM_DESCRIPTION) @PathVariable(ALARM_ID) String strAlarmId) throws ThingsboardException { | |
113 | 146 | checkParameter(ALARM_ID, strAlarmId); |
114 | 147 | try { |
115 | 148 | AlarmId alarmId = new AlarmId(toUUID(strAlarmId)); |
... | ... | @@ -124,15 +157,19 @@ public class AlarmController extends BaseController { |
124 | 157 | sendAlarmDeleteNotificationMsg(getTenantId(), alarmId, relatedEdgeIds, alarm); |
125 | 158 | |
126 | 159 | return alarmService.deleteAlarm(getTenantId(), alarmId); |
127 | - } catch (Exception e) { | |
160 | + } catch (Exception e) { | |
128 | 161 | throw handleException(e); |
129 | 162 | } |
130 | 163 | } |
131 | 164 | |
132 | - @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") | |
165 | + @ApiOperation(value = "Acknowledge Alarm (ackAlarm)", | |
166 | + notes = "Acknowledge the Alarm. " + | |
167 | + "Once acknowledged, the 'ack_ts' field will be set to current timestamp and special rule chain event 'ALARM_ACK' will be generated. " + | |
168 | + "Referencing non-existing Alarm Id will cause an error.", produces = MediaType.APPLICATION_JSON_VALUE) | |
169 | + @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") | |
133 | 170 | @RequestMapping(value = "/alarm/{alarmId}/ack", method = RequestMethod.POST) |
134 | 171 | @ResponseStatus(value = HttpStatus.OK) |
135 | - public void ackAlarm(@PathVariable(ALARM_ID) String strAlarmId) throws ThingsboardException { | |
172 | + public void ackAlarm(@ApiParam(value = ALARM_ID_PARAM_DESCRIPTION) @PathVariable(ALARM_ID) String strAlarmId) throws ThingsboardException { | |
136 | 173 | checkParameter(ALARM_ID, strAlarmId); |
137 | 174 | try { |
138 | 175 | AlarmId alarmId = new AlarmId(toUUID(strAlarmId)); |
... | ... | @@ -149,10 +186,14 @@ public class AlarmController extends BaseController { |
149 | 186 | } |
150 | 187 | } |
151 | 188 | |
152 | - @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") | |
189 | + @ApiOperation(value = "Clear Alarm (clearAlarm)", | |
190 | + notes = "Clear the Alarm. " + | |
191 | + "Once cleared, the 'clear_ts' field will be set to current timestamp and special rule chain event 'ALARM_CLEAR' will be generated. " + | |
192 | + "Referencing non-existing Alarm Id will cause an error.", produces = MediaType.APPLICATION_JSON_VALUE) | |
193 | + @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") | |
153 | 194 | @RequestMapping(value = "/alarm/{alarmId}/clear", method = RequestMethod.POST) |
154 | 195 | @ResponseStatus(value = HttpStatus.OK) |
155 | - public void clearAlarm(@PathVariable(ALARM_ID) String strAlarmId) throws ThingsboardException { | |
196 | + public void clearAlarm(@ApiParam(value = ALARM_ID_PARAM_DESCRIPTION) @PathVariable(ALARM_ID) String strAlarmId) throws ThingsboardException { | |
156 | 197 | checkParameter(ALARM_ID, strAlarmId); |
157 | 198 | try { |
158 | 199 | AlarmId alarmId = new AlarmId(toUUID(strAlarmId)); |
... | ... | @@ -169,21 +210,36 @@ public class AlarmController extends BaseController { |
169 | 210 | } |
170 | 211 | } |
171 | 212 | |
213 | + @ApiOperation(value = "Get Alarms (getAlarms)", | |
214 | + notes = "Returns a page of alarms for the selected entity. Specifying both parameters 'searchStatus' and 'status' at the same time will cause an error. " + | |
215 | + PAGE_DATA_PARAMETERS, produces = MediaType.APPLICATION_JSON_VALUE) | |
172 | 216 | @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") |
173 | 217 | @RequestMapping(value = "/alarm/{entityType}/{entityId}", method = RequestMethod.GET) |
174 | 218 | @ResponseBody |
175 | 219 | public PageData<AlarmInfo> getAlarms( |
176 | - @PathVariable("entityType") String strEntityType, | |
177 | - @PathVariable("entityId") String strEntityId, | |
220 | + @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION) | |
221 | + @PathVariable(ENTITY_TYPE) String strEntityType, | |
222 | + @ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION) | |
223 | + @PathVariable(ENTITY_ID) String strEntityId, | |
224 | + @ApiParam(value = ALARM_QUERY_SEARCH_STATUS_DESCRIPTION, allowableValues = ALARM_QUERY_SEARCH_STATUS_ALLOWABLE_VALUES) | |
178 | 225 | @RequestParam(required = false) String searchStatus, |
226 | + @ApiParam(value = ALARM_QUERY_STATUS_DESCRIPTION, allowableValues = ALARM_QUERY_STATUS_ALLOWABLE_VALUES) | |
179 | 227 | @RequestParam(required = false) String status, |
228 | + @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) | |
180 | 229 | @RequestParam int pageSize, |
230 | + @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) | |
181 | 231 | @RequestParam int page, |
232 | + @ApiParam(value = ALARM_QUERY_TEXT_SEARCH_DESCRIPTION) | |
182 | 233 | @RequestParam(required = false) String textSearch, |
234 | + @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = ALARM_SORT_PROPERTY_ALLOWABLE_VALUES) | |
183 | 235 | @RequestParam(required = false) String sortProperty, |
236 | + @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) | |
184 | 237 | @RequestParam(required = false) String sortOrder, |
238 | + @ApiParam(value = ALARM_QUERY_START_TIME_DESCRIPTION) | |
185 | 239 | @RequestParam(required = false) Long startTime, |
240 | + @ApiParam(value = ALARM_QUERY_END_TIME_DESCRIPTION) | |
186 | 241 | @RequestParam(required = false) Long endTime, |
242 | + @ApiParam(value = ALARM_QUERY_FETCH_ORIGINATOR_DESCRIPTION) | |
187 | 243 | @RequestParam(required = false) Boolean fetchOriginator |
188 | 244 | ) throws ThingsboardException { |
189 | 245 | checkParameter("EntityId", strEntityId); |
... | ... | @@ -204,20 +260,35 @@ public class AlarmController extends BaseController { |
204 | 260 | throw handleException(e); |
205 | 261 | } |
206 | 262 | } |
207 | - | |
208 | - @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") | |
263 | + @ApiOperation(value = "Get All Alarms (getAllAlarms)", | |
264 | + notes = "Returns a page of alarms that belongs to the current user owner. " + | |
265 | + "If the user has the authority of 'Tenant Administrator', the server returns alarms that belongs to the tenant of current user. " + | |
266 | + "If the user has the authority of 'Customer User', the server returns alarms that belongs to the customer of current user. " + | |
267 | + "Specifying both parameters 'searchStatus' and 'status' at the same time will cause an error. " + | |
268 | + PAGE_DATA_PARAMETERS, produces = MediaType.APPLICATION_JSON_VALUE) | |
269 | + @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") | |
209 | 270 | @RequestMapping(value = "/alarms", method = RequestMethod.GET) |
210 | 271 | @ResponseBody |
211 | 272 | public PageData<AlarmInfo> getAllAlarms( |
273 | + @ApiParam(value = ALARM_QUERY_SEARCH_STATUS_DESCRIPTION, allowableValues = ALARM_QUERY_SEARCH_STATUS_ALLOWABLE_VALUES) | |
212 | 274 | @RequestParam(required = false) String searchStatus, |
275 | + @ApiParam(value = ALARM_QUERY_STATUS_DESCRIPTION, allowableValues = ALARM_QUERY_STATUS_ALLOWABLE_VALUES) | |
213 | 276 | @RequestParam(required = false) String status, |
277 | + @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) | |
214 | 278 | @RequestParam int pageSize, |
279 | + @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) | |
215 | 280 | @RequestParam int page, |
281 | + @ApiParam(value = ALARM_QUERY_TEXT_SEARCH_DESCRIPTION) | |
216 | 282 | @RequestParam(required = false) String textSearch, |
283 | + @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = ALARM_SORT_PROPERTY_ALLOWABLE_VALUES) | |
217 | 284 | @RequestParam(required = false) String sortProperty, |
285 | + @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) | |
218 | 286 | @RequestParam(required = false) String sortOrder, |
287 | + @ApiParam(value = ALARM_QUERY_START_TIME_DESCRIPTION) | |
219 | 288 | @RequestParam(required = false) Long startTime, |
289 | + @ApiParam(value = ALARM_QUERY_END_TIME_DESCRIPTION) | |
220 | 290 | @RequestParam(required = false) Long endTime, |
291 | + @ApiParam(value = ALARM_QUERY_FETCH_ORIGINATOR_DESCRIPTION) | |
221 | 292 | @RequestParam(required = false) Boolean fetchOriginator |
222 | 293 | ) throws ThingsboardException { |
223 | 294 | AlarmSearchStatus alarmSearchStatus = StringUtils.isEmpty(searchStatus) ? null : AlarmSearchStatus.valueOf(searchStatus); |
... | ... | @@ -239,13 +310,21 @@ public class AlarmController extends BaseController { |
239 | 310 | } |
240 | 311 | } |
241 | 312 | |
242 | - @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") | |
313 | + @ApiOperation(value = "Get Highest Alarm Severity (getHighestAlarmSeverity)", | |
314 | + notes = "Search the alarms by originator ('entityType' and entityId') and optional 'status' or 'searchStatus' filters and returns the highest AlarmSeverity(CRITICAL, MAJOR, MINOR, WARNING or INDETERMINATE). " + | |
315 | + "Specifying both parameters 'searchStatus' and 'status' at the same time will cause an error." | |
316 | + , produces = MediaType.APPLICATION_JSON_VALUE) | |
317 | + @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") | |
243 | 318 | @RequestMapping(value = "/alarm/highestSeverity/{entityType}/{entityId}", method = RequestMethod.GET) |
244 | 319 | @ResponseBody |
245 | 320 | public AlarmSeverity getHighestAlarmSeverity( |
246 | - @PathVariable("entityType") String strEntityType, | |
247 | - @PathVariable("entityId") String strEntityId, | |
321 | + @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) | |
322 | + @PathVariable(ENTITY_TYPE) String strEntityType, | |
323 | + @ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true) | |
324 | + @PathVariable(ENTITY_ID) String strEntityId, | |
325 | + @ApiParam(value = ALARM_QUERY_SEARCH_STATUS_DESCRIPTION, allowableValues = ALARM_QUERY_SEARCH_STATUS_ALLOWABLE_VALUES) | |
248 | 326 | @RequestParam(required = false) String searchStatus, |
327 | + @ApiParam(value = ALARM_QUERY_STATUS_DESCRIPTION, allowableValues = ALARM_QUERY_STATUS_ALLOWABLE_VALUES) | |
249 | 328 | @RequestParam(required = false) String status |
250 | 329 | ) throws ThingsboardException { |
251 | 330 | checkParameter("EntityId", strEntityId); | ... | ... |
... | ... | @@ -157,6 +157,8 @@ public abstract class BaseController { |
157 | 157 | |
158 | 158 | public static final String CUSTOMER_ID = "customerId"; |
159 | 159 | public static final String TENANT_ID = "tenantId"; |
160 | + public static final String ENTITY_ID = "entityId"; | |
161 | + public static final String ENTITY_TYPE = "entityType"; | |
160 | 162 | |
161 | 163 | public static final String PAGE_DATA_PARAMETERS = "You can specify parameters to filter the results. " + |
162 | 164 | "The result is wrapped with PageData object that allows you to iterate over result set using pagination. " + |
... | ... | @@ -169,6 +171,10 @@ public abstract class BaseController { |
169 | 171 | public static final String CUSTOMER_ID_PARAM_DESCRIPTION = "A string value representing the customer id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'"; |
170 | 172 | public static final String USER_ID_PARAM_DESCRIPTION = "A string value representing the user id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'"; |
171 | 173 | public static final String ASSET_ID_PARAM_DESCRIPTION = "A string value representing the asset id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'"; |
174 | + public static final String ALARM_ID_PARAM_DESCRIPTION = "A string value representing the alarm id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'"; | |
175 | + public static final String ENTITY_ID_PARAM_DESCRIPTION = "A string value representing the entity id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'"; | |
176 | + public static final String ENTITY_TYPE_PARAM_DESCRIPTION = "A string value representing the entity type. For example, 'DEVICE'"; | |
177 | + | |
172 | 178 | |
173 | 179 | protected final String PAGE_SIZE_DESCRIPTION = "Maximum amount of entities in a one page"; |
174 | 180 | protected final String PAGE_NUMBER_DESCRIPTION = "Sequence number of page starting from 0"; |
... | ... | @@ -179,22 +185,29 @@ public abstract class BaseController { |
179 | 185 | protected final String DASHBOARD_TEXT_SEARCH_DESCRIPTION = "The case insensitive 'startsWith' filter based on the dashboard title."; |
180 | 186 | protected final String DEVICE_TEXT_SEARCH_DESCRIPTION = "The case insensitive 'startsWith' filter based on the device name."; |
181 | 187 | protected final String CUSTOMER_TEXT_SEARCH_DESCRIPTION = "The case insensitive 'startsWith' filter based on the customer title."; |
188 | + protected final String EVENT_TEXT_SEARCH_DESCRIPTION = "The value is not used in searching."; | |
182 | 189 | protected final String SORT_PROPERTY_DESCRIPTION = "Property of entity to sort by"; |
183 | 190 | protected final String DASHBOARD_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, title"; |
184 | 191 | protected final String CUSTOMER_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, title, email, country, city"; |
185 | 192 | protected final String DEVICE_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, name, deviceProfileName, label, customerTitle"; |
186 | 193 | protected final String ASSET_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, name, type, label, customerTitle"; |
194 | + protected final String ALARM_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, startTs, endTs, type, ackTs, clearTs, severity, status"; | |
195 | + protected final String EVENT_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, id"; | |
187 | 196 | protected final String SORT_ORDER_DESCRIPTION = "Sort order. ASC (ASCENDING) or DESC (DESCENDING)"; |
188 | 197 | protected final String SORT_ORDER_ALLOWABLE_VALUES = "ASC, DESC"; |
189 | 198 | 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 | 199 | 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 | - protected static final String ENTITY_TYPE_DESCRIPTION = "A string value representing the entity type. For example, 'DEVICE'"; | |
193 | - protected static final String ENTITY_ID_DESCRIPTION = "A string value representing the entity id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'"; | |
200 | + protected final String ALARM_INFO_DESCRIPTION = "Alarm Info is an extension of the default Alarm object that also contains name of the alarm originator."; | |
201 | + protected 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. "; | |
194 | 202 | |
195 | 203 | protected final String DEVICE_NAME_DESCRIPTION = "A string value representing the Device name."; |
196 | 204 | protected final String ASSET_NAME_DESCRIPTION = "A string value representing the Asset name."; |
197 | 205 | |
206 | + protected final String EVENT_START_TIME_DESCRIPTION = "Timestamp. Events with creation time before it won't be queried."; | |
207 | + protected final String EVENT_END_TIME_DESCRIPTION = "Timestamp. Events with creation time after it won't be queried."; | |
208 | + protected static final String RELATION_TYPE_PARAM_DESCRIPTION = "A string value representing relation type between entities. For example, 'Contains', 'Manages'. It can be any string value."; | |
209 | + protected static final String RELATION_TYPE_GROUP_PARAM_DESCRIPTION = "A string value representing relation type group. For example, 'COMMON'"; | |
210 | + | |
198 | 211 | public static final String INCORRECT_TENANT_ID = "Incorrect tenantId "; |
199 | 212 | protected static final String DEFAULT_DASHBOARD = "defaultDashboardId"; |
200 | 213 | protected static final String HOME_DASHBOARD = "homeDashboardId"; | ... | ... |
... | ... | @@ -141,7 +141,8 @@ public class DeviceController extends BaseController { |
141 | 141 | "Device credentials are also generated if not provided in the 'accessToken' request parameter. " + |
142 | 142 | "The newly created device id will be present in the response. " + |
143 | 143 | "Specify existing Device id to update the device. " + |
144 | - "Referencing non-existing device Id will cause 'Not Found' error.") | |
144 | + "Referencing non-existing device Id will cause 'Not Found' error." + | |
145 | + "\n\nDevice name is unique in the scope of tenant. Use unique identifiers like MAC or IMEI for the device names and non-unique 'label' field for user-friendly visualization purposes.") | |
145 | 146 | @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") |
146 | 147 | @RequestMapping(value = "/device", method = RequestMethod.POST) |
147 | 148 | @ResponseBody | ... | ... |
... | ... | @@ -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 org.springframework.http.HttpStatus; |
21 | +import org.springframework.http.MediaType; | |
19 | 22 | import org.springframework.security.access.prepost.PreAuthorize; |
20 | 23 | import org.springframework.web.bind.annotation.RequestBody; |
21 | 24 | import org.springframework.web.bind.annotation.RequestMapping; |
... | ... | @@ -52,10 +55,26 @@ public class EntityRelationController extends BaseController { |
52 | 55 | public static final String RELATION_TYPE = "relationType"; |
53 | 56 | public static final String TO_ID = "toId"; |
54 | 57 | |
58 | + private static final String SECURITY_CHECKS_ENTITIES_DESCRIPTION = "\n\nIf the user has the authority of 'System Administrator', the server checks that 'from' and 'to' entities are owned by the sysadmin. " + | |
59 | + "If the user has the authority of 'Tenant Administrator', the server checks that 'from' and 'to' entities are owned by the same tenant. " + | |
60 | + "If the user has the authority of 'Customer User', the server checks that the 'from' and 'to' entities are assigned to the same customer."; | |
61 | + | |
62 | + private static final String SECURITY_CHECKS_ENTITY_DESCRIPTION = "\n\nIf the user has the authority of 'System Administrator', the server checks that 'from' and 'to' entities are owned by the sysadmin. " + | |
63 | + "If the user has the authority of 'Tenant Administrator', the server checks that the entity is owned by the same tenant. " + | |
64 | + "If the user has the authority of 'Customer User', the server checks that the entity is assigned to the same customer."; | |
65 | + | |
66 | + | |
67 | + @ApiOperation(value = "Create Relation (saveRelation)", | |
68 | + notes = "Creates or updates a relation between two entities in the platform. " + | |
69 | + "Relations unique key is a combination of from/to entity id and relation type group and relation type. " + | |
70 | + "\n\nIf the user has the authority of 'System Administrator', the server checks that 'from' and 'to' entities are owned by the sysadmin. " + | |
71 | + "If the user has the authority of 'Tenant Administrator', the server checks that 'from' and 'to' entities are owned by the same tenant. " + | |
72 | + "If the user has the authority of 'Customer User', the server checks that the 'from' and 'to' entities are assigned to the same customer.") | |
55 | 73 | @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") |
56 | 74 | @RequestMapping(value = "/relation", method = RequestMethod.POST) |
57 | 75 | @ResponseStatus(value = HttpStatus.OK) |
58 | - public void saveRelation(@RequestBody EntityRelation relation) throws ThingsboardException { | |
76 | + public void saveRelation(@ApiParam(value = "A JSON value representing the relation.", required = true) | |
77 | + @RequestBody EntityRelation relation) throws ThingsboardException { | |
59 | 78 | try { |
60 | 79 | checkNotNull(relation); |
61 | 80 | checkEntityId(relation.getFrom(), Operation.WRITE); |
... | ... | @@ -80,14 +99,17 @@ public class EntityRelationController extends BaseController { |
80 | 99 | } |
81 | 100 | } |
82 | 101 | |
102 | + @ApiOperation(value = "Delete Relation (deleteRelation)", | |
103 | + notes = "Deletes a relation between two entities in the platform. " + SECURITY_CHECKS_ENTITIES_DESCRIPTION) | |
83 | 104 | @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") |
84 | 105 | @RequestMapping(value = "/relation", method = RequestMethod.DELETE, params = {FROM_ID, FROM_TYPE, RELATION_TYPE, TO_ID, TO_TYPE}) |
85 | 106 | @ResponseStatus(value = HttpStatus.OK) |
86 | - public void deleteRelation(@RequestParam(FROM_ID) String strFromId, | |
87 | - @RequestParam(FROM_TYPE) String strFromType, | |
88 | - @RequestParam(RELATION_TYPE) String strRelationType, | |
89 | - @RequestParam(value = "relationTypeGroup", required = false) String strRelationTypeGroup, | |
90 | - @RequestParam(TO_ID) String strToId, @RequestParam(TO_TYPE) String strToType) throws ThingsboardException { | |
107 | + public void deleteRelation(@ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true) @RequestParam(FROM_ID) String strFromId, | |
108 | + @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) @RequestParam(FROM_TYPE) String strFromType, | |
109 | + @ApiParam(value = RELATION_TYPE_PARAM_DESCRIPTION, required = true) @RequestParam(RELATION_TYPE) String strRelationType, | |
110 | + @ApiParam(value = RELATION_TYPE_GROUP_PARAM_DESCRIPTION) @RequestParam(value = "relationTypeGroup", required = false) String strRelationTypeGroup, | |
111 | + @ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true) @RequestParam(TO_ID) String strToId, | |
112 | + @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) @RequestParam(TO_TYPE) String strToType) throws ThingsboardException { | |
91 | 113 | checkParameter(FROM_ID, strFromId); |
92 | 114 | checkParameter(FROM_TYPE, strFromType); |
93 | 115 | checkParameter(RELATION_TYPE, strRelationType); |
... | ... | @@ -119,11 +141,14 @@ public class EntityRelationController extends BaseController { |
119 | 141 | } |
120 | 142 | } |
121 | 143 | |
144 | + @ApiOperation(value = "Delete Relations (deleteRelations)", | |
145 | + notes = "Deletes all the relation (both 'from' and 'to' direction) for the specified entity. " + | |
146 | + SECURITY_CHECKS_ENTITY_DESCRIPTION) | |
122 | 147 | @PreAuthorize("hasAnyAuthority('SYS_ADMIN','TENANT_ADMIN', 'CUSTOMER_USER')") |
123 | - @RequestMapping(value = "/relations", method = RequestMethod.DELETE, params = {"id", "type"}) | |
148 | + @RequestMapping(value = "/relations", method = RequestMethod.DELETE, params = {"entityId", "entityType"}) | |
124 | 149 | @ResponseStatus(value = HttpStatus.OK) |
125 | - public void deleteRelations(@RequestParam("entityId") String strId, | |
126 | - @RequestParam("entityType") String strType) throws ThingsboardException { | |
150 | + public void deleteRelations(@ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true) @RequestParam("entityId") String strId, | |
151 | + @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) @RequestParam("entityType") String strType) throws ThingsboardException { | |
127 | 152 | checkParameter("entityId", strId); |
128 | 153 | checkParameter("entityType", strType); |
129 | 154 | EntityId entityId = EntityIdFactory.getByTypeAndId(strType, strId); |
... | ... | @@ -137,14 +162,18 @@ public class EntityRelationController extends BaseController { |
137 | 162 | } |
138 | 163 | } |
139 | 164 | |
165 | + @ApiOperation(value = "Get Relation (getRelation)", | |
166 | + notes = "Returns relation object between two specified entities if present. Otherwise throws exception." + SECURITY_CHECKS_ENTITIES_DESCRIPTION, | |
167 | + produces = MediaType.APPLICATION_JSON_VALUE) | |
140 | 168 | @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") |
141 | 169 | @RequestMapping(value = "/relation", method = RequestMethod.GET, params = {FROM_ID, FROM_TYPE, RELATION_TYPE, TO_ID, TO_TYPE}) |
142 | 170 | @ResponseBody |
143 | - public EntityRelation getRelation(@RequestParam(FROM_ID) String strFromId, | |
144 | - @RequestParam(FROM_TYPE) String strFromType, | |
145 | - @RequestParam(RELATION_TYPE) String strRelationType, | |
146 | - @RequestParam(value = "relationTypeGroup", required = false) String strRelationTypeGroup, | |
147 | - @RequestParam(TO_ID) String strToId, @RequestParam(TO_TYPE) String strToType) throws ThingsboardException { | |
171 | + public EntityRelation getRelation(@ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true) @RequestParam(FROM_ID) String strFromId, | |
172 | + @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) @RequestParam(FROM_TYPE) String strFromType, | |
173 | + @ApiParam(value = RELATION_TYPE_PARAM_DESCRIPTION, required = true) @RequestParam(RELATION_TYPE) String strRelationType, | |
174 | + @ApiParam(value = RELATION_TYPE_GROUP_PARAM_DESCRIPTION) @RequestParam(value = "relationTypeGroup", required = false) String strRelationTypeGroup, | |
175 | + @ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true) @RequestParam(TO_ID) String strToId, | |
176 | + @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) @RequestParam(TO_TYPE) String strToType) throws ThingsboardException { | |
148 | 177 | try { |
149 | 178 | checkParameter(FROM_ID, strFromId); |
150 | 179 | checkParameter(FROM_TYPE, strFromType); |
... | ... | @@ -162,11 +191,16 @@ public class EntityRelationController extends BaseController { |
162 | 191 | } |
163 | 192 | } |
164 | 193 | |
194 | + @ApiOperation(value = "Get List of Relations (findByFrom)", | |
195 | + notes = "Returns list of relation objects for the specified entity by the 'from' direction. " + | |
196 | + SECURITY_CHECKS_ENTITY_DESCRIPTION, | |
197 | + produces = MediaType.APPLICATION_JSON_VALUE) | |
165 | 198 | @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") |
166 | 199 | @RequestMapping(value = "/relations", method = RequestMethod.GET, params = {FROM_ID, FROM_TYPE}) |
167 | 200 | @ResponseBody |
168 | - public List<EntityRelation> findByFrom(@RequestParam(FROM_ID) String strFromId, | |
169 | - @RequestParam(FROM_TYPE) String strFromType, | |
201 | + public List<EntityRelation> findByFrom(@ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true) @RequestParam(FROM_ID) String strFromId, | |
202 | + @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) @RequestParam(FROM_TYPE) String strFromType, | |
203 | + @ApiParam(value = RELATION_TYPE_GROUP_PARAM_DESCRIPTION) | |
170 | 204 | @RequestParam(value = "relationTypeGroup", required = false) String strRelationTypeGroup) throws ThingsboardException { |
171 | 205 | checkParameter(FROM_ID, strFromId); |
172 | 206 | checkParameter(FROM_TYPE, strFromType); |
... | ... | @@ -180,11 +214,16 @@ public class EntityRelationController extends BaseController { |
180 | 214 | } |
181 | 215 | } |
182 | 216 | |
217 | + @ApiOperation(value = "Get List of Relation Infos (findInfoByFrom)", | |
218 | + notes = "Returns list of relation info objects for the specified entity by the 'from' direction. " + | |
219 | + SECURITY_CHECKS_ENTITY_DESCRIPTION +" " + RELATION_INFO_DESCRIPTION, | |
220 | + produces = MediaType.APPLICATION_JSON_VALUE) | |
183 | 221 | @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") |
184 | 222 | @RequestMapping(value = "/relations/info", method = RequestMethod.GET, params = {FROM_ID, FROM_TYPE}) |
185 | 223 | @ResponseBody |
186 | - public List<EntityRelationInfo> findInfoByFrom(@RequestParam(FROM_ID) String strFromId, | |
187 | - @RequestParam(FROM_TYPE) String strFromType, | |
224 | + public List<EntityRelationInfo> findInfoByFrom(@ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true) @RequestParam(FROM_ID) String strFromId, | |
225 | + @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) @RequestParam(FROM_TYPE) String strFromType, | |
226 | + @ApiParam(value = RELATION_TYPE_GROUP_PARAM_DESCRIPTION) | |
188 | 227 | @RequestParam(value = "relationTypeGroup", required = false) String strRelationTypeGroup) throws ThingsboardException { |
189 | 228 | checkParameter(FROM_ID, strFromId); |
190 | 229 | checkParameter(FROM_TYPE, strFromType); |
... | ... | @@ -198,12 +237,17 @@ public class EntityRelationController extends BaseController { |
198 | 237 | } |
199 | 238 | } |
200 | 239 | |
240 | + @ApiOperation(value = "Get List of Relations (findByFrom)", | |
241 | + notes = "Returns list of relation objects for the specified entity by the 'from' direction and relation type. " + | |
242 | + SECURITY_CHECKS_ENTITY_DESCRIPTION, | |
243 | + produces = MediaType.APPLICATION_JSON_VALUE) | |
201 | 244 | @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") |
202 | 245 | @RequestMapping(value = "/relations", method = RequestMethod.GET, params = {FROM_ID, FROM_TYPE, RELATION_TYPE}) |
203 | 246 | @ResponseBody |
204 | - public List<EntityRelation> findByFrom(@RequestParam(FROM_ID) String strFromId, | |
205 | - @RequestParam(FROM_TYPE) String strFromType, | |
206 | - @RequestParam(RELATION_TYPE) String strRelationType, | |
247 | + public List<EntityRelation> findByFrom(@ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true) @RequestParam(FROM_ID) String strFromId, | |
248 | + @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) @RequestParam(FROM_TYPE) String strFromType, | |
249 | + @ApiParam(value = RELATION_TYPE_PARAM_DESCRIPTION, required = true) @RequestParam(RELATION_TYPE) String strRelationType, | |
250 | + @ApiParam(value = RELATION_TYPE_GROUP_PARAM_DESCRIPTION) | |
207 | 251 | @RequestParam(value = "relationTypeGroup", required = false) String strRelationTypeGroup) throws ThingsboardException { |
208 | 252 | checkParameter(FROM_ID, strFromId); |
209 | 253 | checkParameter(FROM_TYPE, strFromType); |
... | ... | @@ -218,11 +262,16 @@ public class EntityRelationController extends BaseController { |
218 | 262 | } |
219 | 263 | } |
220 | 264 | |
265 | + @ApiOperation(value = "Get List of Relations (findByTo)", | |
266 | + notes = "Returns list of relation objects for the specified entity by the 'to' direction. " + | |
267 | + SECURITY_CHECKS_ENTITY_DESCRIPTION, | |
268 | + produces = MediaType.APPLICATION_JSON_VALUE) | |
221 | 269 | @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") |
222 | 270 | @RequestMapping(value = "/relations", method = RequestMethod.GET, params = {TO_ID, TO_TYPE}) |
223 | 271 | @ResponseBody |
224 | - public List<EntityRelation> findByTo(@RequestParam(TO_ID) String strToId, | |
225 | - @RequestParam(TO_TYPE) String strToType, | |
272 | + public List<EntityRelation> findByTo(@ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true) @RequestParam(TO_ID) String strToId, | |
273 | + @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) @RequestParam(TO_TYPE) String strToType, | |
274 | + @ApiParam(value = RELATION_TYPE_GROUP_PARAM_DESCRIPTION) | |
226 | 275 | @RequestParam(value = "relationTypeGroup", required = false) String strRelationTypeGroup) throws ThingsboardException { |
227 | 276 | checkParameter(TO_ID, strToId); |
228 | 277 | checkParameter(TO_TYPE, strToType); |
... | ... | @@ -236,11 +285,16 @@ public class EntityRelationController extends BaseController { |
236 | 285 | } |
237 | 286 | } |
238 | 287 | |
288 | + @ApiOperation(value = "Get List of Relation Infos (findInfoByTo)", | |
289 | + notes = "Returns list of relation info objects for the specified entity by the 'to' direction. " + | |
290 | + SECURITY_CHECKS_ENTITY_DESCRIPTION + " " + RELATION_INFO_DESCRIPTION, | |
291 | + produces = MediaType.APPLICATION_JSON_VALUE) | |
239 | 292 | @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") |
240 | 293 | @RequestMapping(value = "/relations/info", method = RequestMethod.GET, params = {TO_ID, TO_TYPE}) |
241 | 294 | @ResponseBody |
242 | - public List<EntityRelationInfo> findInfoByTo(@RequestParam(TO_ID) String strToId, | |
243 | - @RequestParam(TO_TYPE) String strToType, | |
295 | + public List<EntityRelationInfo> findInfoByTo(@ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true) @RequestParam(TO_ID) String strToId, | |
296 | + @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) @RequestParam(TO_TYPE) String strToType, | |
297 | + @ApiParam(value = RELATION_TYPE_GROUP_PARAM_DESCRIPTION) | |
244 | 298 | @RequestParam(value = "relationTypeGroup", required = false) String strRelationTypeGroup) throws ThingsboardException { |
245 | 299 | checkParameter(TO_ID, strToId); |
246 | 300 | checkParameter(TO_TYPE, strToType); |
... | ... | @@ -254,12 +308,17 @@ public class EntityRelationController extends BaseController { |
254 | 308 | } |
255 | 309 | } |
256 | 310 | |
311 | + @ApiOperation(value = "Get List of Relations (findByTo)", | |
312 | + notes = "Returns list of relation objects for the specified entity by the 'to' direction and relation type. " + | |
313 | + SECURITY_CHECKS_ENTITY_DESCRIPTION, | |
314 | + produces = MediaType.APPLICATION_JSON_VALUE) | |
257 | 315 | @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") |
258 | 316 | @RequestMapping(value = "/relations", method = RequestMethod.GET, params = {TO_ID, TO_TYPE, RELATION_TYPE}) |
259 | 317 | @ResponseBody |
260 | - public List<EntityRelation> findByTo(@RequestParam(TO_ID) String strToId, | |
261 | - @RequestParam(TO_TYPE) String strToType, | |
262 | - @RequestParam(RELATION_TYPE) String strRelationType, | |
318 | + public List<EntityRelation> findByTo(@ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true) @RequestParam(TO_ID) String strToId, | |
319 | + @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) @RequestParam(TO_TYPE) String strToType, | |
320 | + @ApiParam(value = RELATION_TYPE_PARAM_DESCRIPTION, required = true) @RequestParam(RELATION_TYPE) String strRelationType, | |
321 | + @ApiParam(value = RELATION_TYPE_GROUP_PARAM_DESCRIPTION) | |
263 | 322 | @RequestParam(value = "relationTypeGroup", required = false) String strRelationTypeGroup) throws ThingsboardException { |
264 | 323 | checkParameter(TO_ID, strToId); |
265 | 324 | checkParameter(TO_TYPE, strToType); |
... | ... | @@ -274,10 +333,15 @@ public class EntityRelationController extends BaseController { |
274 | 333 | } |
275 | 334 | } |
276 | 335 | |
336 | + @ApiOperation(value = "Find related entities (findByQuery)", | |
337 | + notes = "Returns all entities that are related to the specific entity. " + | |
338 | + "The entity id, relation type, entity types, depth of the search, and other query parameters defined using complex 'EntityRelationsQuery' object. " + | |
339 | + "See 'Model' tab of the Parameters for more info.", produces = MediaType.APPLICATION_JSON_VALUE) | |
277 | 340 | @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") |
278 | 341 | @RequestMapping(value = "/relations", method = RequestMethod.POST) |
279 | 342 | @ResponseBody |
280 | - public List<EntityRelation> findByQuery(@RequestBody EntityRelationsQuery query) throws ThingsboardException { | |
343 | + public List<EntityRelation> findByQuery(@ApiParam(value = "A JSON value representing the entity relations query object.", required = true) | |
344 | + @RequestBody EntityRelationsQuery query) throws ThingsboardException { | |
281 | 345 | checkNotNull(query); |
282 | 346 | checkNotNull(query.getParameters()); |
283 | 347 | checkNotNull(query.getFilters()); |
... | ... | @@ -289,10 +353,15 @@ public class EntityRelationController extends BaseController { |
289 | 353 | } |
290 | 354 | } |
291 | 355 | |
356 | + @ApiOperation(value = "Find related entity infos (findInfoByQuery)", | |
357 | + notes = "Returns all entity infos that are related to the specific entity. " + | |
358 | + "The entity id, relation type, entity types, depth of the search, and other query parameters defined using complex 'EntityRelationsQuery' object. " + | |
359 | + "See 'Model' tab of the Parameters for more info. " + RELATION_INFO_DESCRIPTION, produces = MediaType.APPLICATION_JSON_VALUE) | |
292 | 360 | @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") |
293 | 361 | @RequestMapping(value = "/relations/info", method = RequestMethod.POST) |
294 | 362 | @ResponseBody |
295 | - public List<EntityRelationInfo> findInfoByQuery(@RequestBody EntityRelationsQuery query) throws ThingsboardException { | |
363 | + public List<EntityRelationInfo> findInfoByQuery(@ApiParam(value = "A JSON value representing the entity relations query object.", required = true) | |
364 | + @RequestBody EntityRelationsQuery query) throws ThingsboardException { | |
296 | 365 | checkNotNull(query); |
297 | 366 | checkNotNull(query.getParameters()); |
298 | 367 | checkNotNull(query.getFilters()); | ... | ... |
... | ... | @@ -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 org.springframework.beans.factory.annotation.Autowired; |
21 | +import org.springframework.http.MediaType; | |
19 | 22 | import org.springframework.security.access.prepost.PreAuthorize; |
20 | 23 | import org.springframework.web.bind.annotation.PathVariable; |
21 | 24 | import org.springframework.web.bind.annotation.RequestBody; |
... | ... | @@ -45,20 +48,34 @@ public class EventController extends BaseController { |
45 | 48 | @Autowired |
46 | 49 | private EventService eventService; |
47 | 50 | |
51 | + @ApiOperation(value = "Get Events (getEvents)", | |
52 | + notes = "Returns a page of events for specified entity by specifying event type." + | |
53 | + PAGE_DATA_PARAMETERS, produces = MediaType.APPLICATION_JSON_VALUE) | |
48 | 54 | @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") |
49 | 55 | @RequestMapping(value = "/events/{entityType}/{entityId}/{eventType}", method = RequestMethod.GET) |
50 | 56 | @ResponseBody |
51 | 57 | public PageData<Event> getEvents( |
52 | - @PathVariable("entityType") String strEntityType, | |
53 | - @PathVariable("entityId") String strEntityId, | |
58 | + @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) | |
59 | + @PathVariable(ENTITY_TYPE) String strEntityType, | |
60 | + @ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true) | |
61 | + @PathVariable(ENTITY_ID) String strEntityId, | |
62 | + @ApiParam(value = "A string value representing event type", example = "STATS", required = true) | |
54 | 63 | @PathVariable("eventType") String eventType, |
55 | - @RequestParam("tenantId") String strTenantId, | |
64 | + @ApiParam(value = TENANT_ID_PARAM_DESCRIPTION, required = true) | |
65 | + @RequestParam(TENANT_ID) String strTenantId, | |
66 | + @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) | |
56 | 67 | @RequestParam int pageSize, |
68 | + @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) | |
57 | 69 | @RequestParam int page, |
70 | + @ApiParam(value = EVENT_TEXT_SEARCH_DESCRIPTION) | |
58 | 71 | @RequestParam(required = false) String textSearch, |
72 | + @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = EVENT_SORT_PROPERTY_ALLOWABLE_VALUES) | |
59 | 73 | @RequestParam(required = false) String sortProperty, |
74 | + @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) | |
60 | 75 | @RequestParam(required = false) String sortOrder, |
76 | + @ApiParam(value = EVENT_START_TIME_DESCRIPTION) | |
61 | 77 | @RequestParam(required = false) Long startTime, |
78 | + @ApiParam(value = EVENT_END_TIME_DESCRIPTION) | |
62 | 79 | @RequestParam(required = false) Long endTime) throws ThingsboardException { |
63 | 80 | checkParameter("EntityId", strEntityId); |
64 | 81 | checkParameter("EntityType", strEntityType); |
... | ... | @@ -74,19 +91,32 @@ public class EventController extends BaseController { |
74 | 91 | } |
75 | 92 | } |
76 | 93 | |
94 | + @ApiOperation(value = "Get Events (getEvents)", | |
95 | + notes = "Returns a page of events for specified entity." + | |
96 | + PAGE_DATA_PARAMETERS, produces = MediaType.APPLICATION_JSON_VALUE) | |
77 | 97 | @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") |
78 | 98 | @RequestMapping(value = "/events/{entityType}/{entityId}", method = RequestMethod.GET) |
79 | 99 | @ResponseBody |
80 | 100 | public PageData<Event> getEvents( |
81 | - @PathVariable("entityType") String strEntityType, | |
82 | - @PathVariable("entityId") String strEntityId, | |
101 | + @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) | |
102 | + @PathVariable(ENTITY_TYPE) String strEntityType, | |
103 | + @ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true) | |
104 | + @PathVariable(ENTITY_ID) String strEntityId, | |
105 | + @ApiParam(value = TENANT_ID_PARAM_DESCRIPTION, required = true) | |
83 | 106 | @RequestParam("tenantId") String strTenantId, |
107 | + @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) | |
84 | 108 | @RequestParam int pageSize, |
109 | + @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) | |
85 | 110 | @RequestParam int page, |
111 | + @ApiParam(value = EVENT_TEXT_SEARCH_DESCRIPTION) | |
86 | 112 | @RequestParam(required = false) String textSearch, |
113 | + @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = EVENT_SORT_PROPERTY_ALLOWABLE_VALUES) | |
87 | 114 | @RequestParam(required = false) String sortProperty, |
115 | + @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) | |
88 | 116 | @RequestParam(required = false) String sortOrder, |
117 | + @ApiParam(value = EVENT_START_TIME_DESCRIPTION) | |
89 | 118 | @RequestParam(required = false) Long startTime, |
119 | + @ApiParam(value = EVENT_END_TIME_DESCRIPTION) | |
90 | 120 | @RequestParam(required = false) Long endTime) throws ThingsboardException { |
91 | 121 | checkParameter("EntityId", strEntityId); |
92 | 122 | checkParameter("EntityType", strEntityType); |
... | ... | @@ -104,20 +134,34 @@ public class EventController extends BaseController { |
104 | 134 | } |
105 | 135 | } |
106 | 136 | |
137 | + @ApiOperation(value = "Get Events (getEvents)", | |
138 | + notes = "Returns a page of events for specified entity by specifying event filter." + | |
139 | + PAGE_DATA_PARAMETERS, produces = MediaType.APPLICATION_JSON_VALUE) | |
107 | 140 | @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") |
108 | 141 | @RequestMapping(value = "/events/{entityType}/{entityId}", method = RequestMethod.POST) |
109 | 142 | @ResponseBody |
110 | 143 | public PageData<Event> getEvents( |
111 | - @PathVariable("entityType") String strEntityType, | |
112 | - @PathVariable("entityId") String strEntityId, | |
113 | - @RequestParam("tenantId") String strTenantId, | |
144 | + @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) | |
145 | + @PathVariable(ENTITY_TYPE) String strEntityType, | |
146 | + @ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true) | |
147 | + @PathVariable(ENTITY_ID) String strEntityId, | |
148 | + @ApiParam(value = TENANT_ID_PARAM_DESCRIPTION, required = true) | |
149 | + @RequestParam(TENANT_ID) String strTenantId, | |
150 | + @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) | |
114 | 151 | @RequestParam int pageSize, |
152 | + @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) | |
115 | 153 | @RequestParam int page, |
154 | + @ApiParam(value = "A JSON value representing the event filter.", required = true) | |
116 | 155 | @RequestBody EventFilter eventFilter, |
156 | + @ApiParam(value = EVENT_TEXT_SEARCH_DESCRIPTION) | |
117 | 157 | @RequestParam(required = false) String textSearch, |
158 | + @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = EVENT_SORT_PROPERTY_ALLOWABLE_VALUES) | |
118 | 159 | @RequestParam(required = false) String sortProperty, |
160 | + @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) | |
119 | 161 | @RequestParam(required = false) String sortOrder, |
162 | + @ApiParam(value = EVENT_START_TIME_DESCRIPTION) | |
120 | 163 | @RequestParam(required = false) Long startTime, |
164 | + @ApiParam(value = EVENT_END_TIME_DESCRIPTION) | |
121 | 165 | @RequestParam(required = false) Long endTime) throws ThingsboardException { |
122 | 166 | checkParameter("EntityId", strEntityId); |
123 | 167 | checkParameter("EntityType", strEntityType); |
... | ... | @@ -127,7 +171,7 @@ public class EventController extends BaseController { |
127 | 171 | EntityId entityId = EntityIdFactory.getByTypeAndId(strEntityType, strEntityId); |
128 | 172 | checkEntityId(entityId, Operation.READ); |
129 | 173 | |
130 | - if(sortProperty != null && sortProperty.equals("createdTime") && eventFilter.hasFilterForJsonBody()) { | |
174 | + if (sortProperty != null && sortProperty.equals("createdTime") && eventFilter.hasFilterForJsonBody()) { | |
131 | 175 | sortProperty = ModelConstants.CREATED_TIME_PROPERTY; |
132 | 176 | } |
133 | 177 | ... | ... |
... | ... | @@ -26,6 +26,8 @@ import com.google.common.util.concurrent.MoreExecutors; |
26 | 26 | import com.google.gson.JsonElement; |
27 | 27 | import com.google.gson.JsonParseException; |
28 | 28 | import com.google.gson.JsonParser; |
29 | +import io.swagger.annotations.ApiOperation; | |
30 | +import io.swagger.annotations.ApiParam; | |
29 | 31 | import lombok.extern.slf4j.Slf4j; |
30 | 32 | import org.springframework.beans.factory.annotation.Autowired; |
31 | 33 | import org.springframework.beans.factory.annotation.Value; |
... | ... | @@ -48,7 +50,6 @@ import org.thingsboard.server.common.data.EntityType; |
48 | 50 | import org.thingsboard.server.common.data.TenantProfile; |
49 | 51 | import org.thingsboard.server.common.data.audit.ActionType; |
50 | 52 | import org.thingsboard.server.common.data.exception.ThingsboardException; |
51 | -import org.thingsboard.server.common.data.id.CustomerId; | |
52 | 53 | import org.thingsboard.server.common.data.id.DeviceId; |
53 | 54 | import org.thingsboard.server.common.data.id.EntityId; |
54 | 55 | import org.thingsboard.server.common.data.id.EntityIdFactory; |
... | ... | @@ -108,6 +109,17 @@ import java.util.stream.Collectors; |
108 | 109 | @Slf4j |
109 | 110 | public class TelemetryController extends BaseController { |
110 | 111 | |
112 | + private static final String ATTRIBUTES_SCOPE_DESCRIPTION = "A string value representing the attributes scope. For example, 'SERVER_SCOPE'."; | |
113 | + private static final String ATTRIBUTES_KEYS_DESCRIPTION = "A string value representing the comma-separated list of attributes keys. For example, 'active,inactivityAlarmTime'."; | |
114 | + private static final String ATTRIBUTES_SCOPE_ALLOWED_VALUES = "SERVER_SCOPE, CLIENT_SCOPE, SHARED_SCOPE"; | |
115 | + private static final String ATTRIBUTES_JSON_REQUEST_DESCRIPTION = "A string value representing the json object. For example, '{\"key\":\"value\"}'"; | |
116 | + | |
117 | + private static final String TELEMETRY_KEYS_DESCRIPTION = "A string value representing the comma-separated list of timeseries keys. If keys are not selected, the result will return all latest timeseries. For example, 'temp,humidity'."; | |
118 | + private static final String TELEMETRY_SCOPE_DESCRIPTION = "Value is not used in the API call implementation"; | |
119 | + private static final String TELEMETRY_JSON_REQUEST_DESCRIPTION = "A string value representing the json object. For example, '{\"key\":\"value\"}' or '{\"ts\":1527863043000,\"values\":{\"key1\":\"value1\",\"key2\":\"value2\"}}'"; | |
120 | + | |
121 | + private static final String STRICT_DATA_TYPES_DESCRIPTION = "A boolean value to specify if values of selected timeseries keys will representing a string (by default) or use strict data type."; | |
122 | + | |
111 | 123 | @Autowired |
112 | 124 | private TimeseriesService tsService; |
113 | 125 | |
... | ... | @@ -133,62 +145,81 @@ public class TelemetryController extends BaseController { |
133 | 145 | } |
134 | 146 | } |
135 | 147 | |
148 | + @ApiOperation(value = "Get all attribute keys (getAttributeKeys)", | |
149 | + notes = "Returns key names for the selected entity.") | |
136 | 150 | @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") |
137 | 151 | @RequestMapping(value = "/{entityType}/{entityId}/keys/attributes", method = RequestMethod.GET) |
138 | 152 | @ResponseBody |
139 | 153 | public DeferredResult<ResponseEntity> getAttributeKeys( |
140 | - @PathVariable("entityType") String entityType, @PathVariable("entityId") String entityIdStr) throws ThingsboardException { | |
154 | + @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION) @PathVariable("entityType") String entityType, | |
155 | + @ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION) @PathVariable("entityId") String entityIdStr) throws ThingsboardException { | |
141 | 156 | return accessValidator.validateEntityAndCallback(getCurrentUser(), Operation.READ_ATTRIBUTES, entityType, entityIdStr, this::getAttributeKeysCallback); |
142 | 157 | } |
143 | 158 | |
159 | + @ApiOperation(value = "Get all attributes by scope (getAttributeKeysByScope)", | |
160 | + notes = "Returns key names of specified scope for the selected entity.") | |
144 | 161 | @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") |
145 | 162 | @RequestMapping(value = "/{entityType}/{entityId}/keys/attributes/{scope}", method = RequestMethod.GET) |
146 | 163 | @ResponseBody |
147 | 164 | public DeferredResult<ResponseEntity> getAttributeKeysByScope( |
148 | - @PathVariable("entityType") String entityType, @PathVariable("entityId") String entityIdStr | |
149 | - , @PathVariable("scope") String scope) throws ThingsboardException { | |
165 | + @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION) @PathVariable("entityType") String entityType, | |
166 | + @ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION) @PathVariable("entityId") String entityIdStr, | |
167 | + @ApiParam(value = ATTRIBUTES_SCOPE_DESCRIPTION, allowableValues = ATTRIBUTES_SCOPE_ALLOWED_VALUES) @PathVariable("scope") String scope) throws ThingsboardException { | |
150 | 168 | return accessValidator.validateEntityAndCallback(getCurrentUser(), Operation.READ_ATTRIBUTES, entityType, entityIdStr, |
151 | 169 | (result, tenantId, entityId) -> getAttributeKeysCallback(result, tenantId, entityId, scope)); |
152 | 170 | } |
153 | 171 | |
172 | + @ApiOperation(value = "Get attributes (getAttributes)", | |
173 | + notes = "Returns JSON array of AttributeData objects for the selected entity.") | |
154 | 174 | @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") |
155 | 175 | @RequestMapping(value = "/{entityType}/{entityId}/values/attributes", method = RequestMethod.GET) |
156 | 176 | @ResponseBody |
157 | 177 | public DeferredResult<ResponseEntity> getAttributes( |
158 | - @PathVariable("entityType") String entityType, @PathVariable("entityId") String entityIdStr, | |
159 | - @RequestParam(name = "keys", required = false) String keysStr) throws ThingsboardException { | |
178 | + @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION) @PathVariable("entityType") String entityType, | |
179 | + @ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION) @PathVariable("entityId") String entityIdStr, | |
180 | + @ApiParam(value = ATTRIBUTES_KEYS_DESCRIPTION) @RequestParam(name = "keys", required = false) String keysStr) throws ThingsboardException { | |
160 | 181 | SecurityUser user = getCurrentUser(); |
161 | 182 | return accessValidator.validateEntityAndCallback(getCurrentUser(), Operation.READ_ATTRIBUTES, entityType, entityIdStr, |
162 | 183 | (result, tenantId, entityId) -> getAttributeValuesCallback(result, user, entityId, null, keysStr)); |
163 | 184 | } |
164 | 185 | |
186 | + @ApiOperation(value = "Get attributes by scope (getAttributesByScope)", | |
187 | + notes = "Returns JSON array of AttributeData objects for the selected entity.") | |
165 | 188 | @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") |
166 | 189 | @RequestMapping(value = "/{entityType}/{entityId}/values/attributes/{scope}", method = RequestMethod.GET) |
167 | 190 | @ResponseBody |
168 | 191 | public DeferredResult<ResponseEntity> getAttributesByScope( |
169 | - @PathVariable("entityType") String entityType, @PathVariable("entityId") String entityIdStr, | |
170 | - @PathVariable("scope") String scope, | |
171 | - @RequestParam(name = "keys", required = false) String keysStr) throws ThingsboardException { | |
192 | + @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION) @PathVariable("entityType") String entityType, | |
193 | + @ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION) @PathVariable("entityId") String entityIdStr, | |
194 | + @ApiParam(value = ATTRIBUTES_SCOPE_DESCRIPTION, allowableValues = ATTRIBUTES_SCOPE_ALLOWED_VALUES) @PathVariable("scope") String scope, | |
195 | + @ApiParam(value = ATTRIBUTES_KEYS_DESCRIPTION) @RequestParam(name = "keys", required = false) String keysStr) throws ThingsboardException { | |
172 | 196 | SecurityUser user = getCurrentUser(); |
173 | 197 | return accessValidator.validateEntityAndCallback(getCurrentUser(), Operation.READ_ATTRIBUTES, entityType, entityIdStr, |
174 | 198 | (result, tenantId, entityId) -> getAttributeValuesCallback(result, user, entityId, scope, keysStr)); |
175 | 199 | } |
176 | 200 | |
201 | + @ApiOperation(value = "Get timeseries keys (getTimeseriesKeys)", | |
202 | + notes = "Returns latest timeseries keys for selected entity.") | |
177 | 203 | @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") |
178 | 204 | @RequestMapping(value = "/{entityType}/{entityId}/keys/timeseries", method = RequestMethod.GET) |
179 | 205 | @ResponseBody |
180 | 206 | public DeferredResult<ResponseEntity> getTimeseriesKeys( |
181 | - @PathVariable("entityType") String entityType, @PathVariable("entityId") String entityIdStr) throws ThingsboardException { | |
207 | + @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION) @PathVariable("entityType") String entityType, | |
208 | + @ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION) @PathVariable("entityId") String entityIdStr) throws ThingsboardException { | |
182 | 209 | return accessValidator.validateEntityAndCallback(getCurrentUser(), Operation.READ_TELEMETRY, entityType, entityIdStr, |
183 | 210 | (result, tenantId, entityId) -> Futures.addCallback(tsService.findAllLatest(tenantId, entityId), getTsKeysToResponseCallback(result), MoreExecutors.directExecutor())); |
184 | 211 | } |
185 | 212 | |
213 | + @ApiOperation(value = "Get latest timeseries (getLatestTimeseries)", | |
214 | + notes = "Returns JSON object with mapping latest timeseries keys to JSON arrays of TsData objects for the selected entity.") | |
186 | 215 | @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") |
187 | 216 | @RequestMapping(value = "/{entityType}/{entityId}/values/timeseries", method = RequestMethod.GET) |
188 | 217 | @ResponseBody |
189 | 218 | public DeferredResult<ResponseEntity> getLatestTimeseries( |
190 | - @PathVariable("entityType") String entityType, @PathVariable("entityId") String entityIdStr, | |
191 | - @RequestParam(name = "keys", required = false) String keysStr, | |
219 | + @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION) @PathVariable("entityType") String entityType, | |
220 | + @ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION) @PathVariable("entityId") String entityIdStr, | |
221 | + @ApiParam(value = TELEMETRY_KEYS_DESCRIPTION) @RequestParam(name = "keys", required = false) String keysStr, | |
222 | + @ApiParam(value = STRICT_DATA_TYPES_DESCRIPTION) | |
192 | 223 | @RequestParam(name = "useStrictDataTypes", required = false, defaultValue = "false") Boolean useStrictDataTypes) throws ThingsboardException { |
193 | 224 | SecurityUser user = getCurrentUser(); |
194 | 225 | |
... | ... | @@ -196,20 +227,30 @@ public class TelemetryController extends BaseController { |
196 | 227 | (result, tenantId, entityId) -> getLatestTimeseriesValuesCallback(result, user, entityId, keysStr, useStrictDataTypes)); |
197 | 228 | } |
198 | 229 | |
199 | - | |
230 | + @ApiOperation(value = "Get timeseries (getTimeseries)", | |
231 | + notes = "Returns JSON object with mapping timeseries keys to JSON arrays of TsData objects based on specified filters for the selected entity.") | |
200 | 232 | @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") |
201 | 233 | @RequestMapping(value = "/{entityType}/{entityId}/values/timeseries", method = RequestMethod.GET, params = {"keys", "startTs", "endTs"}) |
202 | 234 | @ResponseBody |
203 | 235 | public DeferredResult<ResponseEntity> getTimeseries( |
204 | - @PathVariable("entityType") String entityType, | |
205 | - @PathVariable("entityId") String entityIdStr, | |
206 | - @RequestParam(name = "keys") String keys, | |
236 | + @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION) @PathVariable("entityType") String entityType, | |
237 | + @ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION) @PathVariable("entityId") String entityIdStr, | |
238 | + @ApiParam(value = TELEMETRY_KEYS_DESCRIPTION) @RequestParam(name = "keys") String keys, | |
239 | + @ApiParam(value = "A long value representing the start timestamp(milliseconds) of search time range.") | |
207 | 240 | @RequestParam(name = "startTs") Long startTs, |
241 | + @ApiParam(value = "A long value representing the end timestamp(milliseconds) of search time range.") | |
208 | 242 | @RequestParam(name = "endTs") Long endTs, |
243 | + @ApiParam(value = "A long value representing the aggregation interval(milliseconds) range.") | |
209 | 244 | @RequestParam(name = "interval", defaultValue = "0") Long interval, |
245 | + @ApiParam(value = "An integer value representing max number of selected data points.", defaultValue = "100") | |
210 | 246 | @RequestParam(name = "limit", defaultValue = "100") Integer limit, |
247 | + @ApiParam(value = "A string value representing the aggregation function. " + | |
248 | + "If the interval is not specified, 'agg' parameter will be converted to 'NONE' value.", | |
249 | + allowableValues = "MIN, MAX, AVG, SUM, COUNT, NONE") | |
211 | 250 | @RequestParam(name = "agg", defaultValue = "NONE") String aggStr, |
251 | + @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) | |
212 | 252 | @RequestParam(name = "orderBy", defaultValue = "DESC") String orderBy, |
253 | + @ApiParam(value = STRICT_DATA_TYPES_DESCRIPTION) | |
213 | 254 | @RequestParam(name = "useStrictDataTypes", required = false, defaultValue = "false") Boolean useStrictDataTypes) throws ThingsboardException { |
214 | 255 | return accessValidator.validateEntityAndCallback(getCurrentUser(), Operation.READ_TELEMETRY, entityType, entityIdStr, |
215 | 256 | (result, tenantId, entityId) -> { |
... | ... | @@ -222,64 +263,89 @@ public class TelemetryController extends BaseController { |
222 | 263 | }); |
223 | 264 | } |
224 | 265 | |
266 | + @ApiOperation(value = "Save or update device attributes (saveDeviceAttributes)") | |
225 | 267 | @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") |
226 | 268 | @RequestMapping(value = "/{deviceId}/{scope}", method = RequestMethod.POST) |
227 | 269 | @ResponseBody |
228 | - public DeferredResult<ResponseEntity> saveDeviceAttributes(@PathVariable("deviceId") String deviceIdStr, @PathVariable("scope") String scope, | |
229 | - @RequestBody JsonNode request) throws ThingsboardException { | |
270 | + public DeferredResult<ResponseEntity> saveDeviceAttributes( | |
271 | + @ApiParam(value = DEVICE_ID_PARAM_DESCRIPTION) @PathVariable("deviceId") String deviceIdStr, | |
272 | + @ApiParam(value = ATTRIBUTES_SCOPE_DESCRIPTION, allowableValues = ATTRIBUTES_SCOPE_ALLOWED_VALUES) @PathVariable("scope") String scope, | |
273 | + @ApiParam(value = ATTRIBUTES_JSON_REQUEST_DESCRIPTION) @RequestBody JsonNode request) throws ThingsboardException { | |
230 | 274 | EntityId entityId = EntityIdFactory.getByTypeAndUuid(EntityType.DEVICE, deviceIdStr); |
231 | 275 | return saveAttributes(getTenantId(), entityId, scope, request); |
232 | 276 | } |
233 | 277 | |
278 | + @ApiOperation(value = "Save or update attributes (saveEntityAttributesV1)") | |
234 | 279 | @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") |
235 | 280 | @RequestMapping(value = "/{entityType}/{entityId}/{scope}", method = RequestMethod.POST) |
236 | 281 | @ResponseBody |
237 | - public DeferredResult<ResponseEntity> saveEntityAttributesV1(@PathVariable("entityType") String entityType, @PathVariable("entityId") String entityIdStr, | |
238 | - @PathVariable("scope") String scope, | |
239 | - @RequestBody JsonNode request) throws ThingsboardException { | |
282 | + public DeferredResult<ResponseEntity> saveEntityAttributesV1( | |
283 | + @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION) @PathVariable("entityType") String entityType, | |
284 | + @ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION) @PathVariable("entityId") String entityIdStr, | |
285 | + @ApiParam(value = ATTRIBUTES_SCOPE_DESCRIPTION, allowableValues = ATTRIBUTES_SCOPE_ALLOWED_VALUES) @PathVariable("scope") String scope, | |
286 | + @ApiParam(value = ATTRIBUTES_JSON_REQUEST_DESCRIPTION) @RequestBody JsonNode request) throws ThingsboardException { | |
240 | 287 | EntityId entityId = EntityIdFactory.getByTypeAndId(entityType, entityIdStr); |
241 | 288 | return saveAttributes(getTenantId(), entityId, scope, request); |
242 | 289 | } |
243 | 290 | |
291 | + @ApiOperation(value = "Save or update attributes (saveEntityAttributesV2)") | |
244 | 292 | @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") |
245 | 293 | @RequestMapping(value = "/{entityType}/{entityId}/attributes/{scope}", method = RequestMethod.POST) |
246 | 294 | @ResponseBody |
247 | - public DeferredResult<ResponseEntity> saveEntityAttributesV2(@PathVariable("entityType") String entityType, @PathVariable("entityId") String entityIdStr, | |
248 | - @PathVariable("scope") String scope, | |
249 | - @RequestBody JsonNode request) throws ThingsboardException { | |
295 | + public DeferredResult<ResponseEntity> saveEntityAttributesV2( | |
296 | + @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION) @PathVariable("entityType") String entityType, | |
297 | + @ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION) @PathVariable("entityId") String entityIdStr, | |
298 | + @ApiParam(value = ATTRIBUTES_SCOPE_DESCRIPTION, allowableValues = ATTRIBUTES_SCOPE_ALLOWED_VALUES) @PathVariable("scope") String scope, | |
299 | + @ApiParam(value = ATTRIBUTES_JSON_REQUEST_DESCRIPTION) @RequestBody JsonNode request) throws ThingsboardException { | |
250 | 300 | EntityId entityId = EntityIdFactory.getByTypeAndId(entityType, entityIdStr); |
251 | 301 | return saveAttributes(getTenantId(), entityId, scope, request); |
252 | 302 | } |
253 | 303 | |
304 | + @ApiOperation(value = "Save or update telemetry (saveEntityTelemetry)") | |
254 | 305 | @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") |
255 | 306 | @RequestMapping(value = "/{entityType}/{entityId}/timeseries/{scope}", method = RequestMethod.POST) |
256 | 307 | @ResponseBody |
257 | - public DeferredResult<ResponseEntity> saveEntityTelemetry(@PathVariable("entityType") String entityType, @PathVariable("entityId") String entityIdStr, | |
258 | - @PathVariable("scope") String scope, | |
259 | - @RequestBody String requestBody) throws ThingsboardException { | |
308 | + public DeferredResult<ResponseEntity> saveEntityTelemetry( | |
309 | + @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION) @PathVariable("entityType") String entityType, | |
310 | + @ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION) @PathVariable("entityId") String entityIdStr, | |
311 | + @ApiParam(value = TELEMETRY_SCOPE_DESCRIPTION) @PathVariable("scope") String scope, | |
312 | + @ApiParam(value = TELEMETRY_JSON_REQUEST_DESCRIPTION) @RequestBody String requestBody) throws ThingsboardException { | |
260 | 313 | EntityId entityId = EntityIdFactory.getByTypeAndId(entityType, entityIdStr); |
261 | 314 | return saveTelemetry(getTenantId(), entityId, requestBody, 0L); |
262 | 315 | } |
263 | 316 | |
317 | + @ApiOperation(value = "Save or update telemetry with TTL (saveEntityTelemetryWithTTL)", | |
318 | + notes = "The TTL parameter is used to extract the number of days to store the data.") | |
264 | 319 | @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") |
265 | 320 | @RequestMapping(value = "/{entityType}/{entityId}/timeseries/{scope}/{ttl}", method = RequestMethod.POST) |
266 | 321 | @ResponseBody |
267 | - public DeferredResult<ResponseEntity> saveEntityTelemetryWithTTL(@PathVariable("entityType") String entityType, @PathVariable("entityId") String entityIdStr, | |
268 | - @PathVariable("scope") String scope, @PathVariable("ttl") Long ttl, | |
269 | - @RequestBody String requestBody) throws ThingsboardException { | |
322 | + public DeferredResult<ResponseEntity> saveEntityTelemetryWithTTL( | |
323 | + @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION) @PathVariable("entityType") String entityType, | |
324 | + @ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION) @PathVariable("entityId") String entityIdStr, | |
325 | + @ApiParam(value = TELEMETRY_SCOPE_DESCRIPTION) @PathVariable("scope") String scope, | |
326 | + @ApiParam(value = "A long value representing TTL(Time to Live) parameter.") @PathVariable("ttl") Long ttl, | |
327 | + @ApiParam(value = TELEMETRY_JSON_REQUEST_DESCRIPTION) @RequestBody String requestBody) throws ThingsboardException { | |
270 | 328 | EntityId entityId = EntityIdFactory.getByTypeAndId(entityType, entityIdStr); |
271 | 329 | return saveTelemetry(getTenantId(), entityId, requestBody, ttl); |
272 | 330 | } |
273 | 331 | |
332 | + @ApiOperation(value = "Delete entity timeseries (deleteEntityTimeseries)", | |
333 | + notes = "Delete timeseries in the specified time range for selected entity.") | |
274 | 334 | @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") |
275 | 335 | @RequestMapping(value = "/{entityType}/{entityId}/timeseries/delete", method = RequestMethod.DELETE) |
276 | 336 | @ResponseBody |
277 | - public DeferredResult<ResponseEntity> deleteEntityTimeseries(@PathVariable("entityType") String entityType, @PathVariable("entityId") String entityIdStr, | |
278 | - @RequestParam(name = "keys") String keysStr, | |
279 | - @RequestParam(name = "deleteAllDataForKeys", defaultValue = "false") boolean deleteAllDataForKeys, | |
280 | - @RequestParam(name = "startTs", required = false) Long startTs, | |
281 | - @RequestParam(name = "endTs", required = false) Long endTs, | |
282 | - @RequestParam(name = "rewriteLatestIfDeleted", defaultValue = "false") boolean rewriteLatestIfDeleted) throws ThingsboardException { | |
337 | + public DeferredResult<ResponseEntity> deleteEntityTimeseries( | |
338 | + @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION) @PathVariable("entityType") String entityType, | |
339 | + @ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION) @PathVariable("entityId") String entityIdStr, | |
340 | + @ApiParam(value = TELEMETRY_KEYS_DESCRIPTION) @RequestParam(name = "keys") String keysStr, | |
341 | + @ApiParam(value = "A boolean value to specify if should be deleted all data for selected keys or only data that are in the selected time range.") | |
342 | + @RequestParam(name = "deleteAllDataForKeys", defaultValue = "false") boolean deleteAllDataForKeys, | |
343 | + @ApiParam(value = "A long value representing the start timestamp(milliseconds) of removal time range.") | |
344 | + @RequestParam(name = "startTs", required = false) Long startTs, | |
345 | + @ApiParam(value = "A long value representing the end timestamp(milliseconds) of removal time range.") | |
346 | + @RequestParam(name = "endTs", required = false) Long endTs, | |
347 | + @ApiParam(value = "If the parameter is set to true, the latest telemetry will be rewritten if the current latest value was removed, otherwise, the new latest value will not set.") | |
348 | + @RequestParam(name = "rewriteLatestIfDeleted", defaultValue = "false") boolean rewriteLatestIfDeleted) throws ThingsboardException { | |
283 | 349 | EntityId entityId = EntityIdFactory.getByTypeAndId(entityType, entityIdStr); |
284 | 350 | return deleteTimeseries(entityId, keysStr, deleteAllDataForKeys, startTs, endTs, rewriteLatestIfDeleted); |
285 | 351 | } |
... | ... | @@ -311,7 +377,6 @@ public class TelemetryController extends BaseController { |
311 | 377 | for (String key : keys) { |
312 | 378 | deleteTsKvQueries.add(new BaseDeleteTsKvQuery(key, deleteFromTs, deleteToTs, rewriteLatestIfDeleted)); |
313 | 379 | } |
314 | - | |
315 | 380 | ListenableFuture<List<Void>> future = tsService.remove(user.getTenantId(), entityId, deleteTsKvQueries); |
316 | 381 | Futures.addCallback(future, new FutureCallback<List<Void>>() { |
317 | 382 | @Override |
... | ... | @@ -329,22 +394,29 @@ public class TelemetryController extends BaseController { |
329 | 394 | }); |
330 | 395 | } |
331 | 396 | |
397 | + @ApiOperation(value = "Delete device attributes (deleteEntityAttributes)", | |
398 | + notes = "Delete attributes of specified scope for selected device.") | |
332 | 399 | @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") |
333 | 400 | @RequestMapping(value = "/{deviceId}/{scope}", method = RequestMethod.DELETE) |
334 | 401 | @ResponseBody |
335 | - public DeferredResult<ResponseEntity> deleteEntityAttributes(@PathVariable("deviceId") String deviceIdStr, | |
336 | - @PathVariable("scope") String scope, | |
337 | - @RequestParam(name = "keys") String keysStr) throws ThingsboardException { | |
402 | + public DeferredResult<ResponseEntity> deleteEntityAttributes( | |
403 | + @ApiParam(value = DEVICE_ID_PARAM_DESCRIPTION) @PathVariable("deviceId") String deviceIdStr, | |
404 | + @ApiParam(value = ATTRIBUTES_SCOPE_DESCRIPTION, allowableValues = ATTRIBUTES_SCOPE_ALLOWED_VALUES) @PathVariable("scope") String scope, | |
405 | + @ApiParam(value = ATTRIBUTES_KEYS_DESCRIPTION) @RequestParam(name = "keys") String keysStr) throws ThingsboardException { | |
338 | 406 | EntityId entityId = EntityIdFactory.getByTypeAndUuid(EntityType.DEVICE, deviceIdStr); |
339 | 407 | return deleteAttributes(entityId, scope, keysStr); |
340 | 408 | } |
341 | 409 | |
410 | + @ApiOperation(value = "Delete entity attributes (deleteEntityAttributes)", | |
411 | + notes = "Delete attributes of specified scope for selected entity.") | |
342 | 412 | @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") |
343 | 413 | @RequestMapping(value = "/{entityType}/{entityId}/{scope}", method = RequestMethod.DELETE) |
344 | 414 | @ResponseBody |
345 | - public DeferredResult<ResponseEntity> deleteEntityAttributes(@PathVariable("entityType") String entityType, @PathVariable("entityId") String entityIdStr, | |
346 | - @PathVariable("scope") String scope, | |
347 | - @RequestParam(name = "keys") String keysStr) throws ThingsboardException { | |
415 | + public DeferredResult<ResponseEntity> deleteEntityAttributes( | |
416 | + @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION) @PathVariable("entityType") String entityType, | |
417 | + @ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION) @PathVariable("entityId") String entityIdStr, | |
418 | + @ApiParam(value = ATTRIBUTES_SCOPE_DESCRIPTION, allowableValues = ATTRIBUTES_SCOPE_ALLOWED_VALUES) @PathVariable("scope") String scope, | |
419 | + @ApiParam(value = ATTRIBUTES_KEYS_DESCRIPTION) @RequestParam(name = "keys") String keysStr) throws ThingsboardException { | |
348 | 420 | EntityId entityId = EntityIdFactory.getByTypeAndId(entityType, entityIdStr); |
349 | 421 | return deleteAttributes(entityId, scope, keysStr); |
350 | 422 | } | ... | ... |
... | ... | @@ -16,6 +16,8 @@ |
16 | 16 | package org.thingsboard.server.common.data; |
17 | 17 | |
18 | 18 | import com.fasterxml.jackson.databind.JsonNode; |
19 | +import io.swagger.annotations.ApiModel; | |
20 | +import io.swagger.annotations.ApiModelProperty; | |
19 | 21 | import lombok.Data; |
20 | 22 | import org.thingsboard.server.common.data.id.EntityId; |
21 | 23 | import org.thingsboard.server.common.data.id.EventId; |
... | ... | @@ -25,12 +27,18 @@ import org.thingsboard.server.common.data.id.TenantId; |
25 | 27 | * @author Andrew Shvayka |
26 | 28 | */ |
27 | 29 | @Data |
30 | +@ApiModel | |
28 | 31 | public class Event extends BaseData<EventId> { |
29 | 32 | |
33 | + @ApiModelProperty(position = 1, value = "JSON object with Tenant Id.", readOnly = true) | |
30 | 34 | private TenantId tenantId; |
35 | + @ApiModelProperty(position = 2, value = "Event type", example = "STATS") | |
31 | 36 | private String type; |
37 | + @ApiModelProperty(position = 3, value = "string", example = "784f394c-42b6-435a-983c-b7beff2784f9") | |
32 | 38 | private String uid; |
39 | + @ApiModelProperty(position = 4, value = "JSON object with Entity Id for which event is created.", readOnly = true) | |
33 | 40 | private EntityId entityId; |
41 | + @ApiModelProperty(position = 5, value = "Event body.", dataType = "com.fasterxml.jackson.databind.JsonNode") | |
34 | 42 | private transient JsonNode body; |
35 | 43 | |
36 | 44 | public Event() { |
... | ... | @@ -45,4 +53,9 @@ public class Event extends BaseData<EventId> { |
45 | 53 | super(event); |
46 | 54 | } |
47 | 55 | |
56 | + @ApiModelProperty(position = 6, value = "Timestamp of the event creation, in milliseconds", example = "1609459200000", readOnly = true) | |
57 | + @Override | |
58 | + public long getCreatedTime() { | |
59 | + return super.getCreatedTime(); | |
60 | + } | |
48 | 61 | } | ... | ... |
... | ... | @@ -17,6 +17,8 @@ package org.thingsboard.server.common.data.alarm; |
17 | 17 | |
18 | 18 | import com.fasterxml.jackson.annotation.JsonProperty; |
19 | 19 | import com.fasterxml.jackson.databind.JsonNode; |
20 | +import io.swagger.annotations.ApiModel; | |
21 | +import io.swagger.annotations.ApiModelProperty; | |
20 | 22 | import lombok.AllArgsConstructor; |
21 | 23 | import lombok.Builder; |
22 | 24 | import lombok.Data; |
... | ... | @@ -34,23 +36,41 @@ import java.util.List; |
34 | 36 | /** |
35 | 37 | * Created by ashvayka on 11.05.17. |
36 | 38 | */ |
39 | +@ApiModel | |
37 | 40 | @Data |
38 | 41 | @Builder |
39 | 42 | @AllArgsConstructor |
40 | 43 | public class Alarm extends BaseData<AlarmId> implements HasName, HasTenantId, HasCustomerId { |
41 | 44 | |
45 | + @ApiModelProperty(position = 3, value = "JSON object with Tenant Id", readOnly = true) | |
42 | 46 | private TenantId tenantId; |
47 | + | |
48 | + @ApiModelProperty(position = 4, value = "JSON object with Customer Id", readOnly = true) | |
43 | 49 | private CustomerId customerId; |
50 | + | |
51 | + @ApiModelProperty(position = 6, required = true, value = "representing type of the Alarm", example = "High Temperature Alarm") | |
44 | 52 | private String type; |
53 | + @ApiModelProperty(position = 7, required = true, value = "JSON object with alarm originator id") | |
45 | 54 | private EntityId originator; |
55 | + @ApiModelProperty(position = 8, required = true, value = "Alarm severity", example = "CRITICAL") | |
46 | 56 | private AlarmSeverity severity; |
57 | + @ApiModelProperty(position = 9, required = true, value = "Alarm status", example = "CLEARED_UNACK") | |
47 | 58 | private AlarmStatus status; |
59 | + @ApiModelProperty(position = 10, value = "Timestamp of the alarm start time, in milliseconds", example = "1634058704565") | |
48 | 60 | private long startTs; |
61 | + @ApiModelProperty(position = 11, value = "Timestamp of the alarm end time(last time update), in milliseconds", example = "1634111163522") | |
49 | 62 | private long endTs; |
63 | + @ApiModelProperty(position = 12, value = "Timestamp of the alarm acknowledgement, in milliseconds", example = "1634115221948") | |
50 | 64 | private long ackTs; |
65 | + @ApiModelProperty(position = 13, value = "Timestamp of the alarm clearing, in milliseconds", example = "1634114528465") | |
51 | 66 | private long clearTs; |
67 | + @ApiModelProperty(position = 14, value = "JSON object with alarm details") | |
52 | 68 | private transient JsonNode details; |
69 | + @ApiModelProperty(position = 15, value = "Propagation flag to specify if alarm should be propagated to parent entities of alarm originator", example = "true") | |
53 | 70 | private boolean propagate; |
71 | + @ApiModelProperty(position = 16, value = "JSON array of relation types that should be used for propagation. " + | |
72 | + "By default, 'propagateRelationTypes' array is empty which means that the alarm will propagate based on any relation type to parent entities. " + | |
73 | + "This parameter should be used only in case when 'propagate' parameter is set to true, otherwise, 'propagateRelationTypes' array will ignoned.") | |
54 | 74 | private List<String> propagateRelationTypes; |
55 | 75 | |
56 | 76 | public Alarm() { |
... | ... | @@ -81,7 +101,25 @@ public class Alarm extends BaseData<AlarmId> implements HasName, HasTenantId, Ha |
81 | 101 | |
82 | 102 | @Override |
83 | 103 | @JsonProperty(access = JsonProperty.Access.READ_ONLY) |
104 | + @ApiModelProperty(position = 5, required = true, value = "representing type of the Alarm", example = "High Temperature Alarm") | |
84 | 105 | public String getName() { |
85 | 106 | return type; |
86 | 107 | } |
108 | + | |
109 | + @ApiModelProperty(position = 1, value = "JSON object with the alarm Id. " + | |
110 | + "Specify this field to update the alarm. " + | |
111 | + "Referencing non-existing alarm Id will cause error. " + | |
112 | + "Omit this field to create new alarm." ) | |
113 | + @Override | |
114 | + public AlarmId getId() { | |
115 | + return super.getId(); | |
116 | + } | |
117 | + | |
118 | + | |
119 | + @ApiModelProperty(position = 2, value = "Timestamp of the alarm creation, in milliseconds", example = "1634058704567", readOnly = true) | |
120 | + @Override | |
121 | + public long getCreatedTime() { | |
122 | + return super.getCreatedTime(); | |
123 | + } | |
124 | + | |
87 | 125 | } | ... | ... |
... | ... | @@ -15,10 +15,15 @@ |
15 | 15 | */ |
16 | 16 | package org.thingsboard.server.common.data.alarm; |
17 | 17 | |
18 | +import io.swagger.annotations.ApiModel; | |
19 | +import io.swagger.annotations.ApiModelProperty; | |
20 | + | |
21 | +@ApiModel | |
18 | 22 | public class AlarmInfo extends Alarm { |
19 | 23 | |
20 | 24 | private static final long serialVersionUID = 2807343093519543363L; |
21 | 25 | |
26 | + @ApiModelProperty(position = 17, value = "Alarm originator name", example = "Thermostat") | |
22 | 27 | private String originatorName; |
23 | 28 | |
24 | 29 | public AlarmInfo() { | ... | ... |
... | ... | @@ -15,10 +15,12 @@ |
15 | 15 | */ |
16 | 16 | package org.thingsboard.server.common.data.event; |
17 | 17 | |
18 | +import io.swagger.annotations.ApiModel; | |
18 | 19 | import lombok.Data; |
19 | 20 | import org.thingsboard.server.common.data.StringUtils; |
20 | 21 | |
21 | 22 | @Data |
23 | +@ApiModel | |
22 | 24 | public abstract class DebugEvent implements EventFilter { |
23 | 25 | |
24 | 26 | private String msgDirectionType; | ... | ... |
... | ... | @@ -15,10 +15,12 @@ |
15 | 15 | */ |
16 | 16 | package org.thingsboard.server.common.data.event; |
17 | 17 | |
18 | +import io.swagger.annotations.ApiModel; | |
18 | 19 | import lombok.Data; |
19 | 20 | import org.thingsboard.server.common.data.StringUtils; |
20 | 21 | |
21 | 22 | @Data |
23 | +@ApiModel | |
22 | 24 | public class ErrorEventFilter implements EventFilter { |
23 | 25 | private String server; |
24 | 26 | private String method; | ... | ... |
... | ... | @@ -16,10 +16,11 @@ |
16 | 16 | package org.thingsboard.server.common.data.event; |
17 | 17 | |
18 | 18 | import com.fasterxml.jackson.annotation.JsonIgnore; |
19 | -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; | |
20 | 19 | import com.fasterxml.jackson.annotation.JsonSubTypes; |
21 | 20 | import com.fasterxml.jackson.annotation.JsonTypeInfo; |
21 | +import io.swagger.annotations.ApiModel; | |
22 | 22 | |
23 | +@ApiModel | |
23 | 24 | @JsonTypeInfo( |
24 | 25 | use = JsonTypeInfo.Id.NAME, |
25 | 26 | include = JsonTypeInfo.As.PROPERTY, | ... | ... |
... | ... | @@ -15,10 +15,12 @@ |
15 | 15 | */ |
16 | 16 | package org.thingsboard.server.common.data.event; |
17 | 17 | |
18 | +import io.swagger.annotations.ApiModel; | |
18 | 19 | import lombok.Data; |
19 | 20 | import org.thingsboard.server.common.data.StringUtils; |
20 | 21 | |
21 | 22 | @Data |
23 | +@ApiModel | |
22 | 24 | public class LifeCycleEventFilter implements EventFilter { |
23 | 25 | private String server; |
24 | 26 | private String event; | ... | ... |
... | ... | @@ -15,10 +15,12 @@ |
15 | 15 | */ |
16 | 16 | package org.thingsboard.server.common.data.event; |
17 | 17 | |
18 | +import io.swagger.annotations.ApiModel; | |
18 | 19 | import lombok.Data; |
19 | 20 | import org.thingsboard.server.common.data.StringUtils; |
20 | 21 | |
21 | 22 | @Data |
23 | +@ApiModel | |
22 | 24 | public class StatisticsEventFilter implements EventFilter { |
23 | 25 | private String server; |
24 | 26 | private Integer messagesProcessed; | ... | ... |
... | ... | @@ -18,6 +18,8 @@ package org.thingsboard.server.common.data.id; |
18 | 18 | import com.fasterxml.jackson.annotation.JsonIgnore; |
19 | 19 | import com.fasterxml.jackson.databind.annotation.JsonDeserialize; |
20 | 20 | import com.fasterxml.jackson.databind.annotation.JsonSerialize; |
21 | +import io.swagger.annotations.ApiModel; | |
22 | +import io.swagger.annotations.ApiModelProperty; | |
21 | 23 | import org.thingsboard.server.common.data.EntityType; |
22 | 24 | |
23 | 25 | import java.io.Serializable; |
... | ... | @@ -29,12 +31,15 @@ import java.util.UUID; |
29 | 31 | |
30 | 32 | @JsonDeserialize(using = EntityIdDeserializer.class) |
31 | 33 | @JsonSerialize(using = EntityIdSerializer.class) |
34 | +@ApiModel | |
32 | 35 | public interface EntityId extends HasUUID, Serializable { //NOSONAR, the constant is closely related to EntityId |
33 | 36 | |
34 | 37 | UUID NULL_UUID = UUID.fromString("13814000-1dd2-11b2-8080-808080808080"); |
35 | 38 | |
39 | + @ApiModelProperty(position = 1, required = true, value = "string", example = "784f394c-42b6-435a-983c-b7beff2784f9") | |
36 | 40 | UUID getId(); |
37 | 41 | |
42 | + @ApiModelProperty(position = 2, required = true, value = "string", example = "DEVICE") | |
38 | 43 | EntityType getEntityType(); |
39 | 44 | |
40 | 45 | @JsonIgnore | ... | ... |
... | ... | @@ -16,18 +16,17 @@ |
16 | 16 | package org.thingsboard.server.common.data.relation; |
17 | 17 | |
18 | 18 | import com.fasterxml.jackson.annotation.JsonIgnore; |
19 | -import com.fasterxml.jackson.core.JsonProcessingException; | |
20 | 19 | import com.fasterxml.jackson.databind.JsonNode; |
21 | -import com.fasterxml.jackson.databind.ObjectMapper; | |
20 | +import io.swagger.annotations.ApiModel; | |
21 | +import io.swagger.annotations.ApiModelProperty; | |
22 | 22 | import lombok.extern.slf4j.Slf4j; |
23 | 23 | import org.thingsboard.server.common.data.SearchTextBasedWithAdditionalInfo; |
24 | 24 | import org.thingsboard.server.common.data.id.EntityId; |
25 | 25 | |
26 | -import java.io.ByteArrayInputStream; | |
27 | -import java.io.IOException; | |
28 | 26 | import java.io.Serializable; |
29 | 27 | |
30 | 28 | @Slf4j |
29 | +@ApiModel | |
31 | 30 | public class EntityRelation implements Serializable { |
32 | 31 | |
33 | 32 | private static final long serialVersionUID = 2807343040519543363L; |
... | ... | @@ -72,6 +71,7 @@ public class EntityRelation implements Serializable { |
72 | 71 | this.additionalInfo = entityRelation.getAdditionalInfo(); |
73 | 72 | } |
74 | 73 | |
74 | + @ApiModelProperty(position = 1, value = "JSON object with [from] Entity Id.", readOnly = true) | |
75 | 75 | public EntityId getFrom() { |
76 | 76 | return from; |
77 | 77 | } |
... | ... | @@ -80,6 +80,7 @@ public class EntityRelation implements Serializable { |
80 | 80 | this.from = from; |
81 | 81 | } |
82 | 82 | |
83 | + @ApiModelProperty(position = 2, value = "JSON object with [to] Entity Id.", readOnly = true) | |
83 | 84 | public EntityId getTo() { |
84 | 85 | return to; |
85 | 86 | } |
... | ... | @@ -88,6 +89,7 @@ public class EntityRelation implements Serializable { |
88 | 89 | this.to = to; |
89 | 90 | } |
90 | 91 | |
92 | + @ApiModelProperty(position = 3, value = "String value of relation type.", example = "Contains") | |
91 | 93 | public String getType() { |
92 | 94 | return type; |
93 | 95 | } |
... | ... | @@ -96,6 +98,7 @@ public class EntityRelation implements Serializable { |
96 | 98 | this.type = type; |
97 | 99 | } |
98 | 100 | |
101 | + @ApiModelProperty(position = 4, value = "Represents the type group of the relation.", example = "COMMON") | |
99 | 102 | public RelationTypeGroup getTypeGroup() { |
100 | 103 | return typeGroup; |
101 | 104 | } |
... | ... | @@ -104,6 +107,7 @@ public class EntityRelation implements Serializable { |
104 | 107 | this.typeGroup = typeGroup; |
105 | 108 | } |
106 | 109 | |
110 | + @ApiModelProperty(position = 5, value = "Additional parameters of the relation", dataType = "com.fasterxml.jackson.databind.JsonNode") | |
107 | 111 | public JsonNode getAdditionalInfo() { |
108 | 112 | return SearchTextBasedWithAdditionalInfo.getJson(() -> additionalInfo, () -> additionalInfoBytes); |
109 | 113 | } | ... | ... |
... | ... | @@ -15,6 +15,8 @@ |
15 | 15 | */ |
16 | 16 | package org.thingsboard.server.common.data.relation; |
17 | 17 | |
18 | +import io.swagger.annotations.ApiModelProperty; | |
19 | + | |
18 | 20 | public class EntityRelationInfo extends EntityRelation { |
19 | 21 | |
20 | 22 | private static final long serialVersionUID = 2807343097519543363L; |
... | ... | @@ -30,6 +32,7 @@ public class EntityRelationInfo extends EntityRelation { |
30 | 32 | super(entityRelation); |
31 | 33 | } |
32 | 34 | |
35 | + @ApiModelProperty(position = 6, value = "Name of the entity for [from] direction.", readOnly = true, example = "A4B72CCDFF33") | |
33 | 36 | public String getFromName() { |
34 | 37 | return fromName; |
35 | 38 | } |
... | ... | @@ -38,6 +41,7 @@ public class EntityRelationInfo extends EntityRelation { |
38 | 41 | this.fromName = fromName; |
39 | 42 | } |
40 | 43 | |
44 | + @ApiModelProperty(position = 7, value = "Name of the entity for [to] direction.", readOnly = true, example = "A4B72CCDFF35") | |
41 | 45 | public String getToName() { |
42 | 46 | return toName; |
43 | 47 | } | ... | ... |
... | ... | @@ -15,6 +15,8 @@ |
15 | 15 | */ |
16 | 16 | package org.thingsboard.server.common.data.relation; |
17 | 17 | |
18 | +import io.swagger.annotations.ApiModel; | |
19 | +import io.swagger.annotations.ApiModelProperty; | |
18 | 20 | import lombok.Data; |
19 | 21 | |
20 | 22 | import java.util.List; |
... | ... | @@ -23,9 +25,12 @@ import java.util.List; |
23 | 25 | * Created by ashvayka on 02.05.17. |
24 | 26 | */ |
25 | 27 | @Data |
28 | +@ApiModel | |
26 | 29 | public class EntityRelationsQuery { |
27 | 30 | |
31 | + @ApiModelProperty(position = 2, value = "Main search parameters.") | |
28 | 32 | private RelationsSearchParameters parameters; |
33 | + @ApiModelProperty(position = 1, value = "Main filters.") | |
29 | 34 | private List<RelationEntityTypeFilter> filters; |
30 | 35 | |
31 | 36 | } | ... | ... |
... | ... | @@ -15,6 +15,8 @@ |
15 | 15 | */ |
16 | 16 | package org.thingsboard.server.common.data.relation; |
17 | 17 | |
18 | +import io.swagger.annotations.ApiModel; | |
19 | +import io.swagger.annotations.ApiModelProperty; | |
18 | 20 | import lombok.AllArgsConstructor; |
19 | 21 | import lombok.Data; |
20 | 22 | import org.thingsboard.server.common.data.EntityType; |
... | ... | @@ -26,9 +28,12 @@ import java.util.List; |
26 | 28 | */ |
27 | 29 | @Data |
28 | 30 | @AllArgsConstructor |
31 | +@ApiModel | |
29 | 32 | public class RelationEntityTypeFilter { |
30 | 33 | |
34 | + @ApiModelProperty(position = 1, value = "Type of the relation between root entity and other entity (e.g. 'Contains' or 'Manages').", example = "Contains") | |
31 | 35 | private String relationType; |
32 | 36 | |
37 | + @ApiModelProperty(position = 2, value = "Array of entity types to filter the related entities (e.g. 'DEVICE', 'ASSET').") | |
33 | 38 | private List<EntityType> entityTypes; |
34 | 39 | } | ... | ... |
common/data/src/main/java/org/thingsboard/server/common/data/relation/RelationsSearchParameters.java
... | ... | @@ -15,6 +15,7 @@ |
15 | 15 | */ |
16 | 16 | package org.thingsboard.server.common.data.relation; |
17 | 17 | |
18 | +import com.fasterxml.jackson.annotation.JsonIgnore; | |
18 | 19 | import io.swagger.annotations.ApiModel; |
19 | 20 | import io.swagger.annotations.ApiModelProperty; |
20 | 21 | import lombok.AllArgsConstructor; |
... | ... | @@ -33,7 +34,7 @@ import java.util.UUID; |
33 | 34 | @AllArgsConstructor |
34 | 35 | public class RelationsSearchParameters { |
35 | 36 | |
36 | - @ApiModelProperty(position = 1, value = "Root entity id to start search from.") | |
37 | + @ApiModelProperty(position = 1, value = "Root entity id to start search from.", example = "784f394c-42b6-435a-983c-b7beff2784f9") | |
37 | 38 | private UUID rootId; |
38 | 39 | @ApiModelProperty(position = 2, value = "Type of the root entity.") |
39 | 40 | private EntityType rootType; |
... | ... | @@ -59,6 +60,7 @@ public class RelationsSearchParameters { |
59 | 60 | this.fetchLastLevelOnly = fetchLastLevelOnly; |
60 | 61 | } |
61 | 62 | |
63 | + @JsonIgnore | |
62 | 64 | public EntityId getEntityId() { |
63 | 65 | return EntityIdFactory.getByTypeAndUuid(rootType, rootId); |
64 | 66 | } | ... | ... |