@ -59,10 +63,14 @@ public class AdminController extends BaseController {
@Autowired
privateUpdateServiceupdateService;
@ApiOperation(value="Get the Administration Settings object using key (getAdminSettings)",
notes="Get the Administration Settings object using specified string key. Referencing non-existing key will cause an error."+SYSTEM_AUTHORITY_PARAGRAPH)
@ -75,10 +83,17 @@ public class AdminController extends BaseController {
}
}
@ApiOperation(value="Get the Administration Settings object using key (getAdminSettings)",
notes="Creates or Updates the Administration Settings. Platform generates random Administration Settings Id during settings creation. "+
"The Administration Settings Id will be present in the response. Specify the Administration Settings Id when you would like to update the Administration Settings. "+
"Referencing non-existing Administration Settings Id will cause an error."+SYSTEM_AUTHORITY_PARAGRAPH)
privatestaticfinalStringALARM_SECURITY_CHECK="If the user has the authority of 'Tenant Administrator', the server checks that the originator of alarm is owned by the same tenant. "+
"If the user has the authority of 'Customer User', the server checks that the originator of alarm belongs to the customer. ";
privatestaticfinalStringALARM_QUERY_SEARCH_STATUS_DESCRIPTION="A string value representing one of the AlarmSearchStatus enumeration value";
privatestaticfinalStringALARM_QUERY_TEXT_SEARCH_DESCRIPTION="The case insensitive 'startsWith' filter based on of next alarm fields: type, severity or status";
privatestaticfinalStringALARM_QUERY_START_TIME_DESCRIPTION="The start timestamp in milliseconds of the search time range over the Alarm class field: 'createdTime'.";
privatestaticfinalStringALARM_QUERY_END_TIME_DESCRIPTION="The end timestamp in milliseconds of the search time range over the Alarm class field: 'createdTime'.";
privatestaticfinalStringALARM_QUERY_FETCH_ORIGINATOR_DESCRIPTION="A boolean value to specify if the alarm originator name will be "+
"filled in the AlarmInfo object field: 'originatorName' or will returns as null.";
@ApiOperation(value="Create or update Alarm (saveAlarm)",
notes="Creates or Updates the Alarm. "+
"When creating alarm, platform generates Alarm Id as [time-based UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_1_(date-time_and_MAC_address). "+
"The newly created Alarm id will be present in the response. Specify existing Alarm id to update the alarm. "+
"Referencing non-existing Alarm Id will cause 'Not Found' error. "+
"\n\nPlatform also deduplicate the alarms based on the entity id of originator and alarm 'type'. "+
"For example, if the user or system component create the alarm with the type 'HighTemperature' for device 'Device A' the new active alarm is created. "+
"If the user tries to create 'HighTemperature' alarm for the same device again, the previous alarm will be updated (the 'end_ts' will be set to current timestamp). "+
"If the user clears the alarm (see 'Clear Alarm(clearAlarm)'), than new alarm with the same type and same device may be created. "+TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH
notes="Deletes the Alarm. Referencing non-existing Alarm Id will cause an error."+TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH,produces=MediaType.APPLICATION_JSON_VALUE)
notes="Returns a page of alarms for the selected entity. Specifying both parameters 'searchStatus' and 'status' at the same time will cause an error. "+
notes="Search the alarms by originator ('entityType' and entityId') and optional 'status' or 'searchStatus' filters and returns the highest AlarmSeverity(CRITICAL, MAJOR, MINOR, WARNING or INDETERMINATE). "+
"Specifying both parameters 'searchStatus' and 'status' at the same time will cause an error."+TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH
@ -75,10 +97,16 @@ public class AssetController extends BaseController {
publicstaticfinalStringASSET_ID="assetId";
@ApiOperation(value="Get Asset (getAssetById)",
notes="Fetch the Asset object based on the provided Asset Id. "+
"If the user has the authority of 'Tenant Administrator', the server checks that the asset is owned by the same tenant. "+
"If the user has the authority of 'Customer User', the server checks that the asset is assigned to the same customer."+TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH
@ -101,10 +135,15 @@ public class AssetController extends BaseController {
}
}
@ApiOperation(value="Create Or Update Asset (saveAsset)",
notes="Creates or Updates the Asset. When creating asset, platform generates Asset Id as [time-based UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_1_(date-time_and_MAC_address) "+
"The newly created Asset id will be present in the response. "+
"Specify existing Asset id to update the asset. "+
"Referencing non-existing Asset Id will cause 'Not Found' error."+TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH,produces=MediaType.APPLICATION_JSON_VALUE)
@ -140,10 +179,12 @@ public class AssetController extends BaseController {
}
}
@ApiOperation(value="Delete asset (deleteAsset)",
notes="Deletes the asset and all the relations (from and to the asset). Referencing non-existing asset Id will cause an error."+TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH)
@ -167,11 +208,13 @@ public class AssetController extends BaseController {
}
}
@ApiOperation(value="Assign asset to customer (assignAssetToCustomer)",
notes="Creates assignment of the asset to customer. Customer will be able to query asset afterwards."+TENANT_AUTHORITY_PARAGRAPH,produces=MediaType.APPLICATION_JSON_VALUE)
@ -201,10 +244,12 @@ public class AssetController extends BaseController {
}
}
@ApiOperation(value="Unassign asset from customer (unassignAssetFromCustomer)",
notes="Clears assignment of the asset to customer. Customer will not be able to query asset afterwards."+TENANT_AUTHORITY_PARAGRAPH,produces=MediaType.APPLICATION_JSON_VALUE)
@ -235,10 +280,14 @@ public class AssetController extends BaseController {
}
}
@ApiOperation(value="Make asset publicly available (assignAssetToPublicCustomer)",
notes="Asset will be available for non-authorized (not logged-in) users. "+
"This is useful to create dashboards that you plan to share/embed on a publicly available website. "+
"However, users that are logged-in and belong to different tenant will not be able to access the asset."+TENANT_AUTHORITY_PARAGRAPH,produces=MediaType.APPLICATION_JSON_VALUE)
notes="Requested asset must be owned by tenant that the user belongs to. "+
"Asset name is an unique property of asset. So it can be used to identify the asset."+TENANT_AUTHORITY_PARAGRAPH,produces=MediaType.APPLICATION_JSON_VALUE)
@ -374,10 +465,13 @@ public class AssetController extends BaseController {
}
}
@ApiOperation(value="Get Assets By Ids (getAssetsByIds)",
notes="Requested assets must be owned by tenant or assigned to customer which user is performing the request. ",produces=MediaType.APPLICATION_JSON_VALUE)
notes="Returns a set of unique asset types based on assets that are either owned by the tenant or assigned to the customer which user is performing the request.",produces=MediaType.APPLICATION_JSON_VALUE)
privatestaticfinalStringAUDIT_LOG_QUERY_START_TIME_DESCRIPTION="The start timestamp in milliseconds of the search time range over the AuditLog class field: 'createdTime'.";
privatestaticfinalStringAUDIT_LOG_QUERY_END_TIME_DESCRIPTION="The end timestamp in milliseconds of the search time range over the AuditLog class field: 'createdTime'.";
privatestaticfinalStringAUDIT_LOG_QUERY_ACTION_TYPES_DESCRIPTION="A String value representing comma-separated list of action types. "+
"This parameter is optional, but it can be used to filter results to fetch only audit logs of specific action types. "+
"For example, 'LOGIN', 'LOGOUT'. See the 'Model' tab of the Response Class for more details.";
privatestaticfinalStringAUDIT_LOG_SORT_PROPERTY_DESCRIPTION="Property of audit log to sort by. "+
"See the 'Model' tab of the Response Class for more details. "+
"Note: entityType sort property is not defined in the AuditLog class, however, it can be used to sort audit logs by types of entities that were logged.";
@ApiOperation(value="Get audit logs by customer id (getAuditLogsByCustomerId)",
notes="Returns a page of audit logs related to the targeted customer entities (devices, assets, etc.), "+
"and users actions (login, logout, etc.) that belong to this customer. "+
@ -85,6 +94,8 @@ public class AuthController extends BaseController {
}
}
@ApiOperation(value="Logout (logout)",
notes="Special API call to record the 'logout' of the user to the Audit Logs. Since platform uses [JWT](https://jwt.io/), the actual logout is the procedure of clearing the [JWT](https://jwt.io/) token on the client side. ")
@ -92,13 +103,17 @@ public class AuthController extends BaseController {
logLogoutAction(request);
}
@ApiOperation(value="Change password for current User (changePassword)",
notes="Change the password for the User which credentials are used to perform this REST API call. Be aware that previously generated [JWT](https://jwt.io/) tokens will be still valid until they expire.")
@ -135,8 +152,13 @@ public class AuthController extends BaseController {
}
}
@ApiOperation(value="Check Activate User Token (checkActivateToken)",
notes="Checks the activation token and forwards user to 'Create Password' page. "+
"If token is valid, returns '303 See Other' (redirect) response code with the correct address of 'Create Password' page and same 'activateToken' specified in the URL parameters. "+
notes="Checks the password reset token and forwards user to 'Reset Password' page. "+
"If token is valid, returns '303 See Other' (redirect) response code with the correct address of 'Reset Password' page and same 'resetToken' specified in the URL parameters. "+
publicstaticfinalStringCUSTOMER_SECURITY_CHECK="If the user has the authority of 'Tenant Administrator', the server checks that the customer is owned by the same tenant. "+
"If the user has the authority of 'Customer User', the server checks that the user belongs to the customer.";
@ -102,10 +135,15 @@ public class CustomerController extends BaseController {
}
}
@ApiOperation(value="Create or update Customer (saveCustomer)",
notes="Creates or Updates the Customer. When creating customer, platform generates Customer Id as [time-based UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_1_(date-time_and_MAC_address) "+
"The newly created Customer Id will be present in the response. "+
"Specify existing Customer Id to update the Customer. "+
"Referencing non-existing Customer Id will cause 'Not Found' error."+TENANT_AUTHORITY_PARAGRAPH)
publicstaticfinalStringDASHBOARD_INFO_DEFINITION="The Dashboard Info object contains lightweight information about the dashboard (e.g. title, image, assigned customers) but does not contain the heavyweight configuration JSON.";
publicstaticfinalStringDASHBOARD_DEFINITION="The Dashboard object is a heavyweight object that contains information about the dashboard (e.g. title, image, assigned customers) and also configuration JSON (e.g. layouts, widgets, entity aliases).";
publicstaticfinalStringHIDDEN_FOR_MOBILE="Exclude dashboards that are hidden for mobile";
@Value("${dashboard.max_datapoints_limit}")
@Value("${ui.dashboard.max_datapoints_limit}")
privatelongmaxDatapointsLimit;
@ApiOperation(value="Get server time (getServerTime)",
notes="Get the server time (milliseconds since January 1, 1970 UTC). "+
"Used to adjust view of the dashboards according to the difference between browser and server time.")
@ -113,10 +159,20 @@ public class DashboardController extends BaseController {
}
}
@ApiOperation(value="Create Or Update Dashboard (saveDashboard)",
notes="Create or update the Dashboard. When creating dashboard, platform generates Dashboard Id as [time-based UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_1_(date-time_and_MAC_address)."+
"The newly created Dashboard id will be present in the response. "+
"Specify existing Dashboard id to update the dashboard. "+
"Referencing non-existing dashboard Id will cause 'Not Found' error. "+
@ -235,11 +309,20 @@ public class DashboardController extends BaseController {
}
}
@ApiOperation(value="Update the Dashboard Customers (updateDashboardCustomers)",
notes="Updates the list of Customers that this Dashboard is assigned to. Removes previous assignments to customers that are not in the provided list. "+
"Returns the Dashboard object. "+TENANT_AUTHORITY_PARAGRAPH,
@ -301,11 +384,19 @@ public class DashboardController extends BaseController {
}
}
@ApiOperation(value="Adds the Dashboard Customers (addDashboardCustomers)",
notes="Adds the list of Customers to the existing list of assignments for the Dashboard. Keeps previous assignments to customers that are not in the provided list. "+
"Returns the Dashboard object."+TENANT_AUTHORITY_PARAGRAPH,
@ -345,11 +436,19 @@ public class DashboardController extends BaseController {
}
}
@ApiOperation(value="Remove the Dashboard Customers (removeDashboardCustomers)",
notes="Removes the list of Customers from the existing list of assignments for the Dashboard. Keeps other assignments to customers that are not in the provided list. "+
"Returns the Dashboard object."+TENANT_AUTHORITY_PARAGRAPH,
@ -415,10 +524,16 @@ public class DashboardController extends BaseController {
}
}
@ApiOperation(value="Unassign the Dashboard from Public Customer (unassignDashboardFromPublicCustomer)",
notes="Unassigns the dashboard from a special, auto-generated 'Public' Customer. Once unassigned, unauthenticated users may no longer browse the dashboard. "+
"Returns the Dashboard object."+TENANT_AUTHORITY_PARAGRAPH,
@ -512,6 +658,12 @@ public class DashboardController extends BaseController {
}
}
@ApiOperation(value="Get Home Dashboard (getHomeDashboard)",
notes="Returns the home dashboard object that is configured as 'homeDashboardId' parameter in the 'additionalInfo' of the User. "+
"If 'homeDashboardId' parameter is not set on the User level and the User has authority 'CUSTOMER_USER', check the same parameter for the corresponding Customer. "+
"If 'homeDashboardId' parameter is not set on the User and Customer levels then checks the same parameter for the Tenant that owns the user. "
@ -543,6 +695,12 @@ public class DashboardController extends BaseController {
}
}
@ApiOperation(value="Get Home Dashboard Info (getHomeDashboardInfo)",
notes="Returns the home dashboard info object that is configured as 'homeDashboardId' parameter in the 'additionalInfo' of the User. "+
"If 'homeDashboardId' parameter is not set on the User level and the User has authority 'CUSTOMER_USER', check the same parameter for the corresponding Customer. "+
"If 'homeDashboardId' parameter is not set on the User and Customer levels then checks the same parameter for the Tenant that owns the user. "+
@ -574,6 +732,10 @@ public class DashboardController extends BaseController {
}
}
@ApiOperation(value="Get Tenant Home Dashboard Info (getTenantHomeDashboardInfo)",
notes="Returns the home dashboard info object that is configured as 'homeDashboardId' parameter in the 'additionalInfo' of the corresponding tenant. "+
@ -123,11 +165,20 @@ public class DeviceController extends BaseController {
}
}
@ApiOperation(value="Create Or Update Device (saveDevice)",
notes="Create or update the Device. When creating device, platform generates Device Id as [time-based UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_1_(date-time_and_MAC_address). "+
"Device credentials are also generated if not provided in the 'accessToken' request parameter. "+
"The newly created device id will be present in the response. "+
"Specify existing Device id to update the device. "+
"Referencing non-existing device Id will cause 'Not Found' error."+
"\n\nDevice name is unique in the scope of tenant. Use unique identifiers like MAC or IMEI for the device names and non-unique 'label' field for user-friendly visualization purposes."
@ApiOperation(value="Create Device (saveDevice) with credentials ",
notes="Create or update the Device. When creating device, platform generates Device Id as [time-based UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_1_(date-time_and_MAC_address). "+
"Requires to provide the Device Credentials object as well. Useful to create device and credentials in one request. "+
"You may find the example of LwM2M device and RPK credentials below: \n\n"+
notes="Deletes the device, it's credentials and all the relations (from and to the device). Referencing non-existing device Id will cause an error."+TENANT_AUTHORITY_PARAGRAPH)
notes="If during device creation there wasn't specified any credentials, platform generates random 'ACCESS_TOKEN' credentials."+TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH)
"Use this method to update the device credentials. First use 'getDeviceCredentialsByDeviceId' to get the credentials id and value. "+
"Then use current method to update the credentials type and value. It is not possible to create multiple device credentials for the same device. "+
"The structure of device credentials id and value is simple for the 'ACCESS_TOKEN' but is much more complex for the 'MQTT_BASIC' or 'LWM2M_CREDENTIALS'."+TENANT_AUTHORITY_PARAGRAPH)
@ -446,10 +597,13 @@ public class DeviceController extends BaseController {
}
}
@ApiOperation(value="Get Devices By Ids (getDevicesByIds)",
notes="Requested devices must be owned by tenant or assigned to customer which user is performing the request. "+TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH)
notes="Returns a set of unique device profile names based on devices that are either owned by the tenant or assigned to the customer which user is performing the request."
notes="Get a set of unique time-series keys used by devices that belong to specified profile. "+
"If profile is not set returns a list of unique keys among all profiles. "+
"The call is used for auto-complete in the UI forms. "+
"The implementation limits the number of devices that participate in search to 100 as a trade of between accurate results and time-consuming queries. "+
notes="Get a set of unique attribute keys used by devices that belong to specified profile. "+
"If profile is not set returns a list of unique keys among all profiles. "+
"The call is used for auto-complete in the UI forms. "+
"The implementation limits the number of devices that participate in search to 100 as a trade of between accurate results and time-consuming queries. "+
@ -135,10 +185,21 @@ public class DeviceProfileController extends BaseController {
}
}
@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. "+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+
publicstaticfinalStringEDGE_SECURITY_CHECK="If the user has the authority of 'Tenant Administrator', the server checks that the edge is owned by the same tenant. "+
"If the user has the authority of 'Customer User', the server checks that the edge is assigned to the same customer.";
@ApiOperation(value="Is edges support enabled (isEdgesSupportEnabled)",
notes="Returns 'true' if edges support enabled on server, 'false' - otherwise.")
@ -117,10 +148,19 @@ public class EdgeController extends BaseController {
}
}
@ApiOperation(value="Create Or Update Edge (saveEdge)",
notes="Create or update the Edge. When creating edge, platform generates Edge Id as [time-based UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_1_(date-time_and_MAC_address). "+
"The newly created edge id will be present in the response. "+
"Specify existing Edge id to update the edge. "+
"Referencing non-existing Edge Id will cause 'Not Found' error."+
"\n\nEdge name is unique in the scope of tenant. Use unique identifiers like MAC or IMEI for the edge names and non-unique 'label' field for user-friendly visualization purposes."
notes="Returns a set of unique edge types based on edges that are either owned by the tenant or assigned to the customer which user is performing the request."
notes="Returns list of rule chains ids that are not assigned to particular edge, but these rule chains are present in the already assigned rule chains to edge."+TENANT_AUTHORITY_PARAGRAPH)
@ -83,12 +98,18 @@ public class EntityQueryController extends BaseController {
}
}
@ApiOperation(value="Find Entity Keys by Query",
notes="Uses entity data query (see 'Find Entity Data by Query') to find first 100 entities. Then fetch and return all unique time-series and/or attribute keys. Used mostly for UI hints.")
privatestaticfinalStringSECURITY_CHECKS_ENTITIES_DESCRIPTION="\n\nIf the user has the authority of 'System Administrator', the server checks that 'from' and 'to' entities are owned by the sysadmin. "+
"If the user has the authority of 'Tenant Administrator', the server checks that 'from' and 'to' entities are owned by the same tenant. "+
"If the user has the authority of 'Customer User', the server checks that the 'from' and 'to' entities are assigned to the same customer.";
privatestaticfinalStringSECURITY_CHECKS_ENTITY_DESCRIPTION="\n\nIf the user has the authority of 'System Administrator', the server checks that the entity is owned by the sysadmin. "+
"If the user has the authority of 'Tenant Administrator', the server checks that the entity is owned by the same tenant. "+
"If the user has the authority of 'Customer User', the server checks that the entity is assigned to the same customer.";
@ -552,10 +647,16 @@ public class EntityViewController extends BaseController {
}
}
@ApiOperation(value="Find related entity views (findByQuery)",
notes="Returns all entity views that are related to the specific entity. "+
"The entity id, relation type, entity view types, depth of the search, and other query parameters defined using complex 'EntityViewSearchQuery' object. "+
"See 'Model' tab of the Parameters for more info."+TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH)
notes="Returns a set of unique entity view types based on entity views that are either owned by the tenant or assigned to the customer which user is performing the request."
notes="Get the Lwm2m Bootstrap SecurityInfo object (of the current server) based on the provided isBootstrapServer parameter. If isBootstrapServer == true, get the parameters of the current Bootstrap Server. If isBootstrapServer == false, get the parameters of the current Lwm2m Server. Used for client settings when starting the client in Bootstrap mode. "+
privatestaticfinalStringOAUTH2_CLIENT_REGISTRATION_TEMPLATE_DEFINITION="Client registration template is OAuth2 provider configuration template with default settings for registering new OAuth2 clients";
@ApiOperation(value="Create or update OAuth2 client registration template (saveClientRegistrationTemplate)"+SYSTEM_AUTHORITY_PARAGRAPH,
publicvoiddeleteClientRegistrationTemplate(@ApiParam(value="String representation of client registration template id to delete",example="139b1f81-2f5d-11ec-9dbe-9b627e1a88f4")
@ApiOperation(value="Download OTA Package (downloadOtaPackage)",notes="Download OTA Package based on the provided OTA Package Id."+TENANT_AUTHORITY_PARAGRAPH)
@ -107,10 +137,19 @@ public class OtaPackageController extends BaseController {
}
}
@ApiOperation(value="Create Or Update OTA Package Info (saveOtaPackageInfo)",
notes="Create or update the OTA Package Info. When creating OTA Package Info, platform generates OTA Package id as [time-based UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_1_(date-time_and_MAC_address). "+
"The newly created OTA Package id will be present in the response. "+
"Specify existing OTA Package id to update the OTA Package Info. "+
"Referencing non-existing OTA Package Id will cause 'Not Found' error. "+
"\n\nOTA Package combination of the title with the version is unique in the scope of tenant. "+TENANT_AUTHORITY_PARAGRAPH,
privatestaticfinalStringRPC_REQUEST_DESCRIPTION="Sends the one-way remote-procedure call (RPC) request to device. "+
"The RPC call is A JSON that contains the method name ('method'), parameters ('params') and multiple optional fields. "+
"See example below. We will review the properties of the RPC call one-by-one below. "+
"\n\n"+MARKDOWN_CODE_BLOCK_START+
"{\n"+
" \"method\": \"setGpio\",\n"+
" \"params\": {\n"+
" \"pin\": 7,\n"+
" \"value\": 1\n"+
" },\n"+
" \"persistent\": false,\n"+
" \"timeout\": 5000\n"+
"}"+
MARKDOWN_CODE_BLOCK_END+
"\n\n### Server-side RPC structure\n"+
"\n"+
"The body of server-side RPC request consists of multiple fields:\n"+
"\n"+
"* **method** - mandatory, name of the method to distinct the RPC calls.\n"+
" For example, \"getCurrentTime\" or \"getWeatherForecast\". The value of the parameter is a string.\n"+
"* **params** - mandatory, parameters used for processing of the request. The value is a JSON. Leave empty JSON \"{}\" if no parameters needed.\n"+
"* **timeout** - optional, value of the processing timeout in milliseconds. The default value is 10000 (10 seconds). The minimum value is 5000 (5 seconds).\n"+
"* **expirationTime** - optional, value of the epoch time (in milliseconds, UTC timezone). Overrides **timeout** if present.\n"+
"* **persistent** - optional, indicates persistent RPC. The default value is \"false\".\n"+
"* **retries** - optional, defines how many times persistent RPC will be re-sent in case of failures on the network and/or device side.\n"+
"* **additionalInfo** - optional, defines metadata for the persistent RPC that will be added to the persistent RPC events.";
"In case of persistent RPC, the result of this call is 'rpcId' UUID. In case of lightweight RPC, "+
"the result of this call is the response from device, or 504 Gateway Timeout if device is offline.";
privatestaticfinalStringONE_WAY_RPC_REQUEST_DESCRIPTION="Sends the one-way remote-procedure call (RPC) request to device. "+RPC_REQUEST_DESCRIPTION+ONE_WAY_RPC_RESULT+TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH;
privatestaticfinalStringTWO_WAY_RPC_REQUEST_DESCRIPTION="Sends the two-way remote-procedure call (RPC) request to device. "+RPC_REQUEST_DESCRIPTION+TWO_WAY_RPC_RESULT+TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH;
@ -79,31 +166,62 @@ public class RpcV2Controller extends AbstractRpcController {
}
}
@ApiOperation(value="Get persistent RPC requests",notes="Allows to query RPC calls for specific device using pagination."+TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH)
@ -135,11 +183,18 @@ public class RuleChainController extends BaseController {
}
}
@ApiOperation(value="Create Or Update Rule Chain (saveRuleChain)",
notes="Create or update the Rule Chain. When creating Rule Chain, platform generates Rule Chain Id as [time-based UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_1_(date-time_and_MAC_address). "+
"The newly created Rule Chain Id will be present in the response. "+
"Specify existing Rule Chain id to update the rule chain. "+
"Referencing non-existing rule chain Id will cause 'Not Found' error."+
@ -53,10 +71,12 @@ public class TbResourceController extends BaseController {
publicstaticfinalStringRESOURCE_ID="resourceId";
@ApiOperation(value="Download Resource (downloadResource)",notes="Download Resource based on the provided Resource Id."+SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH)
@ -100,10 +130,19 @@ public class TbResourceController extends BaseController {
}
}
@ApiOperation(value="Create Or Update Resource (saveResource)",
notes="Create or update the Resource. When creating the Resource, platform generates Resource id as [time-based UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_1_(date-time_and_MAC_address). "+
"The newly created Resource id will be present in the response. "+
"Specify existing Resource id to update the Resource. "+
"Referencing non-existing Resource Id will cause 'Not Found' error. "+
"\n\nResource combination of the title with the key is unique in the scope of tenant. "+SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH,
@ApiResponse(code=401,message="User is not authorized to save device attributes for selected device. Most likely, User belongs to different Customer or Tenant."),
@ApiResponse(code=500,message="The exception was thrown during processing the request. "+
"Platform creates an audit log event about device attributes updates with action type 'ATTRIBUTES_UPDATED' that includes an error stacktrace."),
@ApiOperation(value="Delete entity time-series data (deleteEntityTimeseries)",
notes="Delete time-series for selected entity based on entity id, entity type and keys."+
" Use 'deleteAllDataForKeys' to delete all time-series data."+
" Use 'startTs' and 'endTs' to specify time-range instead. "+
" Use 'rewriteLatestIfDeleted' to rewrite latest value (stored in separate table for performance) after deletion of the time range. "+
TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH,
produces=MediaType.APPLICATION_JSON_VALUE)
@ApiResponses(value={
@ApiResponse(code=200,message="Timeseries for the selected keys in the request was removed. "+
"Platform creates an audit log event about entity timeseries removal with action type 'TIMESERIES_DELETED'."),
@ApiResponse(code=400,message="Platform returns a bad request in case if keys list is empty or start and end timestamp values is empty when deleteAllDataForKeys is set to false."),
@ApiResponse(code=401,message="User is not authorized to delete entity timeseries for selected entity. Most likely, User belongs to different Customer or Tenant."),
@ApiResponse(code=500,message="The exception was thrown during processing the request. "+
"Platform creates an audit log event about entity timeseries removal with action type 'TIMESERIES_DELETED' that includes an error stacktrace."),
@ApiParam(value="If the parameter is set to true, the latest telemetry will be rewritten in case that current latest value was removed, otherwise, in case that parameter is set to false the new latest value will not set.")
notes="Delete device attributes using provided Device Id, scope and a list of keys. "+
"Referencing a non-existing Device Id will cause an error"+TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH,
produces=MediaType.APPLICATION_JSON_VALUE)
@ApiResponses(value={
@ApiResponse(code=200,message="Device attributes was removed for the selected keys in the request. "+
"Platform creates an audit log event about device attributes removal with action type 'ATTRIBUTES_DELETED'."),
@ApiResponse(code=400,message="Platform returns a bad request in case if keys or scope are not specified."),
@ApiResponse(code=401,message="User is not authorized to delete device attributes for selected entity. Most likely, User belongs to different Customer or Tenant."),
@ApiResponse(code=500,message="The exception was thrown during processing the request. "+
"Platform creates an audit log event about device attributes removal with action type 'ATTRIBUTES_DELETED' that includes an error stacktrace."),
@ApiResponse(code=200,message="Entity attributes was removed for the selected keys in the request. "+
"Platform creates an audit log event about entity attributes removal with action type 'ATTRIBUTES_DELETED'."),
@ApiResponse(code=400,message="Platform returns a bad request in case if keys or scope are not specified."),
@ApiResponse(code=401,message="User is not authorized to delete entity attributes for selected entity. Most likely, User belongs to different Customer or Tenant."),
@ApiResponse(code=500,message="The exception was thrown during processing the request. "+
"Platform creates an audit log event about entity attributes removal with action type 'ATTRIBUTES_DELETED' that includes an error stacktrace."),
@ -83,10 +110,19 @@ public class TenantController extends BaseController {
}
}
@ApiOperation(value="Create Or update Tenant (saveTenant)",
notes="Create or update the Tenant. When creating tenant, platform generates Tenant Id as [time-based UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_1_(date-time_and_MAC_address). "+
"Default Rule Chain and Device profile are also generated for the new tenants automatically. "+
"The newly created Tenant Id will be present in the response. "+
"Specify existing Tenant Id id to update the Tenant. "+
"Referencing non-existing Tenant Id will cause 'Not Found' error."+
notes="Deletes the tenant, it's customers, rule chains, devices and all other related entities. Referencing non-existing tenant Id will cause an error."+SYSTEM_AUTHORITY_PARAGRAPH)
@ -124,14 +164,21 @@ public class TenantController extends BaseController {
}
}
@ApiOperation(value="Get Tenants (getTenants)",notes="Returns a page of tenants registered in the platform. "+PAGE_DATA_PARAMETERS+SYSTEM_AUTHORITY_PARAGRAPH)
@ -81,10 +109,65 @@ public class TenantProfileController extends BaseController {
}
}
@ApiOperation(value="Create Or update Tenant Profile (saveTenantProfile)",
notes="Create or update the Tenant Profile. When creating tenant profile, platform generates Tenant Profile Id as [time-based UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_1_(date-time_and_MAC_address). "+
"The newly created Tenant Profile Id will be present in the response. "+
"Specify existing Tenant Profile Id id to update the Tenant Profile. "+
"Referencing non-existing Tenant Profile Id will cause 'Not Found' error. "+
"\n\nUpdate of the tenant profile configuration will cause immediate recalculation of API limits for all affected Tenants. "+
"\n\nThe **'profileData'** object is the part of Tenant Profile that defines API limits and Rate limits. "+
"\n\nYou have an ability to define maximum number of devices ('maxDevice'), assets ('maxAssets') and other entities. "+
"You may also define maximum number of messages to be processed per month ('maxTransportMessages', 'maxREExecutions', etc). "+
"The '*RateLimit' defines the rate limits using simple syntax. For example, '1000:1,20000:60' means up to 1000 events per second but no more than 20000 event per minute. "+
"Let's review the example of tenant profile data below: "+
notes="Deletes the tenant profile. Referencing non-existing tenant profile Id will cause an error. Referencing profile that is used by the tenants will cause an error. "+SYSTEM_AUTHORITY_PARAGRAPH)
@ -135,14 +226,21 @@ public class TenantProfileController extends BaseController {
}
}
@ApiOperation(value="Get Tenant Profiles (getTenantProfiles)",notes="Returns a page of tenant profiles registered in the platform. "+PAGE_DATA_PARAMETERS+SYSTEM_AUTHORITY_PARAGRAPH)
@ -151,14 +249,22 @@ public class TenantProfileController extends BaseController {
}
}
@ApiOperation(value="Get Tenant Profiles Info (getTenantProfileInfos)",notes="Returns a page of tenant profile info objects registered in the platform. "
@ -112,10 +143,16 @@ public class UserController extends BaseController {
returnuserTokenAccessEnabled;
}
@ApiOperation(value="Get User Token (getUserToken)",
notes="Returns the token of the User based on the provided User Id. "+
"If the user who performs the request has the authority of 'SYS_ADMIN', it is possible to get the token of any tenant administrator. "+
"If the user who performs the request has the authority of 'TENANT_ADMIN', it is possible to get the token of any customer user that belongs to the same tenant. ")
@ApiOperation(value="Save Or update User (saveUser)",
notes="Create or update the User. When creating user, platform generates User Id as [time-based UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_1_(date-time_and_MAC_address). "+
"The newly created User Id will be present in the response. "+
"Specify existing User Id to update the device. "+
"Referencing non-existing User Id will cause 'Not Found' error."+
"\n\nDevice email is unique for entire platform setup.")
@ -188,10 +229,13 @@ public class UserController extends BaseController {
}
}
@ApiOperation(value="Send or re-send the activation email",
notes="Force send the activation email to the user. Useful to resend the email if user has accidentally deleted it. "+SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH)
@ -331,11 +408,16 @@ public class UserController extends BaseController {
}
}
@ApiOperation(value="Enable/Disable User credentials (setUserCredentialsEnabled)",
notes="Enables or Disables user credentials. Useful when you would like to block user account without deleting it. "+PAGE_DATA_PARAMETERS+TENANT_AUTHORITY_PARAGRAPH)
privatestaticfinalStringWIDGET_TYPE_DESCRIPTION="Widget Type represents the template for widget creation. Widget Type and Widget are similar to class and object in OOP theory.";
privatestaticfinalStringWIDGET_TYPE_DETAILS_DESCRIPTION="Widget Type Details extend Widget Type and add image and description properties. "+
"Those properties are useful to edit the Widget Type but they are not required for Dashboard rendering. ";
privatestaticfinalStringWIDGET_TYPE_INFO_DESCRIPTION="Widget Type Info is a lightweight object that represents Widget Type but does not contain the heavyweight widget descriptor JSON";
@ApiOperation(value="Get Widget Type Details (getWidgetTypeById)",
notes="Get the Widget Type Details based on the provided Widget Type Id. "+WIDGET_TYPE_DETAILS_DESCRIPTION+SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH)
@ -61,10 +76,21 @@ public class WidgetTypeController extends BaseController {
}
}
@ApiOperation(value="Create Or Update Widget Type (saveWidgetType)",
notes="Create or update the Widget Type. "+WIDGET_TYPE_DESCRIPTION+" "+
"When creating the Widget Type, platform generates Widget Type Id as [time-based UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_1_(date-time_and_MAC_address). "+
"The newly created Widget Type Id will be present in the response. "+
"Specify existing Widget Type id to update the Widget Type. "+
"Referencing non-existing Widget Type Id will cause 'Not Found' error."+
"\n\nWidget Type alias is unique in the scope of Widget Bundle. "+
"Special Tenant Id '13814000-1dd2-11b2-8080-808080808080' is automatically used if the create request is sent by user with 'SYS_ADMIN' authority."
@ -101,11 +131,15 @@ public class WidgetTypeController extends BaseController {
}
}
@ApiOperation(value="Get all Widget types for specified Bundle (getBundleWidgetTypes)",
notes="Returns an array of Widget Type objects that belong to specified Widget Bundle."+WIDGET_TYPE_DESCRIPTION+" "+SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH)
@ -120,11 +154,15 @@ public class WidgetTypeController extends BaseController {
}
}
@ApiOperation(value="Get all Widget types details for specified Bundle (getBundleWidgetTypes)",
notes="Returns an array of Widget Type Details objects that belong to specified Widget Bundle."+WIDGET_TYPE_DETAILS_DESCRIPTION+" "+SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH)
privatestaticfinalStringWIDGET_BUNDLE_DESCRIPTION="Widget Bundle represents a group(bundle) of widgets. Widgets are grouped into bundle by type or use case. ";
@ -57,10 +77,21 @@ public class WidgetsBundleController extends BaseController {
}
}
@ApiOperation(value="Create Or Update Widget Bundle (saveWidgetsBundle)",
notes="Create or update the Widget Bundle. "+WIDGET_BUNDLE_DESCRIPTION+" "+
"When creating the bundle, platform generates Widget Bundle Id as [time-based UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_1_(date-time_and_MAC_address). "+
"The newly created Widget Bundle Id will be present in the response. "+
"Specify existing Widget Bundle id to update the Widget Bundle. "+
"Referencing non-existing Widget Bundle Id will cause 'Not Found' error."+
"\n\nWidget Bundle alias is unique in the scope of tenant. "+
"Special Tenant Id '13814000-1dd2-11b2-8080-808080808080' is automatically used if the create bundle request is sent by user with 'SYS_ADMIN' authority."
@ -119,6 +162,8 @@ public class WidgetsBundleController extends BaseController {
}
}
@ApiOperation(value="Get all Widget Bundles (getWidgetsBundles)",
notes="Returns an array of Widget Bundle objects that are available for current user."+WIDGET_BUNDLE_DESCRIPTION+" "+AVAILABLE_FOR_ANY_AUTHORIZED_USER)
log.trace("[{}][{}][{}][{}] Received stale subscription update: {}",sessionId,cmdId,subscriptionUpdate.getSubscriptionId(),keyType,subscriptionUpdate);
@ -55,41 +56,7 @@ public abstract class AbstractMqttTimeseriesProtoIntegrationTest extends Abstrac
@Test
publicvoidtestPushTelemetry()throwsException{
super.processBeforeTest("Test Post Telemetry device proto payload","Test Post Telemetry gateway proto payload",TransportPayloadType.PROTOBUF,POST_DATA_TELEMETRY_TOPIC,null);
@ -121,14 +88,7 @@ public abstract class AbstractMqttTimeseriesProtoIntegrationTest extends Abstrac
" }\n"+
"}";
super.processBeforeTest("Test Post Telemetry device proto payload","Test Post Telemetry gateway proto payload",TransportPayloadType.PROTOBUF,POST_DATA_TELEMETRY_TOPIC,null,schemaStr,null,null,null,null,null,DeviceProfileProvisionType.DISABLED);
super.processBeforeTest("Test Post Telemetry device proto payload","Test Post Telemetry gateway proto payload",TransportPayloadType.PROTOBUF,POST_DATA_TELEMETRY_TOPIC,null);
@ -237,14 +190,7 @@ public abstract class AbstractMqttTimeseriesProtoIntegrationTest extends Abstrac
" }\n"+
"}";
super.processBeforeTest("Test Post Telemetry device proto payload","Test Post Telemetry gateway proto payload",TransportPayloadType.PROTOBUF,POST_DATA_TELEMETRY_TOPIC,null,schemaStr,null,null,null,null,null,DeviceProfileProvisionType.DISABLED);
super.processBeforeTest("Test Post Telemetry device proto payload","Test Post Telemetry gateway proto payload",TransportPayloadType.PROTOBUF,POST_DATA_TELEMETRY_TOPIC,null);
super.processBeforeTest("Test Post Telemetry device proto payload","Test Post Telemetry gateway proto payload",TransportPayloadType.PROTOBUF,POST_DATA_TELEMETRY_TOPIC,null);
super.processBeforeTest("Test Post Telemetry device proto payload","Test Post Telemetry gateway proto payload",TransportPayloadType.PROTOBUF,POST_DATA_TELEMETRY_TOPIC,null);
super.processBeforeTest("Test Post Telemetry device proto payload","Test Post Telemetry gateway proto payload",TransportPayloadType.PROTOBUF,null,null,null,null,null,null,null,null,DeviceProfileProvisionType.DISABLED);
@ -310,6 +276,48 @@ public abstract class AbstractMqttTimeseriesProtoIntegrationTest extends Abstrac
@ -76,6 +149,7 @@ public class Customer extends ContactBased<CustomerId> implements HasTenantId {
@Override
@JsonProperty(access=Access.READ_ONLY)
@ApiModelProperty(position=4,value="Name of the customer. Read-only, duplicated from title for backward compatibility",example="Company A",readOnly=true)
@ -86,6 +108,7 @@ public class DashboardInfo extends SearchTextBased<DashboardId> implements HasNa
this.assignedCustomers=assignedCustomers;
}
@ApiModelProperty(position=6,value="Hide dashboard from mobile devices. Useful if the dashboard is not designed for small screens.",readOnly=true)
publicbooleanisMobileHide(){
returnmobileHide;
}
@ -94,6 +117,7 @@ public class DashboardInfo extends SearchTextBased<DashboardId> implements HasNa
this.mobileHide=mobileHide;
}
@ApiModelProperty(position=7,value="Order on mobile devices. Useful to adjust sorting of the dashboards for mobile applications",readOnly=true)
publicIntegergetMobileOrder(){
returnmobileOrder;
}
@ -152,6 +176,7 @@ public class DashboardInfo extends SearchTextBased<DashboardId> implements HasNa
}
}
@ApiModelProperty(position=4,value="Same as title of the dashboard. Read-only field. Update the 'title' to change the 'name' of the dashboard.",readOnly=true)
@ApiModelProperty(position=13,value="Title of the Customer that owns the device.",readOnly=true)
privateStringcustomerTitle;
@ApiModelProperty(position=14,value="Indicates special 'Public' Customer that is auto-generated to use the devices on public dashboards.",readOnly=true)
privatebooleancustomerIsPublic;
@ApiModelProperty(position=15,value="Name of the corresponding Device Profile.",readOnly=true)
@ApiModelProperty(position=12,value="Either URL or Base64 data of the icon. Used in the mobile application to visualize set of device profiles in the grid view. ")
privateStringimage;
privatebooleanisDefault;
@ApiModelProperty(position=16,value="Type of the profile. Always 'DEFAULT' for now. Reserved for future use.")
privateDeviceProfileTypetype;
@ApiModelProperty(position=14,value="Type of the transport used to connect the device. Default transport supports HTTP, CoAP and MQTT.")
@ApiModelProperty(position=7,value="Reference to the rule chain. "+
"If present, the specified rule chain will be used to process all messages related to device, including telemetry, attribute updates, etc. "+
"Otherwise, the root rule chain will be used to process those messages.")
privateRuleChainIddefaultRuleChainId;
@ApiModelProperty(position=6,value="Reference to the dashboard. Used in the mobile application to open the default dashboard when user navigates to device details.")
privateDashboardIddefaultDashboardId;
@NoXss
@ApiModelProperty(position=8,value="Reference to the rule engine queue. "+
"If present, the specified queue will be used to store all unprocessed messages related to device, including telemetry, attribute updates, etc. "+
"Otherwise, the 'Main' queue will be used to store those messages.")
privateStringdefaultQueueName;
@Valid
privatetransientDeviceProfileDataprofileData;
@JsonIgnore
privatebyte[]profileDataBytes;
@NoXss
@ApiModelProperty(position=13,value="Unique provisioning key used by 'Device Provisioning' feature.")
privateStringprovisionDeviceKey;
@ApiModelProperty(position=9,value="Reference to the firmware OTA package. If present, the specified package will be used as default device firmware. ")
privateOtaPackageIdfirmwareId;
@ApiModelProperty(position=10,value="Reference to the software OTA package. If present, the specified package will be used as default device software. ")
privateOtaPackageIdsoftwareId;
publicDeviceProfile(){
@ -88,16 +107,32 @@ public class DeviceProfile extends SearchTextBased<DeviceProfileId> implements H
this.softwareId=deviceProfile.getSoftwareId();
}
@ApiModelProperty(position=1,value="JSON object with the device profile Id. "+
"Specify this field to update the device profile. "+
"Referencing non-existing device profile Id will cause error. "+
"Omit this field to create new device profile.")
@Override
publicDeviceProfileIdgetId(){
returnsuper.getId();
}
@ApiModelProperty(position=2,value="Timestamp of the profile creation, in milliseconds",example="1609459200000",readOnly=true)
@Override
publiclonggetCreatedTime(){
returnsuper.getCreatedTime();
}
@Override
publicStringgetSearchText(){
returngetName();
}
@Override
publicStringgetName(){
returnname;
@ApiModelProperty(position=5,value="Used to mark the default profile. Default profile is used when the device profile is not specified during device creation.")
publicbooleanisDefault(){
returnisDefault;
}
@ApiModelProperty(position=16,value="Complex JSON object that includes addition device profile configuration (transport, alarm rules, etc).")
@ApiModelProperty(position=3,value="Either URL or Base64 data of the icon. Used in the mobile application to visualize set of device profiles in the grid view. ")
privatefinalStringimage;
@ApiModelProperty(position=4,value="Reference to the dashboard. Used in the mobile application to open the default dashboard when user navigates to device details.")
privatefinalDashboardIddefaultDashboardId;
@ApiModelProperty(position=5,value="Type of the profile. Always 'DEFAULT' for now. Reserved for future use.")
privatefinalDeviceProfileTypetype;
@ApiModelProperty(position=6,value="Type of the transport used to connect the device. Default transport supports HTTP, CoAP and MQTT.")
@ApiModelProperty(position=8,required=true,value="Set of telemetry and attribute keys to expose via Entity View.")
privateTelemetryEntityViewkeys;
@ApiModelProperty(position=9,value="Represents the start time of the interval that is used to limit access to target device telemetry. Customer will not be able to see entity telemetry that is outside the specified interval;")
privatelongstartTimeMs;
@ApiModelProperty(position=10,value="Represents the end time of the interval that is used to limit access to target device telemetry. Customer will not be able to see entity telemetry that is outside the specified interval;")
privatelongendTimeMs;
publicEntityView(){
@ -73,6 +81,7 @@ public class EntityView extends SearchTextBasedWithAdditionalInfo<EntityViewId>
returngetName()/*What the ...*/;
}
@ApiModelProperty(position=4,value="JSON object with Customer Id. Use 'assignEntityViewToCustomer' to change the Customer Id.",readOnly=true)
@Override
publicCustomerIdgetCustomerId(){
returncustomerId;
@ -83,8 +92,31 @@ public class EntityView extends SearchTextBasedWithAdditionalInfo<EntityViewId>
returnname;
}
@ApiModelProperty(position=3,value="JSON object with Tenant Id.",readOnly=true)
@Override
publicTenantIdgetTenantId(){
returntenantId;
}
@ApiModelProperty(position=1,value="JSON object with the Entity View Id. "+
"Specify this field to update the Entity View. "+
"Referencing non-existing Entity View Id will cause error. "+
"Omit this field to create new Entity View.")
@Override
publicEntityViewIdgetId(){
returnsuper.getId();
}
@ApiModelProperty(position=2,value="Timestamp of the Entity View creation, in milliseconds",example="1609459200000",readOnly=true)
@Override
publiclonggetCreatedTime(){
returnsuper.getCreatedTime();
}
@ApiModelProperty(position=11,value="Additional parameters of the device",dataType="com.fasterxml.jackson.databind.JsonNode")
@ApiModelProperty(position=12,value="Title of the Customer that owns the entity view.",readOnly=true)
privateStringcustomerTitle;
@ApiModelProperty(position=13,value="Indicates special 'Public' Customer that is auto-generated to use the entity view on public dashboards.",readOnly=true)
@ApiModelProperty(position=10,value="Indicates OTA Package 'has data'. Field is returned from DB ('true' if data exists or url is set). If OTA Package 'has data' is 'false' we can not assign the OTA Package to the Device or Device Profile.",example="true",readOnly=true)