diff --git a/application/src/main/java/org/thingsboard/server/controller/ControllerConstants.java b/application/src/main/java/org/thingsboard/server/controller/ControllerConstants.java
index 1cb794c2ec..7701a19f02 100644
--- a/application/src/main/java/org/thingsboard/server/controller/ControllerConstants.java
+++ b/application/src/main/java/org/thingsboard/server/controller/ControllerConstants.java
@@ -207,45 +207,130 @@ public class ControllerConstants {
protected static final String IS_BOOTSTRAP_SERVER_PARAM_DESCRIPTION = "A Boolean value representing the Server SecurityInfo for future Bootstrap client mode settings. Values: 'true' for Bootstrap Server; 'false' for Lwm2m Server. ";
- protected static final String DEVICE_WITH_DEVICE_CREDENTIALS_PARAM_DESCRIPTION =
+ protected static final String DEVICE_WITH_DEVICE_CREDENTIALS_ACCESS_TOKEN_PARAM_DESCRIPTION =
"{\n" +
" \"device\": {\n" +
- " \"name\": \"LwRpk00000000\",\n" +
- " \"type\": \"lwm2mProfileRpk\"\n" +
- " },\n" +
+ " \"name\":\"Name_DeviceWithCredantial_AccessToken\",\n" +
+ " \"label\":\"Label_DeviceWithCredantial_AccessToken\",\n" +
+ " \"deviceProfileId\":{\n" +
+ " \"id\":\"9d9588c0-06c9-11ee-b618-19be30fdeb60\",\n" +
+ " \"entityType\":\"DEVICE_PROFILE\"\n" +
+ " }\n" +
+ " },\n" +
" \"credentials\": {\n" +
- " \"id\": \"null\",\n" +
- " \"createdTime\": 0,\n" +
- " \"deviceId\": \"null\",\n" +
- " \"credentialsType\": \"LWM2M_CREDENTIALS\",\n" +
- " \"credentialsId\": \"LwRpk00000000\",\n" +
- " \"credentialsValue\": {\n" +
- " \"client\": {\n" +
- " \"endpoint\": \"LwRpk00000000\",\n" +
- " \"securityConfigClientMode\": \"RPK\",\n" +
- " \"key\": \"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEUEBxNl/RcYJNm8mk91CyVXoIJiROYDlXcSSqK6e5bDHwOW4ZiN2lNnXalyF0Jxw8MbAytnDMERXyAja5VEMeVQ==\"\n" +
- " },\n" +
- " \"bootstrap\": {\n" +
- " \"bootstrapServer\": {\n" +
- " \"securityMode\": \"RPK\",\n" +
- " \"clientPublicKeyOrId\": \"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEUEBxNl/RcYJNm8mk91CyVXoIJiROYDlXcSSqK6e5bDHwOW4ZiN2lNnXalyF0Jxw8MbAytnDMERXyAja5VEMeVQ==\",\n" +
- " \"clientSecretKey\": \"MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgd9GAx7yZW37autew5KZykn4IgRpge/tZSjnudnZJnMahRANCAARQQHE2X9Fxgk2byaT3ULJVeggmJE5gOVdxJKorp7lsMfA5bhmI3aU2ddqXIXQnHDwxsDK2cMwRFfICNrlUQx5V\"\n" +
- " },\n" +
- " \"lwm2mServer\": {\n" +
- " \"securityMode\": \"RPK\",\n" +
- " \"clientPublicKeyOrId\": \"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEUEBxNl/RcYJNm8mk91CyVXoIJiROYDlXcSSqK6e5bDHwOW4ZiN2lNnXalyF0Jxw8MbAytnDMERXyAja5VEMeVQ==\",\n" +
- " \"clientSecretKey\": \"MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgd9GAx7yZW37autew5KZykn4IgRpge/tZSjnudnZJnMahRANCAARQQHE2X9Fxgk2byaT3ULJVeggmJE5gOVdxJKorp7lsMfA5bhmI3aU2ddqXIXQnHDwxsDK2cMwRFfICNrlUQx5V\"\n" +
- " }\n" +
- " }\n" +
- " }\n" +
- " }\n" +
+ " \"credentialsType\": \"ACCESS_TOKEN\",\n" +
+ " \"credentialsId\": \"6hmxew8pmmzng4e3une2\"\n" +
+ " }\n" +
"}";
- protected static final String DEVICE_WITH_DEVICE_CREDENTIALS_PARAM_DESCRIPTION_MARKDOWN =
- MARKDOWN_CODE_BLOCK_START + DEVICE_WITH_DEVICE_CREDENTIALS_PARAM_DESCRIPTION + MARKDOWN_CODE_BLOCK_END;
+ protected static final String DEVICE_WITH_DEVICE_CREDENTIALS_ACCESS_TOKEN_DEFAULT_PARAM_DESCRIPTION =
+ "{\n" +
+ " \"device\": {\n" +
+ " \"name\":\"Name_DeviceWithCredantial_AccessToken_Default\",\n" +
+ " \"label\":\"Label_DeviceWithCredantial_AccessToken_Default\",\n" +
+ " \"type\": \"default\"\n" +
+ " },\n" +
+ " \"credentials\": {\n" +
+ " \"credentialsType\": \"ACCESS_TOKEN\",\n" +
+ " \"credentialsId\": \"6hmxew8pmmzng4e3une3\"\n" +
+ " }\n" +
+ "}";
+
+ protected static final String certificateValue = "\"-----BEGIN CERTIFICATE----- " +
+ "MIICMTCCAdegAwIBAgIUI9dBuwN6pTtK6uZ03rkiCwV4wEYwCgYIKoZIzj0EAwIwbjELMAkGA1UEBhMCVVMxETAPBgNVBAgMCE5ldyBZb3JrMRowGAYDVQQKDBFUaGluZ3NCb2FyZCwgSW5jLjEwMC4GA1UEAwwnZGV2aWNlQ2VydGlmaWNhdGVAWDUwOVByb3Zpc2lvblN0cmF0ZWd5MB4XDTIzMDMyOTE0NTYxN1oXDTI0MDMyODE0NTYxN1owbjELMAkGA1UEBhMCVVMxETAPBgNVBAgMCE5ldyBZb3JrMRowGAYDVQQKDBFUaGluZ3NCb2FyZCwgSW5jLjEwMC4GA1UEAwwnZGV2aWNlQ2VydGlmaWNhdGVAWDUwOVByb3Zpc2lvblN0cmF0ZWd5MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE9Zo791qKQiGNBm11r4ZGxh+w+ossZL3xc46ufq5QckQHP7zkD2XDAcmP5GvdkM1sBFN9AWaCkQfNnWmfERsOOKNTMFEwHQYDVR0OBBYEFFFc5uyCyglQoZiKhzXzMcQ3BKORMB8GA1UdIwQYMBaAFFFc5uyCyglQoZiKhzXzMcQ3BKORMA8GA1UdEwEB/wQFMAMBAf8wCgYIKoZIzj0EAwIDSAAwRQIhANbA9CuhoOifZMMmqkpuld+65CR+ItKdXeRAhLMZuccuAiB0FSQB34zMutXrZj1g8Gl5OkE7YryFHbei1z0SveHR8g== " +
+ "-----END CERTIFICATE-----\"";
+
+ protected static final String certificateId = "\"84f5911765abba1f96bf4165604e9e90338fc6214081a8e623b6ff9669aedb27\"";
+
+ protected static final String DEVICE_WITH_DEVICE_CREDENTIALS_X509_CERTIFICATE_PARAM_DESCRIPTION =
+ "{\n" +
+ " \"device\": {\n" +
+ " \"name\":\"Name_DeviceWithCredantial_X509_Certificate\",\n" +
+ " \"label\":\"Label_DeviceWithCredantial_X509_Certificate\",\n" +
+ " \"deviceProfileId\":{\n" +
+ " \"id\":\"9d9588c0-06c9-11ee-b618-19be30fdeb60\",\n" +
+ " \"entityType\":\"DEVICE_PROFILE\"\n" +
+ " }\n" +
+ " },\n" +
+ " \"credentials\": {\n" +
+ " \"credentialsType\": \"X509_CERTIFICATE\",\n" +
+ " \"credentialsId\": " + certificateId + ",\n" +
+ " \"credentialsValue\": " + certificateValue + "\n" +
+ " }\n" +
+ "}";
+
+ protected static final String MQTT_BASIC_VALUE = "\"{\\\"clientId\\\":\\\"5euh5nzm34bjjh1efmlt\\\",\\\"userName\\\":\\\"onasd1lgwasmjl7v2v7h\\\",\\\"password\\\":\\\"b9xtm4ny8kt9zewaga5o\\\"}\"";
+
+ protected static final String DEVICE_WITH_DEVICE_CREDENTIALS_MQTT_BASIC_PARAM_DESCRIPTION =
+ "{\n" +
+ " \"device\": {\n" +
+ " \"name\":\"Name_DeviceWithCredantial_MQTT_Basic\",\n" +
+ " \"label\":\"Label_DeviceWithCredantial_MQTT_Basic\",\n" +
+ " \"deviceProfileId\":{\n" +
+ " \"id\":\"9d9588c0-06c9-11ee-b618-19be30fdeb60\",\n" +
+ " \"entityType\":\"DEVICE_PROFILE\"\n" +
+ " }\n" +
+ " },\n" +
+ " \"credentials\": {\n" +
+ " \"credentialsType\": \"MQTT_BASIC\",\n" +
+ " \"credentialsValue\": " + MQTT_BASIC_VALUE + "\n" +
+ " }\n" +
+ "}";
+
+ protected static final String CREDENTIALS_VALUE_LVM2M_RPK_DESCRIPTION =
+ " \"{" +
+ "\\\"client\\\":{ " +
+ "\\\"endpoint\\\":\\\"LwRpk00000000\\\", " +
+ "\\\"securityConfigClientMode\\\":\\\"RPK\\\", " +
+ "\\\"key\\\":\\\"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEUEBxNl/RcYJNm8mk91CyVXoIJiROYDlXcSSqK6e5bDHwOW4ZiN2lNnXalyF0Jxw8MbAytnDMERXyAja5VEMeVQ==\\\"" +
+ " }, " +
+ "\\\"bootstrap\\\":{ " +
+ "\\\"bootstrapServer\\\":{ " +
+ "\\\"securityMode\\\":\\\"RPK\\\", " +
+ "\\\"clientPublicKeyOrId\\\":\\\"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEUEBxNl/RcYJNm8mk91CyVXoIJiROYDlXcSSqK6e5bDHwOW4ZiN2lNnXalyF0Jxw8MbAytnDMERXyAja5VEMeVQ==\\\", " +
+ "\\\"clientSecretKey\\\":\\\"MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgd9GAx7yZW37autew5KZykn4IgRpge/tZSjnudnZJnMahRANCAARQQHE2X9Fxgk2byaT3ULJVeggmJE5gOVdxJKorp7lsMfA5bhmI3aU2ddqXIXQnHDwxsDK2cMwRFfICNrlUQx5V\\\"" +
+ "}, " +
+ "\\\"lwm2mServer\\\":{ \\\"securityMode\\\":\\\"RPK\\\", " +
+ "\\\"clientPublicKeyOrId\\\":\\\"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEUEBxNl/RcYJNm8mk91CyVXoIJiROYDlXcSSqK6e5bDHwOW4ZiN2lNnXalyF0Jxw8MbAytnDMERXyAja5VEMeVQ==\\\", " +
+ "\\\"clientSecretKey\\\":\\\"MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgd9GAx7yZW37autew5KZykn4IgRpge/tZSjnudnZJnMahRANCAARQQHE2X9Fxgk2byaT3ULJVeggmJE5gOVdxJKorp7lsMfA5bhmI3aU2ddqXIXQnHDwxsDK2cMwRFfICNrlUQx5V\\\"" +
+ "}" +
+ "} " +
+ "}\"";
+
+ protected static final String DEVICE_WITH_DEVICE_CREDENTIALS_PARAM_LVM2M_RPK_DESCRIPTION =
+ "{\n" +
+ " \"device\": {\n" +
+ " \"name\":\"Name_LwRpk00000000\",\n" +
+ " \"label\":\"Label_LwRpk00000000\",\n" +
+ " \"deviceProfileId\":{\n" +
+ " \"id\":\"a660bd50-10ef-11ee-8737-b5634e73c779\",\n" +
+ " \"entityType\":\"DEVICE_PROFILE\"\n" +
+ " }\n" +
+ " },\n" +
+ " \"credentials\": {\n" +
+ " \"credentialsType\": \"LWM2M_CREDENTIALS\",\n" +
+ " \"credentialsId\": \"LwRpk00000000\",\n" +
+ " \"credentialsValue\":\n" + CREDENTIALS_VALUE_LVM2M_RPK_DESCRIPTION + "\n" +
+ " }\n" +
+ "}";
+
+ protected static final String DEVICE_WITH_DEVICE_CREDENTIALS_PARAM_ACCESS_TOKEN_DESCRIPTION_MARKDOWN =
+ MARKDOWN_CODE_BLOCK_START + DEVICE_WITH_DEVICE_CREDENTIALS_ACCESS_TOKEN_PARAM_DESCRIPTION + MARKDOWN_CODE_BLOCK_END;
+
+ protected static final String DEVICE_WITH_DEVICE_CREDENTIALS_PARAM_ACCESS_TOKEN_DEFAULT_DESCRIPTION_MARKDOWN =
+ MARKDOWN_CODE_BLOCK_START + DEVICE_WITH_DEVICE_CREDENTIALS_ACCESS_TOKEN_DEFAULT_PARAM_DESCRIPTION + MARKDOWN_CODE_BLOCK_END;
+
+ protected static final String DEVICE_WITH_DEVICE_CREDENTIALS_PARAM_X509_CERTIFICATE_DESCRIPTION_MARKDOWN =
+ MARKDOWN_CODE_BLOCK_START + DEVICE_WITH_DEVICE_CREDENTIALS_X509_CERTIFICATE_PARAM_DESCRIPTION + MARKDOWN_CODE_BLOCK_END;
+
+ protected static final String DEVICE_WITH_DEVICE_CREDENTIALS_PARAM_MQTT_BASIC_DESCRIPTION_MARKDOWN =
+ MARKDOWN_CODE_BLOCK_START + DEVICE_WITH_DEVICE_CREDENTIALS_MQTT_BASIC_PARAM_DESCRIPTION + MARKDOWN_CODE_BLOCK_END;
+
+ protected static final String DEVICE_WITH_DEVICE_CREDENTIALS_PARAM_LVM2M_RPK_DESCRIPTION_MARKDOWN =
+ MARKDOWN_CODE_BLOCK_START + DEVICE_WITH_DEVICE_CREDENTIALS_PARAM_LVM2M_RPK_DESCRIPTION + MARKDOWN_CODE_BLOCK_END;
- protected static final String FILTER_VALUE_TYPE = NEW_LINE + "## Value Type and Operations" + NEW_LINE +
+ protected static final String FILTER_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 +
@@ -254,7 +339,7 @@ public class ControllerConstants {
" * '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";
- protected static final String DEVICE_PROFILE_ALARM_SCHEDULE_SPECIFIC_TIME_EXAMPLE = MARKDOWN_CODE_BLOCK_START +
+ protected static final String DEVICE_PROFILE_ALARM_SCHEDULE_SPECIFIC_TIME_EXAMPLE = MARKDOWN_CODE_BLOCK_START +
"{\n" +
" \"schedule\":{\n" +
" \"type\":\"SPECIFIC_TIME\",\n" +
@@ -269,7 +354,7 @@ public class ControllerConstants {
" }\n" +
"}" +
MARKDOWN_CODE_BLOCK_END;
- protected static final String DEVICE_PROFILE_ALARM_SCHEDULE_CUSTOM_EXAMPLE = MARKDOWN_CODE_BLOCK_START +
+ protected static final String DEVICE_PROFILE_ALARM_SCHEDULE_CUSTOM_EXAMPLE = MARKDOWN_CODE_BLOCK_START +
"{\n" +
" \"schedule\":{\n" +
" \"type\":\"CUSTOM\",\n" +
@@ -321,9 +406,9 @@ public class ControllerConstants {
" }\n" +
"}" +
MARKDOWN_CODE_BLOCK_END;
- protected static final String DEVICE_PROFILE_ALARM_SCHEDULE_ALWAYS_EXAMPLE = MARKDOWN_CODE_BLOCK_START + "\"schedule\": null" + MARKDOWN_CODE_BLOCK_END;
+ protected static final String DEVICE_PROFILE_ALARM_SCHEDULE_ALWAYS_EXAMPLE = MARKDOWN_CODE_BLOCK_START + "\"schedule\": null" + MARKDOWN_CODE_BLOCK_END;
- protected static final String DEVICE_PROFILE_ALARM_CONDITION_REPEATING_EXAMPLE = MARKDOWN_CODE_BLOCK_START +
+ protected static final String DEVICE_PROFILE_ALARM_CONDITION_REPEATING_EXAMPLE = MARKDOWN_CODE_BLOCK_START +
"{\n" +
" \"spec\":{\n" +
" \"type\":\"REPEATING\",\n" +
@@ -339,7 +424,8 @@ public class ControllerConstants {
" }\n" +
"}" +
MARKDOWN_CODE_BLOCK_END;
- protected static final String DEVICE_PROFILE_ALARM_CONDITION_DURATION_EXAMPLE = MARKDOWN_CODE_BLOCK_START +
+
+ protected static final String DEVICE_PROFILE_ALARM_CONDITION_DURATION_EXAMPLE = MARKDOWN_CODE_BLOCK_START +
"{\n" +
" \"spec\":{\n" +
" \"type\":\"DURATION\",\n" +
diff --git a/application/src/main/java/org/thingsboard/server/controller/DeviceController.java b/application/src/main/java/org/thingsboard/server/controller/DeviceController.java
index bb34f6d5b2..f033b2758f 100644
--- a/application/src/main/java/org/thingsboard/server/controller/DeviceController.java
+++ b/application/src/main/java/org/thingsboard/server/controller/DeviceController.java
@@ -93,7 +93,11 @@ import static org.thingsboard.server.controller.ControllerConstants.DEVICE_PROFI
import static org.thingsboard.server.controller.ControllerConstants.DEVICE_SORT_PROPERTY_ALLOWABLE_VALUES;
import static org.thingsboard.server.controller.ControllerConstants.DEVICE_TEXT_SEARCH_DESCRIPTION;
import static org.thingsboard.server.controller.ControllerConstants.DEVICE_TYPE_DESCRIPTION;
-import static org.thingsboard.server.controller.ControllerConstants.DEVICE_WITH_DEVICE_CREDENTIALS_PARAM_DESCRIPTION_MARKDOWN;
+import static org.thingsboard.server.controller.ControllerConstants.DEVICE_WITH_DEVICE_CREDENTIALS_PARAM_ACCESS_TOKEN_DEFAULT_DESCRIPTION_MARKDOWN;
+import static org.thingsboard.server.controller.ControllerConstants.DEVICE_WITH_DEVICE_CREDENTIALS_PARAM_ACCESS_TOKEN_DESCRIPTION_MARKDOWN;
+import static org.thingsboard.server.controller.ControllerConstants.DEVICE_WITH_DEVICE_CREDENTIALS_PARAM_LVM2M_RPK_DESCRIPTION_MARKDOWN;
+import static org.thingsboard.server.controller.ControllerConstants.DEVICE_WITH_DEVICE_CREDENTIALS_PARAM_MQTT_BASIC_DESCRIPTION_MARKDOWN;
+import static org.thingsboard.server.controller.ControllerConstants.DEVICE_WITH_DEVICE_CREDENTIALS_PARAM_X509_CERTIFICATE_DESCRIPTION_MARKDOWN;
import static org.thingsboard.server.controller.ControllerConstants.EDGE_ASSIGN_ASYNC_FIRST_STEP_DESCRIPTION;
import static org.thingsboard.server.controller.ControllerConstants.EDGE_ASSIGN_RECEIVE_STEP_DESCRIPTION;
import static org.thingsboard.server.controller.ControllerConstants.EDGE_ID_PARAM_DESCRIPTION;
@@ -182,9 +186,20 @@ public class DeviceController extends BaseController {
@ApiOperation(value = "Create Device (saveDevice) with credentials ",
notes = "Create or update the Device. When creating device, platform generates Device Id as " + UUID_WIKI_LINK +
- "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" +
- DEVICE_WITH_DEVICE_CREDENTIALS_PARAM_DESCRIPTION_MARKDOWN +
+ "Requires to provide the Device Credentials object as well as an existing device profile ID or use \"default\".\n" +
+ "You may find the example of device with different type of credentials below: \n\n" +
+ "- Credentials type: \"Access token\" with device profile ID below: \n\n" +
+ DEVICE_WITH_DEVICE_CREDENTIALS_PARAM_ACCESS_TOKEN_DESCRIPTION_MARKDOWN + "\n\n" +
+ "- Credentials type: \"Access token\" with device profile default below: \n\n" +
+ DEVICE_WITH_DEVICE_CREDENTIALS_PARAM_ACCESS_TOKEN_DEFAULT_DESCRIPTION_MARKDOWN + "\n\n" +
+ "- Credentials type: \"X509\" with device profile ID below: \n\n" +
+ "Note: credentialsId - format Sha3Hash, certificateValue - format PEM (with \"--BEGIN CERTIFICATE----\" and -\"----END CERTIFICATE-\").\n\n" +
+ DEVICE_WITH_DEVICE_CREDENTIALS_PARAM_X509_CERTIFICATE_DESCRIPTION_MARKDOWN + "\n\n" +
+ "- Credentials type: \"MQTT_BASIC\" with device profile ID below: \n\n" +
+ DEVICE_WITH_DEVICE_CREDENTIALS_PARAM_MQTT_BASIC_DESCRIPTION_MARKDOWN + "\n\n" +
+ "- You may find the example of LwM2M device and RPK credentials below: \n\n" +
+ "Note: LwM2M device - only existing device profile ID (Transport configuration -> Transport type: \"LWM2M\".\n\n" +
+ DEVICE_WITH_DEVICE_CREDENTIALS_PARAM_LVM2M_RPK_DESCRIPTION_MARKDOWN + "\n\n" +
"Remove 'id', 'tenantId' and optionally 'customerId' from the request body example (below) to create new Device entity. " +
TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH)
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")