@ -155,6 +155,8 @@ public abstract class BaseController {
/*Swagger UI description*/
protectedstaticfinalStringNEW_LINE="\n\n";
publicstaticfinalStringCUSTOMER_ID="customerId";
publicstaticfinalStringTENANT_ID="tenantId";
publicstaticfinalStringDEVICE_ID="deviceId";
@ -263,7 +265,7 @@ public abstract class BaseController {
protectedstaticfinalStringEVENT_END_TIME_DESCRIPTION="Timestamp. Events with creation time after it won't be queried.";
protectedstaticfinalStringEDGE_UNASSIGN_ASYNC_FIRST_STEP_DESCRIPTION="Unassignment works in async way - first, 'unassign' notification event pushed to edge queue on platform. ";
protectedstaticfinalStringEDGE_UNASSIGN_RECEIVE_STEP_DESCRIPTION="(Edge will receive this instantly, if it's currently connected, or once it's going to be connected to platform)";
protectedstaticfinalStringEDGE_UNASSIGN_RECEIVE_STEP_DESCRIPTION="(Edge will receive this instantly, if it's currently connected, or once it's going to be connected to platform)";
protectedstaticfinalStringEDGE_ASSIGN_ASYNC_FIRST_STEP_DESCRIPTION="Assignment works in async way - first, notification event pushed to edge service queue on platform. ";
protectedstaticfinalStringEDGE_ASSIGN_RECEIVE_STEP_DESCRIPTION="(Edge will receive this instantly, if it's currently connected, or once it's going to be connected to platform)";
@ -281,6 +283,114 @@ public abstract class BaseController {
protectedstaticfinalStringFILTER_VALUE_TYPE=NEW_LINE+"## Value Type and Operations"+NEW_LINE+
"Provides a hint about the data type of the entity field that is defined in the filter key. "+
"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."+
"The following filter value types and corresponding predicate operations are supported: "+NEW_LINE+
" * 'STRING' - used to filter any 'String' or 'JSON' values. Operations: EQUAL, NOT_EQUAL, STARTS_WITH, ENDS_WITH, CONTAINS, NOT_CONTAINS; \n"+
" * 'NUMERIC' - used for 'Long' and 'Double' values. Operations: EQUAL, NOT_EQUAL, GREATER, LESS, GREATER_OR_EQUAL, LESS_OR_EQUAL; \n"+
" * 'BOOLEAN' - used for boolean values. Operations: EQUAL, NOT_EQUAL;\n"+
" * 'DATE_TIME' - similar to numeric, transforms value to milliseconds since epoch. Operations: EQUAL, NOT_EQUAL, GREATER, LESS, GREATER_OR_EQUAL, LESS_OR_EQUAL; \n";
protectedstaticfinalStringRELATION_TYPE_PARAM_DESCRIPTION="A string value representing relation type between entities. For example, 'Contains', 'Manages'. It can be any string value.";
protectedstaticfinalStringRELATION_TYPE_GROUP_PARAM_DESCRIPTION="A string value representing relation type group. For example, 'COMMON'";
"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"+
" * 'ATTRIBUTE' - used for attributes values;\n"+
" * 'TIME_SERIES' - used for time-series values;\n"+
" * 'ENTITY_FIELD' - used for accessing entity fields like 'name', 'label', etc. The list of available fields depends on the entity type;\n"+
" * 'CONSTANT' - constant value specified."+NEW_LINE+"Let's review the example:"+NEW_LINE+
"Filter Predicate defines the logical expression to evaluate. The list of available operations depends on the filter value type, see above. "+
"Platform supports 4 predicate types: 'STRING', 'NUMERIC', 'BOOLEAN' and 'COMPLEX'. The last one allows to combine multiple operations over one filter key."+NEW_LINE+
"Simple predicate example to check 'value < 100': "+NEW_LINE+
MARKDOWN_CODE_BLOCK_START+
"{\n"+
" \"operation\": \"LESS\",\n"+
" \"value\": {\n"+
" \"userValue\": null,\n"+
" \"defaultValue\": 100,\n"+
" \"dynamicValue\": null\n"+
" },\n"+
" \"type\": \"NUMERIC\"\n"+
"}"+
MARKDOWN_CODE_BLOCK_END+NEW_LINE+
"Complex predicate example, to check 'value < 10 or value > 20': "+NEW_LINE+
MARKDOWN_CODE_BLOCK_START+
"{\n"+
" \"type\": \"COMPLEX\",\n"+
" \"operation\": \"OR\",\n"+
" \"predicates\": [\n"+
" {\n"+
" \"operation\": \"LESS\",\n"+
" \"value\": {\n"+
" \"userValue\": null,\n"+
" \"defaultValue\": 10,\n"+
" \"dynamicValue\": null\n"+
" },\n"+
" \"type\": \"NUMERIC\"\n"+
" },\n"+
" {\n"+
" \"operation\": \"GREATER\",\n"+
" \"value\": {\n"+
" \"userValue\": null,\n"+
" \"defaultValue\": 20,\n"+
" \"dynamicValue\": null\n"+
" },\n"+
" \"type\": \"NUMERIC\"\n"+
" }\n"+
" ]\n"+
"}"+
MARKDOWN_CODE_BLOCK_END+NEW_LINE+
"More complex predicate example, to check 'value < 10 or (value > 50 && value < 60)': "+NEW_LINE+
MARKDOWN_CODE_BLOCK_START+
"{\n"+
" \"type\": \"COMPLEX\",\n"+
" \"operation\": \"OR\",\n"+
" \"predicates\": [\n"+
" {\n"+
" \"operation\": \"LESS\",\n"+
" \"value\": {\n"+
" \"userValue\": null,\n"+
" \"defaultValue\": 10,\n"+
" \"dynamicValue\": null\n"+
" },\n"+
" \"type\": \"NUMERIC\"\n"+
" },\n"+
" {\n"+
" \"type\": \"COMPLEX\",\n"+
" \"operation\": \"AND\",\n"+
" \"predicates\": [\n"+
" {\n"+
" \"operation\": \"GREATER\",\n"+
" \"value\": {\n"+
" \"userValue\": null,\n"+
" \"defaultValue\": 50,\n"+
" \"dynamicValue\": null\n"+
" },\n"+
" \"type\": \"NUMERIC\"\n"+
" },\n"+
" {\n"+
" \"operation\": \"LESS\",\n"+
" \"value\": {\n"+
" \"userValue\": null,\n"+
" \"defaultValue\": 60,\n"+
" \"dynamicValue\": null\n"+
" },\n"+
" \"type\": \"NUMERIC\"\n"+
" }\n"+
" ]\n"+
" }\n"+
" ]\n"+
"}"+
MARKDOWN_CODE_BLOCK_END+NEW_LINE+
"You may also want to replace hardcoded values (for example, temperature > 20) with the more dynamic "+
"expression (for example, temperature > value of the tenant attribute with key 'temperatureThreshold'). "+
"It is possible to use 'dynamicValue' to define attribute of the tenant, customer or device. "+
"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. "+
"The 'sourceAttribute' can be inherited from the owner of the specified 'sourceType' if 'inherit' is set to true.";
privatestaticfinalStringDEVICE_PROFILE_DATA_DEFINITION=NEW_LINE+"# Device profile data definition"+NEW_LINE+
"Device profile data object contains alarm rules configuration, device provision strategy and transport type configuration for device connectivity. Let's review some examples. "+
"First one is the default device profile data configuration and second one - the custom one. "+
"Alarm Schedule JSON object represents the time interval during which the alarm rule is active. Note, "+
NEW_LINE+DEVICE_PROFILE_ALARM_SCHEDULE_ALWAYS_EXAMPLE+NEW_LINE+"means alarm rule is active all the time. "+
"**'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). "+
"**'enabled'** flag specifies if item in a custom rule is active for specific day of the week:"+NEW_LINE+
privatestaticfinalStringALARM_CONDITION_TYPE="# Alarm condition type (**'spec'**)"+NEW_LINE+
"Alarm condition type can be either simple, duration, or repeating. For example, 5 times in a row or during 5 minutes."+NEW_LINE+
"Note, **'userValue'** field is not used and reserved for future usage, **'dynamicValue'** is used for condition appliance by using the value of the **'sourceAttribute'** "+
"or else **'defaultValue'** is used (if **'sourceAttribute'** is absent).\n"+
"\n**'sourceType'** of the **'sourceAttribute'** can be: \n"+
" * 'CURRENT_DEVICE';\n"+
" * 'CURRENT_CUSTOMER';\n"+
" * 'CURRENT_TENANT'."+NEW_LINE+
"**'sourceAttribute'** can be inherited from the owner if **'inherit'** is set to true (for CURRENT_DEVICE and CURRENT_CUSTOMER)."+NEW_LINE+
@ -169,12 +616,13 @@ public class DeviceProfileController extends BaseController {
}
}
@ApiOperation(value="Create Or Update Device Profile (saveDevice)",
@ApiOperation(value="Create Or Update Device Profile (saveDeviceProfile)",
notes="Create or update the Device Profile. When creating device profile, platform generates device profile id as [time-based UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_1_(date-time_and_MAC_address). "+
"The newly created device profile id will be present in the response. "+
"Specify existing device profile id to update the device profile. "+
"Referencing non-existing device profile Id will cause 'Not Found' error. "+
"\n\nDevice profile name is unique in the scope of tenant. Only one 'default' device profile may exist in scope of tenant."+TENANT_AUTHORITY_PARAGRAPH,
"Referencing non-existing device profile Id will cause 'Not Found' error. "+NEW_LINE+
"Device profile name is unique in the scope of tenant. Only one 'default' device profile may exist in scope of tenant."+DEVICE_PROFILE_DATA+
@ -165,7 +165,7 @@ public class EntityQueryController extends BaseController {
FETCH_LAST_LEVEL_ONLY_DESCRIPTION+
"The 'filter' object allows you to define the relation type and set of acceptable entity types to search for. "+
"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"+
"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"+
"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"+
MARKDOWN_CODE_BLOCK_START+
"{\n"+
" \"type\": \"relationsQuery\",\n"+
@ -185,7 +185,7 @@ public class EntityQueryController extends BaseController {
" ]\n"+
" }\n"+
" ]\n"+
"}"+
"}"+
MARKDOWN_CODE_BLOCK_END+
"";
@ -197,7 +197,7 @@ public class EntityQueryController extends BaseController {
"The 'relationType' defines the type of the relation to search for. "+
"The 'assetTypes' defines the type of the asset to search for. "+
"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"+
"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"+
"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"+
MARKDOWN_CODE_BLOCK_START+
"{\n"+
" \"type\": \"assetSearchQuery\",\n"+
@ -212,7 +212,7 @@ public class EntityQueryController extends BaseController {
" \"assetTypes\": [\n"+
" \"charging station\"\n"+
" ]\n"+
"}"+
"}"+
MARKDOWN_CODE_BLOCK_END+
"";
@ -223,7 +223,7 @@ public class EntityQueryController extends BaseController {
"The 'relationType' defines the type of the relation to search for. "+
"The 'deviceTypes' defines the type of the device to search for. "+
"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"+
"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"+
"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"+
MARKDOWN_CODE_BLOCK_START+
"{\n"+
" \"type\": \"deviceSearchQuery\",\n"+
@ -239,7 +239,7 @@ public class EntityQueryController extends BaseController {
" \"Air Quality Sensor\",\n"+
" \"Charging port\"\n"+
" ]\n"+
"}"+
"}"+
MARKDOWN_CODE_BLOCK_END+
"";
@ -250,7 +250,7 @@ public class EntityQueryController extends BaseController {
"The 'relationType' defines the type of the relation to search for. "+
"The 'entityViewTypes' defines the type of the entity view to search for. "+
"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"+
"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"+
"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"+
MARKDOWN_CODE_BLOCK_START+
"{\n"+
" \"type\": \"entityViewSearchQuery\",\n"+
@ -265,7 +265,7 @@ public class EntityQueryController extends BaseController {
" \"entityViewTypes\": [\n"+
" \"Concrete mixer\"\n"+
" ]\n"+
"}"+
"}"+
MARKDOWN_CODE_BLOCK_END+
"";
@ -276,7 +276,7 @@ public class EntityQueryController extends BaseController {
"The 'relationType' defines the type of the relation to search for. "+
"The 'deviceTypes' defines the type of the device to search for. "+
"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"+
"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"+
"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"+
MARKDOWN_CODE_BLOCK_START+
"{\n"+
" \"type\": \"deviceSearchQuery\",\n"+
@ -291,27 +291,27 @@ public class EntityQueryController extends BaseController {
" \"edgeTypes\": [\n"+
" \"Factory\"\n"+
" ]\n"+
"}"+
"}"+
MARKDOWN_CODE_BLOCK_END+
"";
privatestaticfinalStringEMPTY="\n\n## Entity Type Filter\n\n"+
"Allows to filter multiple entities of the same type using the **'starts with'** expression over entity name. "+
"For example, this entity filter selects all devices which name starts with 'Air Quality':\n\n"+
"For example, this entity filter selects all devices which name starts with 'Air Quality':\n\n"+
MARKDOWN_CODE_BLOCK_START+
""+
""+
MARKDOWN_CODE_BLOCK_END+
"";
privatestaticfinalStringENTITY_FILTERS=
"\n\n # Entity Filters"+
"\nEntity Filter body depends on the 'type' parameter. Let's review available entity filter types. In fact, they do correspond to available dashboard aliases."+
"\nEntity Filter body depends on the 'type' parameter. Let's review available entity filter types. In fact, they do correspond to available dashboard aliases."+
"Filter Key defines either entity field, attribute or telemetry. It is a JSON object that consists the key name and type. "+
"The following filter key types are supported: \n\n"+
"The following filter key types are supported: \n\n"+
" * 'CLIENT_ATTRIBUTE' - used for client attributes; \n"+
" * 'SHARED_ATTRIBUTE' - used for shared attributes; \n"+
" * 'SERVER_ATTRIBUTE' - used for server attributes; \n"+
@ -328,19 +328,10 @@ public class EntityQueryController extends BaseController {
MARKDOWN_CODE_BLOCK_END+
"";
privatestaticfinalStringFILTER_VALUE_TYPE="\n\n## Value Type and Operations\n\n"+
"Provides a hint about the data type of the entity field that is defined in the filter key. "+
"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."+
"The following filter value types and corresponding predicate operations are supported: \n\n"+
" * 'STRING' - used to filter any 'String' or 'JSON' values. Operations: EQUAL, NOT_EQUAL, STARTS_WITH, ENDS_WITH, CONTAINS, NOT_CONTAINS; \n"+
" * 'NUMERIC' - used for 'Long' and 'Double' values. Operations: EQUAL, NOT_EQUAL, GREATER, LESS, GREATER_OR_EQUAL, LESS_OR_EQUAL; \n"+
" * 'BOOLEAN' - used for boolean values; Operations: EQUAL, NOT_EQUAL \n"+
" * 'DATE_TIME' - similar to numeric, transforms value to milliseconds since epoch. Operations: EQUAL, NOT_EQUAL, GREATER, LESS, GREATER_OR_EQUAL, LESS_OR_EQUAL; \n";
"Filter Predicate defines the logical expression to evaluate. The list of available operations depends on the filter value type, see above. "+
"Platform supports 4 predicate types: 'STRING', 'NUMERIC', 'BOOLEAN' and 'COMPLEX'. The last one allows to combine multiple operations over one filter key."+
"\n\nSimple predicate example to check 'value < 100': \n\n"+
"\n\nSimple predicate example to check 'value < 100': \n\n"+
MARKDOWN_CODE_BLOCK_START+
"{\n"+
" \"operation\": \"LESS\",\n"+
@ -351,7 +342,7 @@ public class EntityQueryController extends BaseController {
" \"type\": \"NUMERIC\"\n"+
"}"+
MARKDOWN_CODE_BLOCK_END+
"\n\nComplex predicate example, to check 'value < 10 or value > 20': \n\n"+
"\n\nComplex predicate example, to check 'value < 10 or value > 20': \n\n"+
MARKDOWN_CODE_BLOCK_START+
"{\n"+
" \"type\": \"COMPLEX\",\n"+
@ -376,7 +367,7 @@ public class EntityQueryController extends BaseController {
" ]\n"+
"}"+
MARKDOWN_CODE_BLOCK_END+
"\n\nMore complex predicate example, to check 'value < 10 or (value > 50 && value < 60)': \n\n"+
"\n\nMore complex predicate example, to check 'value < 10 or (value > 50 && value < 60)': \n\n"+
MARKDOWN_CODE_BLOCK_START+
"{\n"+
" \"type\": \"COMPLEX\",\n"+
@ -461,16 +452,16 @@ public class EntityQueryController extends BaseController {
"For example, \"temperature > 20 or temperature< 10\" or \"name starts with 'T', and attribute 'model' is 'T1000', and timeseries field 'batteryLevel' > 40\"."+
"\n\nLet's review the example:"+
"\n\n"+MARKDOWN_CODE_BLOCK_START+
"{\n"+
"\n\nOptional **key filters** allow to filter results of the entity filter by complex criteria against "+
"For example, \"temperature > 20 or temperature< 10\" or \"name starts with 'T', and attribute 'model' is 'T1000', and timeseries field 'batteryLevel' > 40\"."+
"\n\nLet's review the example:"+
"\n\n"+MARKDOWN_CODE_BLOCK_START+
"{\n"+
" \"entityFilter\": {\n"+
" \"type\": \"entityType\",\n"+
" \"entityType\": \"DEVICE\"\n"+
@ -492,12 +483,12 @@ public class EntityQueryController extends BaseController {
" }\n"+
" }\n"+
" ]\n"+
"}"+
MARKDOWN_CODE_BLOCK_END+
"\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:"+
ENTITY_FILTERS+
KEY_FILTERS+
TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH;;
"}"+
MARKDOWN_CODE_BLOCK_END+
"\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:"+
"For example, \"temperature > 20 or temperature< 10\" or \"name starts with 'T', and attribute 'model' is 'T1000', and timeseries field 'batteryLevel' > 40\"."+
"For example, \"temperature > 20 or temperature< 10\" or \"name starts with 'T', and attribute 'model' is 'T1000', and timeseries field 'batteryLevel' > 40\"."+
"\n\nThe **entity fields** and **latest values** contains list of entity fields and latest attribute/telemetry fields to fetch for each entity."+
"\n\nThe **page link** contains information about the page to fetch and the sort ordering."+
"\n\nLet's review the example:"+
@ -575,7 +566,7 @@ public class EntityQueryController extends BaseController {
" \"direction\": \"ASC\"\n"+
" }\n"+
" }\n"+
"}"+
"}"+
MARKDOWN_CODE_BLOCK_END+
"\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:"+
ENTITY_FILTERS+
@ -672,7 +663,7 @@ public class EntityQueryController extends BaseController {
@ApiModelProperty(position=1,value="JSON object for specifying alarm condition by specific key")
privateAlarmConditionFilterKeykey;
@ApiModelProperty(position=2,value="String representation of the type of the value",example="NUMERIC")
privateEntityKeyValueTypevalueType;
@NoXss
@ApiModelProperty(position=3,value="Value used in Constant comparison. For other types, such as TIME_SERIES or ATTRIBUTE, the predicate condition is used")
@ApiModelProperty(position=1,value="JSON object representing the alarm rule condition")
privateAlarmConditioncondition;
@ApiModelProperty(position=2,value="JSON object representing time interval during which the rule is active")
privateAlarmScheduleschedule;
// Advanced
@NoXss
@ApiModelProperty(position=3,value="String value representing the additional details for an alarm rule")
privateStringalarmDetails;
@ApiModelProperty(position=4,value="JSON object with the dashboard Id representing the reference to alarm details dashboard used by mobile application")
@ApiModelProperty(position=1,value="String value representing the alarm rule id",example="highTemperatureAlarmID")
privateStringid;
@NoXss
@ApiModelProperty(position=2,value="String value representing type of the alarm",example="High Temperature Alarm")
privateStringalarmType;
@Valid
@ApiModelProperty(position=3,value="Complex JSON object representing create alarm rules. The unique create alarm rule can be created for each alarm severity type. "+
"There can be 5 create alarm rules configured per a single alarm type. See method implementation notes and AlarmRule model for more details")