Commit fbdb7bf224645d0f24b33f01e4a8042fdcb4959d

Authored by Andrii Shvaika
1 parent 45424ded

Move constants to ControllerConstants

Showing 31 changed files with 1620 additions and 1318 deletions
@@ -41,6 +41,8 @@ import org.thingsboard.server.service.security.permission.Resource; @@ -41,6 +41,8 @@ import org.thingsboard.server.service.security.permission.Resource;
41 import org.thingsboard.server.service.security.system.SystemSecurityService; 41 import org.thingsboard.server.service.security.system.SystemSecurityService;
42 import org.thingsboard.server.service.update.UpdateService; 42 import org.thingsboard.server.service.update.UpdateService;
43 43
  44 +import static org.thingsboard.server.controller.ControllerConstants.SYSTEM_AUTHORITY_PARAGRAPH;
  45 +
44 @RestController 46 @RestController
45 @TbCoreComponent 47 @TbCoreComponent
46 @RequestMapping("/api/admin") 48 @RequestMapping("/api/admin")
@@ -52,6 +52,21 @@ import org.thingsboard.server.service.security.permission.Resource; @@ -52,6 +52,21 @@ import org.thingsboard.server.service.security.permission.Resource;
52 52
53 import java.util.List; 53 import java.util.List;
54 54
  55 +import static org.thingsboard.server.controller.ControllerConstants.ALARM_ID_PARAM_DESCRIPTION;
  56 +import static org.thingsboard.server.controller.ControllerConstants.ALARM_INFO_DESCRIPTION;
  57 +import static org.thingsboard.server.controller.ControllerConstants.ALARM_SORT_PROPERTY_ALLOWABLE_VALUES;
  58 +import static org.thingsboard.server.controller.ControllerConstants.ENTITY_ID;
  59 +import static org.thingsboard.server.controller.ControllerConstants.ENTITY_ID_PARAM_DESCRIPTION;
  60 +import static org.thingsboard.server.controller.ControllerConstants.ENTITY_TYPE;
  61 +import static org.thingsboard.server.controller.ControllerConstants.ENTITY_TYPE_PARAM_DESCRIPTION;
  62 +import static org.thingsboard.server.controller.ControllerConstants.PAGE_DATA_PARAMETERS;
  63 +import static org.thingsboard.server.controller.ControllerConstants.PAGE_NUMBER_DESCRIPTION;
  64 +import static org.thingsboard.server.controller.ControllerConstants.PAGE_SIZE_DESCRIPTION;
  65 +import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_ALLOWABLE_VALUES;
  66 +import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_DESCRIPTION;
  67 +import static org.thingsboard.server.controller.ControllerConstants.SORT_PROPERTY_DESCRIPTION;
  68 +import static org.thingsboard.server.controller.ControllerConstants.TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH;
  69 +
55 @RestController 70 @RestController
56 @TbCoreComponent 71 @TbCoreComponent
57 @RequestMapping("/api") 72 @RequestMapping("/api")
@@ -64,6 +64,26 @@ import java.util.ArrayList; @@ -64,6 +64,26 @@ import java.util.ArrayList;
64 import java.util.List; 64 import java.util.List;
65 import java.util.stream.Collectors; 65 import java.util.stream.Collectors;
66 66
  67 +import static org.thingsboard.server.controller.ControllerConstants.ASSET_ID_PARAM_DESCRIPTION;
  68 +import static org.thingsboard.server.controller.ControllerConstants.ASSET_INFO_DESCRIPTION;
  69 +import static org.thingsboard.server.controller.ControllerConstants.ASSET_NAME_DESCRIPTION;
  70 +import static org.thingsboard.server.controller.ControllerConstants.ASSET_SORT_PROPERTY_ALLOWABLE_VALUES;
  71 +import static org.thingsboard.server.controller.ControllerConstants.ASSET_TEXT_SEARCH_DESCRIPTION;
  72 +import static org.thingsboard.server.controller.ControllerConstants.ASSET_TYPE_DESCRIPTION;
  73 +import static org.thingsboard.server.controller.ControllerConstants.CUSTOMER_ID_PARAM_DESCRIPTION;
  74 +import static org.thingsboard.server.controller.ControllerConstants.EDGE_ASSIGN_ASYNC_FIRST_STEP_DESCRIPTION;
  75 +import static org.thingsboard.server.controller.ControllerConstants.EDGE_ASSIGN_RECEIVE_STEP_DESCRIPTION;
  76 +import static org.thingsboard.server.controller.ControllerConstants.EDGE_ID_PARAM_DESCRIPTION;
  77 +import static org.thingsboard.server.controller.ControllerConstants.EDGE_UNASSIGN_ASYNC_FIRST_STEP_DESCRIPTION;
  78 +import static org.thingsboard.server.controller.ControllerConstants.EDGE_UNASSIGN_RECEIVE_STEP_DESCRIPTION;
  79 +import static org.thingsboard.server.controller.ControllerConstants.PAGE_DATA_PARAMETERS;
  80 +import static org.thingsboard.server.controller.ControllerConstants.PAGE_NUMBER_DESCRIPTION;
  81 +import static org.thingsboard.server.controller.ControllerConstants.PAGE_SIZE_DESCRIPTION;
  82 +import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_ALLOWABLE_VALUES;
  83 +import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_DESCRIPTION;
  84 +import static org.thingsboard.server.controller.ControllerConstants.SORT_PROPERTY_DESCRIPTION;
  85 +import static org.thingsboard.server.controller.ControllerConstants.TENANT_AUTHORITY_PARAGRAPH;
  86 +import static org.thingsboard.server.controller.ControllerConstants.TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH;
67 import static org.thingsboard.server.controller.EdgeController.EDGE_ID; 87 import static org.thingsboard.server.controller.EdgeController.EDGE_ID;
68 import static org.thingsboard.server.dao.asset.BaseAssetService.TB_SERVICE_QUEUE; 88 import static org.thingsboard.server.dao.asset.BaseAssetService.TB_SERVICE_QUEUE;
69 89
@@ -42,6 +42,19 @@ import java.util.List; @@ -42,6 +42,19 @@ import java.util.List;
42 import java.util.UUID; 42 import java.util.UUID;
43 import java.util.stream.Collectors; 43 import java.util.stream.Collectors;
44 44
  45 +import static org.thingsboard.server.controller.ControllerConstants.AUDIT_LOG_SORT_PROPERTY_ALLOWABLE_VALUES;
  46 +import static org.thingsboard.server.controller.ControllerConstants.AUDIT_LOG_TEXT_SEARCH_DESCRIPTION;
  47 +import static org.thingsboard.server.controller.ControllerConstants.CUSTOMER_ID_PARAM_DESCRIPTION;
  48 +import static org.thingsboard.server.controller.ControllerConstants.ENTITY_ID_PARAM_DESCRIPTION;
  49 +import static org.thingsboard.server.controller.ControllerConstants.ENTITY_TYPE_PARAM_DESCRIPTION;
  50 +import static org.thingsboard.server.controller.ControllerConstants.PAGE_DATA_PARAMETERS;
  51 +import static org.thingsboard.server.controller.ControllerConstants.PAGE_NUMBER_DESCRIPTION;
  52 +import static org.thingsboard.server.controller.ControllerConstants.PAGE_SIZE_DESCRIPTION;
  53 +import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_ALLOWABLE_VALUES;
  54 +import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_DESCRIPTION;
  55 +import static org.thingsboard.server.controller.ControllerConstants.TENANT_AUTHORITY_PARAGRAPH;
  56 +import static org.thingsboard.server.controller.ControllerConstants.USER_ID_PARAM_DESCRIPTION;
  57 +
45 @RestController 58 @RestController
46 @TbCoreComponent 59 @TbCoreComponent
47 @RequestMapping("/api") 60 @RequestMapping("/api")
@@ -147,6 +147,8 @@ import java.util.Optional; @@ -147,6 +147,8 @@ import java.util.Optional;
147 import java.util.Set; 147 import java.util.Set;
148 import java.util.UUID; 148 import java.util.UUID;
149 149
  150 +import static org.thingsboard.server.controller.ControllerConstants.DEFAULT_PAGE_SIZE;
  151 +import static org.thingsboard.server.controller.ControllerConstants.INCORRECT_TENANT_ID;
