Commit fe70b091b6b799083d21d8b3c9dc784c2a508c87

Authored by ShvaykaD
2 parents 4aef4404 4783d7dd

merge with upstream

Showing 22 changed files with 486 additions and 112 deletions
@@ -15,8 +15,11 @@ @@ -15,8 +15,11 @@
15 */ 15 */
16 package org.thingsboard.server.controller; 16 package org.thingsboard.server.controller;
17 17
  18 +import io.swagger.annotations.ApiOperation;
  19 +import io.swagger.annotations.ApiParam;
18 import org.apache.commons.lang3.StringUtils; 20 import org.apache.commons.lang3.StringUtils;
19 import org.springframework.http.HttpStatus; 21 import org.springframework.http.HttpStatus;
  22 +import org.springframework.http.MediaType;
20 import org.springframework.security.access.prepost.PreAuthorize; 23 import org.springframework.security.access.prepost.PreAuthorize;
21 import org.springframework.web.bind.annotation.PathVariable; 24 import org.springframework.web.bind.annotation.PathVariable;
22 import org.springframework.web.bind.annotation.RequestBody; 25 import org.springframework.web.bind.annotation.RequestBody;
@@ -55,11 +58,25 @@ import java.util.List; @@ -55,11 +58,25 @@ import java.util.List;
55 public class AlarmController extends BaseController { 58 public class AlarmController extends BaseController {
56 59
57 public static final String ALARM_ID = "alarmId"; 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 @RequestMapping(value = "/alarm/{alarmId}", method = RequestMethod.GET) 76 @RequestMapping(value = "/alarm/{alarmId}", method = RequestMethod.GET)
61 @ResponseBody 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 checkParameter(ALARM_ID, strAlarmId); 80 checkParameter(ALARM_ID, strAlarmId);
64 try { 81 try {
65 AlarmId alarmId = new AlarmId(toUUID(strAlarmId)); 82 AlarmId alarmId = new AlarmId(toUUID(strAlarmId));
@@ -69,10 +86,14 @@ public class AlarmController extends BaseController { @@ -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 @RequestMapping(value = "/alarm/info/{alarmId}", method = RequestMethod.GET) 93 @RequestMapping(value = "/alarm/info/{alarmId}", method = RequestMethod.GET)
74 @ResponseBody 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 checkParameter(ALARM_ID, strAlarmId); 97 checkParameter(ALARM_ID, strAlarmId);
77 try { 98 try {
78 AlarmId alarmId = new AlarmId(toUUID(strAlarmId)); 99 AlarmId alarmId = new AlarmId(toUUID(strAlarmId));
@@ -82,10 +103,20 @@ public class AlarmController extends BaseController { @@ -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 @RequestMapping(value = "/alarm", method = RequestMethod.POST) 117 @RequestMapping(value = "/alarm", method = RequestMethod.POST)
87 @ResponseBody 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 try { 120 try {
90 alarm.setTenantId(getCurrentUser().getTenantId()); 121 alarm.setTenantId(getCurrentUser().getTenantId());
91 122
@@ -106,10 +137,12 @@ public class AlarmController extends BaseController { @@ -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 @RequestMapping(value = "/alarm/{alarmId}", method = RequestMethod.DELETE) 143 @RequestMapping(value = "/alarm/{alarmId}", method = RequestMethod.DELETE)
111 @ResponseBody 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 checkParameter(ALARM_ID, strAlarmId); 146 checkParameter(ALARM_ID, strAlarmId);
114 try { 147 try {
115 AlarmId alarmId = new AlarmId(toUUID(strAlarmId)); 148 AlarmId alarmId = new AlarmId(toUUID(strAlarmId));
@@ -124,15 +157,19 @@ public class AlarmController extends BaseController { @@ -124,15 +157,19 @@ public class AlarmController extends BaseController {
124 sendAlarmDeleteNotificationMsg(getTenantId(), alarmId, relatedEdgeIds, alarm); 157 sendAlarmDeleteNotificationMsg(getTenantId(), alarmId, relatedEdgeIds, alarm);
125 158
126 return alarmService.deleteAlarm(getTenantId(), alarmId); 159 return alarmService.deleteAlarm(getTenantId(), alarmId);
127 - } catch (Exception e) { 160 + } catch (Exception e) {
128 throw handleException(e); 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 @RequestMapping(value = "/alarm/{alarmId}/ack", method = RequestMethod.POST) 170 @RequestMapping(value = "/alarm/{alarmId}/ack", method = RequestMethod.POST)
134 @ResponseStatus(value = HttpStatus.OK) 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 checkParameter(ALARM_ID, strAlarmId); 173 checkParameter(ALARM_ID, strAlarmId);
137 try { 174 try {
138 AlarmId alarmId = new AlarmId(toUUID(strAlarmId)); 175 AlarmId alarmId = new AlarmId(toUUID(strAlarmId));
@@ -149,10 +186,14 @@ public class AlarmController extends BaseController { @@ -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 @RequestMapping(value = "/alarm/{alarmId}/clear", method = RequestMethod.POST) 194 @RequestMapping(value = "/alarm/{alarmId}/clear", method = RequestMethod.POST)
154 @ResponseStatus(value = HttpStatus.OK) 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 checkParameter(ALARM_ID, strAlarmId); 197 checkParameter(ALARM_ID, strAlarmId);
157 try { 198 try {
158 AlarmId alarmId = new AlarmId(toUUID(strAlarmId)); 199 AlarmId alarmId = new AlarmId(toUUID(strAlarmId));
@@ -169,21 +210,36 @@ public class AlarmController extends BaseController { @@ -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 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") 216 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
173 @RequestMapping(value = "/alarm/{entityType}/{entityId}", method = RequestMethod.GET) 217 @RequestMapping(value = "/alarm/{entityType}/{entityId}", method = RequestMethod.GET)
174 @ResponseBody 218 @ResponseBody
175 public PageData<AlarmInfo> getAlarms( 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 @RequestParam(required = false) String searchStatus, 225 @RequestParam(required = false) String searchStatus,
  226 + @ApiParam(value = ALARM_QUERY_STATUS_DESCRIPTION, allowableValues = ALARM_QUERY_STATUS_ALLOWABLE_VALUES)
179 @RequestParam(required = false) String status, 227 @RequestParam(required = false) String status,
  228 + @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true)
180 @RequestParam int pageSize, 229 @RequestParam int pageSize,
  230 + @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true)
181 @RequestParam int page, 231 @RequestParam int page,
  232 + @ApiParam(value = ALARM_QUERY_TEXT_SEARCH_DESCRIPTION)
182 @RequestParam(required = false) String textSearch, 233 @RequestParam(required = false) String textSearch,
  234 + @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = ALARM_SORT_PROPERTY_ALLOWABLE_VALUES)
183 @RequestParam(required = false) String sortProperty, 235 @RequestParam(required = false) String sortProperty,
  236 + @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES)
184 @RequestParam(required = false) String sortOrder, 237 @RequestParam(required = false) String sortOrder,
  238 + @ApiParam(value = ALARM_QUERY_START_TIME_DESCRIPTION)
185 @RequestParam(required = false) Long startTime, 239 @RequestParam(required = false) Long startTime,
  240 + @ApiParam(value = ALARM_QUERY_END_TIME_DESCRIPTION)
186 @RequestParam(required = false) Long endTime, 241 @RequestParam(required = false) Long endTime,
  242 + @ApiParam(value = ALARM_QUERY_FETCH_ORIGINATOR_DESCRIPTION)
187 @RequestParam(required = false) Boolean fetchOriginator 243 @RequestParam(required = false) Boolean fetchOriginator
188 ) throws ThingsboardException { 244 ) throws ThingsboardException {
189 checkParameter("EntityId", strEntityId); 245 checkParameter("EntityId", strEntityId);
@@ -204,20 +260,35 @@ public class AlarmController extends BaseController { @@ -204,20 +260,35 @@ public class AlarmController extends BaseController {
204 throw handleException(e); 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 @RequestMapping(value = "/alarms", method = RequestMethod.GET) 270 @RequestMapping(value = "/alarms", method = RequestMethod.GET)
210 @ResponseBody 271 @ResponseBody
211 public PageData<AlarmInfo> getAllAlarms( 272 public PageData<AlarmInfo> getAllAlarms(
  273 + @ApiParam(value = ALARM_QUERY_SEARCH_STATUS_DESCRIPTION, allowableValues = ALARM_QUERY_SEARCH_STATUS_ALLOWABLE_VALUES)
212 @RequestParam(required = false) String searchStatus, 274 @RequestParam(required = false) String searchStatus,
  275 + @ApiParam(value = ALARM_QUERY_STATUS_DESCRIPTION, allowableValues = ALARM_QUERY_STATUS_ALLOWABLE_VALUES)
213 @RequestParam(required = false) String status, 276 @RequestParam(required = false) String status,
  277 + @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true)
214 @RequestParam int pageSize, 278 @RequestParam int pageSize,
  279 + @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true)
215 @RequestParam int page, 280 @RequestParam int page,
  281 + @ApiParam(value = ALARM_QUERY_TEXT_SEARCH_DESCRIPTION)
216 @RequestParam(required = false) String textSearch, 282 @RequestParam(required = false) String textSearch,
  283 + @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = ALARM_SORT_PROPERTY_ALLOWABLE_VALUES)
217 @RequestParam(required = false) String sortProperty, 284 @RequestParam(required = false) String sortProperty,
  285 + @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES)
218 @RequestParam(required = false) String sortOrder, 286 @RequestParam(required = false) String sortOrder,
  287 + @ApiParam(value = ALARM_QUERY_START_TIME_DESCRIPTION)
219 @RequestParam(required = false) Long startTime, 288 @RequestParam(required = false) Long startTime,
  289 + @ApiParam(value = ALARM_QUERY_END_TIME_DESCRIPTION)
220 @RequestParam(required = false) Long endTime, 290 @RequestParam(required = false) Long endTime,
  291 + @ApiParam(value = ALARM_QUERY_FETCH_ORIGINATOR_DESCRIPTION)
221 @RequestParam(required = false) Boolean fetchOriginator 292 @RequestParam(required = false) Boolean fetchOriginator
222 ) throws ThingsboardException { 293 ) throws ThingsboardException {
223 AlarmSearchStatus alarmSearchStatus = StringUtils.isEmpty(searchStatus) ? null : AlarmSearchStatus.valueOf(searchStatus); 294 AlarmSearchStatus alarmSearchStatus = StringUtils.isEmpty(searchStatus) ? null : AlarmSearchStatus.valueOf(searchStatus);
@@ -239,13 +310,21 @@ public class AlarmController extends BaseController { @@ -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 @RequestMapping(value = "/alarm/highestSeverity/{entityType}/{entityId}", method = RequestMethod.GET) 318 @RequestMapping(value = "/alarm/highestSeverity/{entityType}/{entityId}", method = RequestMethod.GET)
244 @ResponseBody 319 @ResponseBody
245 public AlarmSeverity getHighestAlarmSeverity( 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 @RequestParam(required = false) String searchStatus, 326 @RequestParam(required = false) String searchStatus,
  327 + @ApiParam(value = ALARM_QUERY_STATUS_DESCRIPTION, allowableValues = ALARM_QUERY_STATUS_ALLOWABLE_VALUES)
249 @RequestParam(required = false) String status 328 @RequestParam(required = false) String status
250 ) throws ThingsboardException { 329 ) throws ThingsboardException {
251 checkParameter("EntityId", strEntityId); 330 checkParameter("EntityId", strEntityId);
@@ -157,6 +157,8 @@ public abstract class BaseController { @@ -157,6 +157,8 @@ public abstract class BaseController {
157 157
158 public static final String CUSTOMER_ID = "customerId"; 158 public static final String CUSTOMER_ID = "customerId";
159 public static final String TENANT_ID = "tenantId"; 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 public static final String PAGE_DATA_PARAMETERS = "You can specify parameters to filter the results. " + 163 public static final String PAGE_DATA_PARAMETERS = "You can specify parameters to filter the results. " +
162 "The result is wrapped with PageData object that allows you to iterate over result set using pagination. " + 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,6 +171,10 @@ public abstract class BaseController {
169 public static final String CUSTOMER_ID_PARAM_DESCRIPTION = "A string value representing the customer id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'"; 171 public static final String CUSTOMER_ID_PARAM_DESCRIPTION = "A string value representing the customer id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'";
170 public static final String USER_ID_PARAM_DESCRIPTION = "A string value representing the user id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'"; 172 public static final String USER_ID_PARAM_DESCRIPTION = "A string value representing the user id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'";
171 public static final String ASSET_ID_PARAM_DESCRIPTION = "A string value representing the asset id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'"; 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 protected final String PAGE_SIZE_DESCRIPTION = "Maximum amount of entities in a one page"; 179 protected final String PAGE_SIZE_DESCRIPTION = "Maximum amount of entities in a one page";
174 protected final String PAGE_NUMBER_DESCRIPTION = "Sequence number of page starting from 0"; 180 protected final String PAGE_NUMBER_DESCRIPTION = "Sequence number of page starting from 0";
@@ -179,22 +185,29 @@ public abstract class BaseController { @@ -179,22 +185,29 @@ public abstract class BaseController {
179 protected final String DASHBOARD_TEXT_SEARCH_DESCRIPTION = "The case insensitive 'startsWith' filter based on the dashboard title."; 185 protected final String DASHBOARD_TEXT_SEARCH_DESCRIPTION = "The case insensitive 'startsWith' filter based on the dashboard title.";
180 protected final String DEVICE_TEXT_SEARCH_DESCRIPTION = "The case insensitive 'startsWith' filter based on the device name."; 186 protected final String DEVICE_TEXT_SEARCH_DESCRIPTION = "The case insensitive 'startsWith' filter based on the device name.";
181 protected final String CUSTOMER_TEXT_SEARCH_DESCRIPTION = "The case insensitive 'startsWith' filter based on the customer title."; 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 protected final String SORT_PROPERTY_DESCRIPTION = "Property of entity to sort by"; 189 protected final String SORT_PROPERTY_DESCRIPTION = "Property of entity to sort by";
183 protected final String DASHBOARD_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, title"; 190 protected final String DASHBOARD_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, title";
184 protected final String CUSTOMER_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, title, email, country, city"; 191 protected final String CUSTOMER_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, title, email, country, city";
185 protected final String DEVICE_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, name, deviceProfileName, label, customerTitle"; 192 protected final String DEVICE_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, name, deviceProfileName, label, customerTitle";
186 protected final String ASSET_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, name, type, label, customerTitle"; 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 protected final String SORT_ORDER_DESCRIPTION = "Sort order. ASC (ASCENDING) or DESC (DESCENDING)"; 196 protected final String SORT_ORDER_DESCRIPTION = "Sort order. ASC (ASCENDING) or DESC (DESCENDING)";
188 protected final String SORT_ORDER_ALLOWABLE_VALUES = "ASC, DESC"; 197 protected final String SORT_ORDER_ALLOWABLE_VALUES = "ASC, DESC";
189 protected final String DEVICE_INFO_DESCRIPTION = "Device Info is an extension of the default Device object that contains information about the assigned customer name and device profile name. "; 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 protected final String ASSET_INFO_DESCRIPTION = "Asset Info is an extension of the default Asset object that contains information about the assigned customer name. "; 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 protected final String DEVICE_NAME_DESCRIPTION = "A string value representing the Device name."; 203 protected final String DEVICE_NAME_DESCRIPTION = "A string value representing the Device name.";
196 protected final String ASSET_NAME_DESCRIPTION = "A string value representing the Asset name."; 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 public static final String INCORRECT_TENANT_ID = "Incorrect tenantId "; 211 public static final String INCORRECT_TENANT_ID = "Incorrect tenantId ";
199 protected static final String DEFAULT_DASHBOARD = "defaultDashboardId"; 212 protected static final String DEFAULT_DASHBOARD = "defaultDashboardId";
200 protected static final String HOME_DASHBOARD = "homeDashboardId"; 213 protected static final String HOME_DASHBOARD = "homeDashboardId";
@@ -141,7 +141,8 @@ public class DeviceController extends BaseController { @@ -141,7 +141,8 @@ public class DeviceController extends BaseController {
141 "Device credentials are also generated if not provided in the 'accessToken' request parameter. " + 141 "Device credentials are also generated if not provided in the 'accessToken' request parameter. " +
142 "The newly created device id will be present in the response. " + 142 "The newly created device id will be present in the response. " +
143 "Specify existing Device id to update the device. " + 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 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") 146 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
146 @RequestMapping(value = "/device", method = RequestMethod.POST) 147 @RequestMapping(value = "/device", method = RequestMethod.POST)
147 @ResponseBody 148 @ResponseBody
@@ -15,7 +15,10 @@ @@ -15,7 +15,10 @@
15 */ 15 */
16 package org.thingsboard.server.controller; 16 package org.thingsboard.server.controller;
17 17
  18 +import io.swagger.annotations.ApiOperation;
  19 +import io.swagger.annotations.ApiParam;
18 import org.springframework.http.HttpStatus; 20 import org.springframework.http.HttpStatus;
  21 +import org.springframework.http.MediaType;
19 import org.springframework.security.access.prepost.PreAuthorize; 22 import org.springframework.security.access.prepost.PreAuthorize;
20 import org.springframework.web.bind.annotation.RequestBody; 23 import org.springframework.web.bind.annotation.RequestBody;
21 import org.springframework.web.bind.annotation.RequestMapping; 24 import org.springframework.web.bind.annotation.RequestMapping;
@@ -52,10 +55,26 @@ public class EntityRelationController extends BaseController { @@ -52,10 +55,26 @@ public class EntityRelationController extends BaseController {
52 public static final String RELATION_TYPE = "relationType"; 55 public static final String RELATION_TYPE = "relationType";
53 public static final String TO_ID = "toId"; 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 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") 73 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
56 @RequestMapping(value = "/relation", method = RequestMethod.POST) 74 @RequestMapping(value = "/relation", method = RequestMethod.POST)
57 @ResponseStatus(value = HttpStatus.OK) 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 try { 78 try {
60 checkNotNull(relation); 79 checkNotNull(relation);
61 checkEntityId(relation.getFrom(), Operation.WRITE); 80 checkEntityId(relation.getFrom(), Operation.WRITE);
@@ -80,14 +99,17 @@ public class EntityRelationController extends BaseController { @@ -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 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") 104 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
84 @RequestMapping(value = "/relation", method = RequestMethod.DELETE, params = {FROM_ID, FROM_TYPE, RELATION_TYPE, TO_ID, TO_TYPE}) 105 @RequestMapping(value = "/relation", method = RequestMethod.DELETE, params = {FROM_ID, FROM_TYPE, RELATION_TYPE, TO_ID, TO_TYPE})
85 @ResponseStatus(value = HttpStatus.OK) 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 checkParameter(FROM_ID, strFromId); 113 checkParameter(FROM_ID, strFromId);
92 checkParameter(FROM_TYPE, strFromType); 114 checkParameter(FROM_TYPE, strFromType);
93 checkParameter(RELATION_TYPE, strRelationType); 115 checkParameter(RELATION_TYPE, strRelationType);
@@ -119,11 +141,14 @@ public class EntityRelationController extends BaseController { @@ -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 @PreAuthorize("hasAnyAuthority('SYS_ADMIN','TENANT_ADMIN', 'CUSTOMER_USER')") 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 @ResponseStatus(value = HttpStatus.OK) 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 checkParameter("entityId", strId); 152 checkParameter("entityId", strId);
128 checkParameter("entityType", strType); 153 checkParameter("entityType", strType);
129 EntityId entityId = EntityIdFactory.getByTypeAndId(strType, strId); 154 EntityId entityId = EntityIdFactory.getByTypeAndId(strType, strId);
@@ -137,14 +162,18 @@ public class EntityRelationController extends BaseController { @@ -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 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") 168 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
141 @RequestMapping(value = "/relation", method = RequestMethod.GET, params = {FROM_ID, FROM_TYPE, RELATION_TYPE, TO_ID, TO_TYPE}) 169 @RequestMapping(value = "/relation", method = RequestMethod.GET, params = {FROM_ID, FROM_TYPE, RELATION_TYPE, TO_ID, TO_TYPE})
142 @ResponseBody 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 try { 177 try {
149 checkParameter(FROM_ID, strFromId); 178 checkParameter(FROM_ID, strFromId);
150 checkParameter(FROM_TYPE, strFromType); 179 checkParameter(FROM_TYPE, strFromType);
@@ -162,11 +191,16 @@ public class EntityRelationController extends BaseController { @@ -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 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") 198 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
166 @RequestMapping(value = "/relations", method = RequestMethod.GET, params = {FROM_ID, FROM_TYPE}) 199 @RequestMapping(value = "/relations", method = RequestMethod.GET, params = {FROM_ID, FROM_TYPE})
167 @ResponseBody 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 @RequestParam(value = "relationTypeGroup", required = false) String strRelationTypeGroup) throws ThingsboardException { 204 @RequestParam(value = "relationTypeGroup", required = false) String strRelationTypeGroup) throws ThingsboardException {
171 checkParameter(FROM_ID, strFromId); 205 checkParameter(FROM_ID, strFromId);
172 checkParameter(FROM_TYPE, strFromType); 206 checkParameter(FROM_TYPE, strFromType);
@@ -180,11 +214,16 @@ public class EntityRelationController extends BaseController { @@ -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 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") 221 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
184 @RequestMapping(value = "/relations/info", method = RequestMethod.GET, params = {FROM_ID, FROM_TYPE}) 222 @RequestMapping(value = "/relations/info", method = RequestMethod.GET, params = {FROM_ID, FROM_TYPE})
185 @ResponseBody 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 @RequestParam(value = "relationTypeGroup", required = false) String strRelationTypeGroup) throws ThingsboardException { 227 @RequestParam(value = "relationTypeGroup", required = false) String strRelationTypeGroup) throws ThingsboardException {
189 checkParameter(FROM_ID, strFromId); 228 checkParameter(FROM_ID, strFromId);
190 checkParameter(FROM_TYPE, strFromType); 229 checkParameter(FROM_TYPE, strFromType);
@@ -198,12 +237,17 @@ public class EntityRelationController extends BaseController { @@ -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 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") 244 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
202 @RequestMapping(value = "/relations", method = RequestMethod.GET, params = {FROM_ID, FROM_TYPE, RELATION_TYPE}) 245 @RequestMapping(value = "/relations", method = RequestMethod.GET, params = {FROM_ID, FROM_TYPE, RELATION_TYPE})
203 @ResponseBody 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 @RequestParam(value = "relationTypeGroup", required = false) String strRelationTypeGroup) throws ThingsboardException { 251 @RequestParam(value = "relationTypeGroup", required = false) String strRelationTypeGroup) throws ThingsboardException {
208 checkParameter(FROM_ID, strFromId); 252 checkParameter(FROM_ID, strFromId);
209 checkParameter(FROM_TYPE, strFromType); 253 checkParameter(FROM_TYPE, strFromType);
@@ -218,11 +262,16 @@ public class EntityRelationController extends BaseController { @@ -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 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") 269 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
222 @RequestMapping(value = "/relations", method = RequestMethod.GET, params = {TO_ID, TO_TYPE}) 270 @RequestMapping(value = "/relations", method = RequestMethod.GET, params = {TO_ID, TO_TYPE})
223 @ResponseBody 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 @RequestParam(value = "relationTypeGroup", required = false) String strRelationTypeGroup) throws ThingsboardException { 275 @RequestParam(value = "relationTypeGroup", required = false) String strRelationTypeGroup) throws ThingsboardException {
227 checkParameter(TO_ID, strToId); 276 checkParameter(TO_ID, strToId);
228 checkParameter(TO_TYPE, strToType); 277 checkParameter(TO_TYPE, strToType);
@@ -236,11 +285,16 @@ public class EntityRelationController extends BaseController { @@ -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 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") 292 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
240 @RequestMapping(value = "/relations/info", method = RequestMethod.GET, params = {TO_ID, TO_TYPE}) 293 @RequestMapping(value = "/relations/info", method = RequestMethod.GET, params = {TO_ID, TO_TYPE})
241 @ResponseBody 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 @RequestParam(value = "relationTypeGroup", required = false) String strRelationTypeGroup) throws ThingsboardException { 298 @RequestParam(value = "relationTypeGroup", required = false) String strRelationTypeGroup) throws ThingsboardException {
245 checkParameter(TO_ID, strToId); 299 checkParameter(TO_ID, strToId);
246 checkParameter(TO_TYPE, strToType); 300 checkParameter(TO_TYPE, strToType);
@@ -254,12 +308,17 @@ public class EntityRelationController extends BaseController { @@ -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 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") 315 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
258 @RequestMapping(value = "/relations", method = RequestMethod.GET, params = {TO_ID, TO_TYPE, RELATION_TYPE}) 316 @RequestMapping(value = "/relations", method = RequestMethod.GET, params = {TO_ID, TO_TYPE, RELATION_TYPE})
259 @ResponseBody 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 @RequestParam(value = "relationTypeGroup", required = false) String strRelationTypeGroup) throws ThingsboardException { 322 @RequestParam(value = "relationTypeGroup", required = false) String strRelationTypeGroup) throws ThingsboardException {
264 checkParameter(TO_ID, strToId); 323 checkParameter(TO_ID, strToId);
265 checkParameter(TO_TYPE, strToType); 324 checkParameter(TO_TYPE, strToType);
@@ -274,10 +333,15 @@ public class EntityRelationController extends BaseController { @@ -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 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") 340 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
278 @RequestMapping(value = "/relations", method = RequestMethod.POST) 341 @RequestMapping(value = "/relations", method = RequestMethod.POST)
279 @ResponseBody 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 checkNotNull(query); 345 checkNotNull(query);
282 checkNotNull(query.getParameters()); 346 checkNotNull(query.getParameters());
283 checkNotNull(query.getFilters()); 347 checkNotNull(query.getFilters());
@@ -289,10 +353,15 @@ public class EntityRelationController extends BaseController { @@ -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 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") 360 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
293 @RequestMapping(value = "/relations/info", method = RequestMethod.POST) 361 @RequestMapping(value = "/relations/info", method = RequestMethod.POST)
294 @ResponseBody 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 checkNotNull(query); 365 checkNotNull(query);
297 checkNotNull(query.getParameters()); 366 checkNotNull(query.getParameters());
298 checkNotNull(query.getFilters()); 367 checkNotNull(query.getFilters());
@@ -15,7 +15,10 @@ @@ -15,7 +15,10 @@
15 */ 15 */
16 package org.thingsboard.server.controller; 16 package org.thingsboard.server.controller;
17 17
  18 +import io.swagger.annotations.ApiOperation;
  19 +import io.swagger.annotations.ApiParam;
18 import org.springframework.beans.factory.annotation.Autowired; 20 import org.springframework.beans.factory.annotation.Autowired;
  21 +import org.springframework.http.MediaType;
19 import org.springframework.security.access.prepost.PreAuthorize; 22 import org.springframework.security.access.prepost.PreAuthorize;
20 import org.springframework.web.bind.annotation.PathVariable; 23 import org.springframework.web.bind.annotation.PathVariable;
21 import org.springframework.web.bind.annotation.RequestBody; 24 import org.springframework.web.bind.annotation.RequestBody;
@@ -45,20 +48,34 @@ public class EventController extends BaseController { @@ -45,20 +48,34 @@ public class EventController extends BaseController {
45 @Autowired 48 @Autowired
46 private EventService eventService; 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 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") 54 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
49 @RequestMapping(value = "/events/{entityType}/{entityId}/{eventType}", method = RequestMethod.GET) 55 @RequestMapping(value = "/events/{entityType}/{entityId}/{eventType}", method = RequestMethod.GET)
50 @ResponseBody 56 @ResponseBody
51 public PageData<Event> getEvents( 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 @PathVariable("eventType") String eventType, 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 @RequestParam int pageSize, 67 @RequestParam int pageSize,
  68 + @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true)
57 @RequestParam int page, 69 @RequestParam int page,
  70 + @ApiParam(value = EVENT_TEXT_SEARCH_DESCRIPTION)
58 @RequestParam(required = false) String textSearch, 71 @RequestParam(required = false) String textSearch,
  72 + @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = EVENT_SORT_PROPERTY_ALLOWABLE_VALUES)
59 @RequestParam(required = false) String sortProperty, 73 @RequestParam(required = false) String sortProperty,
  74 + @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES)
60 @RequestParam(required = false) String sortOrder, 75 @RequestParam(required = false) String sortOrder,
  76 + @ApiParam(value = EVENT_START_TIME_DESCRIPTION)
61 @RequestParam(required = false) Long startTime, 77 @RequestParam(required = false) Long startTime,
  78 + @ApiParam(value = EVENT_END_TIME_DESCRIPTION)
62 @RequestParam(required = false) Long endTime) throws ThingsboardException { 79 @RequestParam(required = false) Long endTime) throws ThingsboardException {
63 checkParameter("EntityId", strEntityId); 80 checkParameter("EntityId", strEntityId);
64 checkParameter("EntityType", strEntityType); 81 checkParameter("EntityType", strEntityType);
@@ -74,19 +91,32 @@ public class EventController extends BaseController { @@ -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 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") 97 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
78 @RequestMapping(value = "/events/{entityType}/{entityId}", method = RequestMethod.GET) 98 @RequestMapping(value = "/events/{entityType}/{entityId}", method = RequestMethod.GET)
79 @ResponseBody 99 @ResponseBody
80 public PageData<Event> getEvents( 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 @RequestParam("tenantId") String strTenantId, 106 @RequestParam("tenantId") String strTenantId,
  107 + @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true)
84 @RequestParam int pageSize, 108 @RequestParam int pageSize,
  109 + @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true)
85 @RequestParam int page, 110 @RequestParam int page,
  111 + @ApiParam(value = EVENT_TEXT_SEARCH_DESCRIPTION)
86 @RequestParam(required = false) String textSearch, 112 @RequestParam(required = false) String textSearch,
  113 + @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = EVENT_SORT_PROPERTY_ALLOWABLE_VALUES)
87 @RequestParam(required = false) String sortProperty, 114 @RequestParam(required = false) String sortProperty,
  115 + @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES)
88 @RequestParam(required = false) String sortOrder, 116 @RequestParam(required = false) String sortOrder,
  117 + @ApiParam(value = EVENT_START_TIME_DESCRIPTION)
89 @RequestParam(required = false) Long startTime, 118 @RequestParam(required = false) Long startTime,
  119 + @ApiParam(value = EVENT_END_TIME_DESCRIPTION)
90 @RequestParam(required = false) Long endTime) throws ThingsboardException { 120 @RequestParam(required = false) Long endTime) throws ThingsboardException {
91 checkParameter("EntityId", strEntityId); 121 checkParameter("EntityId", strEntityId);
92 checkParameter("EntityType", strEntityType); 122 checkParameter("EntityType", strEntityType);
@@ -104,20 +134,34 @@ public class EventController extends BaseController { @@ -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 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") 140 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
108 @RequestMapping(value = "/events/{entityType}/{entityId}", method = RequestMethod.POST) 141 @RequestMapping(value = "/events/{entityType}/{entityId}", method = RequestMethod.POST)
109 @ResponseBody 142 @ResponseBody
110 public PageData<Event> getEvents( 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 @RequestParam int pageSize, 151 @RequestParam int pageSize,
  152 + @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true)
115 @RequestParam int page, 153 @RequestParam int page,
  154 + @ApiParam(value = "A JSON value representing the event filter.", required = true)
116 @RequestBody EventFilter eventFilter, 155 @RequestBody EventFilter eventFilter,
  156 + @ApiParam(value = EVENT_TEXT_SEARCH_DESCRIPTION)
117 @RequestParam(required = false) String textSearch, 157 @RequestParam(required = false) String textSearch,
  158 + @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = EVENT_SORT_PROPERTY_ALLOWABLE_VALUES)
118 @RequestParam(required = false) String sortProperty, 159 @RequestParam(required = false) String sortProperty,
  160 + @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES)
119 @RequestParam(required = false) String sortOrder, 161 @RequestParam(required = false) String sortOrder,
  162 + @ApiParam(value = EVENT_START_TIME_DESCRIPTION)
120 @RequestParam(required = false) Long startTime, 163 @RequestParam(required = false) Long startTime,
  164 + @ApiParam(value = EVENT_END_TIME_DESCRIPTION)
121 @RequestParam(required = false) Long endTime) throws ThingsboardException { 165 @RequestParam(required = false) Long endTime) throws ThingsboardException {
122 checkParameter("EntityId", strEntityId); 166 checkParameter("EntityId", strEntityId);
123 checkParameter("EntityType", strEntityType); 167 checkParameter("EntityType", strEntityType);
@@ -127,7 +171,7 @@ public class EventController extends BaseController { @@ -127,7 +171,7 @@ public class EventController extends BaseController {
127 EntityId entityId = EntityIdFactory.getByTypeAndId(strEntityType, strEntityId); 171 EntityId entityId = EntityIdFactory.getByTypeAndId(strEntityType, strEntityId);
128 checkEntityId(entityId, Operation.READ); 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 sortProperty = ModelConstants.CREATED_TIME_PROPERTY; 175 sortProperty = ModelConstants.CREATED_TIME_PROPERTY;
132 } 176 }
133 177
@@ -26,6 +26,8 @@ import com.google.common.util.concurrent.MoreExecutors; @@ -26,6 +26,8 @@ import com.google.common.util.concurrent.MoreExecutors;
26 import com.google.gson.JsonElement; 26 import com.google.gson.JsonElement;
27 import com.google.gson.JsonParseException; 27 import com.google.gson.JsonParseException;
28 import com.google.gson.JsonParser; 28 import com.google.gson.JsonParser;
  29 +import io.swagger.annotations.ApiOperation;
  30 +import io.swagger.annotations.ApiParam;
29 import lombok.extern.slf4j.Slf4j; 31 import lombok.extern.slf4j.Slf4j;
30 import org.springframework.beans.factory.annotation.Autowired; 32 import org.springframework.beans.factory.annotation.Autowired;
31 import org.springframework.beans.factory.annotation.Value; 33 import org.springframework.beans.factory.annotation.Value;
@@ -48,7 +50,6 @@ import org.thingsboard.server.common.data.EntityType; @@ -48,7 +50,6 @@ import org.thingsboard.server.common.data.EntityType;
48 import org.thingsboard.server.common.data.TenantProfile; 50 import org.thingsboard.server.common.data.TenantProfile;
49 import org.thingsboard.server.common.data.audit.ActionType; 51 import org.thingsboard.server.common.data.audit.ActionType;
50 import org.thingsboard.server.common.data.exception.ThingsboardException; 52 import org.thingsboard.server.common.data.exception.ThingsboardException;
51 -import org.thingsboard.server.common.data.id.CustomerId;  
52 import org.thingsboard.server.common.data.id.DeviceId; 53 import org.thingsboard.server.common.data.id.DeviceId;
53 import org.thingsboard.server.common.data.id.EntityId; 54 import org.thingsboard.server.common.data.id.EntityId;
54 import org.thingsboard.server.common.data.id.EntityIdFactory; 55 import org.thingsboard.server.common.data.id.EntityIdFactory;
@@ -108,6 +109,17 @@ import java.util.stream.Collectors; @@ -108,6 +109,17 @@ import java.util.stream.Collectors;
108 @Slf4j 109 @Slf4j
109 public class TelemetryController extends BaseController { 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 @Autowired 123 @Autowired
112 private TimeseriesService tsService; 124 private TimeseriesService tsService;
113 125
@@ -133,62 +145,81 @@ public class TelemetryController extends BaseController { @@ -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 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") 150 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
137 @RequestMapping(value = "/{entityType}/{entityId}/keys/attributes", method = RequestMethod.GET) 151 @RequestMapping(value = "/{entityType}/{entityId}/keys/attributes", method = RequestMethod.GET)
138 @ResponseBody 152 @ResponseBody
139 public DeferredResult<ResponseEntity> getAttributeKeys( 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 return accessValidator.validateEntityAndCallback(getCurrentUser(), Operation.READ_ATTRIBUTES, entityType, entityIdStr, this::getAttributeKeysCallback); 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 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") 161 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
145 @RequestMapping(value = "/{entityType}/{entityId}/keys/attributes/{scope}", method = RequestMethod.GET) 162 @RequestMapping(value = "/{entityType}/{entityId}/keys/attributes/{scope}", method = RequestMethod.GET)
146 @ResponseBody 163 @ResponseBody
147 public DeferredResult<ResponseEntity> getAttributeKeysByScope( 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 return accessValidator.validateEntityAndCallback(getCurrentUser(), Operation.READ_ATTRIBUTES, entityType, entityIdStr, 168 return accessValidator.validateEntityAndCallback(getCurrentUser(), Operation.READ_ATTRIBUTES, entityType, entityIdStr,
151 (result, tenantId, entityId) -> getAttributeKeysCallback(result, tenantId, entityId, scope)); 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 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") 174 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
155 @RequestMapping(value = "/{entityType}/{entityId}/values/attributes", method = RequestMethod.GET) 175 @RequestMapping(value = "/{entityType}/{entityId}/values/attributes", method = RequestMethod.GET)
156 @ResponseBody 176 @ResponseBody
157 public DeferredResult<ResponseEntity> getAttributes( 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 SecurityUser user = getCurrentUser(); 181 SecurityUser user = getCurrentUser();
161 return accessValidator.validateEntityAndCallback(getCurrentUser(), Operation.READ_ATTRIBUTES, entityType, entityIdStr, 182 return accessValidator.validateEntityAndCallback(getCurrentUser(), Operation.READ_ATTRIBUTES, entityType, entityIdStr,
162 (result, tenantId, entityId) -> getAttributeValuesCallback(result, user, entityId, null, keysStr)); 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 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") 188 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
166 @RequestMapping(value = "/{entityType}/{entityId}/values/attributes/{scope}", method = RequestMethod.GET) 189 @RequestMapping(value = "/{entityType}/{entityId}/values/attributes/{scope}", method = RequestMethod.GET)
167 @ResponseBody 190 @ResponseBody
168 public DeferredResult<ResponseEntity> getAttributesByScope( 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 SecurityUser user = getCurrentUser(); 196 SecurityUser user = getCurrentUser();
173 return accessValidator.validateEntityAndCallback(getCurrentUser(), Operation.READ_ATTRIBUTES, entityType, entityIdStr, 197 return accessValidator.validateEntityAndCallback(getCurrentUser(), Operation.READ_ATTRIBUTES, entityType, entityIdStr,
174 (result, tenantId, entityId) -> getAttributeValuesCallback(result, user, entityId, scope, keysStr)); 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 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") 203 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
178 @RequestMapping(value = "/{entityType}/{entityId}/keys/timeseries", method = RequestMethod.GET) 204 @RequestMapping(value = "/{entityType}/{entityId}/keys/timeseries", method = RequestMethod.GET)
179 @ResponseBody 205 @ResponseBody
180 public DeferredResult<ResponseEntity> getTimeseriesKeys( 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 return accessValidator.validateEntityAndCallback(getCurrentUser(), Operation.READ_TELEMETRY, entityType, entityIdStr, 209 return accessValidator.validateEntityAndCallback(getCurrentUser(), Operation.READ_TELEMETRY, entityType, entityIdStr,
183 (result, tenantId, entityId) -> Futures.addCallback(tsService.findAllLatest(tenantId, entityId), getTsKeysToResponseCallback(result), MoreExecutors.directExecutor())); 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 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") 215 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
187 @RequestMapping(value = "/{entityType}/{entityId}/values/timeseries", method = RequestMethod.GET) 216 @RequestMapping(value = "/{entityType}/{entityId}/values/timeseries", method = RequestMethod.GET)
188 @ResponseBody 217 @ResponseBody
189 public DeferredResult<ResponseEntity> getLatestTimeseries( 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 @RequestParam(name = "useStrictDataTypes", required = false, defaultValue = "false") Boolean useStrictDataTypes) throws ThingsboardException { 223 @RequestParam(name = "useStrictDataTypes", required = false, defaultValue = "false") Boolean useStrictDataTypes) throws ThingsboardException {
193 SecurityUser user = getCurrentUser(); 224 SecurityUser user = getCurrentUser();
194 225
@@ -196,20 +227,30 @@ public class TelemetryController extends BaseController { @@ -196,20 +227,30 @@ public class TelemetryController extends BaseController {
196 (result, tenantId, entityId) -> getLatestTimeseriesValuesCallback(result, user, entityId, keysStr, useStrictDataTypes)); 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 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") 232 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
201 @RequestMapping(value = "/{entityType}/{entityId}/values/timeseries", method = RequestMethod.GET, params = {"keys", "startTs", "endTs"}) 233 @RequestMapping(value = "/{entityType}/{entityId}/values/timeseries", method = RequestMethod.GET, params = {"keys", "startTs", "endTs"})
202 @ResponseBody 234 @ResponseBody
203 public DeferredResult<ResponseEntity> getTimeseries( 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 @RequestParam(name = "startTs") Long startTs, 240 @RequestParam(name = "startTs") Long startTs,
  241 + @ApiParam(value = "A long value representing the end timestamp(milliseconds) of search time range.")
208 @RequestParam(name = "endTs") Long endTs, 242 @RequestParam(name = "endTs") Long endTs,
  243 + @ApiParam(value = "A long value representing the aggregation interval(milliseconds) range.")
209 @RequestParam(name = "interval", defaultValue = "0") Long interval, 244 @RequestParam(name = "interval", defaultValue = "0") Long interval,
  245 + @ApiParam(value = "An integer value representing max number of selected data points.", defaultValue = "100")
210 @RequestParam(name = "limit", defaultValue = "100") Integer limit, 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 @RequestParam(name = "agg", defaultValue = "NONE") String aggStr, 250 @RequestParam(name = "agg", defaultValue = "NONE") String aggStr,
  251 + @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES)
212 @RequestParam(name = "orderBy", defaultValue = "DESC") String orderBy, 252 @RequestParam(name = "orderBy", defaultValue = "DESC") String orderBy,
  253 + @ApiParam(value = STRICT_DATA_TYPES_DESCRIPTION)
213 @RequestParam(name = "useStrictDataTypes", required = false, defaultValue = "false") Boolean useStrictDataTypes) throws ThingsboardException { 254 @RequestParam(name = "useStrictDataTypes", required = false, defaultValue = "false") Boolean useStrictDataTypes) throws ThingsboardException {
214 return accessValidator.validateEntityAndCallback(getCurrentUser(), Operation.READ_TELEMETRY, entityType, entityIdStr, 255 return accessValidator.validateEntityAndCallback(getCurrentUser(), Operation.READ_TELEMETRY, entityType, entityIdStr,
215 (result, tenantId, entityId) -> { 256 (result, tenantId, entityId) -> {
@@ -222,64 +263,89 @@ public class TelemetryController extends BaseController { @@ -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 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") 267 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
226 @RequestMapping(value = "/{deviceId}/{scope}", method = RequestMethod.POST) 268 @RequestMapping(value = "/{deviceId}/{scope}", method = RequestMethod.POST)
227 @ResponseBody 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 EntityId entityId = EntityIdFactory.getByTypeAndUuid(EntityType.DEVICE, deviceIdStr); 274 EntityId entityId = EntityIdFactory.getByTypeAndUuid(EntityType.DEVICE, deviceIdStr);
231 return saveAttributes(getTenantId(), entityId, scope, request); 275 return saveAttributes(getTenantId(), entityId, scope, request);
232 } 276 }
233 277
  278 + @ApiOperation(value = "Save or update attributes (saveEntityAttributesV1)")
234 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") 279 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
235 @RequestMapping(value = "/{entityType}/{entityId}/{scope}", method = RequestMethod.POST) 280 @RequestMapping(value = "/{entityType}/{entityId}/{scope}", method = RequestMethod.POST)
236 @ResponseBody 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 EntityId entityId = EntityIdFactory.getByTypeAndId(entityType, entityIdStr); 287 EntityId entityId = EntityIdFactory.getByTypeAndId(entityType, entityIdStr);
241 return saveAttributes(getTenantId(), entityId, scope, request); 288 return saveAttributes(getTenantId(), entityId, scope, request);
242 } 289 }
243 290
  291 + @ApiOperation(value = "Save or update attributes (saveEntityAttributesV2)")
244 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") 292 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
245 @RequestMapping(value = "/{entityType}/{entityId}/attributes/{scope}", method = RequestMethod.POST) 293 @RequestMapping(value = "/{entityType}/{entityId}/attributes/{scope}", method = RequestMethod.POST)
246 @ResponseBody 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 EntityId entityId = EntityIdFactory.getByTypeAndId(entityType, entityIdStr); 300 EntityId entityId = EntityIdFactory.getByTypeAndId(entityType, entityIdStr);
251 return saveAttributes(getTenantId(), entityId, scope, request); 301 return saveAttributes(getTenantId(), entityId, scope, request);
252 } 302 }
253 303
  304 + @ApiOperation(value = "Save or update telemetry (saveEntityTelemetry)")
254 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") 305 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
255 @RequestMapping(value = "/{entityType}/{entityId}/timeseries/{scope}", method = RequestMethod.POST) 306 @RequestMapping(value = "/{entityType}/{entityId}/timeseries/{scope}", method = RequestMethod.POST)
256 @ResponseBody 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 EntityId entityId = EntityIdFactory.getByTypeAndId(entityType, entityIdStr); 313 EntityId entityId = EntityIdFactory.getByTypeAndId(entityType, entityIdStr);
261 return saveTelemetry(getTenantId(), entityId, requestBody, 0L); 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 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") 319 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
265 @RequestMapping(value = "/{entityType}/{entityId}/timeseries/{scope}/{ttl}", method = RequestMethod.POST) 320 @RequestMapping(value = "/{entityType}/{entityId}/timeseries/{scope}/{ttl}", method = RequestMethod.POST)
266 @ResponseBody 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 EntityId entityId = EntityIdFactory.getByTypeAndId(entityType, entityIdStr); 328 EntityId entityId = EntityIdFactory.getByTypeAndId(entityType, entityIdStr);
271 return saveTelemetry(getTenantId(), entityId, requestBody, ttl); 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 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") 334 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
275 @RequestMapping(value = "/{entityType}/{entityId}/timeseries/delete", method = RequestMethod.DELETE) 335 @RequestMapping(value = "/{entityType}/{entityId}/timeseries/delete", method = RequestMethod.DELETE)
276 @ResponseBody 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 EntityId entityId = EntityIdFactory.getByTypeAndId(entityType, entityIdStr); 349 EntityId entityId = EntityIdFactory.getByTypeAndId(entityType, entityIdStr);
284 return deleteTimeseries(entityId, keysStr, deleteAllDataForKeys, startTs, endTs, rewriteLatestIfDeleted); 350 return deleteTimeseries(entityId, keysStr, deleteAllDataForKeys, startTs, endTs, rewriteLatestIfDeleted);
285 } 351 }
@@ -311,7 +377,6 @@ public class TelemetryController extends BaseController { @@ -311,7 +377,6 @@ public class TelemetryController extends BaseController {
311 for (String key : keys) { 377 for (String key : keys) {
312 deleteTsKvQueries.add(new BaseDeleteTsKvQuery(key, deleteFromTs, deleteToTs, rewriteLatestIfDeleted)); 378 deleteTsKvQueries.add(new BaseDeleteTsKvQuery(key, deleteFromTs, deleteToTs, rewriteLatestIfDeleted));
313 } 379 }
314 -  
315 ListenableFuture<List<Void>> future = tsService.remove(user.getTenantId(), entityId, deleteTsKvQueries); 380 ListenableFuture<List<Void>> future = tsService.remove(user.getTenantId(), entityId, deleteTsKvQueries);
316 Futures.addCallback(future, new FutureCallback<List<Void>>() { 381 Futures.addCallback(future, new FutureCallback<List<Void>>() {
317 @Override 382 @Override
@@ -329,22 +394,29 @@ public class TelemetryController extends BaseController { @@ -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 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") 399 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
333 @RequestMapping(value = "/{deviceId}/{scope}", method = RequestMethod.DELETE) 400 @RequestMapping(value = "/{deviceId}/{scope}", method = RequestMethod.DELETE)
334 @ResponseBody 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 EntityId entityId = EntityIdFactory.getByTypeAndUuid(EntityType.DEVICE, deviceIdStr); 406 EntityId entityId = EntityIdFactory.getByTypeAndUuid(EntityType.DEVICE, deviceIdStr);
339 return deleteAttributes(entityId, scope, keysStr); 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 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") 412 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
343 @RequestMapping(value = "/{entityType}/{entityId}/{scope}", method = RequestMethod.DELETE) 413 @RequestMapping(value = "/{entityType}/{entityId}/{scope}", method = RequestMethod.DELETE)
344 @ResponseBody 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 EntityId entityId = EntityIdFactory.getByTypeAndId(entityType, entityIdStr); 420 EntityId entityId = EntityIdFactory.getByTypeAndId(entityType, entityIdStr);
349 return deleteAttributes(entityId, scope, keysStr); 421 return deleteAttributes(entityId, scope, keysStr);
350 } 422 }
@@ -16,6 +16,8 @@ @@ -16,6 +16,8 @@
16 package org.thingsboard.server.common.data; 16 package org.thingsboard.server.common.data;
17 17
18 import com.fasterxml.jackson.databind.JsonNode; 18 import com.fasterxml.jackson.databind.JsonNode;
  19 +import io.swagger.annotations.ApiModel;
  20 +import io.swagger.annotations.ApiModelProperty;
19 import lombok.Data; 21 import lombok.Data;
20 import org.thingsboard.server.common.data.id.EntityId; 22 import org.thingsboard.server.common.data.id.EntityId;
21 import org.thingsboard.server.common.data.id.EventId; 23 import org.thingsboard.server.common.data.id.EventId;
@@ -25,12 +27,18 @@ import org.thingsboard.server.common.data.id.TenantId; @@ -25,12 +27,18 @@ import org.thingsboard.server.common.data.id.TenantId;
25 * @author Andrew Shvayka 27 * @author Andrew Shvayka
26 */ 28 */
27 @Data 29 @Data
  30 +@ApiModel
28 public class Event extends BaseData<EventId> { 31 public class Event extends BaseData<EventId> {
29 32
  33 + @ApiModelProperty(position = 1, value = "JSON object with Tenant Id.", readOnly = true)
30 private TenantId tenantId; 34 private TenantId tenantId;
  35 + @ApiModelProperty(position = 2, value = "Event type", example = "STATS")
31 private String type; 36 private String type;
  37 + @ApiModelProperty(position = 3, value = "string", example = "784f394c-42b6-435a-983c-b7beff2784f9")
32 private String uid; 38 private String uid;
  39 + @ApiModelProperty(position = 4, value = "JSON object with Entity Id for which event is created.", readOnly = true)
33 private EntityId entityId; 40 private EntityId entityId;
  41 + @ApiModelProperty(position = 5, value = "Event body.", dataType = "com.fasterxml.jackson.databind.JsonNode")
34 private transient JsonNode body; 42 private transient JsonNode body;
35 43
36 public Event() { 44 public Event() {
@@ -45,4 +53,9 @@ public class Event extends BaseData<EventId> { @@ -45,4 +53,9 @@ public class Event extends BaseData<EventId> {
45 super(event); 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,6 +17,8 @@ package org.thingsboard.server.common.data.alarm;
17 17
18 import com.fasterxml.jackson.annotation.JsonProperty; 18 import com.fasterxml.jackson.annotation.JsonProperty;
19 import com.fasterxml.jackson.databind.JsonNode; 19 import com.fasterxml.jackson.databind.JsonNode;
  20 +import io.swagger.annotations.ApiModel;
  21 +import io.swagger.annotations.ApiModelProperty;
20 import lombok.AllArgsConstructor; 22 import lombok.AllArgsConstructor;
21 import lombok.Builder; 23 import lombok.Builder;
22 import lombok.Data; 24 import lombok.Data;
@@ -34,23 +36,41 @@ import java.util.List; @@ -34,23 +36,41 @@ import java.util.List;
34 /** 36 /**
35 * Created by ashvayka on 11.05.17. 37 * Created by ashvayka on 11.05.17.
36 */ 38 */
  39 +@ApiModel
37 @Data 40 @Data
38 @Builder 41 @Builder
39 @AllArgsConstructor 42 @AllArgsConstructor
40 public class Alarm extends BaseData<AlarmId> implements HasName, HasTenantId, HasCustomerId { 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 private TenantId tenantId; 46 private TenantId tenantId;
  47 +
  48 + @ApiModelProperty(position = 4, value = "JSON object with Customer Id", readOnly = true)
43 private CustomerId customerId; 49 private CustomerId customerId;
  50 +
  51 + @ApiModelProperty(position = 6, required = true, value = "representing type of the Alarm", example = "High Temperature Alarm")
44 private String type; 52 private String type;
  53 + @ApiModelProperty(position = 7, required = true, value = "JSON object with alarm originator id")
45 private EntityId originator; 54 private EntityId originator;
  55 + @ApiModelProperty(position = 8, required = true, value = "Alarm severity", example = "CRITICAL")
46 private AlarmSeverity severity; 56 private AlarmSeverity severity;
  57 + @ApiModelProperty(position = 9, required = true, value = "Alarm status", example = "CLEARED_UNACK")
47 private AlarmStatus status; 58 private AlarmStatus status;
  59 + @ApiModelProperty(position = 10, value = "Timestamp of the alarm start time, in milliseconds", example = "1634058704565")
48 private long startTs; 60 private long startTs;
  61 + @ApiModelProperty(position = 11, value = "Timestamp of the alarm end time(last time update), in milliseconds", example = "1634111163522")
49 private long endTs; 62 private long endTs;
  63 + @ApiModelProperty(position = 12, value = "Timestamp of the alarm acknowledgement, in milliseconds", example = "1634115221948")
50 private long ackTs; 64 private long ackTs;
  65 + @ApiModelProperty(position = 13, value = "Timestamp of the alarm clearing, in milliseconds", example = "1634114528465")
51 private long clearTs; 66 private long clearTs;
  67 + @ApiModelProperty(position = 14, value = "JSON object with alarm details")
52 private transient JsonNode details; 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 private boolean propagate; 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 private List<String> propagateRelationTypes; 74 private List<String> propagateRelationTypes;
55 75
56 public Alarm() { 76 public Alarm() {
@@ -81,7 +101,25 @@ public class Alarm extends BaseData<AlarmId> implements HasName, HasTenantId, Ha @@ -81,7 +101,25 @@ public class Alarm extends BaseData<AlarmId> implements HasName, HasTenantId, Ha
81 101
82 @Override 102 @Override
83 @JsonProperty(access = JsonProperty.Access.READ_ONLY) 103 @JsonProperty(access = JsonProperty.Access.READ_ONLY)
  104 + @ApiModelProperty(position = 5, required = true, value = "representing type of the Alarm", example = "High Temperature Alarm")
84 public String getName() { 105 public String getName() {
85 return type; 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,10 +15,15 @@
15 */ 15 */
16 package org.thingsboard.server.common.data.alarm; 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 public class AlarmInfo extends Alarm { 22 public class AlarmInfo extends Alarm {
19 23
20 private static final long serialVersionUID = 2807343093519543363L; 24 private static final long serialVersionUID = 2807343093519543363L;
21 25
  26 + @ApiModelProperty(position = 17, value = "Alarm originator name", example = "Thermostat")
22 private String originatorName; 27 private String originatorName;
23 28
24 public AlarmInfo() { 29 public AlarmInfo() {
@@ -15,10 +15,12 @@ @@ -15,10 +15,12 @@
15 */ 15 */
16 package org.thingsboard.server.common.data.event; 16 package org.thingsboard.server.common.data.event;
17 17
  18 +import io.swagger.annotations.ApiModel;
18 import lombok.Data; 19 import lombok.Data;
19 import org.thingsboard.server.common.data.StringUtils; 20 import org.thingsboard.server.common.data.StringUtils;
20 21
21 @Data 22 @Data
  23 +@ApiModel
22 public abstract class DebugEvent implements EventFilter { 24 public abstract class DebugEvent implements EventFilter {
23 25
24 private String msgDirectionType; 26 private String msgDirectionType;
@@ -15,6 +15,9 @@ @@ -15,6 +15,9 @@
15 */ 15 */
16 package org.thingsboard.server.common.data.event; 16 package org.thingsboard.server.common.data.event;
17 17
  18 +import io.swagger.annotations.ApiModel;
  19 +
  20 +@ApiModel
18 public class DebugRuleChainEventFilter extends DebugEvent { 21 public class DebugRuleChainEventFilter extends DebugEvent {
19 @Override 22 @Override
20 public EventType getEventType() { 23 public EventType getEventType() {
@@ -15,6 +15,9 @@ @@ -15,6 +15,9 @@
15 */ 15 */
16 package org.thingsboard.server.common.data.event; 16 package org.thingsboard.server.common.data.event;
17 17
  18 +import io.swagger.annotations.ApiModel;
  19 +
  20 +@ApiModel
18 public class DebugRuleNodeEventFilter extends DebugEvent { 21 public class DebugRuleNodeEventFilter extends DebugEvent {
19 @Override 22 @Override
20 public EventType getEventType() { 23 public EventType getEventType() {
@@ -15,10 +15,12 @@ @@ -15,10 +15,12 @@
15 */ 15 */
16 package org.thingsboard.server.common.data.event; 16 package org.thingsboard.server.common.data.event;
17 17
  18 +import io.swagger.annotations.ApiModel;
18 import lombok.Data; 19 import lombok.Data;
19 import org.thingsboard.server.common.data.StringUtils; 20 import org.thingsboard.server.common.data.StringUtils;
20 21
21 @Data 22 @Data
  23 +@ApiModel
22 public class ErrorEventFilter implements EventFilter { 24 public class ErrorEventFilter implements EventFilter {
23 private String server; 25 private String server;
24 private String method; 26 private String method;
@@ -16,10 +16,11 @@ @@ -16,10 +16,11 @@
16 package org.thingsboard.server.common.data.event; 16 package org.thingsboard.server.common.data.event;
17 17
18 import com.fasterxml.jackson.annotation.JsonIgnore; 18 import com.fasterxml.jackson.annotation.JsonIgnore;
19 -import com.fasterxml.jackson.annotation.JsonIgnoreProperties;  
20 import com.fasterxml.jackson.annotation.JsonSubTypes; 19 import com.fasterxml.jackson.annotation.JsonSubTypes;
21 import com.fasterxml.jackson.annotation.JsonTypeInfo; 20 import com.fasterxml.jackson.annotation.JsonTypeInfo;
  21 +import io.swagger.annotations.ApiModel;
22 22
  23 +@ApiModel
23 @JsonTypeInfo( 24 @JsonTypeInfo(
24 use = JsonTypeInfo.Id.NAME, 25 use = JsonTypeInfo.Id.NAME,
25 include = JsonTypeInfo.As.PROPERTY, 26 include = JsonTypeInfo.As.PROPERTY,
@@ -15,10 +15,12 @@ @@ -15,10 +15,12 @@
15 */ 15 */
16 package org.thingsboard.server.common.data.event; 16 package org.thingsboard.server.common.data.event;
17 17
  18 +import io.swagger.annotations.ApiModel;
18 import lombok.Data; 19 import lombok.Data;
19 import org.thingsboard.server.common.data.StringUtils; 20 import org.thingsboard.server.common.data.StringUtils;
20 21
21 @Data 22 @Data
  23 +@ApiModel
22 public class LifeCycleEventFilter implements EventFilter { 24 public class LifeCycleEventFilter implements EventFilter {
23 private String server; 25 private String server;
24 private String event; 26 private String event;
@@ -15,10 +15,12 @@ @@ -15,10 +15,12 @@
15 */ 15 */
16 package org.thingsboard.server.common.data.event; 16 package org.thingsboard.server.common.data.event;
17 17
  18 +import io.swagger.annotations.ApiModel;
18 import lombok.Data; 19 import lombok.Data;
19 import org.thingsboard.server.common.data.StringUtils; 20 import org.thingsboard.server.common.data.StringUtils;
20 21
21 @Data 22 @Data
  23 +@ApiModel
22 public class StatisticsEventFilter implements EventFilter { 24 public class StatisticsEventFilter implements EventFilter {
23 private String server; 25 private String server;
24 private Integer messagesProcessed; 26 private Integer messagesProcessed;
@@ -18,6 +18,8 @@ package org.thingsboard.server.common.data.id; @@ -18,6 +18,8 @@ package org.thingsboard.server.common.data.id;
18 import com.fasterxml.jackson.annotation.JsonIgnore; 18 import com.fasterxml.jackson.annotation.JsonIgnore;
19 import com.fasterxml.jackson.databind.annotation.JsonDeserialize; 19 import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
20 import com.fasterxml.jackson.databind.annotation.JsonSerialize; 20 import com.fasterxml.jackson.databind.annotation.JsonSerialize;
  21 +import io.swagger.annotations.ApiModel;
  22 +import io.swagger.annotations.ApiModelProperty;
21 import org.thingsboard.server.common.data.EntityType; 23 import org.thingsboard.server.common.data.EntityType;
22 24
23 import java.io.Serializable; 25 import java.io.Serializable;
@@ -29,12 +31,15 @@ import java.util.UUID; @@ -29,12 +31,15 @@ import java.util.UUID;
29 31
30 @JsonDeserialize(using = EntityIdDeserializer.class) 32 @JsonDeserialize(using = EntityIdDeserializer.class)
31 @JsonSerialize(using = EntityIdSerializer.class) 33 @JsonSerialize(using = EntityIdSerializer.class)
  34 +@ApiModel
32 public interface EntityId extends HasUUID, Serializable { //NOSONAR, the constant is closely related to EntityId 35 public interface EntityId extends HasUUID, Serializable { //NOSONAR, the constant is closely related to EntityId
33 36
34 UUID NULL_UUID = UUID.fromString("13814000-1dd2-11b2-8080-808080808080"); 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 UUID getId(); 40 UUID getId();
37 41
  42 + @ApiModelProperty(position = 2, required = true, value = "string", example = "DEVICE")
38 EntityType getEntityType(); 43 EntityType getEntityType();
39 44
40 @JsonIgnore 45 @JsonIgnore
@@ -16,18 +16,17 @@ @@ -16,18 +16,17 @@
16 package org.thingsboard.server.common.data.relation; 16 package org.thingsboard.server.common.data.relation;
17 17
18 import com.fasterxml.jackson.annotation.JsonIgnore; 18 import com.fasterxml.jackson.annotation.JsonIgnore;
19 -import com.fasterxml.jackson.core.JsonProcessingException;  
20 import com.fasterxml.jackson.databind.JsonNode; 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 import lombok.extern.slf4j.Slf4j; 22 import lombok.extern.slf4j.Slf4j;
23 import org.thingsboard.server.common.data.SearchTextBasedWithAdditionalInfo; 23 import org.thingsboard.server.common.data.SearchTextBasedWithAdditionalInfo;
24 import org.thingsboard.server.common.data.id.EntityId; 24 import org.thingsboard.server.common.data.id.EntityId;
25 25
26 -import java.io.ByteArrayInputStream;  
27 -import java.io.IOException;  
28 import java.io.Serializable; 26 import java.io.Serializable;
29 27
30 @Slf4j 28 @Slf4j
  29 +@ApiModel
31 public class EntityRelation implements Serializable { 30 public class EntityRelation implements Serializable {
32 31
33 private static final long serialVersionUID = 2807343040519543363L; 32 private static final long serialVersionUID = 2807343040519543363L;
@@ -72,6 +71,7 @@ public class EntityRelation implements Serializable { @@ -72,6 +71,7 @@ public class EntityRelation implements Serializable {
72 this.additionalInfo = entityRelation.getAdditionalInfo(); 71 this.additionalInfo = entityRelation.getAdditionalInfo();
73 } 72 }
74 73
  74 + @ApiModelProperty(position = 1, value = "JSON object with [from] Entity Id.", readOnly = true)
75 public EntityId getFrom() { 75 public EntityId getFrom() {
76 return from; 76 return from;
77 } 77 }
@@ -80,6 +80,7 @@ public class EntityRelation implements Serializable { @@ -80,6 +80,7 @@ public class EntityRelation implements Serializable {
80 this.from = from; 80 this.from = from;
81 } 81 }
82 82
  83 + @ApiModelProperty(position = 2, value = "JSON object with [to] Entity Id.", readOnly = true)
83 public EntityId getTo() { 84 public EntityId getTo() {
84 return to; 85 return to;
85 } 86 }
@@ -88,6 +89,7 @@ public class EntityRelation implements Serializable { @@ -88,6 +89,7 @@ public class EntityRelation implements Serializable {
88 this.to = to; 89 this.to = to;
89 } 90 }
90 91
  92 + @ApiModelProperty(position = 3, value = "String value of relation type.", example = "Contains")
91 public String getType() { 93 public String getType() {
92 return type; 94 return type;
93 } 95 }
@@ -96,6 +98,7 @@ public class EntityRelation implements Serializable { @@ -96,6 +98,7 @@ public class EntityRelation implements Serializable {
96 this.type = type; 98 this.type = type;
97 } 99 }
98 100
  101 + @ApiModelProperty(position = 4, value = "Represents the type group of the relation.", example = "COMMON")
99 public RelationTypeGroup getTypeGroup() { 102 public RelationTypeGroup getTypeGroup() {
100 return typeGroup; 103 return typeGroup;
101 } 104 }
@@ -104,6 +107,7 @@ public class EntityRelation implements Serializable { @@ -104,6 +107,7 @@ public class EntityRelation implements Serializable {
104 this.typeGroup = typeGroup; 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 public JsonNode getAdditionalInfo() { 111 public JsonNode getAdditionalInfo() {
108 return SearchTextBasedWithAdditionalInfo.getJson(() -> additionalInfo, () -> additionalInfoBytes); 112 return SearchTextBasedWithAdditionalInfo.getJson(() -> additionalInfo, () -> additionalInfoBytes);
109 } 113 }
@@ -15,6 +15,8 @@ @@ -15,6 +15,8 @@
15 */ 15 */
16 package org.thingsboard.server.common.data.relation; 16 package org.thingsboard.server.common.data.relation;
17 17
  18 +import io.swagger.annotations.ApiModelProperty;
  19 +
18 public class EntityRelationInfo extends EntityRelation { 20 public class EntityRelationInfo extends EntityRelation {
19 21
20 private static final long serialVersionUID = 2807343097519543363L; 22 private static final long serialVersionUID = 2807343097519543363L;
@@ -30,6 +32,7 @@ public class EntityRelationInfo extends EntityRelation { @@ -30,6 +32,7 @@ public class EntityRelationInfo extends EntityRelation {
30 super(entityRelation); 32 super(entityRelation);
31 } 33 }
32 34
  35 + @ApiModelProperty(position = 6, value = "Name of the entity for [from] direction.", readOnly = true, example = "A4B72CCDFF33")
33 public String getFromName() { 36 public String getFromName() {
34 return fromName; 37 return fromName;
35 } 38 }
@@ -38,6 +41,7 @@ public class EntityRelationInfo extends EntityRelation { @@ -38,6 +41,7 @@ public class EntityRelationInfo extends EntityRelation {
38 this.fromName = fromName; 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 public String getToName() { 45 public String getToName() {
42 return toName; 46 return toName;
43 } 47 }
@@ -15,6 +15,8 @@ @@ -15,6 +15,8 @@
15 */ 15 */
16 package org.thingsboard.server.common.data.relation; 16 package org.thingsboard.server.common.data.relation;
17 17
  18 +import io.swagger.annotations.ApiModel;
  19 +import io.swagger.annotations.ApiModelProperty;
18 import lombok.Data; 20 import lombok.Data;
19 21
20 import java.util.List; 22 import java.util.List;
@@ -23,9 +25,12 @@ import java.util.List; @@ -23,9 +25,12 @@ import java.util.List;
23 * Created by ashvayka on 02.05.17. 25 * Created by ashvayka on 02.05.17.
24 */ 26 */
25 @Data 27 @Data
  28 +@ApiModel
26 public class EntityRelationsQuery { 29 public class EntityRelationsQuery {
27 30
  31 + @ApiModelProperty(position = 2, value = "Main search parameters.")
28 private RelationsSearchParameters parameters; 32 private RelationsSearchParameters parameters;
  33 + @ApiModelProperty(position = 1, value = "Main filters.")
29 private List<RelationEntityTypeFilter> filters; 34 private List<RelationEntityTypeFilter> filters;
30 35
31 } 36 }
@@ -15,6 +15,8 @@ @@ -15,6 +15,8 @@
15 */ 15 */
16 package org.thingsboard.server.common.data.relation; 16 package org.thingsboard.server.common.data.relation;
17 17
  18 +import io.swagger.annotations.ApiModel;
  19 +import io.swagger.annotations.ApiModelProperty;
18 import lombok.AllArgsConstructor; 20 import lombok.AllArgsConstructor;
19 import lombok.Data; 21 import lombok.Data;
20 import org.thingsboard.server.common.data.EntityType; 22 import org.thingsboard.server.common.data.EntityType;
@@ -26,9 +28,12 @@ import java.util.List; @@ -26,9 +28,12 @@ import java.util.List;
26 */ 28 */
27 @Data 29 @Data
28 @AllArgsConstructor 30 @AllArgsConstructor
  31 +@ApiModel
29 public class RelationEntityTypeFilter { 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 private String relationType; 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 private List<EntityType> entityTypes; 38 private List<EntityType> entityTypes;
34 } 39 }
@@ -15,6 +15,7 @@ @@ -15,6 +15,7 @@
15 */ 15 */
16 package org.thingsboard.server.common.data.relation; 16 package org.thingsboard.server.common.data.relation;
17 17
  18 +import com.fasterxml.jackson.annotation.JsonIgnore;
18 import io.swagger.annotations.ApiModel; 19 import io.swagger.annotations.ApiModel;
19 import io.swagger.annotations.ApiModelProperty; 20 import io.swagger.annotations.ApiModelProperty;
20 import lombok.AllArgsConstructor; 21 import lombok.AllArgsConstructor;
@@ -33,7 +34,7 @@ import java.util.UUID; @@ -33,7 +34,7 @@ import java.util.UUID;
33 @AllArgsConstructor 34 @AllArgsConstructor
34 public class RelationsSearchParameters { 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 private UUID rootId; 38 private UUID rootId;
38 @ApiModelProperty(position = 2, value = "Type of the root entity.") 39 @ApiModelProperty(position = 2, value = "Type of the root entity.")
39 private EntityType rootType; 40 private EntityType rootType;
@@ -59,6 +60,7 @@ public class RelationsSearchParameters { @@ -59,6 +60,7 @@ public class RelationsSearchParameters {
59 this.fetchLastLevelOnly = fetchLastLevelOnly; 60 this.fetchLastLevelOnly = fetchLastLevelOnly;
60 } 61 }
61 62
  63 + @JsonIgnore
62 public EntityId getEntityId() { 64 public EntityId getEntityId() {
63 return EntityIdFactory.getByTypeAndUuid(rootType, rootId); 65 return EntityIdFactory.getByTypeAndUuid(rootType, rootId);
64 } 66 }