150 import static org.thingsboard.server.dao.service.Validator.validateId; 152 import static org.thingsboard.server.dao.service.Validator.validateId;
151 153
152 @Slf4j 154 @Slf4j
@@ -155,251 +157,6 @@ public abstract class BaseController { @@ -155,251 +157,6 @@ public abstract class BaseController {
155 157
156 /*Swagger UI description*/ 158 /*Swagger UI description*/
157 159
158 - protected static final String NEW_LINE = "\n\n";  
159 -  
160 - public static final String CUSTOMER_ID = "customerId";  
161 - public static final String TENANT_ID = "tenantId";  
162 - public static final String DEVICE_ID = "deviceId";  
163 - public static final String RPC_ID = "rpcId";  
164 - public static final String ENTITY_ID = "entityId";  
165 - public static final String ENTITY_TYPE = "entityType";  
166 -  
167 - public static final String PAGE_DATA_PARAMETERS = "You can specify parameters to filter the results. " +  
168 - "The result is wrapped with PageData object that allows you to iterate over result set using pagination. " +  
169 - "See the 'Model' tab of the Response Class for more details. ";  
170 - public static final String DASHBOARD_ID_PARAM_DESCRIPTION = "A string value representing the device id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'";  
171 - public static final String RPC_ID_PARAM_DESCRIPTION = "A string value representing the rpc id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'";  
172 - public static final String DEVICE_ID_PARAM_DESCRIPTION = "A string value representing the device id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'";  
173 - public static final String DEVICE_PROFILE_ID_PARAM_DESCRIPTION = "A string value representing the device profile id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'";  
174 - public static final String TENANT_PROFILE_ID_PARAM_DESCRIPTION = "A string value representing the tenant profile id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'";  
175 - public static final String TENANT_ID_PARAM_DESCRIPTION = "A string value representing the tenant id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'";  
176 - public static final String EDGE_ID_PARAM_DESCRIPTION = "A string value representing the edge id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'";  
177 - public static final String CUSTOMER_ID_PARAM_DESCRIPTION = "A string value representing the customer id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'";  
178 - public static final String USER_ID_PARAM_DESCRIPTION = "A string value representing the user id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'";  
179 - public static final String ASSET_ID_PARAM_DESCRIPTION = "A string value representing the asset id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'";  
180 - public static final String ALARM_ID_PARAM_DESCRIPTION = "A string value representing the alarm id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'";  
181 - public static final String ENTITY_ID_PARAM_DESCRIPTION = "A string value representing the entity id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'";  
182 - public static final String OTA_PACKAGE_ID_PARAM_DESCRIPTION = "A string value representing the ota package id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'";  
183 - public static final String ENTITY_TYPE_PARAM_DESCRIPTION = "A string value representing the entity type. For example, 'DEVICE'";  
184 - public static final String RULE_CHAIN_ID_PARAM_DESCRIPTION = "A string value representing the rule chain id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'";  
185 - public static final String WIDGET_BUNDLE_ID_PARAM_DESCRIPTION = "A string value representing the widget bundle id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'";  
186 - public static final String WIDGET_TYPE_ID_PARAM_DESCRIPTION = "A string value representing the widget type id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'";  
187 - public static final String RESOURCE_ID_PARAM_DESCRIPTION = "A string value representing the resource id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'";  
188 -  
189 -  
190 - protected static final String SYSTEM_AUTHORITY_PARAGRAPH = "\n\nAvailable for users with 'SYS_ADMIN' authority.";  
191 - protected static final String SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH = "\n\nAvailable for users with 'SYS_ADMIN' or 'TENANT_ADMIN' authority.";  
192 - protected static final String TENANT_AUTHORITY_PARAGRAPH = "\n\nAvailable for users with 'TENANT_ADMIN' authority.";  
193 - protected static final String TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH = "\n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority.";  
194 - protected static final String CUSTOMER_AUTHORITY_PARAGRAPH = "\n\nAvailable for users with 'CUSTOMER_USER' authority.";  
195 - protected static final String AVAILABLE_FOR_ANY_AUTHORIZED_USER = "\n\nAvailable for any authorized user. ";  
196 -  
197 - protected static final String PAGE_SIZE_DESCRIPTION = "Maximum amount of entities in a one page";  
198 - protected static final String PAGE_NUMBER_DESCRIPTION = "Sequence number of page starting from 0";  
199 - protected static final String DEVICE_TYPE_DESCRIPTION = "Device type as the name of the device profile";  
200 - protected static final String ASSET_TYPE_DESCRIPTION = "Asset type";  
201 - protected static final String EDGE_TYPE_DESCRIPTION = "A string value representing the edge type. For example, 'default'";  
202 - protected static final String RULE_CHAIN_TYPE_DESCRIPTION = "Rule chain type (CORE or EDGE)";  
203 -  
204 - protected static final String ASSET_TEXT_SEARCH_DESCRIPTION = "The case insensitive 'startsWith' filter based on the asset name.";  
205 - protected static final String DASHBOARD_TEXT_SEARCH_DESCRIPTION = "The case insensitive 'startsWith' filter based on the dashboard title.";  
206 - protected static final String WIDGET_BUNDLE_TEXT_SEARCH_DESCRIPTION = "The case insensitive 'startsWith' filter based on the widget bundle title.";  
207 - protected static final String RPC_TEXT_SEARCH_DESCRIPTION = "Not implemented. Leave empty.";  
208 - protected static final String DEVICE_TEXT_SEARCH_DESCRIPTION = "The case insensitive 'startsWith' filter based on the device name.";  
209 - protected static final String USER_TEXT_SEARCH_DESCRIPTION = "The case insensitive 'startsWith' filter based on the user email.";  
210 - protected static final String TENANT_TEXT_SEARCH_DESCRIPTION = "The case insensitive 'startsWith' filter based on the tenant name.";  
211 - protected static final String TENANT_PROFILE_TEXT_SEARCH_DESCRIPTION = "The case insensitive 'startsWith' filter based on the tenant profile name.";  
212 - protected static final String RULE_CHAIN_TEXT_SEARCH_DESCRIPTION = "The case insensitive 'startsWith' filter based on the rule chain name.";  
213 - protected static final String DEVICE_PROFILE_TEXT_SEARCH_DESCRIPTION = "The case insensitive 'startsWith' filter based on the device profile name.";  
214 - protected static final String CUSTOMER_TEXT_SEARCH_DESCRIPTION = "The case insensitive 'startsWith' filter based on the customer title.";  
215 - protected static final String EDGE_TEXT_SEARCH_DESCRIPTION = "The case insensitive 'startsWith' filter based on the edge name.";  
216 - protected static final String EVENT_TEXT_SEARCH_DESCRIPTION = "The value is not used in searching.";  
217 - protected static final String AUDIT_LOG_TEXT_SEARCH_DESCRIPTION = "The case insensitive 'startsWith' filter based on one of the next properties: entityType, entityName, userName, actionType, actionStatus.";  
218 - protected static final String SORT_PROPERTY_DESCRIPTION = "Property of entity to sort by";  
219 - protected static final String DASHBOARD_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, title";  
220 - protected static final String CUSTOMER_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, title, email, country, city";  
221 - protected static final String RPC_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, expirationTime, request, response";  
222 - protected static final String DEVICE_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, name, deviceProfileName, label, customerTitle";  
223 - protected static final String USER_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, firstName, lastName, email";  
224 - protected static final String TENANT_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, title, email, country, state, city, address, address2, zip, phone, email";  
225 - protected static final String TENANT_PROFILE_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, name, description, isDefault";  
226 - protected static final String TENANT_PROFILE_INFO_SORT_PROPERTY_ALLOWABLE_VALUES = "id, name";  
227 - protected static final String TENANT_INFO_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, tenantProfileName, title, email, country, state, city, address, address2, zip, phone, email";  
228 - protected static final String DEVICE_PROFILE_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, name, type, transportType, description, isDefault";  
229 - protected static final String ASSET_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, name, type, label, customerTitle";  
230 - protected static final String ALARM_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, startTs, endTs, type, ackTs, clearTs, severity, status";  
231 - protected static final String EVENT_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, id";  
232 - protected static final String EDGE_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, name, type, label, customerTitle";  
233 - protected static final String RULE_CHAIN_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, name, root";  
234 - protected static final String WIDGET_BUNDLE_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, title, tenantId";  
235 - protected static final String AUDIT_LOG_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, entityType, entityName, userName, actionType, actionStatus";  
236 - protected static final String SORT_ORDER_DESCRIPTION = "Sort order. ASC (ASCENDING) or DESC (DESCENDING)";  
237 - protected static final String SORT_ORDER_ALLOWABLE_VALUES = "ASC, DESC";  
238 - protected static final String RPC_STATUS_ALLOWABLE_VALUES = "QUEUED, SENT, DELIVERED, SUCCESSFUL, TIMEOUT, EXPIRED, FAILED";  
239 - protected static final String RULE_CHAIN_TYPES_ALLOWABLE_VALUES = "CORE, EDGE";  
240 - protected static final String TRANSPORT_TYPE_ALLOWABLE_VALUES = "DEFAULT, MQTT, COAP, LWM2M, SNMP";  
241 - protected static 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. ";  
242 - protected static final String ASSET_INFO_DESCRIPTION = "Asset Info is an extension of the default Asset object that contains information about the assigned customer name. ";  
243 - protected static final String ALARM_INFO_DESCRIPTION = "Alarm Info is an extension of the default Alarm object that also contains name of the alarm originator.";  
244 - protected static final String RELATION_INFO_DESCRIPTION = "Relation Info is an extension of the default Relation object that contains information about the 'from' and 'to' entity names. ";  
245 - protected static final String EDGE_INFO_DESCRIPTION = "Edge Info is an extension of the default Edge object that contains information about the assigned customer name. ";  
246 - protected static final String DEVICE_PROFILE_INFO_DESCRIPTION = "Device Profile Info is a lightweight object that includes main information about Device Profile excluding the heavyweight configuration object. ";  
247 - protected static final String QUEUE_SERVICE_TYPE_DESCRIPTION = "Service type (implemented only for the TB-RULE-ENGINE)";  
248 - protected static final String QUEUE_SERVICE_TYPE_ALLOWABLE_VALUES = "TB-RULE-ENGINE, TB-CORE, TB-TRANSPORT, JS-EXECUTOR";  
249 - protected static final String OTA_PACKAGE_INFO_DESCRIPTION = "OTA Package Info is a lightweight object that includes main information about the OTA Package excluding the heavyweight data. ";  
250 - protected static final String OTA_PACKAGE_DESCRIPTION = "OTA Package is a heavyweight object that includes main information about the OTA Package and also data. ";  
251 - protected static final String OTA_PACKAGE_CHECKSUM_ALGORITHM_ALLOWABLE_VALUES = "MD5, SHA256, SHA384, SHA512, CRC32, MURMUR3_32, MURMUR3_128";  
252 - protected static final String OTA_PACKAGE_TEXT_SEARCH_DESCRIPTION = "The case insensitive 'startsWith' filter based on the ota package title.";  
253 - protected static final String OTA_PACKAGE_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, type, title, version, tag, url, fileName, dataSize, checksum";  
254 - protected static final String RESOURCE_INFO_DESCRIPTION = "Resource Info is a lightweight object that includes main information about the Resource excluding the heavyweight data. ";  
255 - protected static final String RESOURCE_DESCRIPTION = "Resource is a heavyweight object that includes main information about the Resource and also data. ";  
256 - protected static final String RESOURCE_TEXT_SEARCH_DESCRIPTION = "The case insensitive 'startsWith' filter based on the resource title.";  
257 - protected static final String RESOURCE_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, title, resourceType, tenantId";  
258 - protected static final String LWM2M_OBJECT_DESCRIPTION = "LwM2M Object is a object that includes information about the LwM2M model which can be used in transport configuration for the LwM2M device profile. ";  
259 - protected static final String LWM2M_OBJECT_SORT_PROPERTY_ALLOWABLE_VALUES = "id, name";  
260 -  
261 - protected static final String DEVICE_NAME_DESCRIPTION = "A string value representing the Device name.";  
262 - protected static final String ASSET_NAME_DESCRIPTION = "A string value representing the Asset name.";  
263 -  
264 - protected static final String EVENT_START_TIME_DESCRIPTION = "Timestamp. Events with creation time before it won't be queried.";  
265 - protected static final String EVENT_END_TIME_DESCRIPTION = "Timestamp. Events with creation time after it won't be queried.";  
266 -  
267 - protected static final String EDGE_UNASSIGN_ASYNC_FIRST_STEP_DESCRIPTION = "Unassignment works in async way - first, 'unassign' notification event pushed to edge queue on platform. ";  
268 - protected static final String EDGE_UNASSIGN_RECEIVE_STEP_DESCRIPTION = "(Edge will receive this instantly, if it's currently connected, or once it's going to be connected to platform)";  
269 - protected static final String EDGE_ASSIGN_ASYNC_FIRST_STEP_DESCRIPTION = "Assignment works in async way - first, notification event pushed to edge service queue on platform. ";  
270 - protected static final String EDGE_ASSIGN_RECEIVE_STEP_DESCRIPTION = "(Edge will receive this instantly, if it's currently connected, or once it's going to be connected to platform)";  
271 -  
272 - protected static final String MARKDOWN_CODE_BLOCK_START = "```json\n";  
273 - protected static final String MARKDOWN_CODE_BLOCK_END = "\n```";  
274 - protected static final String EVENT_ERROR_FILTER_OBJ = MARKDOWN_CODE_BLOCK_START + "{ \"eventType\": \"ERROR\", \"server\": \"ip-172-31-24-152\", " +  
275 - "\"method\": \"onClusterEventMsg\", \"error\": \"Error Message\" }" + MARKDOWN_CODE_BLOCK_END;  
276 - protected static final String EVENT_LC_EVENT_FILTER_OBJ = MARKDOWN_CODE_BLOCK_START + "{ \"eventType\": \"LC_EVENT\", \"server\": \"ip-172-31-24-152\", \"event\":" +  
277 - " \"STARTED\", \"status\": \"Success\", \"error\": \"Error Message\" }" + MARKDOWN_CODE_BLOCK_END;  
278 - protected static final String EVENT_STATS_FILTER_OBJ = MARKDOWN_CODE_BLOCK_START + "{ \"eventType\": \"STATS\", \"server\": \"ip-172-31-24-152\", \"messagesProcessed\": 10, \"errorsOccurred\": 5 }" + MARKDOWN_CODE_BLOCK_END;  
279 - protected static final String DEBUG_FILTER_OBJ = "\"msgDirectionType\": \"IN\", \"server\": \"ip-172-31-24-152\", \"dataSearch\": \"humidity\", " +  
280 - "\"metadataSearch\": \"deviceName\", \"entityName\": \"DEVICE\", \"relationType\": \"Success\"," +  
281 - " \"entityId\": \"de9d54a0-2b7a-11ec-a3cc-23386423d98f\", \"msgType\": \"POST_TELEMETRY_REQUEST\"," +  
282 - " \"isError\": \"false\", \"error\": \"Error Message\" }";  
283 - protected static final String EVENT_DEBUG_RULE_NODE_FILTER_OBJ = MARKDOWN_CODE_BLOCK_START + "{ \"eventType\": \"DEBUG_RULE_NODE\"," + DEBUG_FILTER_OBJ + MARKDOWN_CODE_BLOCK_END;  
284 - protected static final String EVENT_DEBUG_RULE_CHAIN_FILTER_OBJ = MARKDOWN_CODE_BLOCK_START + "{ \"eventType\": \"DEBUG_RULE_CHAIN\"," + DEBUG_FILTER_OBJ + MARKDOWN_CODE_BLOCK_END;  
285 -  
286 - protected static final String FILTER_VALUE_TYPE = NEW_LINE + "## Value Type and Operations" + NEW_LINE +  
287 - "Provides a hint about the data type of the entity field that is defined in the filter key. " +  
288 - "The value type impacts the list of possible operations that you may use in the corresponding predicate. For example, you may use 'STARTS_WITH' or 'END_WITH', but you can't use 'GREATER_OR_EQUAL' for string values." +  
289 - "The following filter value types and corresponding predicate operations are supported: " + NEW_LINE +  
290 - " * 'STRING' - used to filter any 'String' or 'JSON' values. Operations: EQUAL, NOT_EQUAL, STARTS_WITH, ENDS_WITH, CONTAINS, NOT_CONTAINS; \n" +  
291 - " * 'NUMERIC' - used for 'Long' and 'Double' values. Operations: EQUAL, NOT_EQUAL, GREATER, LESS, GREATER_OR_EQUAL, LESS_OR_EQUAL; \n" +  
292 - " * 'BOOLEAN' - used for boolean values. Operations: EQUAL, NOT_EQUAL;\n" +  
293 - " * 'DATE_TIME' - similar to numeric, transforms value to milliseconds since epoch. Operations: EQUAL, NOT_EQUAL, GREATER, LESS, GREATER_OR_EQUAL, LESS_OR_EQUAL; \n";  
294 -  
295 - protected static final String DEVICE_PROFILE_ALARM_SCHEDULE_SPECIFIC_TIME_EXAMPLE = MARKDOWN_CODE_BLOCK_START +  
296 - "{\n" +  
297 - " \"schedule\":{\n" +  
298 - " \"type\":\"SPECIFIC_TIME\",\n" +  
299 - " \"endsOn\":64800000,\n" +  
300 - " \"startsOn\":43200000,\n" +  
301 - " \"timezone\":\"Europe/Kiev\",\n" +  
302 - " \"daysOfWeek\":[\n" +  
303 - " 1,\n" +  
304 - " 3,\n" +  
305 - " 5\n" +  
306 - " ]\n" +  
307 - " }\n" +  
308 - "}" +  
309 - MARKDOWN_CODE_BLOCK_END;  
310 - protected static final String DEVICE_PROFILE_ALARM_SCHEDULE_CUSTOM_EXAMPLE = MARKDOWN_CODE_BLOCK_START +  
311 - "{\n" +  
312 - " \"schedule\":{\n" +  
313 - " \"type\":\"CUSTOM\",\n" +  
314 - " \"items\":[\n" +  
315 - " {\n" +  
316 - " \"endsOn\":0,\n" +  
317 - " \"enabled\":false,\n" +  
318 - " \"startsOn\":0,\n" +  
319 - " \"dayOfWeek\":1\n" +  
320 - " },\n" +  
321 - " {\n" +  
322 - " \"endsOn\":64800000,\n" +  
323 - " \"enabled\":true,\n" +  
324 - " \"startsOn\":43200000,\n" +  
325 - " \"dayOfWeek\":2\n" +  
326 - " },\n" +  
327 - " {\n" +  
328 - " \"endsOn\":0,\n" +  
329 - " \"enabled\":false,\n" +  
330 - " \"startsOn\":0,\n" +  
331 - " \"dayOfWeek\":3\n" +  
332 - " },\n" +  
333 - " {\n" +  
334 - " \"endsOn\":57600000,\n" +  
335 - " \"enabled\":true,\n" +  
336 - " \"startsOn\":36000000,\n" +  
337 - " \"dayOfWeek\":4\n" +  
338 - " },\n" +  
339 - " {\n" +  
340 - " \"endsOn\":0,\n" +  
341 - " \"enabled\":false,\n" +  
342 - " \"startsOn\":0,\n" +  
343 - " \"dayOfWeek\":5\n" +  
344 - " },\n" +  
345 - " {\n" +  
346 - " \"endsOn\":0,\n" +  
347 - " \"enabled\":false,\n" +  
348 - " \"startsOn\":0,\n" +  
349 - " \"dayOfWeek\":6\n" +  
350 - " },\n" +  
351 - " {\n" +  
352 - " \"endsOn\":0,\n" +  
353 - " \"enabled\":false,\n" +  
354 - " \"startsOn\":0,\n" +  
355 - " \"dayOfWeek\":7\n" +  
356 - " }\n" +  
357 - " ],\n" +  
358 - " \"timezone\":\"Europe/Kiev\"\n" +  
359 - " }\n" +  
360 - "}" +  
361 - MARKDOWN_CODE_BLOCK_END;  
362 - protected static final String DEVICE_PROFILE_ALARM_SCHEDULE_ALWAYS_EXAMPLE = MARKDOWN_CODE_BLOCK_START + "\"schedule\": null" + MARKDOWN_CODE_BLOCK_END;  
363 -  
364 - protected static final String DEVICE_PROFILE_ALARM_CONDITION_REPEATING_EXAMPLE = MARKDOWN_CODE_BLOCK_START +  
365 - "{\n" +  
366 - " \"spec\":{\n" +  
367 - " \"type\":\"REPEATING\",\n" +  
368 - " \"predicate\":{\n" +  
369 - " \"userValue\":null,\n" +  
370 - " \"defaultValue\":5,\n" +  
371 - " \"dynamicValue\":{\n" +  
372 - " \"inherit\":true,\n" +  
373 - " \"sourceType\":\"CURRENT_DEVICE\",\n" +  
374 - " \"sourceAttribute\":\"tempAttr\"\n" +  
375 - " }\n" +  
376 - " }\n" +  
377 - " }\n" +  
378 - "}" +  
379 - MARKDOWN_CODE_BLOCK_END;  
380 - protected static final String DEVICE_PROFILE_ALARM_CONDITION_DURATION_EXAMPLE = MARKDOWN_CODE_BLOCK_START +  
381 - "{\n" +  
382 - " \"spec\":{\n" +  
383 - " \"type\":\"DURATION\",\n" +  
384 - " \"unit\":\"MINUTES\",\n" +  
385 - " \"predicate\":{\n" +  
386 - " \"userValue\":null,\n" +  
387 - " \"defaultValue\":30,\n" +  
388 - " \"dynamicValue\":null\n" +  
389 - " }\n" +  
390 - " }\n" +  
391 - "}" +  
392 - MARKDOWN_CODE_BLOCK_END;  
393 -  
394 - 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.";  
395 - protected static final String RELATION_TYPE_GROUP_PARAM_DESCRIPTION = "A string value representing relation type group. For example, 'COMMON'";  
396 -  
397 - public static final String INCORRECT_TENANT_ID = "Incorrect tenantId ";  
398 - protected static final String DEFAULT_DASHBOARD = "defaultDashboardId";  
399 - protected static final String HOME_DASHBOARD = "homeDashboardId";  
400 -  
401 - private static final int DEFAULT_PAGE_SIZE = 1000;  
402 -  
403 private static final ObjectMapper json = new ObjectMapper(); 160 private static final ObjectMapper json = new ObjectMapper();
404 161
405 @Autowired 162 @Autowired
@@ -35,6 +35,8 @@ import java.util.HashSet; @@ -35,6 +35,8 @@ import java.util.HashSet;
35 import java.util.List; 35 import java.util.List;
36 import java.util.Set; 36 import java.util.Set;
37 37
  38 +import static org.thingsboard.server.controller.ControllerConstants.SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH;
  39 +
38 @RestController 40 @RestController
39 @TbCoreComponent 41 @TbCoreComponent
40 @RequestMapping("/api") 42 @RequestMapping("/api")
  1 +/**
  2 + * Copyright © 2016-2021 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package org.thingsboard.server.controller;
  17 +
  18 +public class ControllerConstants {
  19 +
  20 +
  21 + protected static final String NEW_LINE = "\n\n";
  22 + protected static final int DEFAULT_PAGE_SIZE = 1000;
  23 + protected static final String ENTITY_TYPE = "entityType";
  24 + protected static final String CUSTOMER_ID = "customerId";
  25 + protected static final String TENANT_ID = "tenantId";
  26 + protected static final String DEVICE_ID = "deviceId";
  27 + protected static final String RPC_ID = "rpcId";
  28 + protected static final String ENTITY_ID = "entityId";
  29 + protected static final String PAGE_DATA_PARAMETERS = "You can specify parameters to filter the results. " +
  30 + "The result is wrapped with PageData object that allows you to iterate over result set using pagination. " +
  31 + "See the 'Model' tab of the Response Class for more details. ";
  32 + protected static final String DASHBOARD_ID_PARAM_DESCRIPTION = "A string value representing the device id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'";
  33 + protected static final String RPC_ID_PARAM_DESCRIPTION = "A string value representing the rpc id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'";
  34 + protected static final String DEVICE_ID_PARAM_DESCRIPTION = "A string value representing the device id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'";
  35 + protected static final String DEVICE_PROFILE_ID_PARAM_DESCRIPTION = "A string value representing the device profile id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'";
  36 + protected static final String TENANT_PROFILE_ID_PARAM_DESCRIPTION = "A string value representing the tenant profile id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'";
  37 + protected static final String TENANT_ID_PARAM_DESCRIPTION = "A string value representing the tenant id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'";
  38 + protected static final String EDGE_ID_PARAM_DESCRIPTION = "A string value representing the edge id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'";
  39 + protected static final String CUSTOMER_ID_PARAM_DESCRIPTION = "A string value representing the customer id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'";
  40 + protected static final String USER_ID_PARAM_DESCRIPTION = "A string value representing the user id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'";
  41 + protected static final String ASSET_ID_PARAM_DESCRIPTION = "A string value representing the asset id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'";
  42 + protected static final String ALARM_ID_PARAM_DESCRIPTION = "A string value representing the alarm id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'";
  43 + protected static final String ENTITY_ID_PARAM_DESCRIPTION = "A string value representing the entity id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'";
  44 + protected static final String OTA_PACKAGE_ID_PARAM_DESCRIPTION = "A string value representing the ota package id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'";
  45 + protected static final String ENTITY_TYPE_PARAM_DESCRIPTION = "A string value representing the entity type. For example, 'DEVICE'";
  46 + protected static final String RULE_CHAIN_ID_PARAM_DESCRIPTION = "A string value representing the rule chain id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'";
  47 + protected static final String WIDGET_BUNDLE_ID_PARAM_DESCRIPTION = "A string value representing the widget bundle id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'";
  48 + protected static final String WIDGET_TYPE_ID_PARAM_DESCRIPTION = "A string value representing the widget type id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'";
  49 + protected static final String RESOURCE_ID_PARAM_DESCRIPTION = "A string value representing the resource id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'";
  50 + protected static final String SYSTEM_AUTHORITY_PARAGRAPH = "\n\nAvailable for users with 'SYS_ADMIN' authority.";
  51 + protected static final String SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH = "\n\nAvailable for users with 'SYS_ADMIN' or 'TENANT_ADMIN' authority.";
  52 + protected static final String TENANT_AUTHORITY_PARAGRAPH = "\n\nAvailable for users with 'TENANT_ADMIN' authority.";
  53 + protected static final String TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH = "\n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority.";
  54 + protected static final String CUSTOMER_AUTHORITY_PARAGRAPH = "\n\nAvailable for users with 'CUSTOMER_USER' authority.";
  55 + protected static final String AVAILABLE_FOR_ANY_AUTHORIZED_USER = "\n\nAvailable for any authorized user. ";
  56 + protected static final String PAGE_SIZE_DESCRIPTION = "Maximum amount of entities in a one page";
  57 + protected static final String PAGE_NUMBER_DESCRIPTION = "Sequence number of page starting from 0";
  58 + protected static final String DEVICE_TYPE_DESCRIPTION = "Device type as the name of the device profile";
  59 + protected static final String ASSET_TYPE_DESCRIPTION = "Asset type";
  60 + protected static final String EDGE_TYPE_DESCRIPTION = "A string value representing the edge type. For example, 'default'";
  61 + protected static final String RULE_CHAIN_TYPE_DESCRIPTION = "Rule chain type (CORE or EDGE)";
  62 + protected static final String ASSET_TEXT_SEARCH_DESCRIPTION = "The case insensitive 'startsWith' filter based on the asset name.";
  63 + protected static final String DASHBOARD_TEXT_SEARCH_DESCRIPTION = "The case insensitive 'startsWith' filter based on the dashboard title.";
  64 + protected static final String WIDGET_BUNDLE_TEXT_SEARCH_DESCRIPTION = "The case insensitive 'startsWith' filter based on the widget bundle title.";
  65 + protected static final String RPC_TEXT_SEARCH_DESCRIPTION = "Not implemented. Leave empty.";
  66 + protected static final String DEVICE_TEXT_SEARCH_DESCRIPTION = "The case insensitive 'startsWith' filter based on the device name.";
  67 + protected static final String USER_TEXT_SEARCH_DESCRIPTION = "The case insensitive 'startsWith' filter based on the user email.";
  68 + protected static final String TENANT_TEXT_SEARCH_DESCRIPTION = "The case insensitive 'startsWith' filter based on the tenant name.";
  69 + protected static final String TENANT_PROFILE_TEXT_SEARCH_DESCRIPTION = "The case insensitive 'startsWith' filter based on the tenant profile name.";
  70 + protected static final String RULE_CHAIN_TEXT_SEARCH_DESCRIPTION = "The case insensitive 'startsWith' filter based on the rule chain name.";
  71 + protected static final String DEVICE_PROFILE_TEXT_SEARCH_DESCRIPTION = "The case insensitive 'startsWith' filter based on the device profile name.";
  72 + protected static final String CUSTOMER_TEXT_SEARCH_DESCRIPTION = "The case insensitive 'startsWith' filter based on the customer title.";
  73 + protected static final String EDGE_TEXT_SEARCH_DESCRIPTION = "The case insensitive 'startsWith' filter based on the edge name.";
  74 + protected static final String EVENT_TEXT_SEARCH_DESCRIPTION = "The value is not used in searching.";
  75 + protected static final String AUDIT_LOG_TEXT_SEARCH_DESCRIPTION = "The case insensitive 'startsWith' filter based on one of the next properties: entityType, entityName, userName, actionType, actionStatus.";
  76 + protected static final String SORT_PROPERTY_DESCRIPTION = "Property of entity to sort by";
  77 + protected static final String DASHBOARD_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, title";
  78 + protected static final String CUSTOMER_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, title, email, country, city";
  79 + protected static final String RPC_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, expirationTime, request, response";
  80 + protected static final String DEVICE_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, name, deviceProfileName, label, customerTitle";
  81 + protected static final String USER_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, firstName, lastName, email";
  82 + protected static final String TENANT_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, title, email, country, state, city, address, address2, zip, phone, email";
  83 + protected static final String TENANT_PROFILE_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, name, description, isDefault";
  84 + protected static final String TENANT_PROFILE_INFO_SORT_PROPERTY_ALLOWABLE_VALUES = "id, name";
  85 + protected static final String TENANT_INFO_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, tenantProfileName, title, email, country, state, city, address, address2, zip, phone, email";
  86 + protected static final String DEVICE_PROFILE_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, name, type, transportType, description, isDefault";
  87 + protected static final String ASSET_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, name, type, label, customerTitle";
  88 + protected static final String ALARM_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, startTs, endTs, type, ackTs, clearTs, severity, status";
  89 + protected static final String EVENT_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, id";
  90 + protected static final String EDGE_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, name, type, label, customerTitle";
  91 + protected static final String RULE_CHAIN_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, name, root";
  92 + protected static final String WIDGET_BUNDLE_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, title, tenantId";
  93 + protected static final String AUDIT_LOG_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, entityType, entityName, userName, actionType, actionStatus";
  94 + protected static final String SORT_ORDER_DESCRIPTION = "Sort order. ASC (ASCENDING) or DESC (DESCENDING)";
  95 + protected static final String SORT_ORDER_ALLOWABLE_VALUES = "ASC, DESC";
  96 + protected static final String RPC_STATUS_ALLOWABLE_VALUES = "QUEUED, SENT, DELIVERED, SUCCESSFUL, TIMEOUT, EXPIRED, FAILED";
  97 + protected static final String RULE_CHAIN_TYPES_ALLOWABLE_VALUES = "CORE, EDGE";
  98 + protected static final String TRANSPORT_TYPE_ALLOWABLE_VALUES = "DEFAULT, MQTT, COAP, LWM2M, SNMP";
  99 + protected static 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. ";
  100 + protected static final String ASSET_INFO_DESCRIPTION = "Asset Info is an extension of the default Asset object that contains information about the assigned customer name. ";
  101 + protected static final String ALARM_INFO_DESCRIPTION = "Alarm Info is an extension of the default Alarm object that also contains name of the alarm originator.";
  102 + protected static final String RELATION_INFO_DESCRIPTION = "Relation Info is an extension of the default Relation object that contains information about the 'from' and 'to' entity names. ";
  103 + protected static final String EDGE_INFO_DESCRIPTION = "Edge Info is an extension of the default Edge object that contains information about the assigned customer name. ";
  104 + protected static final String DEVICE_PROFILE_INFO_DESCRIPTION = "Device Profile Info is a lightweight object that includes main information about Device Profile excluding the heavyweight configuration object. ";
  105 + protected static final String QUEUE_SERVICE_TYPE_DESCRIPTION = "Service type (implemented only for the TB-RULE-ENGINE)";
  106 + protected static final String QUEUE_SERVICE_TYPE_ALLOWABLE_VALUES = "TB-RULE-ENGINE, TB-CORE, TB-TRANSPORT, JS-EXECUTOR";
  107 + protected static final String OTA_PACKAGE_INFO_DESCRIPTION = "OTA Package Info is a lightweight object that includes main information about the OTA Package excluding the heavyweight data. ";
  108 + protected static final String OTA_PACKAGE_DESCRIPTION = "OTA Package is a heavyweight object that includes main information about the OTA Package and also data. ";
  109 + protected static final String OTA_PACKAGE_CHECKSUM_ALGORITHM_ALLOWABLE_VALUES = "MD5, SHA256, SHA384, SHA512, CRC32, MURMUR3_32, MURMUR3_128";
  110 + protected static final String OTA_PACKAGE_TEXT_SEARCH_DESCRIPTION = "The case insensitive 'startsWith' filter based on the ota package title.";
  111 + protected static final String OTA_PACKAGE_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, type, title, version, tag, url, fileName, dataSize, checksum";
  112 + protected static final String RESOURCE_INFO_DESCRIPTION = "Resource Info is a lightweight object that includes main information about the Resource excluding the heavyweight data. ";
  113 + protected static final String RESOURCE_DESCRIPTION = "Resource is a heavyweight object that includes main information about the Resource and also data. ";
  114 +
  115 + protected static final String RESOURCE_TEXT_SEARCH_DESCRIPTION = "The case insensitive 'startsWith' filter based on the resource title.";
  116 + protected static final String RESOURCE_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, title, resourceType, tenantId";
  117 + protected static final String LWM2M_OBJECT_DESCRIPTION = "LwM2M Object is a object that includes information about the LwM2M model which can be used in transport configuration for the LwM2M device profile. ";
  118 + protected static final String LWM2M_OBJECT_SORT_PROPERTY_ALLOWABLE_VALUES = "id, name";
  119 +
  120 + protected static final String DEVICE_NAME_DESCRIPTION = "A string value representing the Device name.";
  121 + protected static final String ASSET_NAME_DESCRIPTION = "A string value representing the Asset name.";
  122 +
  123 + protected static final String EVENT_START_TIME_DESCRIPTION = "Timestamp. Events with creation time before it won't be queried.";
  124 + protected static final String EVENT_END_TIME_DESCRIPTION = "Timestamp. Events with creation time after it won't be queried.";
  125 +
  126 + protected static final String EDGE_UNASSIGN_ASYNC_FIRST_STEP_DESCRIPTION = "Unassignment works in async way - first, 'unassign' notification event pushed to edge queue on platform. ";
  127 + protected static final String EDGE_UNASSIGN_RECEIVE_STEP_DESCRIPTION = "(Edge will receive this instantly, if it's currently connected, or once it's going to be connected to platform)";
  128 + protected static final String EDGE_ASSIGN_ASYNC_FIRST_STEP_DESCRIPTION = "Assignment works in async way - first, notification event pushed to edge service queue on platform. ";
  129 + protected static final String EDGE_ASSIGN_RECEIVE_STEP_DESCRIPTION = "(Edge will receive this instantly, if it's currently connected, or once it's going to be connected to platform)";
  130 +
  131 + protected static final String MARKDOWN_CODE_BLOCK_START = "```json\n";
  132 + protected static final String MARKDOWN_CODE_BLOCK_END = "\n```";
  133 + protected static final String EVENT_ERROR_FILTER_OBJ = MARKDOWN_CODE_BLOCK_START + "{ \"eventType\": \"ERROR\", \"server\": \"ip-172-31-24-152\", " +
  134 + "\"method\": \"onClusterEventMsg\", \"error\": \"Error Message\" }" + MARKDOWN_CODE_BLOCK_END;
  135 + protected static final String EVENT_LC_EVENT_FILTER_OBJ = MARKDOWN_CODE_BLOCK_START + "{ \"eventType\": \"LC_EVENT\", \"server\": \"ip-172-31-24-152\", \"event\":" +
  136 + " \"STARTED\", \"status\": \"Success\", \"error\": \"Error Message\" }" + MARKDOWN_CODE_BLOCK_END;
  137 + protected static final String EVENT_STATS_FILTER_OBJ = MARKDOWN_CODE_BLOCK_START + "{ \"eventType\": \"STATS\", \"server\": \"ip-172-31-24-152\", \"messagesProcessed\": 10, \"errorsOccurred\": 5 }" + MARKDOWN_CODE_BLOCK_END;
  138 + protected static final String DEBUG_FILTER_OBJ = "\"msgDirectionType\": \"IN\", \"server\": \"ip-172-31-24-152\", \"dataSearch\": \"humidity\", " +
  139 + "\"metadataSearch\": \"deviceName\", \"entityName\": \"DEVICE\", \"relationType\": \"Success\"," +
  140 + " \"entityId\": \"de9d54a0-2b7a-11ec-a3cc-23386423d98f\", \"msgType\": \"POST_TELEMETRY_REQUEST\"," +
  141 + " \"isError\": \"false\", \"error\": \"Error Message\" }";
  142 + protected static final String EVENT_DEBUG_RULE_NODE_FILTER_OBJ = MARKDOWN_CODE_BLOCK_START + "{ \"eventType\": \"DEBUG_RULE_NODE\"," + DEBUG_FILTER_OBJ + MARKDOWN_CODE_BLOCK_END;
  143 + protected static final String EVENT_DEBUG_RULE_CHAIN_FILTER_OBJ = MARKDOWN_CODE_BLOCK_START + "{ \"eventType\": \"DEBUG_RULE_CHAIN\"," + DEBUG_FILTER_OBJ + MARKDOWN_CODE_BLOCK_END;
  144 +
  145 + protected static final String FILTER_VALUE_TYPE = NEW_LINE + "## Value Type and Operations" + NEW_LINE +
  146 + "Provides a hint about the data type of the entity field that is defined in the filter key. " +
  147 + "The value type impacts the list of possible operations that you may use in the corresponding predicate. For example, you may use 'STARTS_WITH' or 'END_WITH', but you can't use 'GREATER_OR_EQUAL' for string values." +
  148 + "The following filter value types and corresponding predicate operations are supported: " + NEW_LINE +
  149 + " * 'STRING' - used to filter any 'String' or 'JSON' values. Operations: EQUAL, NOT_EQUAL, STARTS_WITH, ENDS_WITH, CONTAINS, NOT_CONTAINS; \n" +
  150 + " * 'NUMERIC' - used for 'Long' and 'Double' values. Operations: EQUAL, NOT_EQUAL, GREATER, LESS, GREATER_OR_EQUAL, LESS_OR_EQUAL; \n" +
  151 + " * 'BOOLEAN' - used for boolean values. Operations: EQUAL, NOT_EQUAL;\n" +
  152 + " * 'DATE_TIME' - similar to numeric, transforms value to milliseconds since epoch. Operations: EQUAL, NOT_EQUAL, GREATER, LESS, GREATER_OR_EQUAL, LESS_OR_EQUAL; \n";
  153 +
  154 + protected static final String DEVICE_PROFILE_ALARM_SCHEDULE_SPECIFIC_TIME_EXAMPLE = MARKDOWN_CODE_BLOCK_START +
  155 + "{\n" +
  156 + " \"schedule\":{\n" +
  157 + " \"type\":\"SPECIFIC_TIME\",\n" +
  158 + " \"endsOn\":64800000,\n" +
  159 + " \"startsOn\":43200000,\n" +
  160 + " \"timezone\":\"Europe/Kiev\",\n" +
  161 + " \"daysOfWeek\":[\n" +
  162 + " 1,\n" +
  163 + " 3,\n" +
  164 + " 5\n" +
  165 + " ]\n" +
  166 + " }\n" +
  167 + "}" +
  168 + MARKDOWN_CODE_BLOCK_END;
  169 + protected static final String DEVICE_PROFILE_ALARM_SCHEDULE_CUSTOM_EXAMPLE = MARKDOWN_CODE_BLOCK_START +
  170 + "{\n" +
  171 + " \"schedule\":{\n" +
  172 + " \"type\":\"CUSTOM\",\n" +
  173 + " \"items\":[\n" +
  174 + " {\n" +
  175 + " \"endsOn\":0,\n" +
  176 + " \"enabled\":false,\n" +
  177 + " \"startsOn\":0,\n" +
  178 + " \"dayOfWeek\":1\n" +
  179 + " },\n" +
  180 + " {\n" +
  181 + " \"endsOn\":64800000,\n" +
  182 + " \"enabled\":true,\n" +
  183 + " \"startsOn\":43200000,\n" +
  184 + " \"dayOfWeek\":2\n" +
  185 + " },\n" +
  186 + " {\n" +
  187 + " \"endsOn\":0,\n" +
  188 + " \"enabled\":false,\n" +
  189 + " \"startsOn\":0,\n" +
  190 + " \"dayOfWeek\":3\n" +
  191 + " },\n" +
  192 + " {\n" +
  193 + " \"endsOn\":57600000,\n" +
  194 + " \"enabled\":true,\n" +
  195 + " \"startsOn\":36000000,\n" +
  196 + " \"dayOfWeek\":4\n" +
  197 + " },\n" +
  198 + " {\n" +
  199 + " \"endsOn\":0,\n" +
  200 + " \"enabled\":false,\n" +
  201 + " \"startsOn\":0,\n" +
  202 + " \"dayOfWeek\":5\n" +
  203 + " },\n" +
  204 + " {\n" +
  205 + " \"endsOn\":0,\n" +
  206 + " \"enabled\":false,\n" +
  207 + " \"startsOn\":0,\n" +
  208 + " \"dayOfWeek\":6\n" +
  209 + " },\n" +
  210 + " {\n" +
  211 + " \"endsOn\":0,\n" +
  212 + " \"enabled\":false,\n" +
  213 + " \"startsOn\":0,\n" +
  214 + " \"dayOfWeek\":7\n" +
  215 + " }\n" +
  216 + " ],\n" +
  217 + " \"timezone\":\"Europe/Kiev\"\n" +
  218 + " }\n" +
  219 + "}" +
  220 + MARKDOWN_CODE_BLOCK_END;
  221 + protected static final String DEVICE_PROFILE_ALARM_SCHEDULE_ALWAYS_EXAMPLE = MARKDOWN_CODE_BLOCK_START + "\"schedule\": null" + MARKDOWN_CODE_BLOCK_END;
  222 +
  223 + protected static final String DEVICE_PROFILE_ALARM_CONDITION_REPEATING_EXAMPLE = MARKDOWN_CODE_BLOCK_START +
  224 + "{\n" +
  225 + " \"spec\":{\n" +
  226 + " \"type\":\"REPEATING\",\n" +
  227 + " \"predicate\":{\n" +
  228 + " \"userValue\":null,\n" +
  229 + " \"defaultValue\":5,\n" +
  230 + " \"dynamicValue\":{\n" +
  231 + " \"inherit\":true,\n" +
  232 + " \"sourceType\":\"CURRENT_DEVICE\",\n" +
  233 + " \"sourceAttribute\":\"tempAttr\"\n" +
  234 + " }\n" +
  235 + " }\n" +
  236 + " }\n" +
  237 + "}" +
  238 + MARKDOWN_CODE_BLOCK_END;
  239 + protected static final String DEVICE_PROFILE_ALARM_CONDITION_DURATION_EXAMPLE = MARKDOWN_CODE_BLOCK_START +
  240 + "{\n" +
  241 + " \"spec\":{\n" +
  242 + " \"type\":\"DURATION\",\n" +
  243 + " \"unit\":\"MINUTES\",\n" +
  244 + " \"predicate\":{\n" +
  245 + " \"userValue\":null,\n" +
  246 + " \"defaultValue\":30,\n" +
  247 + " \"dynamicValue\":null\n" +
  248 + " }\n" +
  249 + " }\n" +
  250 + "}" +
  251 + MARKDOWN_CODE_BLOCK_END;
  252 +
  253 + 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.";
  254 + protected static final String RELATION_TYPE_GROUP_PARAM_DESCRIPTION = "A string value representing relation type group. For example, 'COMMON'";
  255 +
  256 + public static final String INCORRECT_TENANT_ID = "Incorrect tenantId ";
  257 + protected static final String DEFAULT_DASHBOARD = "defaultDashboardId";
  258 + protected static final String HOME_DASHBOARD = "homeDashboardId";
  259 +
  260 + protected static final String SINGLE_ENTITY = "\n\n## Single Entity\n\n" +
  261 + "Allows to filter only one entity based on the id. For example, this entity filter selects certain device:\n\n" +
  262 + MARKDOWN_CODE_BLOCK_START +
  263 + "{\n" +
  264 + " \"type\": \"singleEntity\",\n" +
  265 + " \"singleEntity\": {\n" +
  266 + " \"id\": \"d521edb0-2a7a-11ec-94eb-213c95f54092\",\n" +
  267 + " \"entityType\": \"DEVICE\"\n" +
  268 + " }\n" +
  269 + "}" +
  270 + MARKDOWN_CODE_BLOCK_END +
  271 + "";
  272 +
  273 + protected static final String ENTITY_LIST = "\n\n## Entity List Filter\n\n" +
  274 + "Allows to filter entities of the same type using their ids. For example, this entity filter selects two devices:\n\n" +
  275 + MARKDOWN_CODE_BLOCK_START +
  276 + "{\n" +
  277 + " \"type\": \"entityList\",\n" +
  278 + " \"entityType\": \"DEVICE\",\n" +
  279 + " \"entityList\": [\n" +
  280 + " \"e6501f30-2a7a-11ec-94eb-213c95f54092\",\n" +
  281 + " \"e6657bf0-2a7a-11ec-94eb-213c95f54092\"\n" +
  282 + " ]\n" +
  283 + "}" +
  284 + MARKDOWN_CODE_BLOCK_END +
  285 + "";
  286 +
  287 + protected static final String ENTITY_NAME = "\n\n## Entity Name Filter\n\n" +
  288 + "Allows to filter entities of the same type using the **'starts with'** expression over entity name. " +
  289 + "For example, this entity filter selects all devices which name starts with 'Air Quality':\n\n" +
  290 + MARKDOWN_CODE_BLOCK_START +
  291 + "{\n" +
  292 + " \"type\": \"entityName\",\n" +
  293 + " \"entityType\": \"DEVICE\",\n" +
  294 + " \"entityNameFilter\": \"Air Quality\"\n" +
  295 + "}" +
  296 + MARKDOWN_CODE_BLOCK_END +
  297 + "";
  298 +
  299 + protected static final String ENTITY_TYPE_FILTER = "\n\n## Entity Type Filter\n\n" +
  300 + "Allows to filter entities based on their type (CUSTOMER, USER, DASHBOARD, ASSET, DEVICE, etc)" +
  301 + "For example, this entity filter selects all tenant customers:\n\n" +
  302 + MARKDOWN_CODE_BLOCK_START +
  303 + "{\n" +
  304 + " \"type\": \"entityType\",\n" +
  305 + " \"entityType\": \"CUSTOMER\"\n" +
  306 + "}" +
  307 + MARKDOWN_CODE_BLOCK_END +
  308 + "";
  309 +
  310 + protected static final String ASSET_TYPE = "\n\n## Asset Type Filter\n\n" +
  311 + "Allows to filter assets based on their type and the **'starts with'** expression over their name. " +
  312 + "For example, this entity filter selects all 'charging station' assets which name starts with 'Tesla':\n\n" +
  313 + MARKDOWN_CODE_BLOCK_START +
  314 + "{\n" +
  315 + " \"type\": \"assetType\",\n" +
  316 + " \"assetType\": \"charging station\",\n" +
  317 + " \"assetNameFilter\": \"Tesla\"\n" +
  318 + "}" +
  319 + MARKDOWN_CODE_BLOCK_END +
  320 + "";
  321 +
  322 + protected static final String DEVICE_TYPE = "\n\n## Device Type Filter\n\n" +
  323 + "Allows to filter devices based on their type and the **'starts with'** expression over their name. " +
  324 + "For example, this entity filter selects all 'Temperature Sensor' devices which name starts with 'ABC':\n\n" +
  325 + MARKDOWN_CODE_BLOCK_START +
  326 + "{\n" +
  327 + " \"type\": \"deviceType\",\n" +
  328 + " \"deviceType\": \"Temperature Sensor\",\n" +
  329 + " \"deviceNameFilter\": \"ABC\"\n" +
  330 + "}" +
  331 + MARKDOWN_CODE_BLOCK_END +
  332 + "";
  333 +
  334 + protected static final String EDGE_TYPE = "\n\n## Edge Type Filter\n\n" +
  335 + "Allows to filter edge instances based on their type and the **'starts with'** expression over their name. " +
  336 + "For example, this entity filter selects all 'Factory' edge instances which name starts with 'Nevada':\n\n" +
  337 + MARKDOWN_CODE_BLOCK_START +
  338 + "{\n" +
  339 + " \"type\": \"edgeType\",\n" +
  340 + " \"edgeType\": \"Factory\",\n" +
  341 + " \"edgeNameFilter\": \"Nevada\"\n" +
  342 + "}" +
  343 + MARKDOWN_CODE_BLOCK_END +
  344 + "";
  345 +
  346 + protected static final String ENTITY_VIEW_TYPE = "\n\n## Entity View Filter\n\n" +
  347 + "Allows to filter entity views based on their type and the **'starts with'** expression over their name. " +
  348 + "For example, this entity filter selects all 'Concrete Mixer' entity views which name starts with 'CAT':\n\n" +
  349 + MARKDOWN_CODE_BLOCK_START +
  350 + "{\n" +
  351 + " \"type\": \"entityViewType\",\n" +
  352 + " \"entityViewType\": \"Concrete Mixer\",\n" +
  353 + " \"entityViewNameFilter\": \"CAT\"\n" +
  354 + "}" +
  355 + MARKDOWN_CODE_BLOCK_END +
  356 + "";
  357 +
  358 + protected static final String API_USAGE = "\n\n## Api Usage Filter\n\n" +
  359 + "Allows to query for Api Usage based on optional customer id. If the customer id is not set, returns current tenant API usage." +
  360 + "For example, this entity filter selects the 'Api Usage' entity for customer with id 'e6501f30-2a7a-11ec-94eb-213c95f54092':\n\n" +
  361 + MARKDOWN_CODE_BLOCK_START +
  362 + "{\n" +
  363 + " \"type\": \"apiUsageState\",\n" +
  364 + " \"customerId\": {\n" +
  365 + " \"id\": \"d521edb0-2a7a-11ec-94eb-213c95f54092\",\n" +
  366 + " \"entityType\": \"CUSTOMER\"\n" +
  367 + " }\n" +
  368 + "}" +
  369 + MARKDOWN_CODE_BLOCK_END +
  370 + "";
  371 +
  372 + protected static final String MAX_LEVEL_DESCRIPTION = "Possible direction values are 'TO' and 'FROM'. The 'maxLevel' defines how many relation levels should the query search 'recursively'. ";
  373 + protected static final String FETCH_LAST_LEVEL_ONLY_DESCRIPTION = "Assuming the 'maxLevel' is > 1, the 'fetchLastLevelOnly' defines either to return all related entities or only entities that are on the last level of relations. ";
  374 +
  375 + protected static final String RELATIONS_QUERY_FILTER = "\n\n## Relations Query Filter\n\n" +
  376 + "Allows to filter entities that are related to the provided root entity. " +
  377 + MAX_LEVEL_DESCRIPTION +
  378 + FETCH_LAST_LEVEL_ONLY_DESCRIPTION +
  379 + "The 'filter' object allows you to define the relation type and set of acceptable entity types to search for. " +
  380 + "The relation query calculates all related entities, even if they are filtered using different relation types, and then extracts only those who match the 'filters'.\n\n" +
  381 + "For example, this entity filter selects all devices and assets which are related to the asset with id 'e51de0c0-2a7a-11ec-94eb-213c95f54092':\n\n" +
  382 + MARKDOWN_CODE_BLOCK_START +
  383 + "{\n" +
  384 + " \"type\": \"relationsQuery\",\n" +
  385 + " \"rootEntity\": {\n" +
  386 + " \"entityType\": \"ASSET\",\n" +
  387 + " \"id\": \"e51de0c0-2a7a-11ec-94eb-213c95f54092\"\n" +
  388 + " },\n" +
  389 + " \"direction\": \"FROM\",\n" +
  390 + " \"maxLevel\": 1,\n" +
  391 + " \"fetchLastLevelOnly\": false,\n" +
  392 + " \"filters\": [\n" +
  393 + " {\n" +
  394 + " \"relationType\": \"Contains\",\n" +
  395 + " \"entityTypes\": [\n" +
  396 + " \"DEVICE\",\n" +
  397 + " \"ASSET\"\n" +
  398 + " ]\n" +
  399 + " }\n" +
  400 + " ]\n" +
  401 + "}" +
  402 + MARKDOWN_CODE_BLOCK_END +
  403 + "";
  404 +
  405 +
  406 + protected static final String ASSET_QUERY_FILTER = "\n\n## Asset Search Query\n\n" +
  407 + "Allows to filter assets that are related to the provided root entity. Filters related assets based on the relation type and set of asset types. " +
  408 + MAX_LEVEL_DESCRIPTION +
  409 + FETCH_LAST_LEVEL_ONLY_DESCRIPTION +
  410 + "The 'relationType' defines the type of the relation to search for. " +
  411 + "The 'assetTypes' defines the type of the asset to search for. " +
  412 + "The relation query calculates all related entities, even if they are filtered using different relation types, and then extracts only assets that match 'relationType' and 'assetTypes' conditions.\n\n" +
  413 + "For example, this entity filter selects 'charging station' assets which are related to the asset with id 'e51de0c0-2a7a-11ec-94eb-213c95f54092' using 'Contains' relation:\n\n" +
  414 + MARKDOWN_CODE_BLOCK_START +
  415 + "{\n" +
  416 + " \"type\": \"assetSearchQuery\",\n" +
  417 + " \"rootEntity\": {\n" +
  418 + " \"entityType\": \"ASSET\",\n" +
  419 + " \"id\": \"e51de0c0-2a7a-11ec-94eb-213c95f54092\"\n" +
  420 + " },\n" +
  421 + " \"direction\": \"FROM\",\n" +
  422 + " \"maxLevel\": 1,\n" +
  423 + " \"fetchLastLevelOnly\": false,\n" +
  424 + " \"relationType\": \"Contains\",\n" +
  425 + " \"assetTypes\": [\n" +
  426 + " \"charging station\"\n" +
  427 + " ]\n" +
  428 + "}" +
  429 + MARKDOWN_CODE_BLOCK_END +
  430 + "";
  431 +
  432 + protected static final String DEVICE_QUERY_FILTER = "\n\n## Device Search Query\n\n" +
  433 + "Allows to filter devices that are related to the provided root entity. Filters related devices based on the relation type and set of device types. " +
  434 + MAX_LEVEL_DESCRIPTION +
  435 + FETCH_LAST_LEVEL_ONLY_DESCRIPTION +
  436 + "The 'relationType' defines the type of the relation to search for. " +
  437 + "The 'deviceTypes' defines the type of the device to search for. " +
  438 + "The relation query calculates all related entities, even if they are filtered using different relation types, and then extracts only devices that match 'relationType' and 'deviceTypes' conditions.\n\n" +
  439 + "For example, this entity filter selects 'Charging port' and 'Air Quality Sensor' devices which are related to the asset with id 'e52b0020-2a7a-11ec-94eb-213c95f54092' using 'Contains' relation:\n\n" +
  440 + MARKDOWN_CODE_BLOCK_START +
  441 + "{\n" +
  442 + " \"type\": \"deviceSearchQuery\",\n" +
  443 + " \"rootEntity\": {\n" +
  444 + " \"entityType\": \"ASSET\",\n" +
  445 + " \"id\": \"e52b0020-2a7a-11ec-94eb-213c95f54092\"\n" +
  446 + " },\n" +
  447 + " \"direction\": \"FROM\",\n" +
  448 + " \"maxLevel\": 2,\n" +
  449 + " \"fetchLastLevelOnly\": true,\n" +
  450 + " \"relationType\": \"Contains\",\n" +
  451 + " \"deviceTypes\": [\n" +
  452 + " \"Air Quality Sensor\",\n" +
  453 + " \"Charging port\"\n" +
  454 + " ]\n" +
  455 + "}" +
  456 + MARKDOWN_CODE_BLOCK_END +
  457 + "";
  458 +
  459 + protected static final String EV_QUERY_FILTER = "\n\n## Entity View Query\n\n" +
  460 + "Allows to filter entity views that are related to the provided root entity. Filters related entity views based on the relation type and set of entity view types. " +
  461 + MAX_LEVEL_DESCRIPTION +
  462 + FETCH_LAST_LEVEL_ONLY_DESCRIPTION +
  463 + "The 'relationType' defines the type of the relation to search for. " +
  464 + "The 'entityViewTypes' defines the type of the entity view to search for. " +
  465 + "The relation query calculates all related entities, even if they are filtered using different relation types, and then extracts only devices that match 'relationType' and 'deviceTypes' conditions.\n\n" +
  466 + "For example, this entity filter selects 'Concrete mixer' entity views which are related to the asset with id 'e52b0020-2a7a-11ec-94eb-213c95f54092' using 'Contains' relation:\n\n" +
  467 + MARKDOWN_CODE_BLOCK_START +
  468 + "{\n" +
  469 + " \"type\": \"entityViewSearchQuery\",\n" +
  470 + " \"rootEntity\": {\n" +
  471 + " \"entityType\": \"ASSET\",\n" +
  472 + " \"id\": \"e52b0020-2a7a-11ec-94eb-213c95f54092\"\n" +
  473 + " },\n" +
  474 + " \"direction\": \"FROM\",\n" +
  475 + " \"maxLevel\": 1,\n" +
  476 + " \"fetchLastLevelOnly\": false,\n" +
  477 + " \"relationType\": \"Contains\",\n" +
  478 + " \"entityViewTypes\": [\n" +
  479 + " \"Concrete mixer\"\n" +
  480 + " ]\n" +
  481 + "}" +
  482 + MARKDOWN_CODE_BLOCK_END +
  483 + "";
  484 +
  485 + protected static final String EDGE_QUERY_FILTER = "\n\n## Edge Search Query\n\n" +
  486 + "Allows to filter edge instances that are related to the provided root entity. Filters related edge instances based on the relation type and set of edge types. " +
  487 + MAX_LEVEL_DESCRIPTION +
  488 + FETCH_LAST_LEVEL_ONLY_DESCRIPTION +
  489 + "The 'relationType' defines the type of the relation to search for. " +
  490 + "The 'deviceTypes' defines the type of the device to search for. " +
  491 + "The relation query calculates all related entities, even if they are filtered using different relation types, and then extracts only devices that match 'relationType' and 'deviceTypes' conditions.\n\n" +
  492 + "For example, this entity filter selects 'Factory' edge instances which are related to the asset with id 'e52b0020-2a7a-11ec-94eb-213c95f54092' using 'Contains' relation:\n\n" +
  493 + MARKDOWN_CODE_BLOCK_START +
  494 + "{\n" +
  495 + " \"type\": \"deviceSearchQuery\",\n" +
  496 + " \"rootEntity\": {\n" +
  497 + " \"entityType\": \"ASSET\",\n" +
  498 + " \"id\": \"e52b0020-2a7a-11ec-94eb-213c95f54092\"\n" +
  499 + " },\n" +
  500 + " \"direction\": \"FROM\",\n" +
  501 + " \"maxLevel\": 2,\n" +
  502 + " \"fetchLastLevelOnly\": true,\n" +
  503 + " \"relationType\": \"Contains\",\n" +
  504 + " \"edgeTypes\": [\n" +
  505 + " \"Factory\"\n" +
  506 + " ]\n" +
  507 + "}" +
  508 + MARKDOWN_CODE_BLOCK_END +
  509 + "";
  510 +
  511 + protected static final String EMPTY = "\n\n## Entity Type Filter\n\n" +
  512 + "Allows to filter multiple entities of the same type using the **'starts with'** expression over entity name. " +
  513 + "For example, this entity filter selects all devices which name starts with 'Air Quality':\n\n" +
  514 + MARKDOWN_CODE_BLOCK_START +
  515 + "" +
  516 + MARKDOWN_CODE_BLOCK_END +
  517 + "";
  518 +
  519 + protected static final String ENTITY_FILTERS =
  520 + "\n\n # Entity Filters" +
  521 + "\nEntity Filter body depends on the 'type' parameter. Let's review available entity filter types. In fact, they do correspond to available dashboard aliases." +
  522 + SINGLE_ENTITY + ENTITY_LIST + ENTITY_NAME + ENTITY_TYPE_FILTER + ASSET_TYPE + DEVICE_TYPE + EDGE_TYPE + ENTITY_VIEW_TYPE + API_USAGE + RELATIONS_QUERY_FILTER
  523 + + ASSET_QUERY_FILTER + DEVICE_QUERY_FILTER + EV_QUERY_FILTER + EDGE_QUERY_FILTER;
  524 +
  525 + protected static final String FILTER_KEY = "\n\n## Filter Key\n\n" +
  526 + "Filter Key defines either entity field, attribute or telemetry. It is a JSON object that consists the key name and type. " +
  527 + "The following filter key types are supported: \n\n" +
  528 + " * 'CLIENT_ATTRIBUTE' - used for client attributes; \n" +
  529 + " * 'SHARED_ATTRIBUTE' - used for shared attributes; \n" +
  530 + " * 'SERVER_ATTRIBUTE' - used for server attributes; \n" +
  531 + " * 'ATTRIBUTE' - used for any of the above; \n" +
  532 + " * 'TIME_SERIES' - used for time-series values; \n" +
  533 + " * 'ENTITY_FIELD' - used for accessing entity fields like 'name', 'label', etc. The list of available fields depends on the entity type; \n" +
  534 + " * 'ALARM_FIELD' - similar to entity field, but is used in alarm queries only; \n" +
  535 + "\n\n Let's review the example:\n\n" +
  536 + MARKDOWN_CODE_BLOCK_START +
  537 + "{\n" +
  538 + " \"type\": \"TIME_SERIES\",\n" +
  539 + " \"key\": \"temperature\"\n" +
  540 + "}" +
  541 + MARKDOWN_CODE_BLOCK_END +
  542 + "";
  543 +
  544 + protected static final String FILTER_PREDICATE = "\n\n## Filter Predicate\n\n" +
  545 + "Filter Predicate defines the logical expression to evaluate. The list of available operations depends on the filter value type, see above. " +
  546 + "Platform supports 4 predicate types: 'STRING', 'NUMERIC', 'BOOLEAN' and 'COMPLEX'. The last one allows to combine multiple operations over one filter key." +
  547 + "\n\nSimple predicate example to check 'value < 100': \n\n" +
  548 + MARKDOWN_CODE_BLOCK_START +
  549 + "{\n" +
  550 + " \"operation\": \"LESS\",\n" +
  551 + " \"value\": {\n" +
  552 + " \"defaultValue\": 100,\n" +
  553 + " \"dynamicValue\": null\n" +
  554 + " },\n" +
  555 + " \"type\": \"NUMERIC\"\n" +
  556 + "}" +
  557 + MARKDOWN_CODE_BLOCK_END +
  558 + "\n\nComplex predicate example, to check 'value < 10 or value > 20': \n\n" +
  559 + MARKDOWN_CODE_BLOCK_START +
  560 + "{\n" +
  561 + " \"type\": \"COMPLEX\",\n" +
  562 + " \"operation\": \"OR\",\n" +
  563 + " \"predicates\": [\n" +
  564 + " {\n" +
  565 + " \"operation\": \"LESS\",\n" +
  566 + " \"value\": {\n" +
  567 + " \"defaultValue\": 10,\n" +
  568 + " \"dynamicValue\": null\n" +
  569 + " },\n" +
  570 + " \"type\": \"NUMERIC\"\n" +
  571 + " },\n" +
  572 + " {\n" +
  573 + " \"operation\": \"GREATER\",\n" +
  574 + " \"value\": {\n" +
  575 + " \"defaultValue\": 20,\n" +
  576 + " \"dynamicValue\": null\n" +
  577 + " },\n" +
  578 + " \"type\": \"NUMERIC\"\n" +
  579 + " }\n" +
  580 + " ]\n" +
  581 + "}" +
  582 + MARKDOWN_CODE_BLOCK_END +
  583 + "\n\nMore complex predicate example, to check 'value < 10 or (value > 50 && value < 60)': \n\n" +
  584 + MARKDOWN_CODE_BLOCK_START +
  585 + "{\n" +
  586 + " \"type\": \"COMPLEX\",\n" +
  587 + " \"operation\": \"OR\",\n" +
  588 + " \"predicates\": [\n" +
  589 + " {\n" +
  590 + " \"operation\": \"LESS\",\n" +
  591 + " \"value\": {\n" +
  592 + " \"defaultValue\": 10,\n" +
  593 + " \"dynamicValue\": null\n" +
  594 + " },\n" +
  595 + " \"type\": \"NUMERIC\"\n" +
  596 + " },\n" +
  597 + " {\n" +
  598 + " \"type\": \"COMPLEX\",\n" +
  599 + " \"operation\": \"AND\",\n" +
  600 + " \"predicates\": [\n" +
  601 + " {\n" +
  602 + " \"operation\": \"GREATER\",\n" +
  603 + " \"value\": {\n" +
  604 + " \"defaultValue\": 50,\n" +
  605 + " \"dynamicValue\": null\n" +
  606 + " },\n" +
  607 + " \"type\": \"NUMERIC\"\n" +
  608 + " },\n" +
  609 + " {\n" +
  610 + " \"operation\": \"LESS\",\n" +
  611 + " \"value\": {\n" +
  612 + " \"defaultValue\": 60,\n" +
  613 + " \"dynamicValue\": null\n" +
  614 + " },\n" +
  615 + " \"type\": \"NUMERIC\"\n" +
  616 + " }\n" +
  617 + " ]\n" +
  618 + " }\n" +
  619 + " ]\n" +
  620 + "}" +
  621 + MARKDOWN_CODE_BLOCK_END +
  622 + "\n\n You may also want to replace hardcoded values (for example, temperature > 20) with the more dynamic " +
  623 + "expression (for example, temperature > 'value of the tenant attribute with key 'temperatureThreshold'). " +
  624 + "It is possible to use 'dynamicValue' to define attribute of the tenant, customer or user that is performing the API call. " +
  625 + "See example below: \n\n" +
  626 + MARKDOWN_CODE_BLOCK_START +
  627 + "{\n" +
  628 + " \"operation\": \"GREATER\",\n" +
  629 + " \"value\": {\n" +
  630 + " \"defaultValue\": 0,\n" +
  631 + " \"dynamicValue\": {\n" +
  632 + " \"sourceType\": \"CURRENT_USER\",\n" +
  633 + " \"sourceAttribute\": \"temperatureThreshold\"\n" +
  634 + " }\n" +
  635 + " },\n" +
  636 + " \"type\": \"NUMERIC\"\n" +
  637 + "}" +
  638 + MARKDOWN_CODE_BLOCK_END +
  639 + "\n\n Note that you may use 'CURRENT_USER', 'CURRENT_CUSTOMER' and 'CURRENT_TENANT' as a 'sourceType'. The 'defaultValue' is used when the attribute with such a name is not defined for the chosen source.";
  640 +
  641 + protected static final String KEY_FILTERS =
  642 + "\n\n # Key Filters" +
  643 + "\nKey Filter allows you to define complex logical expressions over entity field, attribute or latest time-series value. The filter is defined using 'key', 'valueType' and 'predicate' objects. " +
  644 + "Single Entity Query may have zero, one or multiple predicates. If multiple filters are defined, they are evaluated using logical 'AND'. " +
  645 + "The example below checks that temperature of the entity is above 20 degrees:" +
  646 + "\n\n" + MARKDOWN_CODE_BLOCK_START +
  647 + "{\n" +
  648 + " \"key\": {\n" +
  649 + " \"type\": \"TIME_SERIES\",\n" +
  650 + " \"key\": \"temperature\"\n" +
  651 + " },\n" +
  652 + " \"valueType\": \"NUMERIC\",\n" +
  653 + " \"predicate\": {\n" +
  654 + " \"operation\": \"GREATER\",\n" +
  655 + " \"value\": {\n" +
  656 + " \"defaultValue\": 20,\n" +
  657 + " \"dynamicValue\": null\n" +
  658 + " },\n" +
  659 + " \"type\": \"NUMERIC\"\n" +
  660 + " }\n" +
  661 + "}" +
  662 + MARKDOWN_CODE_BLOCK_END +
  663 + "\n\n Now let's review 'key', 'valueType' and 'predicate' objects in detail."
  664 + + FILTER_KEY + FILTER_VALUE_TYPE + FILTER_PREDICATE;
  665 +
  666 + protected static final String ENTITY_COUNT_QUERY_DESCRIPTION =
  667 + "Allows to run complex queries to search the count of platform entities (devices, assets, customers, etc) " +
  668 + "based on the combination of main entity filter and multiple key filters. Returns the number of entities that match the query definition.\n\n" +
  669 + "# Query Definition\n\n" +
  670 + "\n\nMain **entity filter** is mandatory and defines generic search criteria. " +
  671 + "For example, \"find all devices with profile 'Moisture Sensor'\" or \"Find all devices related to asset 'Building A'\"" +
  672 + "\n\nOptional **key filters** allow to filter results of the entity filter by complex criteria against " +
  673 + "main entity fields (name, label, type, etc), attributes and telemetry. " +
  674 + "For example, \"temperature > 20 or temperature< 10\" or \"name starts with 'T', and attribute 'model' is 'T1000', and timeseries field 'batteryLevel' > 40\"." +
  675 + "\n\nLet's review the example:" +
  676 + "\n\n" + MARKDOWN_CODE_BLOCK_START +
  677 + "{\n" +
  678 + " \"entityFilter\": {\n" +
  679 + " \"type\": \"entityType\",\n" +
  680 + " \"entityType\": \"DEVICE\"\n" +
  681 + " },\n" +
  682 + " \"keyFilters\": [\n" +
  683 + " {\n" +
  684 + " \"key\": {\n" +
  685 + " \"type\": \"ATTRIBUTE\",\n" +
  686 + " \"key\": \"active\"\n" +
  687 + " },\n" +
  688 + " \"valueType\": \"BOOLEAN\",\n" +
  689 + " \"predicate\": {\n" +
  690 + " \"operation\": \"EQUAL\",\n" +
  691 + " \"value\": {\n" +
  692 + " \"defaultValue\": true,\n" +
  693 + " \"dynamicValue\": null\n" +
  694 + " },\n" +
  695 + " \"type\": \"BOOLEAN\"\n" +
  696 + " }\n" +
  697 + " }\n" +
  698 + " ]\n" +
  699 + "}" +
  700 + MARKDOWN_CODE_BLOCK_END +
  701 + "\n\n Example mentioned above search all devices which have attribute 'active' set to 'true'. Now let's review available entity filters and key filters syntax:" +
  702 + ENTITY_FILTERS +
  703 + KEY_FILTERS +
  704 + ControllerConstants.TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH;
  705 +
  706 + protected static final String ENTITY_DATA_QUERY_DESCRIPTION =
  707 + "Allows to run complex queries over platform entities (devices, assets, customers, etc) " +
  708 + "based on the combination of main entity filter and multiple key filters. " +
  709 + "Returns the paginated result of the query that contains requested entity fields and latest values of requested attributes and time-series data.\n\n" +
  710 + "# Query Definition\n\n" +
  711 + "\n\nMain **entity filter** is mandatory and defines generic search criteria. " +
  712 + "For example, \"find all devices with profile 'Moisture Sensor'\" or \"Find all devices related to asset 'Building A'\"" +
  713 + "\n\nOptional **key filters** allow to filter results of the **entity filter** by complex criteria against " +
  714 + "main entity fields (name, label, type, etc), attributes and telemetry. " +
  715 + "For example, \"temperature > 20 or temperature< 10\" or \"name starts with 'T', and attribute 'model' is 'T1000', and timeseries field 'batteryLevel' > 40\"." +
  716 + "\n\nThe **entity fields** and **latest values** contains list of entity fields and latest attribute/telemetry fields to fetch for each entity." +
  717 + "\n\nThe **page link** contains information about the page to fetch and the sort ordering." +
  718 + "\n\nLet's review the example:" +
  719 + "\n\n" + MARKDOWN_CODE_BLOCK_START +
  720 + "{\n" +
  721 + " \"entityFilter\": {\n" +
  722 + " \"type\": \"entityType\",\n" +
  723 + " \"resolveMultiple\": true,\n" +
  724 + " \"entityType\": \"DEVICE\"\n" +
  725 + " },\n" +
  726 + " \"keyFilters\": [\n" +
  727 + " {\n" +
  728 + " \"key\": {\n" +
  729 + " \"type\": \"TIME_SERIES\",\n" +
  730 + " \"key\": \"temperature\"\n" +
  731 + " },\n" +
  732 + " \"valueType\": \"NUMERIC\",\n" +
  733 + " \"predicate\": {\n" +
  734 + " \"operation\": \"GREATER\",\n" +
  735 + " \"value\": {\n" +
  736 + " \"defaultValue\": 0,\n" +
  737 + " \"dynamicValue\": {\n" +
  738 + " \"sourceType\": \"CURRENT_USER\",\n" +
  739 + " \"sourceAttribute\": \"temperatureThreshold\",\n" +
  740 + " \"inherit\": false\n" +
  741 + " }\n" +
  742 + " },\n" +
  743 + " \"type\": \"NUMERIC\"\n" +
  744 + " }\n" +
  745 + " }\n" +
  746 + " ],\n" +
  747 + " \"entityFields\": [\n" +
  748 + " {\n" +
  749 + " \"type\": \"ENTITY_FIELD\",\n" +
  750 + " \"key\": \"name\"\n" +
  751 + " },\n" +
  752 + " {\n" +
  753 + " \"type\": \"ENTITY_FIELD\",\n" +
  754 + " \"key\": \"label\"\n" +
  755 + " },\n" +
  756 + " {\n" +
  757 + " \"type\": \"ENTITY_FIELD\",\n" +
  758 + " \"key\": \"additionalInfo\"\n" +
  759 + " }\n" +
  760 + " ],\n" +
  761 + " \"latestValues\": [\n" +
  762 + " {\n" +
  763 + " \"type\": \"ATTRIBUTE\",\n" +
  764 + " \"key\": \"model\"\n" +
  765 + " },\n" +
  766 + " {\n" +
  767 + " \"type\": \"TIME_SERIES\",\n" +
  768 + " \"key\": \"temperature\"\n" +
  769 + " }\n" +
  770 + " ],\n" +
  771 + " \"pageLink\": {\n" +
  772 + " \"page\": 0,\n" +
  773 + " \"pageSize\": 10,\n" +
  774 + " \"sortOrder\": {\n" +
  775 + " \"key\": {\n" +
  776 + " \"key\": \"name\",\n" +
  777 + " \"type\": \"ENTITY_FIELD\"\n" +
  778 + " },\n" +
  779 + " \"direction\": \"ASC\"\n" +
  780 + " }\n" +
  781 + " }\n" +
  782 + "}" +
  783 + MARKDOWN_CODE_BLOCK_END +
  784 + "\n\n Example mentioned above search all devices which have attribute 'active' set to 'true'. Now let's review available entity filters and key filters syntax:" +
  785 + ENTITY_FILTERS +
  786 + KEY_FILTERS +
  787 + ControllerConstants.TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH;
  788 +
  789 +
  790 + protected static final String ALARM_DATA_QUERY_DESCRIPTION = "This method description defines how Alarm Data Query extends the Entity Data Query. " +
  791 + "See method 'Find Entity Data by Query' first to get the info about 'Entity Data Query'." +
  792 + "\n\n The platform will first search the entities that match the entity and key filters. Then, the platform will use 'Alarm Page Link' to filter the alarms related to those entities. " +
  793 + "Finally, platform fetch the properties of alarm that are defined in the **'alarmFields'** and combine them with the other entity, attribute and latest time-series fields to return the result. " +
  794 + "\n\n See example of the alarm query below. The query will search first 100 active alarms with type 'Temperature Alarm' or 'Fire Alarm' for any device with current temperature > 0. " +
  795 + "The query will return combination of the entity fields: name of the device, device model and latest temperature reading and alarms fields: createdTime, type, severity and status: " +
  796 + "\n\n" + MARKDOWN_CODE_BLOCK_START +
  797 + "{\n" +
  798 + " \"entityFilter\": {\n" +
  799 + " \"type\": \"entityType\",\n" +
  800 + " \"resolveMultiple\": true,\n" +
  801 + " \"entityType\": \"DEVICE\"\n" +
  802 + " },\n" +
  803 + " \"pageLink\": {\n" +
  804 + " \"page\": 0,\n" +
  805 + " \"pageSize\": 100,\n" +
  806 + " \"textSearch\": null,\n" +
  807 + " \"searchPropagatedAlarms\": false,\n" +
  808 + " \"statusList\": [\n" +
  809 + " \"ACTIVE\"\n" +
  810 + " ],\n" +
  811 + " \"severityList\": [\n" +
  812 + " \"CRITICAL\",\n" +
  813 + " \"MAJOR\"\n" +
  814 + " ],\n" +
  815 + " \"typeList\": [\n" +
  816 + " \"Temperature Alarm\",\n" +
  817 + " \"Fire Alarm\"\n" +
  818 + " ],\n" +
  819 + " \"sortOrder\": {\n" +
  820 + " \"key\": {\n" +
  821 + " \"key\": \"createdTime\",\n" +
  822 + " \"type\": \"ALARM_FIELD\"\n" +
  823 + " },\n" +
  824 + " \"direction\": \"DESC\"\n" +
  825 + " },\n" +
  826 + " \"timeWindow\": 86400000\n" +
  827 + " },\n" +
  828 + " \"keyFilters\": [\n" +
  829 + " {\n" +
  830 + " \"key\": {\n" +
  831 + " \"type\": \"TIME_SERIES\",\n" +
  832 + " \"key\": \"temperature\"\n" +
  833 + " },\n" +
  834 + " \"valueType\": \"NUMERIC\",\n" +
  835 + " \"predicate\": {\n" +
  836 + " \"operation\": \"GREATER\",\n" +
  837 + " \"value\": {\n" +
  838 + " \"defaultValue\": 0,\n" +
  839 + " \"dynamicValue\": null\n" +
  840 + " },\n" +
  841 + " \"type\": \"NUMERIC\"\n" +
  842 + " }\n" +
  843 + " }\n" +
  844 + " ],\n" +
  845 + " \"alarmFields\": [\n" +
  846 + " {\n" +
  847 + " \"type\": \"ALARM_FIELD\",\n" +
  848 + " \"key\": \"createdTime\"\n" +
  849 + " },\n" +
  850 + " {\n" +
  851 + " \"type\": \"ALARM_FIELD\",\n" +
  852 + " \"key\": \"type\"\n" +
  853 + " },\n" +
  854 + " {\n" +
  855 + " \"type\": \"ALARM_FIELD\",\n" +
  856 + " \"key\": \"severity\"\n" +
  857 + " },\n" +
  858 + " {\n" +
  859 + " \"type\": \"ALARM_FIELD\",\n" +
  860 + " \"key\": \"status\"\n" +
  861 + " }\n" +
  862 + " ],\n" +
  863 + " \"entityFields\": [\n" +
  864 + " {\n" +
  865 + " \"type\": \"ENTITY_FIELD\",\n" +
  866 + " \"key\": \"name\"\n" +
  867 + " }\n" +
  868 + " ],\n" +
  869 + " \"latestValues\": [\n" +
  870 + " {\n" +
  871 + " \"type\": \"ATTRIBUTE\",\n" +
  872 + " \"key\": \"model\"\n" +
  873 + " },\n" +
  874 + " {\n" +
  875 + " \"type\": \"TIME_SERIES\",\n" +
  876 + " \"key\": \"temperature\"\n" +
  877 + " }\n" +
  878 + " ]\n" +
  879 + "}" +
  880 + MARKDOWN_CODE_BLOCK_END +
  881 + "";
  882 +
  883 + protected static final String COAP_TRANSPORT_CONFIGURATION_EXAMPLE = MARKDOWN_CODE_BLOCK_START +
  884 + "{\n" +
  885 + " \"type\":\"COAP\",\n" +
  886 + " \"clientSettings\":{\n" +
  887 + " \"edrxCycle\":null,\n" +
  888 + " \"powerMode\":\"DRX\",\n" +
  889 + " \"psmActivityTimer\":null,\n" +
  890 + " \"pagingTransmissionWindow\":null\n" +
  891 + " },\n" +
  892 + " \"coapDeviceTypeConfiguration\":{\n" +
  893 + " \"coapDeviceType\":\"DEFAULT\",\n" +
  894 + " \"transportPayloadTypeConfiguration\":{\n" +
  895 + " \"transportPayloadType\":\"JSON\"\n" +
  896 + " }\n" +
  897 + " }\n" +
  898 + "}"
  899 + + MARKDOWN_CODE_BLOCK_END;
  900 +
  901 + protected static final String TRANSPORT_CONFIGURATION = "# Transport Configuration" + NEW_LINE +
  902 + "5 transport configuration types are available:\n" +
  903 + " * 'DEFAULT';\n" +
  904 + " * 'MQTT';\n" +
  905 + " * 'LWM2M';\n" +
  906 + " * 'COAP';\n" +
  907 + " * 'SNMP'." + NEW_LINE + "Default type supports basic MQTT, HTTP, CoAP and LwM2M transports. " +
  908 + "Please refer to the [docs](https://thingsboard.io/docs/user-guide/device-profiles/#transport-configuration) for more details about other types.\n" +
  909 + "\nSee another example of COAP transport configuration below:" + NEW_LINE + COAP_TRANSPORT_CONFIGURATION_EXAMPLE;
  910 +
  911 + protected static final String ALARM_FILTER_KEY = "## Alarm Filter Key" + NEW_LINE +
  912 + "Filter Key defines either entity field, attribute, telemetry or constant. It is a JSON object that consists the key name and type. The following filter key types are supported:\n" +
  913 + " * 'ATTRIBUTE' - used for attributes values;\n" +
  914 + " * 'TIME_SERIES' - used for time-series values;\n" +
  915 + " * 'ENTITY_FIELD' - used for accessing entity fields like 'name', 'label', etc. The list of available fields depends on the entity type;\n" +
  916 + " * 'CONSTANT' - constant value specified." + NEW_LINE + "Let's review the example:" + NEW_LINE +
  917 + MARKDOWN_CODE_BLOCK_START +
  918 + "{\n" +
  919 + " \"type\": \"TIME_SERIES\",\n" +
  920 + " \"key\": \"temperature\"\n" +
  921 + "}" +
  922 + MARKDOWN_CODE_BLOCK_END;
  923 +
  924 + protected static final String DEVICE_PROFILE_FILTER_PREDICATE = NEW_LINE + "## Filter Predicate" + NEW_LINE +
  925 + "Filter Predicate defines the logical expression to evaluate. The list of available operations depends on the filter value type, see above. " +
  926 + "Platform supports 4 predicate types: 'STRING', 'NUMERIC', 'BOOLEAN' and 'COMPLEX'. The last one allows to combine multiple operations over one filter key." + NEW_LINE +
  927 + "Simple predicate example to check 'value < 100': " + NEW_LINE +
  928 + MARKDOWN_CODE_BLOCK_START +
  929 + "{\n" +
  930 + " \"operation\": \"LESS\",\n" +
  931 + " \"value\": {\n" +
  932 + " \"userValue\": null,\n" +
  933 + " \"defaultValue\": 100,\n" +
  934 + " \"dynamicValue\": null\n" +
  935 + " },\n" +
  936 + " \"type\": \"NUMERIC\"\n" +
  937 + "}" +
  938 + MARKDOWN_CODE_BLOCK_END + NEW_LINE +
  939 + "Complex predicate example, to check 'value < 10 or value > 20': " + NEW_LINE +
  940 + MARKDOWN_CODE_BLOCK_START +
  941 + "{\n" +
  942 + " \"type\": \"COMPLEX\",\n" +
  943 + " \"operation\": \"OR\",\n" +
  944 + " \"predicates\": [\n" +
  945 + " {\n" +
  946 + " \"operation\": \"LESS\",\n" +
  947 + " \"value\": {\n" +
  948 + " \"userValue\": null,\n" +
  949 + " \"defaultValue\": 10,\n" +
  950 + " \"dynamicValue\": null\n" +
  951 + " },\n" +
  952 + " \"type\": \"NUMERIC\"\n" +
  953 + " },\n" +
  954 + " {\n" +
  955 + " \"operation\": \"GREATER\",\n" +
  956 + " \"value\": {\n" +
  957 + " \"userValue\": null,\n" +
  958 + " \"defaultValue\": 20,\n" +
  959 + " \"dynamicValue\": null\n" +
  960 + " },\n" +
  961 + " \"type\": \"NUMERIC\"\n" +
  962 + " }\n" +
  963 + " ]\n" +
  964 + "}" +
  965 + MARKDOWN_CODE_BLOCK_END + NEW_LINE +
  966 + "More complex predicate example, to check 'value < 10 or (value > 50 && value < 60)': " + NEW_LINE +
  967 + MARKDOWN_CODE_BLOCK_START +
  968 + "{\n" +
  969 + " \"type\": \"COMPLEX\",\n" +
  970 + " \"operation\": \"OR\",\n" +
  971 + " \"predicates\": [\n" +
  972 + " {\n" +
  973 + " \"operation\": \"LESS\",\n" +
  974 + " \"value\": {\n" +
  975 + " \"userValue\": null,\n" +
  976 + " \"defaultValue\": 10,\n" +
  977 + " \"dynamicValue\": null\n" +
  978 + " },\n" +
  979 + " \"type\": \"NUMERIC\"\n" +
  980 + " },\n" +
  981 + " {\n" +
  982 + " \"type\": \"COMPLEX\",\n" +
  983 + " \"operation\": \"AND\",\n" +
  984 + " \"predicates\": [\n" +
  985 + " {\n" +
  986 + " \"operation\": \"GREATER\",\n" +
  987 + " \"value\": {\n" +
  988 + " \"userValue\": null,\n" +
  989 + " \"defaultValue\": 50,\n" +
  990 + " \"dynamicValue\": null\n" +
  991 + " },\n" +
  992 + " \"type\": \"NUMERIC\"\n" +
  993 + " },\n" +
  994 + " {\n" +
  995 + " \"operation\": \"LESS\",\n" +
  996 + " \"value\": {\n" +
  997 + " \"userValue\": null,\n" +
  998 + " \"defaultValue\": 60,\n" +
  999 + " \"dynamicValue\": null\n" +
  1000 + " },\n" +
  1001 + " \"type\": \"NUMERIC\"\n" +
  1002 + " }\n" +
  1003 + " ]\n" +
  1004 + " }\n" +
  1005 + " ]\n" +
  1006 + "}" +
  1007 + MARKDOWN_CODE_BLOCK_END + NEW_LINE +
  1008 + "You may also want to replace hardcoded values (for example, temperature > 20) with the more dynamic " +
  1009 + "expression (for example, temperature > value of the tenant attribute with key 'temperatureThreshold'). " +
  1010 + "It is possible to use 'dynamicValue' to define attribute of the tenant, customer or device. " +
  1011 + "See example below:" + NEW_LINE +
  1012 + MARKDOWN_CODE_BLOCK_START +
  1013 + "{\n" +
  1014 + " \"operation\": \"GREATER\",\n" +
  1015 + " \"value\": {\n" +
  1016 + " \"userValue\": null,\n" +
  1017 + " \"defaultValue\": 0,\n" +
  1018 + " \"dynamicValue\": {\n" +
  1019 + " \"inherit\": false,\n" +
  1020 + " \"sourceType\": \"CURRENT_TENANT\",\n" +
  1021 + " \"sourceAttribute\": \"temperatureThreshold\"\n" +
  1022 + " }\n" +
  1023 + " },\n" +
  1024 + " \"type\": \"NUMERIC\"\n" +
  1025 + "}" +
  1026 + MARKDOWN_CODE_BLOCK_END + NEW_LINE +
  1027 + "Note that you may use 'CURRENT_DEVICE', 'CURRENT_CUSTOMER' and 'CURRENT_TENANT' as a 'sourceType'. The 'defaultValue' is used when the attribute with such a name is not defined for the chosen source. " +
  1028 + "The 'sourceAttribute' can be inherited from the owner of the specified 'sourceType' if 'inherit' is set to true.";
  1029 +
  1030 + protected static final String KEY_FILTERS_DESCRIPTION = "# Key Filters" + NEW_LINE +
  1031 + "Key filter objects are created under the **'condition'** array. They allow you to define complex logical expressions over entity field, " +
  1032 + "attribute, latest time-series value or constant. The filter is defined using 'key', 'valueType', " +
  1033 + "'value' (refers to the value of the 'CONSTANT' alarm filter key type) and 'predicate' objects. Let's review each object:" + NEW_LINE +
  1034 + ALARM_FILTER_KEY + FILTER_VALUE_TYPE + NEW_LINE + DEVICE_PROFILE_FILTER_PREDICATE + NEW_LINE;
  1035 +
  1036 + protected static final String DEFAULT_DEVICE_PROFILE_DATA_EXAMPLE = MARKDOWN_CODE_BLOCK_START + "{\n" +
  1037 + " \"alarms\":[\n" +
  1038 + " ],\n" +
  1039 + " \"configuration\":{\n" +
  1040 + " \"type\":\"DEFAULT\"\n" +
  1041 + " },\n" +
  1042 + " \"provisionConfiguration\":{\n" +
  1043 + " \"type\":\"DISABLED\",\n" +
  1044 + " \"provisionDeviceSecret\":null\n" +
  1045 + " },\n" +
  1046 + " \"transportConfiguration\":{\n" +
  1047 + " \"type\":\"DEFAULT\"\n" +
  1048 + " }\n" +
  1049 + "}" + MARKDOWN_CODE_BLOCK_END;
  1050 +
  1051 + protected static final String CUSTOM_DEVICE_PROFILE_DATA_EXAMPLE = MARKDOWN_CODE_BLOCK_START + "{\n" +
  1052 + " \"alarms\":[\n" +
  1053 + " {\n" +
  1054 + " \"id\":\"2492b935-1226-59e9-8615-17d8978a4f93\",\n" +
  1055 + " \"alarmType\":\"Temperature Alarm\",\n" +
  1056 + " \"clearRule\":{\n" +
  1057 + " \"schedule\":null,\n" +
  1058 + " \"condition\":{\n" +
  1059 + " \"spec\":{\n" +
  1060 + " \"type\":\"SIMPLE\"\n" +
  1061 + " },\n" +
  1062 + " \"condition\":[\n" +
  1063 + " {\n" +
  1064 + " \"key\":{\n" +
  1065 + " \"key\":\"temperature\",\n" +
  1066 + " \"type\":\"TIME_SERIES\"\n" +
  1067 + " },\n" +
  1068 + " \"value\":null,\n" +
  1069 + " \"predicate\":{\n" +
  1070 + " \"type\":\"NUMERIC\",\n" +
  1071 + " \"value\":{\n" +
  1072 + " \"userValue\":null,\n" +
  1073 + " \"defaultValue\":30.0,\n" +
  1074 + " \"dynamicValue\":null\n" +
  1075 + " },\n" +
  1076 + " \"operation\":\"LESS\"\n" +
  1077 + " },\n" +
  1078 + " \"valueType\":\"NUMERIC\"\n" +
  1079 + " }\n" +
  1080 + " ]\n" +
  1081 + " },\n" +
  1082 + " \"dashboardId\":null,\n" +
  1083 + " \"alarmDetails\":null\n" +
  1084 + " },\n" +
  1085 + " \"propagate\":false,\n" +
  1086 + " \"createRules\":{\n" +
  1087 + " \"MAJOR\":{\n" +
  1088 + " \"schedule\":{\n" +
  1089 + " \"type\":\"SPECIFIC_TIME\",\n" +
  1090 + " \"endsOn\":64800000,\n" +
  1091 + " \"startsOn\":43200000,\n" +
  1092 + " \"timezone\":\"Europe/Kiev\",\n" +
  1093 + " \"daysOfWeek\":[\n" +
  1094 + " 1,\n" +
  1095 + " 3,\n" +
  1096 + " 5\n" +
  1097 + " ]\n" +
  1098 + " },\n" +
  1099 + " \"condition\":{\n" +
  1100 + " \"spec\":{\n" +
  1101 + " \"type\":\"DURATION\",\n" +
  1102 + " \"unit\":\"MINUTES\",\n" +
  1103 + " \"predicate\":{\n" +
  1104 + " \"userValue\":null,\n" +
  1105 + " \"defaultValue\":30,\n" +
  1106 + " \"dynamicValue\":null\n" +
  1107 + " }\n" +
  1108 + " },\n" +
  1109 + " \"condition\":[\n" +
  1110 + " {\n" +
  1111 + " \"key\":{\n" +
  1112 + " \"key\":\"temperature\",\n" +
  1113 + " \"type\":\"TIME_SERIES\"\n" +
  1114 + " },\n" +
  1115 + " \"value\":null,\n" +
  1116 + " \"predicate\":{\n" +
  1117 + " \"type\":\"COMPLEX\",\n" +
  1118 + " \"operation\":\"OR\",\n" +
  1119 + " \"predicates\":[\n" +
  1120 + " {\n" +
  1121 + " \"type\":\"NUMERIC\",\n" +
  1122 + " \"value\":{\n" +
  1123 + " \"userValue\":null,\n" +
  1124 + " \"defaultValue\":50.0,\n" +
  1125 + " \"dynamicValue\":null\n" +
  1126 + " },\n" +
  1127 + " \"operation\":\"LESS_OR_EQUAL\"\n" +
  1128 + " },\n" +
  1129 + " {\n" +
  1130 + " \"type\":\"NUMERIC\",\n" +
  1131 + " \"value\":{\n" +
  1132 + " \"userValue\":null,\n" +
  1133 + " \"defaultValue\":30.0,\n" +
  1134 + " \"dynamicValue\":null\n" +
  1135 + " },\n" +
  1136 + " \"operation\":\"GREATER\"\n" +
  1137 + " }\n" +
  1138 + " ]\n" +
  1139 + " },\n" +
  1140 + " \"valueType\":\"NUMERIC\"\n" +
  1141 + " }\n" +
  1142 + " ]\n" +
  1143 + " },\n" +
  1144 + " \"dashboardId\":null,\n" +
  1145 + " \"alarmDetails\":null\n" +
  1146 + " },\n" +
  1147 + " \"WARNING\":{\n" +
  1148 + " \"schedule\":{\n" +
  1149 + " \"type\":\"CUSTOM\",\n" +
  1150 + " \"items\":[\n" +
  1151 + " {\n" +
  1152 + " \"endsOn\":0,\n" +
  1153 + " \"enabled\":false,\n" +
  1154 + " \"startsOn\":0,\n" +
  1155 + " \"dayOfWeek\":1\n" +
  1156 + " },\n" +
  1157 + " {\n" +
  1158 + " \"endsOn\":64800000,\n" +
  1159 + " \"enabled\":true,\n" +
  1160 + " \"startsOn\":43200000,\n" +
  1161 + " \"dayOfWeek\":2\n" +
  1162 + " },\n" +
  1163 + " {\n" +
  1164 + " \"endsOn\":0,\n" +
  1165 + " \"enabled\":false,\n" +
  1166 + " \"startsOn\":0,\n" +
  1167 + " \"dayOfWeek\":3\n" +
  1168 + " },\n" +
  1169 + " {\n" +
  1170 + " \"endsOn\":57600000,\n" +
  1171 + " \"enabled\":true,\n" +
  1172 + " \"startsOn\":36000000,\n" +
  1173 + " \"dayOfWeek\":4\n" +
  1174 + " },\n" +
  1175 + " {\n" +
  1176 + " \"endsOn\":0,\n" +
  1177 + " \"enabled\":false,\n" +
  1178 + " \"startsOn\":0,\n" +
  1179 + " \"dayOfWeek\":5\n" +
  1180 + " },\n" +
  1181 + " {\n" +
  1182 + " \"endsOn\":0,\n" +
  1183 + " \"enabled\":false,\n" +
  1184 + " \"startsOn\":0,\n" +
  1185 + " \"dayOfWeek\":6\n" +
  1186 + " },\n" +
  1187 + " {\n" +
  1188 + " \"endsOn\":0,\n" +
  1189 + " \"enabled\":false,\n" +
  1190 + " \"startsOn\":0,\n" +
  1191 + " \"dayOfWeek\":7\n" +
  1192 + " }\n" +
  1193 + " ],\n" +
  1194 + " \"timezone\":\"Europe/Kiev\"\n" +
  1195 + " },\n" +
  1196 + " \"condition\":{\n" +
  1197 + " \"spec\":{\n" +
  1198 + " \"type\":\"REPEATING\",\n" +
  1199 + " \"predicate\":{\n" +
  1200 + " \"userValue\":null,\n" +
  1201 + " \"defaultValue\":5,\n" +
  1202 + " \"dynamicValue\":null\n" +
  1203 + " }\n" +
  1204 + " },\n" +
  1205 + " \"condition\":[\n" +
  1206 + " {\n" +
  1207 + " \"key\":{\n" +
  1208 + " \"key\":\"tempConstant\",\n" +
  1209 + " \"type\":\"CONSTANT\"\n" +
  1210 + " },\n" +
  1211 + " \"value\":30,\n" +
  1212 + " \"predicate\":{\n" +
  1213 + " \"type\":\"NUMERIC\",\n" +
  1214 + " \"value\":{\n" +
  1215 + " \"userValue\":null,\n" +
  1216 + " \"defaultValue\":0.0,\n" +
  1217 + " \"dynamicValue\":{\n" +
  1218 + " \"inherit\":false,\n" +
  1219 + " \"sourceType\":\"CURRENT_DEVICE\",\n" +
  1220 + " \"sourceAttribute\":\"tempThreshold\"\n" +
  1221 + " }\n" +
  1222 + " },\n" +
  1223 + " \"operation\":\"EQUAL\"\n" +
  1224 + " },\n" +
  1225 + " \"valueType\":\"NUMERIC\"\n" +
  1226 + " }\n" +
  1227 + " ]\n" +
  1228 + " },\n" +
  1229 + " \"dashboardId\":null,\n" +
  1230 + " \"alarmDetails\":null\n" +
  1231 + " },\n" +
  1232 + " \"CRITICAL\":{\n" +
  1233 + " \"schedule\":null,\n" +
  1234 + " \"condition\":{\n" +
  1235 + " \"spec\":{\n" +
  1236 + " \"type\":\"SIMPLE\"\n" +
  1237 + " },\n" +
  1238 + " \"condition\":[\n" +
  1239 + " {\n" +
  1240 + " \"key\":{\n" +
  1241 + " \"key\":\"temperature\",\n" +
  1242 + " \"type\":\"TIME_SERIES\"\n" +
  1243 + " },\n" +
  1244 + " \"value\":null,\n" +
  1245 + " \"predicate\":{\n" +
  1246 + " \"type\":\"NUMERIC\",\n" +
  1247 + " \"value\":{\n" +
  1248 + " \"userValue\":null,\n" +
  1249 + " \"defaultValue\":50.0,\n" +
  1250 + " \"dynamicValue\":null\n" +
  1251 + " },\n" +
  1252 + " \"operation\":\"GREATER\"\n" +
  1253 + " },\n" +
  1254 + " \"valueType\":\"NUMERIC\"\n" +
  1255 + " }\n" +
  1256 + " ]\n" +
  1257 + " },\n" +
  1258 + " \"dashboardId\":null,\n" +
  1259 + " \"alarmDetails\":null\n" +
  1260 + " }\n" +
  1261 + " },\n" +
  1262 + " \"propagateRelationTypes\":null\n" +
  1263 + " }\n" +
  1264 + " ],\n" +
  1265 + " \"configuration\":{\n" +
  1266 + " \"type\":\"DEFAULT\"\n" +
  1267 + " },\n" +
  1268 + " \"provisionConfiguration\":{\n" +
  1269 + " \"type\":\"ALLOW_CREATE_NEW_DEVICES\",\n" +
  1270 + " \"provisionDeviceSecret\":\"vaxb9hzqdbz3oqukvomg\"\n" +
  1271 + " },\n" +
  1272 + " \"transportConfiguration\":{\n" +
  1273 + " \"type\":\"MQTT\",\n" +
  1274 + " \"deviceTelemetryTopic\":\"v1/devices/me/telemetry\",\n" +
  1275 + " \"deviceAttributesTopic\":\"v1/devices/me/attributes\",\n" +
  1276 + " \"transportPayloadTypeConfiguration\":{\n" +
  1277 + " \"transportPayloadType\":\"PROTOBUF\",\n" +
  1278 + " \"deviceTelemetryProtoSchema\":\"syntax =\\\"proto3\\\";\\npackage telemetry;\\n\\nmessage SensorDataReading {\\n\\n optional double temperature = 1;\\n optional double humidity = 2;\\n InnerObject innerObject = 3;\\n\\n message InnerObject {\\n optional string key1 = 1;\\n optional bool key2 = 2;\\n optional double key3 = 3;\\n optional int32 key4 = 4;\\n optional string key5 = 5;\\n }\\n}\",\n" +
  1279 + " \"deviceAttributesProtoSchema\":\"syntax =\\\"proto3\\\";\\npackage attributes;\\n\\nmessage SensorConfiguration {\\n optional string firmwareVersion = 1;\\n optional string serialNumber = 2;\\n}\",\n" +
  1280 + " \"deviceRpcRequestProtoSchema\":\"syntax =\\\"proto3\\\";\\npackage rpc;\\n\\nmessage RpcRequestMsg {\\n optional string method = 1;\\n optional int32 requestId = 2;\\n optional string params = 3;\\n}\",\n" +
  1281 + " \"deviceRpcResponseProtoSchema\":\"syntax =\\\"proto3\\\";\\npackage rpc;\\n\\nmessage RpcResponseMsg {\\n optional string payload = 1;\\n}\"\n" +
  1282 + " }\n" +
  1283 + " }\n" +
  1284 + "}" + MARKDOWN_CODE_BLOCK_END;
  1285 + protected static final String DEVICE_PROFILE_DATA_DEFINITION = NEW_LINE + "# Device profile data definition" + NEW_LINE +
  1286 + "Device profile data object contains alarm rules configuration, device provision strategy and transport type configuration for device connectivity. Let's review some examples. " +
  1287 + "First one is the default device profile data configuration and second one - the custom one. " +
  1288 + NEW_LINE + DEFAULT_DEVICE_PROFILE_DATA_EXAMPLE + NEW_LINE + CUSTOM_DEVICE_PROFILE_DATA_EXAMPLE +
  1289 + NEW_LINE + "Let's review some specific objects examples related to the device profile configuration:";
  1290 +
  1291 + protected static final String ALARM_SCHEDULE = NEW_LINE + "# Alarm Schedule" + NEW_LINE +
  1292 + "Alarm Schedule JSON object represents the time interval during which the alarm rule is active. Note, " +
  1293 + NEW_LINE + DEVICE_PROFILE_ALARM_SCHEDULE_ALWAYS_EXAMPLE + NEW_LINE + "means alarm rule is active all the time. " +
  1294 + "**'daysOfWeek'** field represents Monday as 1, Tuesday as 2 and so on. **'startsOn'** and **'endsOn'** fields represent hours in millis (e.g. 64800000 = 18:00 or 6pm). " +
  1295 + "**'enabled'** flag specifies if item in a custom rule is active for specific day of the week:" + NEW_LINE +
  1296 + "## Specific Time Schedule" + NEW_LINE +
  1297 + DEVICE_PROFILE_ALARM_SCHEDULE_SPECIFIC_TIME_EXAMPLE + NEW_LINE +
  1298 + "## Custom Schedule" +
  1299 + NEW_LINE + DEVICE_PROFILE_ALARM_SCHEDULE_CUSTOM_EXAMPLE + NEW_LINE;
  1300 +
  1301 + protected static final String ALARM_CONDITION_TYPE = "# Alarm condition type (**'spec'**)" + NEW_LINE +
  1302 + "Alarm condition type can be either simple, duration, or repeating. For example, 5 times in a row or during 5 minutes." + NEW_LINE +
  1303 + "Note, **'userValue'** field is not used and reserved for future usage, **'dynamicValue'** is used for condition appliance by using the value of the **'sourceAttribute'** " +
  1304 + "or else **'defaultValue'** is used (if **'sourceAttribute'** is absent).\n" +
  1305 + "\n**'sourceType'** of the **'sourceAttribute'** can be: \n" +
  1306 + " * 'CURRENT_DEVICE';\n" +
  1307 + " * 'CURRENT_CUSTOMER';\n" +
  1308 + " * 'CURRENT_TENANT'." + NEW_LINE +
  1309 + "**'sourceAttribute'** can be inherited from the owner if **'inherit'** is set to true (for CURRENT_DEVICE and CURRENT_CUSTOMER)." + NEW_LINE +
  1310 + "## Repeating alarm condition" + NEW_LINE +
  1311 + DEVICE_PROFILE_ALARM_CONDITION_REPEATING_EXAMPLE + NEW_LINE +
  1312 + "## Duration alarm condition" + NEW_LINE +
  1313 + DEVICE_PROFILE_ALARM_CONDITION_DURATION_EXAMPLE + NEW_LINE +
  1314 + "**'unit'** can be: \n" +
  1315 + " * 'SECONDS';\n" +
  1316 + " * 'MINUTES';\n" +
  1317 + " * 'HOURS';\n" +
  1318 + " * 'DAYS'." + NEW_LINE;
  1319 +
  1320 + protected static final String PROVISION_CONFIGURATION = "# Provision Configuration" + NEW_LINE +
  1321 + "There are 3 types of device provision configuration for the device profile: \n" +
  1322 + " * 'DISABLED';\n" +
  1323 + " * 'ALLOW_CREATE_NEW_DEVICES';\n" +
  1324 + " * 'CHECK_PRE_PROVISIONED_DEVICES'." + NEW_LINE +
  1325 + "Please refer to the [docs](https://thingsboard.io/docs/user-guide/device-provisioning/) for more details." + NEW_LINE;
  1326 +
  1327 + protected static final String DEVICE_PROFILE_DATA = DEVICE_PROFILE_DATA_DEFINITION + ALARM_SCHEDULE + ALARM_CONDITION_TYPE +
  1328 + KEY_FILTERS_DESCRIPTION + PROVISION_CONFIGURATION + TRANSPORT_CONFIGURATION;
  1329 +
  1330 + protected static final String DEVICE_PROFILE_ID = "deviceProfileId";
  1331 +
  1332 +}
@@ -47,6 +47,20 @@ import org.thingsboard.server.service.security.permission.Resource; @@ -47,6 +47,20 @@ import org.thingsboard.server.service.security.permission.Resource;
47 47
48 import java.util.List; 48 import java.util.List;
49 49
  50 +import static org.thingsboard.server.controller.ControllerConstants.CUSTOMER_ID;
  51 +import static org.thingsboard.server.controller.ControllerConstants.CUSTOMER_ID_PARAM_DESCRIPTION;
  52 +import static org.thingsboard.server.controller.ControllerConstants.CUSTOMER_SORT_PROPERTY_ALLOWABLE_VALUES;
  53 +import static org.thingsboard.server.controller.ControllerConstants.CUSTOMER_TEXT_SEARCH_DESCRIPTION;
  54 +import static org.thingsboard.server.controller.ControllerConstants.HOME_DASHBOARD;
  55 +import static org.thingsboard.server.controller.ControllerConstants.PAGE_DATA_PARAMETERS;
  56 +import static org.thingsboard.server.controller.ControllerConstants.PAGE_NUMBER_DESCRIPTION;
  57 +import static org.thingsboard.server.controller.ControllerConstants.PAGE_SIZE_DESCRIPTION;
  58 +import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_ALLOWABLE_VALUES;
  59 +import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_DESCRIPTION;
  60 +import static org.thingsboard.server.controller.ControllerConstants.SORT_PROPERTY_DESCRIPTION;
  61 +import static org.thingsboard.server.controller.ControllerConstants.TENANT_AUTHORITY_PARAGRAPH;
  62 +import static org.thingsboard.server.controller.ControllerConstants.TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH;
  63 +
50 @RestController 64 @RestController
51 @TbCoreComponent 65 @TbCoreComponent
52 @RequestMapping("/api") 66 @RequestMapping("/api")
@@ -31,6 +31,7 @@ import org.springframework.web.bind.annotation.RequestParam; @@ -31,6 +31,7 @@ import org.springframework.web.bind.annotation.RequestParam;
31 import org.springframework.web.bind.annotation.ResponseBody; 31 import org.springframework.web.bind.annotation.ResponseBody;
32 import org.springframework.web.bind.annotation.ResponseStatus; 32 import org.springframework.web.bind.annotation.ResponseStatus;
33 import org.springframework.web.bind.annotation.RestController; 33 import org.springframework.web.bind.annotation.RestController;
  34 +import org.thingsboard.common.util.JacksonUtil;
34 import org.thingsboard.server.common.data.Customer; 35 import org.thingsboard.server.common.data.Customer;
35 import org.thingsboard.server.common.data.Dashboard; 36 import org.thingsboard.server.common.data.Dashboard;
36 import org.thingsboard.server.common.data.DashboardInfo; 37 import org.thingsboard.server.common.data.DashboardInfo;
@@ -50,7 +51,6 @@ import org.thingsboard.server.common.data.id.EdgeId; @@ -50,7 +51,6 @@ import org.thingsboard.server.common.data.id.EdgeId;
50 import org.thingsboard.server.common.data.id.TenantId; 51 import org.thingsboard.server.common.data.id.TenantId;
51 import org.thingsboard.server.common.data.page.PageData; 52 import org.thingsboard.server.common.data.page.PageData;
52 import org.thingsboard.server.common.data.page.PageLink; 53 import org.thingsboard.server.common.data.page.PageLink;
53 -import org.thingsboard.common.util.JacksonUtil;  
54 import org.thingsboard.server.common.data.page.TimePageLink; 54 import org.thingsboard.server.common.data.page.TimePageLink;
55 import org.thingsboard.server.queue.util.TbCoreComponent; 55 import org.thingsboard.server.queue.util.TbCoreComponent;
56 import org.thingsboard.server.service.security.model.SecurityUser; 56 import org.thingsboard.server.service.security.model.SecurityUser;
@@ -62,6 +62,27 @@ import java.util.List; @@ -62,6 +62,27 @@ import java.util.List;
62 import java.util.Set; 62 import java.util.Set;
63 import java.util.stream.Collectors; 63 import java.util.stream.Collectors;
64 64
  65 +import static org.thingsboard.server.controller.ControllerConstants.CUSTOMER_ID;
  66 +import static org.thingsboard.server.controller.ControllerConstants.CUSTOMER_ID_PARAM_DESCRIPTION;
  67 +import static org.thingsboard.server.controller.ControllerConstants.DASHBOARD_ID_PARAM_DESCRIPTION;
  68 +import static org.thingsboard.server.controller.ControllerConstants.DASHBOARD_SORT_PROPERTY_ALLOWABLE_VALUES;
  69 +import static org.thingsboard.server.controller.ControllerConstants.DASHBOARD_TEXT_SEARCH_DESCRIPTION;
  70 +import static org.thingsboard.server.controller.ControllerConstants.EDGE_ASSIGN_ASYNC_FIRST_STEP_DESCRIPTION;
  71 +import static org.thingsboard.server.controller.ControllerConstants.EDGE_ASSIGN_RECEIVE_STEP_DESCRIPTION;
  72 +import static org.thingsboard.server.controller.ControllerConstants.EDGE_UNASSIGN_ASYNC_FIRST_STEP_DESCRIPTION;
  73 +import static org.thingsboard.server.controller.ControllerConstants.EDGE_UNASSIGN_RECEIVE_STEP_DESCRIPTION;
  74 +import static org.thingsboard.server.controller.ControllerConstants.PAGE_DATA_PARAMETERS;
  75 +import static org.thingsboard.server.controller.ControllerConstants.PAGE_NUMBER_DESCRIPTION;
  76 +import static org.thingsboard.server.controller.ControllerConstants.PAGE_SIZE_DESCRIPTION;
  77 +import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_ALLOWABLE_VALUES;
  78 +import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_DESCRIPTION;
  79 +import static org.thingsboard.server.controller.ControllerConstants.SORT_PROPERTY_DESCRIPTION;
  80 +import static org.thingsboard.server.controller.ControllerConstants.SYSTEM_AUTHORITY_PARAGRAPH;
  81 +import static org.thingsboard.server.controller.ControllerConstants.TENANT_AUTHORITY_PARAGRAPH;
  82 +import static org.thingsboard.server.controller.ControllerConstants.TENANT_ID;
  83 +import static org.thingsboard.server.controller.ControllerConstants.TENANT_ID_PARAM_DESCRIPTION;
  84 +import static org.thingsboard.server.controller.ControllerConstants.TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH;
  85 +
65 @RestController 86 @RestController
66 @TbCoreComponent 87 @TbCoreComponent
67 @RequestMapping("/api") 88 @RequestMapping("/api")
@@ -86,6 +86,29 @@ import java.util.List; @@ -86,6 +86,29 @@ import java.util.List;
86 import java.util.UUID; 86 import java.util.UUID;
87 import java.util.stream.Collectors; 87 import java.util.stream.Collectors;
88 88
  89 +import static org.thingsboard.server.controller.ControllerConstants.CUSTOMER_AUTHORITY_PARAGRAPH;
  90 +import static org.thingsboard.server.controller.ControllerConstants.CUSTOMER_ID_PARAM_DESCRIPTION;
  91 +import static org.thingsboard.server.controller.ControllerConstants.DEVICE_ID_PARAM_DESCRIPTION;
  92 +import static org.thingsboard.server.controller.ControllerConstants.DEVICE_INFO_DESCRIPTION;
  93 +import static org.thingsboard.server.controller.ControllerConstants.DEVICE_NAME_DESCRIPTION;
  94 +import static org.thingsboard.server.controller.ControllerConstants.DEVICE_PROFILE_ID_PARAM_DESCRIPTION;
  95 +import static org.thingsboard.server.controller.ControllerConstants.DEVICE_SORT_PROPERTY_ALLOWABLE_VALUES;
  96 +import static org.thingsboard.server.controller.ControllerConstants.DEVICE_TEXT_SEARCH_DESCRIPTION;
  97 +import static org.thingsboard.server.controller.ControllerConstants.DEVICE_TYPE_DESCRIPTION;
  98 +import static org.thingsboard.server.controller.ControllerConstants.EDGE_ASSIGN_ASYNC_FIRST_STEP_DESCRIPTION;
  99 +import static org.thingsboard.server.controller.ControllerConstants.EDGE_ASSIGN_RECEIVE_STEP_DESCRIPTION;
  100 +import static org.thingsboard.server.controller.ControllerConstants.EDGE_ID_PARAM_DESCRIPTION;
  101 +import static org.thingsboard.server.controller.ControllerConstants.EDGE_UNASSIGN_ASYNC_FIRST_STEP_DESCRIPTION;
  102 +import static org.thingsboard.server.controller.ControllerConstants.EDGE_UNASSIGN_RECEIVE_STEP_DESCRIPTION;
  103 +import static org.thingsboard.server.controller.ControllerConstants.PAGE_DATA_PARAMETERS;
  104 +import static org.thingsboard.server.controller.ControllerConstants.PAGE_NUMBER_DESCRIPTION;
  105 +import static org.thingsboard.server.controller.ControllerConstants.PAGE_SIZE_DESCRIPTION;
  106 +import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_ALLOWABLE_VALUES;
  107 +import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_DESCRIPTION;
  108 +import static org.thingsboard.server.controller.ControllerConstants.SORT_PROPERTY_DESCRIPTION;
  109 +import static org.thingsboard.server.controller.ControllerConstants.TENANT_AUTHORITY_PARAGRAPH;
  110 +import static org.thingsboard.server.controller.ControllerConstants.TENANT_ID_PARAM_DESCRIPTION;
  111 +import static org.thingsboard.server.controller.ControllerConstants.TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH;
89 import static org.thingsboard.server.controller.EdgeController.EDGE_ID; 112 import static org.thingsboard.server.controller.EdgeController.EDGE_ID;
90 113
91 @RestController 114 @RestController
@@ -49,460 +49,29 @@ import java.util.List; @@ -49,460 +49,29 @@ import java.util.List;
49 import java.util.Objects; 49 import java.util.Objects;
50 import java.util.UUID; 50 import java.util.UUID;
51 51
  52 +import static org.thingsboard.server.controller.ControllerConstants.DEVICE_PROFILE_DATA;
  53 +import static org.thingsboard.server.controller.ControllerConstants.DEVICE_PROFILE_ID;
  54 +import static org.thingsboard.server.controller.ControllerConstants.DEVICE_PROFILE_ID_PARAM_DESCRIPTION;
  55 +import static org.thingsboard.server.controller.ControllerConstants.DEVICE_PROFILE_INFO_DESCRIPTION;
  56 +import static org.thingsboard.server.controller.ControllerConstants.DEVICE_PROFILE_SORT_PROPERTY_ALLOWABLE_VALUES;
  57 +import static org.thingsboard.server.controller.ControllerConstants.DEVICE_PROFILE_TEXT_SEARCH_DESCRIPTION;
  58 +import static org.thingsboard.server.controller.ControllerConstants.NEW_LINE;
  59 +import static org.thingsboard.server.controller.ControllerConstants.PAGE_DATA_PARAMETERS;
  60 +import static org.thingsboard.server.controller.ControllerConstants.PAGE_NUMBER_DESCRIPTION;
  61 +import static org.thingsboard.server.controller.ControllerConstants.PAGE_SIZE_DESCRIPTION;
  62 +import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_ALLOWABLE_VALUES;
  63 +import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_DESCRIPTION;
  64 +import static org.thingsboard.server.controller.ControllerConstants.SORT_PROPERTY_DESCRIPTION;
  65 +import static org.thingsboard.server.controller.ControllerConstants.TENANT_AUTHORITY_PARAGRAPH;
  66 +import static org.thingsboard.server.controller.ControllerConstants.TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH;
  67 +import static org.thingsboard.server.controller.ControllerConstants.TRANSPORT_TYPE_ALLOWABLE_VALUES;
  68 +
52 @RestController 69 @RestController
53 @TbCoreComponent 70 @TbCoreComponent
54 @RequestMapping("/api") 71 @RequestMapping("/api")
55 @Slf4j 72 @Slf4j
56 public class DeviceProfileController extends BaseController { 73 public class DeviceProfileController extends BaseController {
57 74
58 - private static final String COAP_TRANSPORT_CONFIGURATION_EXAMPLE = MARKDOWN_CODE_BLOCK_START +  
59 - "{\n" +  
60 - " \"type\":\"COAP\",\n" +  
61 - " \"clientSettings\":{\n" +  
62 - " \"edrxCycle\":null,\n" +  
63 - " \"powerMode\":\"DRX\",\n" +  
64 - " \"psmActivityTimer\":null,\n" +  
65 - " \"pagingTransmissionWindow\":null\n" +  
66 - " },\n" +  
67 - " \"coapDeviceTypeConfiguration\":{\n" +  
68 - " \"coapDeviceType\":\"DEFAULT\",\n" +  
69 - " \"transportPayloadTypeConfiguration\":{\n" +  
70 - " \"transportPayloadType\":\"JSON\"\n" +  
71 - " }\n" +  
72 - " }\n" +  
73 - "}"  
74 - + MARKDOWN_CODE_BLOCK_END;  
75 -  
76 - private static final String TRANSPORT_CONFIGURATION = "# Transport Configuration" + NEW_LINE +  
77 - "5 transport configuration types are available:\n" +  
78 - " * 'DEFAULT';\n" +  
79 - " * 'MQTT';\n" +  
80 - " * 'LWM2M';\n" +  
81 - " * 'COAP';\n" +  
82 - " * 'SNMP'." + NEW_LINE + "Default type supports basic MQTT, HTTP, CoAP and LwM2M transports. " +  
83 - "Please refer to the [docs](https://thingsboard.io/docs/user-guide/device-profiles/#transport-configuration) for more details about other types.\n" +  
84 - "\nSee another example of COAP transport configuration below:" + NEW_LINE + COAP_TRANSPORT_CONFIGURATION_EXAMPLE;  
85 -  
86 - private static final String ALARM_FILTER_KEY = "## Alarm Filter Key" + NEW_LINE +  
87 - "Filter Key defines either entity field, attribute, telemetry or constant. It is a JSON object that consists the key name and type. The following filter key types are supported:\n" +  
88 - " * 'ATTRIBUTE' - used for attributes values;\n" +  
89 - " * 'TIME_SERIES' - used for time-series values;\n" +  
90 - " * 'ENTITY_FIELD' - used for accessing entity fields like 'name', 'label', etc. The list of available fields depends on the entity type;\n" +  
91 - " * 'CONSTANT' - constant value specified." + NEW_LINE + "Let's review the example:" + NEW_LINE +  
92 - MARKDOWN_CODE_BLOCK_START +  
93 - "{\n" +  
94 - " \"type\": \"TIME_SERIES\",\n" +  
95 - " \"key\": \"temperature\"\n" +  
96 - "}" +  
97 - MARKDOWN_CODE_BLOCK_END;  
98 -  
99 - private static final String FILTER_PREDICATE = NEW_LINE + "## Filter Predicate" + NEW_LINE +  
100 - "Filter Predicate defines the logical expression to evaluate. The list of available operations depends on the filter value type, see above. " +  
101 - "Platform supports 4 predicate types: 'STRING', 'NUMERIC', 'BOOLEAN' and 'COMPLEX'. The last one allows to combine multiple operations over one filter key." + NEW_LINE +  
102 - "Simple predicate example to check 'value < 100': " + NEW_LINE +  
103 - MARKDOWN_CODE_BLOCK_START +  
104 - "{\n" +  
105 - " \"operation\": \"LESS\",\n" +  
106 - " \"value\": {\n" +  
107 - " \"userValue\": null,\n" +  
108 - " \"defaultValue\": 100,\n" +  
109 - " \"dynamicValue\": null\n" +  
110 - " },\n" +  
111 - " \"type\": \"NUMERIC\"\n" +  
112 - "}" +  
113 - MARKDOWN_CODE_BLOCK_END + NEW_LINE +  
114 - "Complex predicate example, to check 'value < 10 or value > 20': " + NEW_LINE +  
115 - MARKDOWN_CODE_BLOCK_START +  
116 - "{\n" +  
117 - " \"type\": \"COMPLEX\",\n" +  
118 - " \"operation\": \"OR\",\n" +  
119 - " \"predicates\": [\n" +  
120 - " {\n" +  
121 - " \"operation\": \"LESS\",\n" +  
122 - " \"value\": {\n" +  
123 - " \"userValue\": null,\n" +  
124 - " \"defaultValue\": 10,\n" +  
125 - " \"dynamicValue\": null\n" +  
126 - " },\n" +  
127 - " \"type\": \"NUMERIC\"\n" +  
128 - " },\n" +  
129 - " {\n" +  
130 - " \"operation\": \"GREATER\",\n" +  
131 - " \"value\": {\n" +  
132 - " \"userValue\": null,\n" +  
133 - " \"defaultValue\": 20,\n" +  
134 - " \"dynamicValue\": null\n" +  
135 - " },\n" +  
136 - " \"type\": \"NUMERIC\"\n" +  
137 - " }\n" +  
138 - " ]\n" +  
139 - "}" +  
140 - MARKDOWN_CODE_BLOCK_END + NEW_LINE +  
141 - "More complex predicate example, to check 'value < 10 or (value > 50 && value < 60)': " + NEW_LINE +  
142 - MARKDOWN_CODE_BLOCK_START +  
143 - "{\n" +  
144 - " \"type\": \"COMPLEX\",\n" +  
145 - " \"operation\": \"OR\",\n" +  
146 - " \"predicates\": [\n" +  
147 - " {\n" +  
148 - " \"operation\": \"LESS\",\n" +  
149 - " \"value\": {\n" +  
150 - " \"userValue\": null,\n" +  
151 - " \"defaultValue\": 10,\n" +  
152 - " \"dynamicValue\": null\n" +  
153 - " },\n" +  
154 - " \"type\": \"NUMERIC\"\n" +  
155 - " },\n" +  
156 - " {\n" +  
157 - " \"type\": \"COMPLEX\",\n" +  
158 - " \"operation\": \"AND\",\n" +  
159 - " \"predicates\": [\n" +  
160 - " {\n" +  
161 - " \"operation\": \"GREATER\",\n" +  
162 - " \"value\": {\n" +  
163 - " \"userValue\": null,\n" +  
164 - " \"defaultValue\": 50,\n" +  
165 - " \"dynamicValue\": null\n" +  
166 - " },\n" +  
167 - " \"type\": \"NUMERIC\"\n" +  
168 - " },\n" +  
169 - " {\n" +  
170 - " \"operation\": \"LESS\",\n" +  
171 - " \"value\": {\n" +  
172 - " \"userValue\": null,\n" +  
173 - " \"defaultValue\": 60,\n" +  
174 - " \"dynamicValue\": null\n" +  
175 - " },\n" +  
176 - " \"type\": \"NUMERIC\"\n" +  
177 - " }\n" +  
178 - " ]\n" +  
179 - " }\n" +  
180 - " ]\n" +  
181 - "}" +  
182 - MARKDOWN_CODE_BLOCK_END + NEW_LINE +  
183 - "You may also want to replace hardcoded values (for example, temperature > 20) with the more dynamic " +  
184 - "expression (for example, temperature > value of the tenant attribute with key 'temperatureThreshold'). " +  
185 - "It is possible to use 'dynamicValue' to define attribute of the tenant, customer or device. " +  
186 - "See example below:" + NEW_LINE +  
187 - MARKDOWN_CODE_BLOCK_START +  
188 - "{\n" +  
189 - " \"operation\": \"GREATER\",\n" +  
190 - " \"value\": {\n" +  
191 - " \"userValue\": null,\n" +  
192 - " \"defaultValue\": 0,\n" +  
193 - " \"dynamicValue\": {\n" +  
194 - " \"inherit\": false,\n" +  
195 - " \"sourceType\": \"CURRENT_TENANT\",\n" +  
196 - " \"sourceAttribute\": \"temperatureThreshold\"\n" +  
197 - " }\n" +  
198 - " },\n" +  
199 - " \"type\": \"NUMERIC\"\n" +  
200 - "}" +  
201 - MARKDOWN_CODE_BLOCK_END + NEW_LINE +  
202 - "Note that you may use 'CURRENT_DEVICE', 'CURRENT_CUSTOMER' and 'CURRENT_TENANT' as a 'sourceType'. The 'defaultValue' is used when the attribute with such a name is not defined for the chosen source. " +  
203 - "The 'sourceAttribute' can be inherited from the owner of the specified 'sourceType' if 'inherit' is set to true.";  
204 -  
205 - private static final String KEY_FILTERS_DESCRIPTION = "# Key Filters" + NEW_LINE +  
206 - "Key filter objects are created under the **'condition'** array. They allow you to define complex logical expressions over entity field, " +  
207 - "attribute, latest time-series value or constant. The filter is defined using 'key', 'valueType', " +  
208 - "'value' (refers to the value of the 'CONSTANT' alarm filter key type) and 'predicate' objects. Let's review each object:" + NEW_LINE +  
209 - ALARM_FILTER_KEY + FILTER_VALUE_TYPE + NEW_LINE + FILTER_PREDICATE + NEW_LINE;  
210 -  
211 - private static final String DEFAULT_DEVICE_PROFILE_DATA_EXAMPLE = MARKDOWN_CODE_BLOCK_START + "{\n" +  
212 - " \"alarms\":[\n" +  
213 - " ],\n" +  
214 - " \"configuration\":{\n" +  
215 - " \"type\":\"DEFAULT\"\n" +  
216 - " },\n" +  
217 - " \"provisionConfiguration\":{\n" +  
218 - " \"type\":\"DISABLED\",\n" +  
219 - " \"provisionDeviceSecret\":null\n" +  
220 - " },\n" +  
221 - " \"transportConfiguration\":{\n" +  
222 - " \"type\":\"DEFAULT\"\n" +  
223 - " }\n" +  
224 - "}" + MARKDOWN_CODE_BLOCK_END;  
225 -  
226 - private static final String CUSTOM_DEVICE_PROFILE_DATA_EXAMPLE = MARKDOWN_CODE_BLOCK_START + "{\n" +  
227 - " \"alarms\":[\n" +  
228 - " {\n" +  
229 - " \"id\":\"2492b935-1226-59e9-8615-17d8978a4f93\",\n" +  
230 - " \"alarmType\":\"Temperature Alarm\",\n" +  
231 - " \"clearRule\":{\n" +  
232 - " \"schedule\":null,\n" +  
233 - " \"condition\":{\n" +  
234 - " \"spec\":{\n" +  
235 - " \"type\":\"SIMPLE\"\n" +  
236 - " },\n" +  
237 - " \"condition\":[\n" +  
238 - " {\n" +  
239 - " \"key\":{\n" +  
240 - " \"key\":\"temperature\",\n" +  
241 - " \"type\":\"TIME_SERIES\"\n" +  
242 - " },\n" +  
243 - " \"value\":null,\n" +  
244 - " \"predicate\":{\n" +  
245 - " \"type\":\"NUMERIC\",\n" +  
246 - " \"value\":{\n" +  
247 - " \"userValue\":null,\n" +  
248 - " \"defaultValue\":30.0,\n" +  
249 - " \"dynamicValue\":null\n" +  
250 - " },\n" +  
251 - " \"operation\":\"LESS\"\n" +  
252 - " },\n" +  
253 - " \"valueType\":\"NUMERIC\"\n" +  
254 - " }\n" +  
255 - " ]\n" +  
256 - " },\n" +  
257 - " \"dashboardId\":null,\n" +  
258 - " \"alarmDetails\":null\n" +  
259 - " },\n" +  
260 - " \"propagate\":false,\n" +  
261 - " \"createRules\":{\n" +  
262 - " \"MAJOR\":{\n" +  
263 - " \"schedule\":{\n" +  
264 - " \"type\":\"SPECIFIC_TIME\",\n" +  
265 - " \"endsOn\":64800000,\n" +  
266 - " \"startsOn\":43200000,\n" +  
267 - " \"timezone\":\"Europe/Kiev\",\n" +  
268 - " \"daysOfWeek\":[\n" +  
269 - " 1,\n" +  
270 - " 3,\n" +  
271 - " 5\n" +  
272 - " ]\n" +  
273 - " },\n" +  
274 - " \"condition\":{\n" +  
275 - " \"spec\":{\n" +  
276 - " \"type\":\"DURATION\",\n" +  
277 - " \"unit\":\"MINUTES\",\n" +  
278 - " \"predicate\":{\n" +  
279 - " \"userValue\":null,\n" +  
280 - " \"defaultValue\":30,\n" +  
281 - " \"dynamicValue\":null\n" +  
282 - " }\n" +  
283 - " },\n" +  
284 - " \"condition\":[\n" +  
285 - " {\n" +  
286 - " \"key\":{\n" +  
287 - " \"key\":\"temperature\",\n" +  
288 - " \"type\":\"TIME_SERIES\"\n" +  
289 - " },\n" +  
290 - " \"value\":null,\n" +  
291 - " \"predicate\":{\n" +  
292 - " \"type\":\"COMPLEX\",\n" +  
293 - " \"operation\":\"OR\",\n" +  
294 - " \"predicates\":[\n" +  
295 - " {\n" +  
296 - " \"type\":\"NUMERIC\",\n" +  
297 - " \"value\":{\n" +  
298 - " \"userValue\":null,\n" +  
299 - " \"defaultValue\":50.0,\n" +  
300 - " \"dynamicValue\":null\n" +  
301 - " },\n" +  
302 - " \"operation\":\"LESS_OR_EQUAL\"\n" +  
303 - " },\n" +  
304 - " {\n" +  
305 - " \"type\":\"NUMERIC\",\n" +  
306 - " \"value\":{\n" +  
307 - " \"userValue\":null,\n" +  
308 - " \"defaultValue\":30.0,\n" +  
309 - " \"dynamicValue\":null\n" +  
310 - " },\n" +  
311 - " \"operation\":\"GREATER\"\n" +  
312 - " }\n" +  
313 - " ]\n" +  
314 - " },\n" +  
315 - " \"valueType\":\"NUMERIC\"\n" +  
316 - " }\n" +  
317 - " ]\n" +  
318 - " },\n" +  
319 - " \"dashboardId\":null,\n" +  
320 - " \"alarmDetails\":null\n" +  
321 - " },\n" +  
322 - " \"WARNING\":{\n" +  
323 - " \"schedule\":{\n" +  
324 - " \"type\":\"CUSTOM\",\n" +  
325 - " \"items\":[\n" +  
326 - " {\n" +  
327 - " \"endsOn\":0,\n" +  
328 - " \"enabled\":false,\n" +  
329 - " \"startsOn\":0,\n" +  
330 - " \"dayOfWeek\":1\n" +  
331 - " },\n" +  
332 - " {\n" +  
333 - " \"endsOn\":64800000,\n" +  
334 - " \"enabled\":true,\n" +  
335 - " \"startsOn\":43200000,\n" +  
336 - " \"dayOfWeek\":2\n" +  
337 - " },\n" +  
338 - " {\n" +  
339 - " \"endsOn\":0,\n" +  
340 - " \"enabled\":false,\n" +  
341 - " \"startsOn\":0,\n" +  
342 - " \"dayOfWeek\":3\n" +  
343 - " },\n" +  
344 - " {\n" +  
345 - " \"endsOn\":57600000,\n" +  
346 - " \"enabled\":true,\n" +  
347 - " \"startsOn\":36000000,\n" +  
348 - " \"dayOfWeek\":4\n" +  
349 - " },\n" +  
350 - " {\n" +  
351 - " \"endsOn\":0,\n" +  
352 - " \"enabled\":false,\n" +  
353 - " \"startsOn\":0,\n" +  
354 - " \"dayOfWeek\":5\n" +  
355 - " },\n" +  
356 - " {\n" +  
357 - " \"endsOn\":0,\n" +  
358 - " \"enabled\":false,\n" +  
359 - " \"startsOn\":0,\n" +  
360 - " \"dayOfWeek\":6\n" +  
361 - " },\n" +  
362 - " {\n" +  
363 - " \"endsOn\":0,\n" +  
364 - " \"enabled\":false,\n" +  
365 - " \"startsOn\":0,\n" +  
366 - " \"dayOfWeek\":7\n" +  
367 - " }\n" +  
368 - " ],\n" +  
369 - " \"timezone\":\"Europe/Kiev\"\n" +  
370 - " },\n" +  
371 - " \"condition\":{\n" +  
372 - " \"spec\":{\n" +  
373 - " \"type\":\"REPEATING\",\n" +  
374 - " \"predicate\":{\n" +  
375 - " \"userValue\":null,\n" +  
376 - " \"defaultValue\":5,\n" +  
377 - " \"dynamicValue\":null\n" +  
378 - " }\n" +  
379 - " },\n" +  
380 - " \"condition\":[\n" +  
381 - " {\n" +  
382 - " \"key\":{\n" +  
383 - " \"key\":\"tempConstant\",\n" +  
384 - " \"type\":\"CONSTANT\"\n" +  
385 - " },\n" +  
386 - " \"value\":30,\n" +  
387 - " \"predicate\":{\n" +  
388 - " \"type\":\"NUMERIC\",\n" +  
389 - " \"value\":{\n" +  
390 - " \"userValue\":null,\n" +  
391 - " \"defaultValue\":0.0,\n" +  
392 - " \"dynamicValue\":{\n" +  
393 - " \"inherit\":false,\n" +  
394 - " \"sourceType\":\"CURRENT_DEVICE\",\n" +  
395 - " \"sourceAttribute\":\"tempThreshold\"\n" +  
396 - " }\n" +  
397 - " },\n" +  
398 - " \"operation\":\"EQUAL\"\n" +  
399 - " },\n" +  
400 - " \"valueType\":\"NUMERIC\"\n" +  
401 - " }\n" +  
402 - " ]\n" +  
403 - " },\n" +  
404 - " \"dashboardId\":null,\n" +  
405 - " \"alarmDetails\":null\n" +  
406 - " },\n" +  
407 - " \"CRITICAL\":{\n" +  
408 - " \"schedule\":null,\n" +  
409 - " \"condition\":{\n" +  
410 - " \"spec\":{\n" +  
411 - " \"type\":\"SIMPLE\"\n" +  
412 - " },\n" +  
413 - " \"condition\":[\n" +  
414 - " {\n" +  
415 - " \"key\":{\n" +  
416 - " \"key\":\"temperature\",\n" +  
417 - " \"type\":\"TIME_SERIES\"\n" +  
418 - " },\n" +  
419 - " \"value\":null,\n" +  
420 - " \"predicate\":{\n" +  
421 - " \"type\":\"NUMERIC\",\n" +  
422 - " \"value\":{\n" +  
423 - " \"userValue\":null,\n" +  
424 - " \"defaultValue\":50.0,\n" +  
425 - " \"dynamicValue\":null\n" +  
426 - " },\n" +  
427 - " \"operation\":\"GREATER\"\n" +  
428 - " },\n" +  
429 - " \"valueType\":\"NUMERIC\"\n" +  
430 - " }\n" +  
431 - " ]\n" +  
432 - " },\n" +  
433 - " \"dashboardId\":null,\n" +  
434 - " \"alarmDetails\":null\n" +  
435 - " }\n" +  
436 - " },\n" +  
437 - " \"propagateRelationTypes\":null\n" +  
438 - " }\n" +  
439 - " ],\n" +  
440 - " \"configuration\":{\n" +  
441 - " \"type\":\"DEFAULT\"\n" +  
442 - " },\n" +  
443 - " \"provisionConfiguration\":{\n" +  
444 - " \"type\":\"ALLOW_CREATE_NEW_DEVICES\",\n" +  
445 - " \"provisionDeviceSecret\":\"vaxb9hzqdbz3oqukvomg\"\n" +  
446 - " },\n" +  
447 - " \"transportConfiguration\":{\n" +  
448 - " \"type\":\"MQTT\",\n" +  
449 - " \"deviceTelemetryTopic\":\"v1/devices/me/telemetry\",\n" +  
450 - " \"deviceAttributesTopic\":\"v1/devices/me/attributes\",\n" +  
451 - " \"transportPayloadTypeConfiguration\":{\n" +  
452 - " \"transportPayloadType\":\"PROTOBUF\",\n" +  
453 - " \"deviceTelemetryProtoSchema\":\"syntax =\\\"proto3\\\";\\npackage telemetry;\\n\\nmessage SensorDataReading {\\n\\n optional double temperature = 1;\\n optional double humidity = 2;\\n InnerObject innerObject = 3;\\n\\n message InnerObject {\\n optional string key1 = 1;\\n optional bool key2 = 2;\\n optional double key3 = 3;\\n optional int32 key4 = 4;\\n optional string key5 = 5;\\n }\\n}\",\n" +  
454 - " \"deviceAttributesProtoSchema\":\"syntax =\\\"proto3\\\";\\npackage attributes;\\n\\nmessage SensorConfiguration {\\n optional string firmwareVersion = 1;\\n optional string serialNumber = 2;\\n}\",\n" +  
455 - " \"deviceRpcRequestProtoSchema\":\"syntax =\\\"proto3\\\";\\npackage rpc;\\n\\nmessage RpcRequestMsg {\\n optional string method = 1;\\n optional int32 requestId = 2;\\n optional string params = 3;\\n}\",\n" +  
456 - " \"deviceRpcResponseProtoSchema\":\"syntax =\\\"proto3\\\";\\npackage rpc;\\n\\nmessage RpcResponseMsg {\\n optional string payload = 1;\\n}\"\n" +  
457 - " }\n" +  
458 - " }\n" +  
459 - "}" + MARKDOWN_CODE_BLOCK_END;  
460 - private static final String DEVICE_PROFILE_DATA_DEFINITION = NEW_LINE + "# Device profile data definition" + NEW_LINE +  
461 - "Device profile data object contains alarm rules configuration, device provision strategy and transport type configuration for device connectivity. Let's review some examples. " +  
462 - "First one is the default device profile data configuration and second one - the custom one. " +  
463 - NEW_LINE + DEFAULT_DEVICE_PROFILE_DATA_EXAMPLE + NEW_LINE + CUSTOM_DEVICE_PROFILE_DATA_EXAMPLE +  
464 - NEW_LINE + "Let's review some specific objects examples related to the device profile configuration:";  
465 -  
466 - private static final String ALARM_SCHEDULE = NEW_LINE + "# Alarm Schedule" + NEW_LINE +  
467 - "Alarm Schedule JSON object represents the time interval during which the alarm rule is active. Note, " +  
468 - NEW_LINE + DEVICE_PROFILE_ALARM_SCHEDULE_ALWAYS_EXAMPLE + NEW_LINE + "means alarm rule is active all the time. " +  
469 - "**'daysOfWeek'** field represents Monday as 1, Tuesday as 2 and so on. **'startsOn'** and **'endsOn'** fields represent hours in millis (e.g. 64800000 = 18:00 or 6pm). " +  
470 - "**'enabled'** flag specifies if item in a custom rule is active for specific day of the week:" + NEW_LINE +  
471 - "## Specific Time Schedule" + NEW_LINE +  
472 - DEVICE_PROFILE_ALARM_SCHEDULE_SPECIFIC_TIME_EXAMPLE + NEW_LINE +  
473 - "## Custom Schedule" +  
474 - NEW_LINE + DEVICE_PROFILE_ALARM_SCHEDULE_CUSTOM_EXAMPLE + NEW_LINE;  
475 -  
476 - private static final String ALARM_CONDITION_TYPE = "# Alarm condition type (**'spec'**)" + NEW_LINE +  
477 - "Alarm condition type can be either simple, duration, or repeating. For example, 5 times in a row or during 5 minutes." + NEW_LINE +  
478 - "Note, **'userValue'** field is not used and reserved for future usage, **'dynamicValue'** is used for condition appliance by using the value of the **'sourceAttribute'** " +  
479 - "or else **'defaultValue'** is used (if **'sourceAttribute'** is absent).\n" +  
480 - "\n**'sourceType'** of the **'sourceAttribute'** can be: \n" +  
481 - " * 'CURRENT_DEVICE';\n" +  
482 - " * 'CURRENT_CUSTOMER';\n" +  
483 - " * 'CURRENT_TENANT'." + NEW_LINE +  
484 - "**'sourceAttribute'** can be inherited from the owner if **'inherit'** is set to true (for CURRENT_DEVICE and CURRENT_CUSTOMER)." + NEW_LINE +  
485 - "## Repeating alarm condition" + NEW_LINE +  
486 - DEVICE_PROFILE_ALARM_CONDITION_REPEATING_EXAMPLE + NEW_LINE +  
487 - "## Duration alarm condition" + NEW_LINE +  
488 - DEVICE_PROFILE_ALARM_CONDITION_DURATION_EXAMPLE + NEW_LINE +  
489 - "**'unit'** can be: \n" +  
490 - " * 'SECONDS';\n" +  
491 - " * 'MINUTES';\n" +  
492 - " * 'HOURS';\n" +  
493 - " * 'DAYS'." + NEW_LINE;  
494 -  
495 - private static final String PROVISION_CONFIGURATION = "# Provision Configuration" + NEW_LINE +  
496 - "There are 3 types of device provision configuration for the device profile: \n" +  
497 - " * 'DISABLED';\n" +  
498 - " * 'ALLOW_CREATE_NEW_DEVICES';\n" +  
499 - " * 'CHECK_PRE_PROVISIONED_DEVICES'." + NEW_LINE +  
500 - "Please refer to the [docs](https://thingsboard.io/docs/user-guide/device-provisioning/) for more details." + NEW_LINE;  
501 -  
502 - private static final String DEVICE_PROFILE_DATA = DEVICE_PROFILE_DATA_DEFINITION + ALARM_SCHEDULE + ALARM_CONDITION_TYPE +  
503 - KEY_FILTERS_DESCRIPTION + PROVISION_CONFIGURATION + TRANSPORT_CONFIGURATION;  
504 -  
505 - private static final String DEVICE_PROFILE_ID = "deviceProfileId";  
506 75
507 @Autowired 76 @Autowired
508 private TimeseriesService timeseriesService; 77 private TimeseriesService timeseriesService;
@@ -69,6 +69,22 @@ import java.util.ArrayList; @@ -69,6 +69,22 @@ import java.util.ArrayList;
69 import java.util.List; 69 import java.util.List;
70 import java.util.stream.Collectors; 70 import java.util.stream.Collectors;
71 71
  72 +import static org.thingsboard.server.controller.ControllerConstants.CUSTOMER_ID_PARAM_DESCRIPTION;
  73 +import static org.thingsboard.server.controller.ControllerConstants.EDGE_ID_PARAM_DESCRIPTION;
  74 +import static org.thingsboard.server.controller.ControllerConstants.EDGE_INFO_DESCRIPTION;
  75 +import static org.thingsboard.server.controller.ControllerConstants.EDGE_SORT_PROPERTY_ALLOWABLE_VALUES;
  76 +import static org.thingsboard.server.controller.ControllerConstants.EDGE_TEXT_SEARCH_DESCRIPTION;
  77 +import static org.thingsboard.server.controller.ControllerConstants.EDGE_TYPE_DESCRIPTION;
  78 +import static org.thingsboard.server.controller.ControllerConstants.PAGE_DATA_PARAMETERS;
  79 +import static org.thingsboard.server.controller.ControllerConstants.PAGE_NUMBER_DESCRIPTION;
  80 +import static org.thingsboard.server.controller.ControllerConstants.PAGE_SIZE_DESCRIPTION;
  81 +import static org.thingsboard.server.controller.ControllerConstants.RULE_CHAIN_ID_PARAM_DESCRIPTION;
  82 +import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_ALLOWABLE_VALUES;
  83 +import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_DESCRIPTION;
  84 +import static org.thingsboard.server.controller.ControllerConstants.SORT_PROPERTY_DESCRIPTION;
  85 +import static org.thingsboard.server.controller.ControllerConstants.TENANT_AUTHORITY_PARAGRAPH;
  86 +import static org.thingsboard.server.controller.ControllerConstants.TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH;
  87 +
72 @RestController 88 @RestController
73 @TbCoreComponent 89 @TbCoreComponent
74 @Slf4j 90 @Slf4j
@@ -37,6 +37,15 @@ import org.thingsboard.server.dao.edge.EdgeEventService; @@ -37,6 +37,15 @@ import org.thingsboard.server.dao.edge.EdgeEventService;
37 import org.thingsboard.server.queue.util.TbCoreComponent; 37 import org.thingsboard.server.queue.util.TbCoreComponent;
38 import org.thingsboard.server.service.security.permission.Operation; 38 import org.thingsboard.server.service.security.permission.Operation;
39 39
  40 +import static org.thingsboard.server.controller.ControllerConstants.EDGE_ID_PARAM_DESCRIPTION;
  41 +import static org.thingsboard.server.controller.ControllerConstants.EDGE_SORT_PROPERTY_ALLOWABLE_VALUES;
  42 +import static org.thingsboard.server.controller.ControllerConstants.PAGE_DATA_PARAMETERS;
  43 +import static org.thingsboard.server.controller.ControllerConstants.PAGE_NUMBER_DESCRIPTION;
  44 +import static org.thingsboard.server.controller.ControllerConstants.PAGE_SIZE_DESCRIPTION;
  45 +import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_ALLOWABLE_VALUES;
  46 +import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_DESCRIPTION;
  47 +import static org.thingsboard.server.controller.ControllerConstants.SORT_PROPERTY_DESCRIPTION;
  48 +
40 @Slf4j 49 @Slf4j
41 @RestController 50 @RestController
42 @TbCoreComponent 51 @TbCoreComponent
@@ -39,634 +39,15 @@ import org.thingsboard.server.common.data.query.EntityDataQuery; @@ -39,634 +39,15 @@ import org.thingsboard.server.common.data.query.EntityDataQuery;
39 import org.thingsboard.server.queue.util.TbCoreComponent; 39 import org.thingsboard.server.queue.util.TbCoreComponent;
40 import org.thingsboard.server.service.query.EntityQueryService; 40 import org.thingsboard.server.service.query.EntityQueryService;
41 41
  42 +import static org.thingsboard.server.controller.ControllerConstants.ALARM_DATA_QUERY_DESCRIPTION;
  43 +import static org.thingsboard.server.controller.ControllerConstants.ENTITY_COUNT_QUERY_DESCRIPTION;
  44 +import static org.thingsboard.server.controller.ControllerConstants.ENTITY_DATA_QUERY_DESCRIPTION;
  45 +
42 @RestController 46 @RestController
43 @TbCoreComponent 47 @TbCoreComponent
44 @RequestMapping("/api") 48 @RequestMapping("/api")
45 public class EntityQueryController extends BaseController { 49 public class EntityQueryController extends BaseController {
46 50
47 - private static final String SINGLE_ENTITY = "\n\n## Single Entity\n\n" +  
48 - "Allows to filter only one entity based on the id. For example, this entity filter selects certain device:\n\n" +  
49 - MARKDOWN_CODE_BLOCK_START +  
50 - "{\n" +  
51 - " \"type\": \"singleEntity\",\n" +  
52 - " \"singleEntity\": {\n" +  
53 - " \"id\": \"d521edb0-2a7a-11ec-94eb-213c95f54092\",\n" +  
54 - " \"entityType\": \"DEVICE\"\n" +  
55 - " }\n" +  
56 - "}" +  
57 - MARKDOWN_CODE_BLOCK_END +  
58 - "";  
59 -  
60 - private static final String ENTITY_LIST = "\n\n## Entity List Filter\n\n" +  
61 - "Allows to filter entities of the same type using their ids. For example, this entity filter selects two devices:\n\n" +  
62 - MARKDOWN_CODE_BLOCK_START +  
63 - "{\n" +  
64 - " \"type\": \"entityList\",\n" +  
65 - " \"entityType\": \"DEVICE\",\n" +  
66 - " \"entityList\": [\n" +  
67 - " \"e6501f30-2a7a-11ec-94eb-213c95f54092\",\n" +  
68 - " \"e6657bf0-2a7a-11ec-94eb-213c95f54092\"\n" +  
69 - " ]\n" +  
70 - "}" +  
71 - MARKDOWN_CODE_BLOCK_END +  
72 - "";  
73 -  
74 - private static final String ENTITY_NAME = "\n\n## Entity Name Filter\n\n" +  
75 - "Allows to filter entities of the same type using the **'starts with'** expression over entity name. " +  
76 - "For example, this entity filter selects all devices which name starts with 'Air Quality':\n\n" +  
77 - MARKDOWN_CODE_BLOCK_START +  
78 - "{\n" +  
79 - " \"type\": \"entityName\",\n" +  
80 - " \"entityType\": \"DEVICE\",\n" +  
81 - " \"entityNameFilter\": \"Air Quality\"\n" +  
82 - "}" +  
83 - MARKDOWN_CODE_BLOCK_END +  
84 - "";  
85 -  
86 - private static final String ENTITY_TYPE = "\n\n## Entity Type Filter\n\n" +  
87 - "Allows to filter entities based on their type (CUSTOMER, USER, DASHBOARD, ASSET, DEVICE, etc)" +  
88 - "For example, this entity filter selects all tenant customers:\n\n" +  
89 - MARKDOWN_CODE_BLOCK_START +  
90 - "{\n" +  
91 - " \"type\": \"entityType\",\n" +  
92 - " \"entityType\": \"CUSTOMER\"\n" +  
93 - "}" +  
94 - MARKDOWN_CODE_BLOCK_END +  
95 - "";  
96 -  
97 - private static final String ASSET_TYPE = "\n\n## Asset Type Filter\n\n" +  
98 - "Allows to filter assets based on their type and the **'starts with'** expression over their name. " +  
99 - "For example, this entity filter selects all 'charging station' assets which name starts with 'Tesla':\n\n" +  
100 - MARKDOWN_CODE_BLOCK_START +  
101 - "{\n" +  
102 - " \"type\": \"assetType\",\n" +  
103 - " \"assetType\": \"charging station\",\n" +  
104 - " \"assetNameFilter\": \"Tesla\"\n" +  
105 - "}" +  
106 - MARKDOWN_CODE_BLOCK_END +  
107 - "";  
108 -  
109 - private static final String DEVICE_TYPE = "\n\n## Device Type Filter\n\n" +  
110 - "Allows to filter devices based on their type and the **'starts with'** expression over their name. " +  
111 - "For example, this entity filter selects all 'Temperature Sensor' devices which name starts with 'ABC':\n\n" +  
112 - MARKDOWN_CODE_BLOCK_START +  
113 - "{\n" +  
114 - " \"type\": \"deviceType\",\n" +  
115 - " \"deviceType\": \"Temperature Sensor\",\n" +  
116 - " \"deviceNameFilter\": \"ABC\"\n" +  
117 - "}" +  
118 - MARKDOWN_CODE_BLOCK_END +  
119 - "";  
120 -  
121 - private static final String EDGE_TYPE = "\n\n## Edge Type Filter\n\n" +  
122 - "Allows to filter edge instances based on their type and the **'starts with'** expression over their name. " +  
123 - "For example, this entity filter selects all 'Factory' edge instances which name starts with 'Nevada':\n\n" +  
124 - MARKDOWN_CODE_BLOCK_START +  
125 - "{\n" +  
126 - " \"type\": \"edgeType\",\n" +  
127 - " \"edgeType\": \"Factory\",\n" +  
128 - " \"edgeNameFilter\": \"Nevada\"\n" +  
129 - "}" +  
130 - MARKDOWN_CODE_BLOCK_END +  
131 - "";  
132 -  
133 - private static final String ENTITY_VIEW_TYPE = "\n\n## Entity View Filter\n\n" +  
134 - "Allows to filter entity views based on their type and the **'starts with'** expression over their name. " +  
135 - "For example, this entity filter selects all 'Concrete Mixer' entity views which name starts with 'CAT':\n\n" +  
136 - MARKDOWN_CODE_BLOCK_START +  
137 - "{\n" +  
138 - " \"type\": \"entityViewType\",\n" +  
139 - " \"entityViewType\": \"Concrete Mixer\",\n" +  
140 - " \"entityViewNameFilter\": \"CAT\"\n" +  
141 - "}" +  
142 - MARKDOWN_CODE_BLOCK_END +  
143 - "";  
144 -  
145 - private static final String API_USAGE = "\n\n## Api Usage Filter\n\n" +  
146 - "Allows to query for Api Usage based on optional customer id. If the customer id is not set, returns current tenant API usage." +  
147 - "For example, this entity filter selects the 'Api Usage' entity for customer with id 'e6501f30-2a7a-11ec-94eb-213c95f54092':\n\n" +  
148 - MARKDOWN_CODE_BLOCK_START +  
149 - "{\n" +  
150 - " \"type\": \"apiUsageState\",\n" +  
151 - " \"customerId\": {\n" +  
152 - " \"id\": \"d521edb0-2a7a-11ec-94eb-213c95f54092\",\n" +  
153 - " \"entityType\": \"CUSTOMER\"\n" +  
154 - " }\n" +  
155 - "}" +  
156 - MARKDOWN_CODE_BLOCK_END +  
157 - "";  
158 -  
159 - private static final String MAX_LEVEL_DESCRIPTION = "Possible direction values are 'TO' and 'FROM'. The 'maxLevel' defines how many relation levels should the query search 'recursively'. ";  
160 - private static final String FETCH_LAST_LEVEL_ONLY_DESCRIPTION = "Assuming the 'maxLevel' is > 1, the 'fetchLastLevelOnly' defines either to return all related entities or only entities that are on the last level of relations. ";  
161 -  
162 - private static final String RELATIONS_QUERY_FILTER = "\n\n## Relations Query Filter\n\n" +  
163 - "Allows to filter entities that are related to the provided root entity. " +  
164 - MAX_LEVEL_DESCRIPTION +  
165 - FETCH_LAST_LEVEL_ONLY_DESCRIPTION +  
166 - "The 'filter' object allows you to define the relation type and set of acceptable entity types to search for. " +  
167 - "The relation query calculates all related entities, even if they are filtered using different relation types, and then extracts only those who match the 'filters'.\n\n" +  
168 - "For example, this entity filter selects all devices and assets which are related to the asset with id 'e51de0c0-2a7a-11ec-94eb-213c95f54092':\n\n" +  
169 - MARKDOWN_CODE_BLOCK_START +  
170 - "{\n" +  
171 - " \"type\": \"relationsQuery\",\n" +  
172 - " \"rootEntity\": {\n" +  
173 - " \"entityType\": \"ASSET\",\n" +  
174 - " \"id\": \"e51de0c0-2a7a-11ec-94eb-213c95f54092\"\n" +  
175 - " },\n" +  
176 - " \"direction\": \"FROM\",\n" +  
177 - " \"maxLevel\": 1,\n" +  
178 - " \"fetchLastLevelOnly\": false,\n" +  
179 - " \"filters\": [\n" +  
180 - " {\n" +  
181 - " \"relationType\": \"Contains\",\n" +  
182 - " \"entityTypes\": [\n" +  
183 - " \"DEVICE\",\n" +  
184 - " \"ASSET\"\n" +  
185 - " ]\n" +  
186 - " }\n" +  
187 - " ]\n" +  
188 - "}" +  
189 - MARKDOWN_CODE_BLOCK_END +  
190 - "";  
191 -  
192 -  
193 - private static final String ASSET_QUERY_FILTER = "\n\n## Asset Search Query\n\n" +  
194 - "Allows to filter assets that are related to the provided root entity. Filters related assets based on the relation type and set of asset types. " +  
195 - MAX_LEVEL_DESCRIPTION +  
196 - FETCH_LAST_LEVEL_ONLY_DESCRIPTION +  
197 - "The 'relationType' defines the type of the relation to search for. " +  
198 - "The 'assetTypes' defines the type of the asset to search for. " +  
199 - "The relation query calculates all related entities, even if they are filtered using different relation types, and then extracts only assets that match 'relationType' and 'assetTypes' conditions.\n\n" +  
200 - "For example, this entity filter selects 'charging station' assets which are related to the asset with id 'e51de0c0-2a7a-11ec-94eb-213c95f54092' using 'Contains' relation:\n\n" +  
201 - MARKDOWN_CODE_BLOCK_START +  
202 - "{\n" +  
203 - " \"type\": \"assetSearchQuery\",\n" +  
204 - " \"rootEntity\": {\n" +  
205 - " \"entityType\": \"ASSET\",\n" +  
206 - " \"id\": \"e51de0c0-2a7a-11ec-94eb-213c95f54092\"\n" +  
207 - " },\n" +  
208 - " \"direction\": \"FROM\",\n" +  
209 - " \"maxLevel\": 1,\n" +  
210 - " \"fetchLastLevelOnly\": false,\n" +  
211 - " \"relationType\": \"Contains\",\n" +  
212 - " \"assetTypes\": [\n" +  
213 - " \"charging station\"\n" +  
214 - " ]\n" +  
215 - "}" +  
216 - MARKDOWN_CODE_BLOCK_END +  
217 - "";  
218 -  
219 - private static final String DEVICE_QUERY_FILTER = "\n\n## Device Search Query\n\n" +  
220 - "Allows to filter devices that are related to the provided root entity. Filters related devices based on the relation type and set of device types. " +  
221 - MAX_LEVEL_DESCRIPTION +  
222 - FETCH_LAST_LEVEL_ONLY_DESCRIPTION +  
223 - "The 'relationType' defines the type of the relation to search for. " +  
224 - "The 'deviceTypes' defines the type of the device to search for. " +  
225 - "The relation query calculates all related entities, even if they are filtered using different relation types, and then extracts only devices that match 'relationType' and 'deviceTypes' conditions.\n\n" +  
226 - "For example, this entity filter selects 'Charging port' and 'Air Quality Sensor' devices which are related to the asset with id 'e52b0020-2a7a-11ec-94eb-213c95f54092' using 'Contains' relation:\n\n" +  
227 - MARKDOWN_CODE_BLOCK_START +  
228 - "{\n" +  
229 - " \"type\": \"deviceSearchQuery\",\n" +  
230 - " \"rootEntity\": {\n" +  
231 - " \"entityType\": \"ASSET\",\n" +  
232 - " \"id\": \"e52b0020-2a7a-11ec-94eb-213c95f54092\"\n" +  
233 - " },\n" +  
234 - " \"direction\": \"FROM\",\n" +  
235 - " \"maxLevel\": 2,\n" +  
236 - " \"fetchLastLevelOnly\": true,\n" +  
237 - " \"relationType\": \"Contains\",\n" +  
238 - " \"deviceTypes\": [\n" +  
239 - " \"Air Quality Sensor\",\n" +  
240 - " \"Charging port\"\n" +  
241 - " ]\n" +  
242 - "}" +  
243 - MARKDOWN_CODE_BLOCK_END +  
244 - "";  
245 -  
246 - private static final String EV_QUERY_FILTER = "\n\n## Entity View Query\n\n" +  
247 - "Allows to filter entity views that are related to the provided root entity. Filters related entity views based on the relation type and set of entity view types. " +  
248 - MAX_LEVEL_DESCRIPTION +  
249 - FETCH_LAST_LEVEL_ONLY_DESCRIPTION +  
250 - "The 'relationType' defines the type of the relation to search for. " +  
251 - "The 'entityViewTypes' defines the type of the entity view to search for. " +  
252 - "The relation query calculates all related entities, even if they are filtered using different relation types, and then extracts only devices that match 'relationType' and 'deviceTypes' conditions.\n\n" +  
253 - "For example, this entity filter selects 'Concrete mixer' entity views which are related to the asset with id 'e52b0020-2a7a-11ec-94eb-213c95f54092' using 'Contains' relation:\n\n" +  
254 - MARKDOWN_CODE_BLOCK_START +  
255 - "{\n" +  
256 - " \"type\": \"entityViewSearchQuery\",\n" +  
257 - " \"rootEntity\": {\n" +  
258 - " \"entityType\": \"ASSET\",\n" +  
259 - " \"id\": \"e52b0020-2a7a-11ec-94eb-213c95f54092\"\n" +  
260 - " },\n" +  
261 - " \"direction\": \"FROM\",\n" +  
262 - " \"maxLevel\": 1,\n" +  
263 - " \"fetchLastLevelOnly\": false,\n" +  
264 - " \"relationType\": \"Contains\",\n" +  
265 - " \"entityViewTypes\": [\n" +  
266 - " \"Concrete mixer\"\n" +  
267 - " ]\n" +  
268 - "}" +  
269 - MARKDOWN_CODE_BLOCK_END +  
270 - "";  
271 -  
272 - private static final String EDGE_QUERY_FILTER = "\n\n## Edge Search Query\n\n" +  
273 - "Allows to filter edge instances that are related to the provided root entity. Filters related edge instances based on the relation type and set of edge types. " +  
274 - MAX_LEVEL_DESCRIPTION +  
275 - FETCH_LAST_LEVEL_ONLY_DESCRIPTION +  
276 - "The 'relationType' defines the type of the relation to search for. " +  
277 - "The 'deviceTypes' defines the type of the device to search for. " +  
278 - "The relation query calculates all related entities, even if they are filtered using different relation types, and then extracts only devices that match 'relationType' and 'deviceTypes' conditions.\n\n" +  
279 - "For example, this entity filter selects 'Factory' edge instances which are related to the asset with id 'e52b0020-2a7a-11ec-94eb-213c95f54092' using 'Contains' relation:\n\n" +  
280 - MARKDOWN_CODE_BLOCK_START +  
281 - "{\n" +  
282 - " \"type\": \"deviceSearchQuery\",\n" +  
283 - " \"rootEntity\": {\n" +  
284 - " \"entityType\": \"ASSET\",\n" +  
285 - " \"id\": \"e52b0020-2a7a-11ec-94eb-213c95f54092\"\n" +  
286 - " },\n" +  
287 - " \"direction\": \"FROM\",\n" +  
288 - " \"maxLevel\": 2,\n" +  
289 - " \"fetchLastLevelOnly\": true,\n" +  
290 - " \"relationType\": \"Contains\",\n" +  
291 - " \"edgeTypes\": [\n" +  
292 - " \"Factory\"\n" +  
293 - " ]\n" +  
294 - "}" +  
295 - MARKDOWN_CODE_BLOCK_END +  
296 - "";  
297 -  
298 - private static final String EMPTY = "\n\n## Entity Type Filter\n\n" +  
299 - "Allows to filter multiple entities of the same type using the **'starts with'** expression over entity name. " +  
300 - "For example, this entity filter selects all devices which name starts with 'Air Quality':\n\n" +  
301 - MARKDOWN_CODE_BLOCK_START +  
302 - "" +  
303 - MARKDOWN_CODE_BLOCK_END +  
304 - "";  
305 -  
306 - private static final String ENTITY_FILTERS =  
307 - "\n\n # Entity Filters" +  
308 - "\nEntity Filter body depends on the 'type' parameter. Let's review available entity filter types. In fact, they do correspond to available dashboard aliases." +  
309 - SINGLE_ENTITY + ENTITY_LIST + ENTITY_NAME + ENTITY_TYPE + ASSET_TYPE + DEVICE_TYPE + EDGE_TYPE + ENTITY_VIEW_TYPE + API_USAGE + RELATIONS_QUERY_FILTER  
310 - + ASSET_QUERY_FILTER + DEVICE_QUERY_FILTER + EV_QUERY_FILTER + EDGE_QUERY_FILTER;  
311 -  
312 - private static final String FILTER_KEY = "\n\n## Filter Key\n\n" +  
313 - "Filter Key defines either entity field, attribute or telemetry. It is a JSON object that consists the key name and type. " +  
314 - "The following filter key types are supported: \n\n" +  
315 - " * 'CLIENT_ATTRIBUTE' - used for client attributes; \n" +  
316 - " * 'SHARED_ATTRIBUTE' - used for shared attributes; \n" +  
317 - " * 'SERVER_ATTRIBUTE' - used for server attributes; \n" +  
318 - " * 'ATTRIBUTE' - used for any of the above; \n" +  
319 - " * 'TIME_SERIES' - used for time-series values; \n" +  
320 - " * 'ENTITY_FIELD' - used for accessing entity fields like 'name', 'label', etc. The list of available fields depends on the entity type; \n" +  
321 - " * 'ALARM_FIELD' - similar to entity field, but is used in alarm queries only; \n" +  
322 - "\n\n Let's review the example:\n\n" +  
323 - MARKDOWN_CODE_BLOCK_START +  
324 - "{\n" +  
325 - " \"type\": \"TIME_SERIES\",\n" +  
326 - " \"key\": \"temperature\"\n" +  
327 - "}" +  
328 - MARKDOWN_CODE_BLOCK_END +  
329 - "";  
330 -  
331 - private static final String FILTER_PREDICATE = "\n\n## Filter Predicate\n\n" +  
332 - "Filter Predicate defines the logical expression to evaluate. The list of available operations depends on the filter value type, see above. " +  
333 - "Platform supports 4 predicate types: 'STRING', 'NUMERIC', 'BOOLEAN' and 'COMPLEX'. The last one allows to combine multiple operations over one filter key." +  
334 - "\n\nSimple predicate example to check 'value < 100': \n\n" +  
335 - MARKDOWN_CODE_BLOCK_START +  
336 - "{\n" +  
337 - " \"operation\": \"LESS\",\n" +  
338 - " \"value\": {\n" +  
339 - " \"defaultValue\": 100,\n" +  
340 - " \"dynamicValue\": null\n" +  
341 - " },\n" +  
342 - " \"type\": \"NUMERIC\"\n" +  
343 - "}" +  
344 - MARKDOWN_CODE_BLOCK_END +  
345 - "\n\nComplex predicate example, to check 'value < 10 or value > 20': \n\n" +  
346 - MARKDOWN_CODE_BLOCK_START +  
347 - "{\n" +  
348 - " \"type\": \"COMPLEX\",\n" +  
349 - " \"operation\": \"OR\",\n" +  
350 - " \"predicates\": [\n" +  
351 - " {\n" +  
352 - " \"operation\": \"LESS\",\n" +  
353 - " \"value\": {\n" +  
354 - " \"defaultValue\": 10,\n" +  
355 - " \"dynamicValue\": null\n" +  
356 - " },\n" +  
357 - " \"type\": \"NUMERIC\"\n" +  
358 - " },\n" +  
359 - " {\n" +  
360 - " \"operation\": \"GREATER\",\n" +  
361 - " \"value\": {\n" +  
362 - " \"defaultValue\": 20,\n" +  
363 - " \"dynamicValue\": null\n" +  
364 - " },\n" +  
365 - " \"type\": \"NUMERIC\"\n" +  
366 - " }\n" +  
367 - " ]\n" +  
368 - "}" +  
369 - MARKDOWN_CODE_BLOCK_END +  
370 - "\n\nMore complex predicate example, to check 'value < 10 or (value > 50 && value < 60)': \n\n" +  
371 - MARKDOWN_CODE_BLOCK_START +  
372 - "{\n" +  
373 - " \"type\": \"COMPLEX\",\n" +  
374 - " \"operation\": \"OR\",\n" +  
375 - " \"predicates\": [\n" +  
376 - " {\n" +  
377 - " \"operation\": \"LESS\",\n" +  
378 - " \"value\": {\n" +  
379 - " \"defaultValue\": 10,\n" +  
380 - " \"dynamicValue\": null\n" +  
381 - " },\n" +  
382 - " \"type\": \"NUMERIC\"\n" +  
383 - " },\n" +  
384 - " {\n" +  
385 - " \"type\": \"COMPLEX\",\n" +  
386 - " \"operation\": \"AND\",\n" +  
387 - " \"predicates\": [\n" +  
388 - " {\n" +  
389 - " \"operation\": \"GREATER\",\n" +  
390 - " \"value\": {\n" +  
391 - " \"defaultValue\": 50,\n" +  
392 - " \"dynamicValue\": null\n" +  
393 - " },\n" +  
394 - " \"type\": \"NUMERIC\"\n" +  
395 - " },\n" +  
396 - " {\n" +  
397 - " \"operation\": \"LESS\",\n" +  
398 - " \"value\": {\n" +  
399 - " \"defaultValue\": 60,\n" +  
400 - " \"dynamicValue\": null\n" +  
401 - " },\n" +  
402 - " \"type\": \"NUMERIC\"\n" +  
403 - " }\n" +  
404 - " ]\n" +  
405 - " }\n" +  
406 - " ]\n" +  
407 - "}" +  
408 - MARKDOWN_CODE_BLOCK_END +  
409 - "\n\n You may also want to replace hardcoded values (for example, temperature > 20) with the more dynamic " +  
410 - "expression (for example, temperature > 'value of the tenant attribute with key 'temperatureThreshold'). " +  
411 - "It is possible to use 'dynamicValue' to define attribute of the tenant, customer or user that is performing the API call. " +  
412 - "See example below: \n\n" +  
413 - MARKDOWN_CODE_BLOCK_START +  
414 - "{\n" +  
415 - " \"operation\": \"GREATER\",\n" +  
416 - " \"value\": {\n" +  
417 - " \"defaultValue\": 0,\n" +  
418 - " \"dynamicValue\": {\n" +  
419 - " \"sourceType\": \"CURRENT_USER\",\n" +  
420 - " \"sourceAttribute\": \"temperatureThreshold\"\n" +  
421 - " }\n" +  
422 - " },\n" +  
423 - " \"type\": \"NUMERIC\"\n" +  
424 - "}" +  
425 - MARKDOWN_CODE_BLOCK_END +  
426 - "\n\n Note that you may use 'CURRENT_USER', 'CURRENT_CUSTOMER' and 'CURRENT_TENANT' as a 'sourceType'. The 'defaultValue' is used when the attribute with such a name is not defined for the chosen source.";  
427 -  
428 - private static final String KEY_FILTERS =  
429 - "\n\n # Key Filters" +  
430 - "\nKey Filter allows you to define complex logical expressions over entity field, attribute or latest time-series value. The filter is defined using 'key', 'valueType' and 'predicate' objects. " +  
431 - "Single Entity Query may have zero, one or multiple predicates. If multiple filters are defined, they are evaluated using logical 'AND'. " +  
432 - "The example below checks that temperature of the entity is above 20 degrees:" +  
433 - "\n\n" + MARKDOWN_CODE_BLOCK_START +  
434 - "{\n" +  
435 - " \"key\": {\n" +  
436 - " \"type\": \"TIME_SERIES\",\n" +  
437 - " \"key\": \"temperature\"\n" +  
438 - " },\n" +  
439 - " \"valueType\": \"NUMERIC\",\n" +  
440 - " \"predicate\": {\n" +  
441 - " \"operation\": \"GREATER\",\n" +  
442 - " \"value\": {\n" +  
443 - " \"defaultValue\": 20,\n" +  
444 - " \"dynamicValue\": null\n" +  
445 - " },\n" +  
446 - " \"type\": \"NUMERIC\"\n" +  
447 - " }\n" +  
448 - "}" +  
449 - MARKDOWN_CODE_BLOCK_END +  
450 - "\n\n Now let's review 'key', 'valueType' and 'predicate' objects in detail."  
451 - + FILTER_KEY + FILTER_VALUE_TYPE + FILTER_PREDICATE;  
452 -  
453 - private static final String ENTITY_COUNT_QUERY_DESCRIPTION =  
454 - "Allows to run complex queries to search the count of platform entities (devices, assets, customers, etc) " +  
455 - "based on the combination of main entity filter and multiple key filters. Returns the number of entities that match the query definition.\n\n" +  
456 - "# Query Definition\n\n" +  
457 - "\n\nMain **entity filter** is mandatory and defines generic search criteria. " +  
458 - "For example, \"find all devices with profile 'Moisture Sensor'\" or \"Find all devices related to asset 'Building A'\"" +  
459 - "\n\nOptional **key filters** allow to filter results of the entity filter by complex criteria against " +  
460 - "main entity fields (name, label, type, etc), attributes and telemetry. " +  
461 - "For example, \"temperature > 20 or temperature< 10\" or \"name starts with 'T', and attribute 'model' is 'T1000', and timeseries field 'batteryLevel' > 40\"." +  
462 - "\n\nLet's review the example:" +  
463 - "\n\n" + MARKDOWN_CODE_BLOCK_START +  
464 - "{\n" +  
465 - " \"entityFilter\": {\n" +  
466 - " \"type\": \"entityType\",\n" +  
467 - " \"entityType\": \"DEVICE\"\n" +  
468 - " },\n" +  
469 - " \"keyFilters\": [\n" +  
470 - " {\n" +  
471 - " \"key\": {\n" +  
472 - " \"type\": \"ATTRIBUTE\",\n" +  
473 - " \"key\": \"active\"\n" +  
474 - " },\n" +  
475 - " \"valueType\": \"BOOLEAN\",\n" +  
476 - " \"predicate\": {\n" +  
477 - " \"operation\": \"EQUAL\",\n" +  
478 - " \"value\": {\n" +  
479 - " \"defaultValue\": true,\n" +  
480 - " \"dynamicValue\": null\n" +  
481 - " },\n" +  
482 - " \"type\": \"BOOLEAN\"\n" +  
483 - " }\n" +  
484 - " }\n" +  
485 - " ]\n" +  
486 - "}" +  
487 - MARKDOWN_CODE_BLOCK_END +  
488 - "\n\n Example mentioned above search all devices which have attribute 'active' set to 'true'. Now let's review available entity filters and key filters syntax:" +  
489 - ENTITY_FILTERS +  
490 - KEY_FILTERS +  
491 - TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH;  
492 -  
493 - private static final String ENTITY_DATA_QUERY_DESCRIPTION =  
494 - "Allows to run complex queries over platform entities (devices, assets, customers, etc) " +  
495 - "based on the combination of main entity filter and multiple key filters. " +  
496 - "Returns the paginated result of the query that contains requested entity fields and latest values of requested attributes and time-series data.\n\n" +  
497 - "# Query Definition\n\n" +  
498 - "\n\nMain **entity filter** is mandatory and defines generic search criteria. " +  
499 - "For example, \"find all devices with profile 'Moisture Sensor'\" or \"Find all devices related to asset 'Building A'\"" +  
500 - "\n\nOptional **key filters** allow to filter results of the **entity filter** by complex criteria against " +  
501 - "main entity fields (name, label, type, etc), attributes and telemetry. " +  
502 - "For example, \"temperature > 20 or temperature< 10\" or \"name starts with 'T', and attribute 'model' is 'T1000', and timeseries field 'batteryLevel' > 40\"." +  
503 - "\n\nThe **entity fields** and **latest values** contains list of entity fields and latest attribute/telemetry fields to fetch for each entity." +  
504 - "\n\nThe **page link** contains information about the page to fetch and the sort ordering." +  
505 - "\n\nLet's review the example:" +  
506 - "\n\n" + MARKDOWN_CODE_BLOCK_START +  
507 - "{\n" +  
508 - " \"entityFilter\": {\n" +  
509 - " \"type\": \"entityType\",\n" +  
510 - " \"resolveMultiple\": true,\n" +  
511 - " \"entityType\": \"DEVICE\"\n" +  
512 - " },\n" +  
513 - " \"keyFilters\": [\n" +  
514 - " {\n" +  
515 - " \"key\": {\n" +  
516 - " \"type\": \"TIME_SERIES\",\n" +  
517 - " \"key\": \"temperature\"\n" +  
518 - " },\n" +  
519 - " \"valueType\": \"NUMERIC\",\n" +  
520 - " \"predicate\": {\n" +  
521 - " \"operation\": \"GREATER\",\n" +  
522 - " \"value\": {\n" +  
523 - " \"defaultValue\": 0,\n" +  
524 - " \"dynamicValue\": {\n" +  
525 - " \"sourceType\": \"CURRENT_USER\",\n" +  
526 - " \"sourceAttribute\": \"temperatureThreshold\",\n" +  
527 - " \"inherit\": false\n" +  
528 - " }\n" +  
529 - " },\n" +  
530 - " \"type\": \"NUMERIC\"\n" +  
531 - " }\n" +  
532 - " }\n" +  
533 - " ],\n" +  
534 - " \"entityFields\": [\n" +  
535 - " {\n" +  
536 - " \"type\": \"ENTITY_FIELD\",\n" +  
537 - " \"key\": \"name\"\n" +  
538 - " },\n" +  
539 - " {\n" +  
540 - " \"type\": \"ENTITY_FIELD\",\n" +  
541 - " \"key\": \"label\"\n" +  
542 - " },\n" +  
543 - " {\n" +  
544 - " \"type\": \"ENTITY_FIELD\",\n" +  
545 - " \"key\": \"additionalInfo\"\n" +  
546 - " }\n" +  
547 - " ],\n" +  
548 - " \"latestValues\": [\n" +  
549 - " {\n" +  
550 - " \"type\": \"ATTRIBUTE\",\n" +  
551 - " \"key\": \"model\"\n" +  
552 - " },\n" +  
553 - " {\n" +  
554 - " \"type\": \"TIME_SERIES\",\n" +  
555 - " \"key\": \"temperature\"\n" +  
556 - " }\n" +  
557 - " ],\n" +  
558 - " \"pageLink\": {\n" +  
559 - " \"page\": 0,\n" +  
560 - " \"pageSize\": 10,\n" +  
561 - " \"sortOrder\": {\n" +  
562 - " \"key\": {\n" +  
563 - " \"key\": \"name\",\n" +  
564 - " \"type\": \"ENTITY_FIELD\"\n" +  
565 - " },\n" +  
566 - " \"direction\": \"ASC\"\n" +  
567 - " }\n" +  
568 - " }\n" +  
569 - "}" +  
570 - MARKDOWN_CODE_BLOCK_END +  
571 - "\n\n Example mentioned above search all devices which have attribute 'active' set to 'true'. Now let's review available entity filters and key filters syntax:" +  
572 - ENTITY_FILTERS +  
573 - KEY_FILTERS +  
574 - TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH;  
575 -  
576 -  
577 - private static final String ALARM_DATA_QUERY_DESCRIPTION = "This method description defines how Alarm Data Query extends the Entity Data Query. " +  
578 - "See method 'Find Entity Data by Query' first to get the info about 'Entity Data Query'." +  
579 - "\n\n The platform will first search the entities that match the entity and key filters. Then, the platform will use 'Alarm Page Link' to filter the alarms related to those entities. " +  
580 - "Finally, platform fetch the properties of alarm that are defined in the **'alarmFields'** and combine them with the other entity, attribute and latest time-series fields to return the result. " +  
581 - "\n\n See example of the alarm query below. The query will search first 100 active alarms with type 'Temperature Alarm' or 'Fire Alarm' for any device with current temperature > 0. " +  
582 - "The query will return combination of the entity fields: name of the device, device model and latest temperature reading and alarms fields: createdTime, type, severity and status: " +  
583 - "\n\n" + MARKDOWN_CODE_BLOCK_START +  
584 - "{\n" +  
585 - " \"entityFilter\": {\n" +  
586 - " \"type\": \"entityType\",\n" +  
587 - " \"resolveMultiple\": true,\n" +  
588 - " \"entityType\": \"DEVICE\"\n" +  
589 - " },\n" +  
590 - " \"pageLink\": {\n" +  
591 - " \"page\": 0,\n" +  
592 - " \"pageSize\": 100,\n" +  
593 - " \"textSearch\": null,\n" +  
594 - " \"searchPropagatedAlarms\": false,\n" +  
595 - " \"statusList\": [\n" +  
596 - " \"ACTIVE\"\n" +  
597 - " ],\n" +  
598 - " \"severityList\": [\n" +  
599 - " \"CRITICAL\",\n" +  
600 - " \"MAJOR\"\n" +  
601 - " ],\n" +  
602 - " \"typeList\": [\n" +  
603 - " \"Temperature Alarm\",\n" +  
604 - " \"Fire Alarm\"\n" +  
605 - " ],\n" +  
606 - " \"sortOrder\": {\n" +  
607 - " \"key\": {\n" +  
608 - " \"key\": \"createdTime\",\n" +  
609 - " \"type\": \"ALARM_FIELD\"\n" +  
610 - " },\n" +  
611 - " \"direction\": \"DESC\"\n" +  
612 - " },\n" +  
613 - " \"timeWindow\": 86400000\n" +  
614 - " },\n" +  
615 - " \"keyFilters\": [\n" +  
616 - " {\n" +  
617 - " \"key\": {\n" +  
618 - " \"type\": \"TIME_SERIES\",\n" +  
619 - " \"key\": \"temperature\"\n" +  
620 - " },\n" +  
621 - " \"valueType\": \"NUMERIC\",\n" +  
622 - " \"predicate\": {\n" +  
623 - " \"operation\": \"GREATER\",\n" +  
624 - " \"value\": {\n" +  
625 - " \"defaultValue\": 0,\n" +  
626 - " \"dynamicValue\": null\n" +  
627 - " },\n" +  
628 - " \"type\": \"NUMERIC\"\n" +  
629 - " }\n" +  
630 - " }\n" +  
631 - " ],\n" +  
632 - " \"alarmFields\": [\n" +  
633 - " {\n" +  
634 - " \"type\": \"ALARM_FIELD\",\n" +  
635 - " \"key\": \"createdTime\"\n" +  
636 - " },\n" +  
637 - " {\n" +  
638 - " \"type\": \"ALARM_FIELD\",\n" +  
639 - " \"key\": \"type\"\n" +  
640 - " },\n" +  
641 - " {\n" +  
642 - " \"type\": \"ALARM_FIELD\",\n" +  
643 - " \"key\": \"severity\"\n" +  
644 - " },\n" +  
645 - " {\n" +  
646 - " \"type\": \"ALARM_FIELD\",\n" +  
647 - " \"key\": \"status\"\n" +  
648 - " }\n" +  
649 - " ],\n" +  
650 - " \"entityFields\": [\n" +  
651 - " {\n" +  
652 - " \"type\": \"ENTITY_FIELD\",\n" +  
653 - " \"key\": \"name\"\n" +  
654 - " }\n" +  
655 - " ],\n" +  
656 - " \"latestValues\": [\n" +  
657 - " {\n" +  
658 - " \"type\": \"ATTRIBUTE\",\n" +  
659 - " \"key\": \"model\"\n" +  
660 - " },\n" +  
661 - " {\n" +  
662 - " \"type\": \"TIME_SERIES\",\n" +  
663 - " \"key\": \"temperature\"\n" +  
664 - " }\n" +  
665 - " ]\n" +  
666 - "}" +  
667 - MARKDOWN_CODE_BLOCK_END +  
668 - "";  
669 -  
670 @Autowired 51 @Autowired
671 private EntityQueryService entityQueryService; 52 private EntityQueryService entityQueryService;
672 53
@@ -43,6 +43,11 @@ import org.thingsboard.server.service.security.permission.Operation; @@ -43,6 +43,11 @@ import org.thingsboard.server.service.security.permission.Operation;
43 import java.util.List; 43 import java.util.List;
44 import java.util.stream.Collectors; 44 import java.util.stream.Collectors;
45 45
  46 +import static org.thingsboard.server.controller.ControllerConstants.ENTITY_ID_PARAM_DESCRIPTION;
  47 +import static org.thingsboard.server.controller.ControllerConstants.ENTITY_TYPE_PARAM_DESCRIPTION;
  48 +import static org.thingsboard.server.controller.ControllerConstants.RELATION_INFO_DESCRIPTION;
  49 +import static org.thingsboard.server.controller.ControllerConstants.RELATION_TYPE_GROUP_PARAM_DESCRIPTION;
  50 +import static org.thingsboard.server.controller.ControllerConstants.RELATION_TYPE_PARAM_DESCRIPTION;
46 51
47 @RestController 52 @RestController
48 @TbCoreComponent 53 @TbCoreComponent
@@ -74,6 +74,11 @@ import java.util.concurrent.ExecutionException; @@ -74,6 +74,11 @@ import java.util.concurrent.ExecutionException;
74 import java.util.stream.Collectors; 74 import java.util.stream.Collectors;
75 75
76 import static org.apache.commons.lang3.StringUtils.isBlank; 76 import static org.apache.commons.lang3.StringUtils.isBlank;
  77 +import static org.thingsboard.server.controller.ControllerConstants.CUSTOMER_ID;
  78 +import static org.thingsboard.server.controller.ControllerConstants.EDGE_ASSIGN_ASYNC_FIRST_STEP_DESCRIPTION;
  79 +import static org.thingsboard.server.controller.ControllerConstants.EDGE_ASSIGN_RECEIVE_STEP_DESCRIPTION;
  80 +import static org.thingsboard.server.controller.ControllerConstants.EDGE_UNASSIGN_ASYNC_FIRST_STEP_DESCRIPTION;
  81 +import static org.thingsboard.server.controller.ControllerConstants.EDGE_UNASSIGN_RECEIVE_STEP_DESCRIPTION;
77 import static org.thingsboard.server.controller.EdgeController.EDGE_ID; 82 import static org.thingsboard.server.controller.EdgeController.EDGE_ID;
78 83
79 /** 84 /**
@@ -40,6 +40,29 @@ import org.thingsboard.server.dao.model.ModelConstants; @@ -40,6 +40,29 @@ import org.thingsboard.server.dao.model.ModelConstants;
40 import org.thingsboard.server.queue.util.TbCoreComponent; 40 import org.thingsboard.server.queue.util.TbCoreComponent;
41 import org.thingsboard.server.service.security.permission.Operation; 41 import org.thingsboard.server.service.security.permission.Operation;
42 42
  43 +import static org.thingsboard.server.controller.ControllerConstants.ENTITY_ID;
  44 +import static org.thingsboard.server.controller.ControllerConstants.ENTITY_ID_PARAM_DESCRIPTION;
  45 +import static org.thingsboard.server.controller.ControllerConstants.ENTITY_TYPE;
  46 +import static org.thingsboard.server.controller.ControllerConstants.ENTITY_TYPE_PARAM_DESCRIPTION;
  47 +import static org.thingsboard.server.controller.ControllerConstants.EVENT_DEBUG_RULE_CHAIN_FILTER_OBJ;
  48 +import static org.thingsboard.server.controller.ControllerConstants.EVENT_DEBUG_RULE_NODE_FILTER_OBJ;
  49 +import static org.thingsboard.server.controller.ControllerConstants.EVENT_END_TIME_DESCRIPTION;
  50 +import static org.thingsboard.server.controller.ControllerConstants.EVENT_ERROR_FILTER_OBJ;
  51 +import static org.thingsboard.server.controller.ControllerConstants.EVENT_LC_EVENT_FILTER_OBJ;
  52 +import static org.thingsboard.server.controller.ControllerConstants.EVENT_SORT_PROPERTY_ALLOWABLE_VALUES;
  53 +import static org.thingsboard.server.controller.ControllerConstants.EVENT_START_TIME_DESCRIPTION;
  54 +import static org.thingsboard.server.controller.ControllerConstants.EVENT_STATS_FILTER_OBJ;
  55 +import static org.thingsboard.server.controller.ControllerConstants.EVENT_TEXT_SEARCH_DESCRIPTION;
  56 +import static org.thingsboard.server.controller.ControllerConstants.NEW_LINE;
  57 +import static org.thingsboard.server.controller.ControllerConstants.PAGE_DATA_PARAMETERS;
  58 +import static org.thingsboard.server.controller.ControllerConstants.PAGE_NUMBER_DESCRIPTION;
  59 +import static org.thingsboard.server.controller.ControllerConstants.PAGE_SIZE_DESCRIPTION;
  60 +import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_ALLOWABLE_VALUES;
  61 +import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_DESCRIPTION;
  62 +import static org.thingsboard.server.controller.ControllerConstants.SORT_PROPERTY_DESCRIPTION;
  63 +import static org.thingsboard.server.controller.ControllerConstants.TENANT_ID;
  64 +import static org.thingsboard.server.controller.ControllerConstants.TENANT_ID_PARAM_DESCRIPTION;
  65 +
43 @RestController 66 @RestController
44 @TbCoreComponent 67 @TbCoreComponent
45 @RequestMapping("/api") 68 @RequestMapping("/api")
@@ -36,6 +36,9 @@ import org.thingsboard.server.service.security.permission.Resource; @@ -36,6 +36,9 @@ import org.thingsboard.server.service.security.permission.Resource;
36 36
37 import java.util.List; 37 import java.util.List;
38 38
  39 +import static org.thingsboard.server.controller.ControllerConstants.SYSTEM_AUTHORITY_PARAGRAPH;
  40 +import static org.thingsboard.server.controller.ControllerConstants.SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH;
  41 +
39 @RestController 42 @RestController
40 @TbCoreComponent 43 @TbCoreComponent
41 @RequestMapping("/api/oauth2/config/template") 44 @RequestMapping("/api/oauth2/config/template")
@@ -43,6 +43,8 @@ import javax.servlet.http.HttpServletRequest; @@ -43,6 +43,8 @@ import javax.servlet.http.HttpServletRequest;
43 import java.util.Enumeration; 43 import java.util.Enumeration;
44 import java.util.List; 44 import java.util.List;
45 45
  46 +import static org.thingsboard.server.controller.ControllerConstants.SYSTEM_AUTHORITY_PARAGRAPH;
  47 +
46 @RestController 48 @RestController
47 @TbCoreComponent 49 @TbCoreComponent
48 @RequestMapping("/api") 50 @RequestMapping("/api")
@@ -49,6 +49,22 @@ import org.thingsboard.server.service.security.permission.Resource; @@ -49,6 +49,22 @@ import org.thingsboard.server.service.security.permission.Resource;
49 49
50 import java.nio.ByteBuffer; 50 import java.nio.ByteBuffer;
51 51
  52 +import static org.thingsboard.server.controller.ControllerConstants.DEVICE_PROFILE_ID_PARAM_DESCRIPTION;
  53 +import static org.thingsboard.server.controller.ControllerConstants.OTA_PACKAGE_CHECKSUM_ALGORITHM_ALLOWABLE_VALUES;
  54 +import static org.thingsboard.server.controller.ControllerConstants.OTA_PACKAGE_DESCRIPTION;
  55 +import static org.thingsboard.server.controller.ControllerConstants.OTA_PACKAGE_ID_PARAM_DESCRIPTION;
  56 +import static org.thingsboard.server.controller.ControllerConstants.OTA_PACKAGE_INFO_DESCRIPTION;
  57 +import static org.thingsboard.server.controller.ControllerConstants.OTA_PACKAGE_SORT_PROPERTY_ALLOWABLE_VALUES;
  58 +import static org.thingsboard.server.controller.ControllerConstants.OTA_PACKAGE_TEXT_SEARCH_DESCRIPTION;
  59 +import static org.thingsboard.server.controller.ControllerConstants.PAGE_DATA_PARAMETERS;
  60 +import static org.thingsboard.server.controller.ControllerConstants.PAGE_NUMBER_DESCRIPTION;
  61 +import static org.thingsboard.server.controller.ControllerConstants.PAGE_SIZE_DESCRIPTION;
  62 +import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_ALLOWABLE_VALUES;
  63 +import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_DESCRIPTION;
  64 +import static org.thingsboard.server.controller.ControllerConstants.SORT_PROPERTY_DESCRIPTION;
  65 +import static org.thingsboard.server.controller.ControllerConstants.TENANT_AUTHORITY_PARAGRAPH;
  66 +import static org.thingsboard.server.controller.ControllerConstants.TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH;
  67 +
52 @Slf4j 68 @Slf4j
53 @RestController 69 @RestController
54 @TbCoreComponent 70 @TbCoreComponent
@@ -32,6 +32,10 @@ import org.thingsboard.server.queue.util.TbCoreComponent; @@ -32,6 +32,10 @@ import org.thingsboard.server.queue.util.TbCoreComponent;
32 32
33 import java.util.Set; 33 import java.util.Set;
34 34
  35 +import static org.thingsboard.server.controller.ControllerConstants.QUEUE_SERVICE_TYPE_ALLOWABLE_VALUES;
  36 +import static org.thingsboard.server.controller.ControllerConstants.QUEUE_SERVICE_TYPE_DESCRIPTION;
  37 +import static org.thingsboard.server.controller.ControllerConstants.TENANT_AUTHORITY_PARAGRAPH;
  38 +
35 @RestController 39 @RestController
36 @TbCoreComponent 40 @TbCoreComponent
37 @RequestMapping("/api") 41 @RequestMapping("/api")
@@ -34,6 +34,9 @@ import org.thingsboard.server.queue.util.TbCoreComponent; @@ -34,6 +34,9 @@ import org.thingsboard.server.queue.util.TbCoreComponent;
34 34
35 import java.util.UUID; 35 import java.util.UUID;
36 36
  37 +import static org.thingsboard.server.controller.ControllerConstants.DEVICE_ID_PARAM_DESCRIPTION;
  38 +import static org.thingsboard.server.controller.ControllerConstants.TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH;
  39 +
37 @RestController 40 @RestController
38 @TbCoreComponent 41 @TbCoreComponent
39 @RequestMapping(TbUrlConstants.RPC_V1_URL_PREFIX) 42 @RequestMapping(TbUrlConstants.RPC_V1_URL_PREFIX)
@@ -53,6 +53,8 @@ import java.util.UUID; @@ -53,6 +53,8 @@ import java.util.UUID;
53 53
54 import static org.thingsboard.server.common.data.DataConstants.RPC_DELETED; 54 import static org.thingsboard.server.common.data.DataConstants.RPC_DELETED;
55 55
  56 +import static org.thingsboard.server.controller.ControllerConstants.*;
  57 +
56 @RestController 58 @RestController
57 @TbCoreComponent 59 @TbCoreComponent
58 @RequestMapping(TbUrlConstants.RPC_V2_URL_PREFIX) 60 @RequestMapping(TbUrlConstants.RPC_V2_URL_PREFIX)
@@ -81,6 +81,25 @@ import java.util.concurrent.ConcurrentMap; @@ -81,6 +81,25 @@ import java.util.concurrent.ConcurrentMap;
81 import java.util.concurrent.TimeUnit; 81 import java.util.concurrent.TimeUnit;
82 import java.util.stream.Collectors; 82 import java.util.stream.Collectors;
83 83
  84 +import static org.thingsboard.server.controller.ControllerConstants.EDGE_ASSIGN_ASYNC_FIRST_STEP_DESCRIPTION;
  85 +import static org.thingsboard.server.controller.ControllerConstants.EDGE_ASSIGN_RECEIVE_STEP_DESCRIPTION;
  86 +import static org.thingsboard.server.controller.ControllerConstants.EDGE_UNASSIGN_ASYNC_FIRST_STEP_DESCRIPTION;
  87 +import static org.thingsboard.server.controller.ControllerConstants.EDGE_UNASSIGN_RECEIVE_STEP_DESCRIPTION;
  88 +import static org.thingsboard.server.controller.ControllerConstants.MARKDOWN_CODE_BLOCK_END;
  89 +import static org.thingsboard.server.controller.ControllerConstants.MARKDOWN_CODE_BLOCK_START;
  90 +import static org.thingsboard.server.controller.ControllerConstants.PAGE_DATA_PARAMETERS;
  91 +import static org.thingsboard.server.controller.ControllerConstants.PAGE_NUMBER_DESCRIPTION;
  92 +import static org.thingsboard.server.controller.ControllerConstants.PAGE_SIZE_DESCRIPTION;
  93 +import static org.thingsboard.server.controller.ControllerConstants.RULE_CHAIN_ID_PARAM_DESCRIPTION;
  94 +import static org.thingsboard.server.controller.ControllerConstants.RULE_CHAIN_SORT_PROPERTY_ALLOWABLE_VALUES;
  95 +import static org.thingsboard.server.controller.ControllerConstants.RULE_CHAIN_TEXT_SEARCH_DESCRIPTION;
  96 +import static org.thingsboard.server.controller.ControllerConstants.RULE_CHAIN_TYPES_ALLOWABLE_VALUES;
  97 +import static org.thingsboard.server.controller.ControllerConstants.RULE_CHAIN_TYPE_DESCRIPTION;
  98 +import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_ALLOWABLE_VALUES;
  99 +import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_DESCRIPTION;
  100 +import static org.thingsboard.server.controller.ControllerConstants.SORT_PROPERTY_DESCRIPTION;
  101 +import static org.thingsboard.server.controller.ControllerConstants.TENANT_AUTHORITY_PARAGRAPH;
  102 +
84 @Slf4j 103 @Slf4j
85 @RestController 104 @RestController
86 @TbCoreComponent 105 @TbCoreComponent
@@ -47,6 +47,22 @@ import org.thingsboard.server.service.security.permission.Resource; @@ -47,6 +47,22 @@ import org.thingsboard.server.service.security.permission.Resource;
47 import java.util.Base64; 47 import java.util.Base64;
48 import java.util.List; 48 import java.util.List;
49 49
  50 +import static org.thingsboard.server.controller.ControllerConstants.LWM2M_OBJECT_DESCRIPTION;
  51 +import static org.thingsboard.server.controller.ControllerConstants.LWM2M_OBJECT_SORT_PROPERTY_ALLOWABLE_VALUES;
  52 +import static org.thingsboard.server.controller.ControllerConstants.PAGE_DATA_PARAMETERS;
  53 +import static org.thingsboard.server.controller.ControllerConstants.PAGE_NUMBER_DESCRIPTION;
  54 +import static org.thingsboard.server.controller.ControllerConstants.PAGE_SIZE_DESCRIPTION;
  55 +import static org.thingsboard.server.controller.ControllerConstants.RESOURCE_DESCRIPTION;
  56 +import static org.thingsboard.server.controller.ControllerConstants.RESOURCE_ID_PARAM_DESCRIPTION;
  57 +import static org.thingsboard.server.controller.ControllerConstants.RESOURCE_INFO_DESCRIPTION;
  58 +import static org.thingsboard.server.controller.ControllerConstants.RESOURCE_SORT_PROPERTY_ALLOWABLE_VALUES;
  59 +import static org.thingsboard.server.controller.ControllerConstants.RESOURCE_TEXT_SEARCH_DESCRIPTION;
  60 +import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_ALLOWABLE_VALUES;
  61 +import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_DESCRIPTION;
  62 +import static org.thingsboard.server.controller.ControllerConstants.SORT_PROPERTY_DESCRIPTION;
  63 +import static org.thingsboard.server.controller.ControllerConstants.SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH;
  64 +import static org.thingsboard.server.controller.ControllerConstants.TENANT_AUTHORITY_PARAGRAPH;
  65 +
50 @Slf4j 66 @Slf4j
51 @RestController 67 @RestController
52 @TbCoreComponent 68 @TbCoreComponent
@@ -103,6 +103,14 @@ import java.util.concurrent.Executors; @@ -103,6 +103,14 @@ import java.util.concurrent.Executors;
103 import java.util.concurrent.TimeUnit; 103 import java.util.concurrent.TimeUnit;
104 import java.util.stream.Collectors; 104 import java.util.stream.Collectors;
105 105
  106 +import static org.thingsboard.server.controller.ControllerConstants.DEVICE_ID_PARAM_DESCRIPTION;
  107 +import static org.thingsboard.server.controller.ControllerConstants.ENTITY_ID_PARAM_DESCRIPTION;
  108 +import static org.thingsboard.server.controller.ControllerConstants.ENTITY_TYPE_PARAM_DESCRIPTION;
  109 +import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_ALLOWABLE_VALUES;
  110 +import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_DESCRIPTION;
  111 +import static org.thingsboard.server.controller.ControllerConstants.TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH;
  112 +
  113 +
106 /** 114 /**
107 * Created by ashvayka on 22.03.18. 115 * Created by ashvayka on 22.03.18.
108 */ 116 */
@@ -43,6 +43,21 @@ import org.thingsboard.server.service.install.InstallScripts; @@ -43,6 +43,21 @@ import org.thingsboard.server.service.install.InstallScripts;
43 import org.thingsboard.server.service.security.permission.Operation; 43 import org.thingsboard.server.service.security.permission.Operation;
44 import org.thingsboard.server.service.security.permission.Resource; 44 import org.thingsboard.server.service.security.permission.Resource;
45 45
  46 +import static org.thingsboard.server.controller.ControllerConstants.HOME_DASHBOARD;
  47 +import static org.thingsboard.server.controller.ControllerConstants.PAGE_DATA_PARAMETERS;
  48 +import static org.thingsboard.server.controller.ControllerConstants.PAGE_NUMBER_DESCRIPTION;
  49 +import static org.thingsboard.server.controller.ControllerConstants.PAGE_SIZE_DESCRIPTION;
  50 +import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_ALLOWABLE_VALUES;
  51 +import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_DESCRIPTION;
  52 +import static org.thingsboard.server.controller.ControllerConstants.SORT_PROPERTY_DESCRIPTION;
  53 +import static org.thingsboard.server.controller.ControllerConstants.SYSTEM_AUTHORITY_PARAGRAPH;
  54 +import static org.thingsboard.server.controller.ControllerConstants.SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH;
  55 +import static org.thingsboard.server.controller.ControllerConstants.TENANT_ID;
  56 +import static org.thingsboard.server.controller.ControllerConstants.TENANT_ID_PARAM_DESCRIPTION;
  57 +import static org.thingsboard.server.controller.ControllerConstants.TENANT_INFO_SORT_PROPERTY_ALLOWABLE_VALUES;
  58 +import static org.thingsboard.server.controller.ControllerConstants.TENANT_SORT_PROPERTY_ALLOWABLE_VALUES;
  59 +import static org.thingsboard.server.controller.ControllerConstants.TENANT_TEXT_SEARCH_DESCRIPTION;
  60 +
46 @RestController 61 @RestController
47 @TbCoreComponent 62 @TbCoreComponent
48 @RequestMapping("/api") 63 @RequestMapping("/api")
@@ -40,6 +40,8 @@ import org.thingsboard.server.queue.util.TbCoreComponent; @@ -40,6 +40,8 @@ import org.thingsboard.server.queue.util.TbCoreComponent;
40 import org.thingsboard.server.service.security.permission.Operation; 40 import org.thingsboard.server.service.security.permission.Operation;
41 import org.thingsboard.server.service.security.permission.Resource; 41 import org.thingsboard.server.service.security.permission.Resource;
42 42
  43 +import static org.thingsboard.server.controller.ControllerConstants.*;
  44 +
43 @RestController 45 @RestController
44 @TbCoreComponent 46 @TbCoreComponent
45 @RequestMapping("/api") 47 @RequestMapping("/api")
@@ -62,6 +62,8 @@ import org.thingsboard.server.service.security.system.SystemSecurityService; @@ -62,6 +62,8 @@ import org.thingsboard.server.service.security.system.SystemSecurityService;
62 import javax.servlet.http.HttpServletRequest; 62 import javax.servlet.http.HttpServletRequest;
63 import java.util.List; 63 import java.util.List;
64 64
  65 +import static org.thingsboard.server.controller.ControllerConstants.*;
  66 +
65 @RequiredArgsConstructor 67 @RequiredArgsConstructor
66 @RestController 68 @RestController
67 @TbCoreComponent 69 @TbCoreComponent
@@ -28,7 +28,6 @@ import org.springframework.web.bind.annotation.RequestParam; @@ -28,7 +28,6 @@ import org.springframework.web.bind.annotation.RequestParam;
28 import org.springframework.web.bind.annotation.ResponseBody; 28 import org.springframework.web.bind.annotation.ResponseBody;
29 import org.springframework.web.bind.annotation.ResponseStatus; 29 import org.springframework.web.bind.annotation.ResponseStatus;
30 import org.springframework.web.bind.annotation.RestController; 30 import org.springframework.web.bind.annotation.RestController;
31 -import org.thingsboard.server.common.data.EntityType;  
32 import org.thingsboard.server.common.data.edge.EdgeEventActionType; 31 import org.thingsboard.server.common.data.edge.EdgeEventActionType;
33 import org.thingsboard.server.common.data.exception.ThingsboardException; 32 import org.thingsboard.server.common.data.exception.ThingsboardException;
34 import org.thingsboard.server.common.data.id.TenantId; 33 import org.thingsboard.server.common.data.id.TenantId;
@@ -44,6 +43,8 @@ import org.thingsboard.server.service.security.permission.Resource; @@ -44,6 +43,8 @@ import org.thingsboard.server.service.security.permission.Resource;
44 43
45 import java.util.List; 44 import java.util.List;
46 45
  46 +import static org.thingsboard.server.controller.ControllerConstants.*;
  47 +
47 @Slf4j 48 @Slf4j
48 @RestController 49 @RestController
49 @TbCoreComponent 50 @TbCoreComponent
@@ -41,6 +41,8 @@ import org.thingsboard.server.service.security.permission.Resource; @@ -41,6 +41,8 @@ import org.thingsboard.server.service.security.permission.Resource;
41 41
42 import java.util.List; 42 import java.util.List;
43 43
  44 +import static org.thingsboard.server.controller.ControllerConstants.*;
  45 +
44 @RestController 46 @RestController
45 @TbCoreComponent 47 @TbCoreComponent
46 @RequestMapping("/api") 48 @RequestMapping("/api")