Commit 2704696f2bc6a1abdf55176ddc8183c4655df8c2

Authored by zbeacon
1 parent 950907d3

Moved provisionDeviceKey as regular column

Showing 27 changed files with 189 additions and 85 deletions
@@ -20,13 +20,16 @@ CREATE TABLE IF NOT EXISTS device_profile ( @@ -20,13 +20,16 @@ CREATE TABLE IF NOT EXISTS device_profile (
20 name varchar(255), 20 name varchar(255),
21 type varchar(255), 21 type varchar(255),
22 transport_type varchar(255), 22 transport_type varchar(255),
  23 + provision_type varchar(255),
23 profile_data jsonb, 24 profile_data jsonb,
24 description varchar, 25 description varchar,
25 search_text varchar(255), 26 search_text varchar(255),
26 is_default boolean, 27 is_default boolean,
27 tenant_id uuid, 28 tenant_id uuid,
28 default_rule_chain_id uuid, 29 default_rule_chain_id uuid,
  30 + provision_device_key varchar,
29 CONSTRAINT device_profile_name_unq_key UNIQUE (tenant_id, name), 31 CONSTRAINT device_profile_name_unq_key UNIQUE (tenant_id, name),
  32 + CONSTRAINT device_provision_key_unq_key UNIQUE (provision_device_key),
30 CONSTRAINT fk_default_rule_chain_device_profile FOREIGN KEY (default_rule_chain_id) REFERENCES rule_chain(id) 33 CONSTRAINT fk_default_rule_chain_device_profile FOREIGN KEY (default_rule_chain_id) REFERENCES rule_chain(id)
31 ); 34 );
32 35
@@ -27,10 +27,8 @@ import org.springframework.util.StringUtils; @@ -27,10 +27,8 @@ import org.springframework.util.StringUtils;
27 import org.thingsboard.server.common.data.DataConstants; 27 import org.thingsboard.server.common.data.DataConstants;
28 import org.thingsboard.server.common.data.Device; 28 import org.thingsboard.server.common.data.Device;
29 import org.thingsboard.server.common.data.DeviceProfile; 29 import org.thingsboard.server.common.data.DeviceProfile;
30 -import org.thingsboard.server.common.data.DeviceProfileType; 30 +import org.thingsboard.server.common.data.DeviceProfileProvisionType;
31 import org.thingsboard.server.common.data.audit.ActionType; 31 import org.thingsboard.server.common.data.audit.ActionType;
32 -import org.thingsboard.server.common.data.device.profile.ProvisionDeviceProfileConfiguration;  
33 -import org.thingsboard.server.common.data.device.profile.ProvisionRequestValidationStrategyType;  
34 import org.thingsboard.server.common.data.id.CustomerId; 32 import org.thingsboard.server.common.data.id.CustomerId;
35 import org.thingsboard.server.common.data.id.TenantId; 33 import org.thingsboard.server.common.data.id.TenantId;
36 import org.thingsboard.server.common.data.id.UserId; 34 import org.thingsboard.server.common.data.id.UserId;
@@ -117,21 +115,18 @@ public class DeviceProvisionServiceImpl implements DeviceProvisionService { @@ -117,21 +115,18 @@ public class DeviceProvisionServiceImpl implements DeviceProvisionService {
117 return Futures.immediateFuture(new ProvisionResponse(null, ProvisionResponseStatus.NOT_FOUND)); 115 return Futures.immediateFuture(new ProvisionResponse(null, ProvisionResponseStatus.NOT_FOUND));
118 } 116 }
119 117
120 - DeviceProfile targetProfile = deviceProfileDao.findProfileByProfileNameAndProfileDataProvisionConfigurationPair(  
121 - provisionRequest.getDeviceType(),  
122 - provisionRequestKey,  
123 - provisionRequestSecret); 118 + DeviceProfile targetProfile = deviceProfileDao.findByProvisionDeviceKeyAndProvisionDeviceSecret(provisionRequestKey, provisionRequestSecret);
124 119
125 - if (targetProfile == null || targetProfile.getProfileData().getConfiguration().getType() != DeviceProfileType.PROVISION) { 120 + if (targetProfile == null ||
  121 + !(targetProfile.getProvisionType() != DeviceProfileProvisionType.ALLOW_CREATE_NEW_DEVICES ||
  122 + targetProfile.getProvisionType() != DeviceProfileProvisionType.CHECK_PRE_PROVISIONED_DEVICES)) {
126 return Futures.immediateFuture(new ProvisionResponse(null, ProvisionResponseStatus.NOT_FOUND)); 123 return Futures.immediateFuture(new ProvisionResponse(null, ProvisionResponseStatus.NOT_FOUND));
127 } 124 }
128 125
129 - ProvisionRequestValidationStrategyType validationStrategy = getStrategy(targetProfile);  
130 -  
131 Device targetDevice = deviceDao.findDeviceByTenantIdAndName(targetProfile.getTenantId().getId(), provisionRequest.getDeviceName()).orElse(null); 126 Device targetDevice = deviceDao.findDeviceByTenantIdAndName(targetProfile.getTenantId().getId(), provisionRequest.getDeviceName()).orElse(null);
132 127
133 - switch(validationStrategy) {  
134 - case CHECK_NEW_DEVICE: 128 + switch(targetProfile.getProvisionType()) {
  129 + case ALLOW_CREATE_NEW_DEVICES:
135 if (targetDevice != null) { 130 if (targetDevice != null) {
136 log.warn("[{}] The device is present and could not be provisioned once more!", targetDevice.getName()); 131 log.warn("[{}] The device is present and could not be provisioned once more!", targetDevice.getName());
137 notify(targetDevice, provisionRequest, DataConstants.PROVISION_FAILURE, false); 132 notify(targetDevice, provisionRequest, DataConstants.PROVISION_FAILURE, false);
@@ -139,15 +134,15 @@ public class DeviceProvisionServiceImpl implements DeviceProvisionService { @@ -139,15 +134,15 @@ public class DeviceProvisionServiceImpl implements DeviceProvisionService {
139 } else { 134 } else {
140 return createDevice(provisionRequest, targetProfile); 135 return createDevice(provisionRequest, targetProfile);
141 } 136 }
142 - case CHECK_PRE_PROVISIONED_DEVICE:  
143 - if (targetDevice != null){ 137 + case CHECK_PRE_PROVISIONED_DEVICES:
  138 + if (targetDevice != null && targetDevice.getDeviceProfileId().equals(targetProfile.getId())){
144 return processProvision(targetDevice, provisionRequest); 139 return processProvision(targetDevice, provisionRequest);
145 } else { 140 } else {
146 log.warn("[{}] Failed to find pre provisioned device!", provisionRequest.getDeviceName()); 141 log.warn("[{}] Failed to find pre provisioned device!", provisionRequest.getDeviceName());
147 return Futures.immediateFuture(new ProvisionResponse(null, ProvisionResponseStatus.FAILURE)); 142 return Futures.immediateFuture(new ProvisionResponse(null, ProvisionResponseStatus.FAILURE));
148 } 143 }
149 default: 144 default:
150 - throw new RuntimeException("Strategy is not supported - " + validationStrategy.name()); 145 + throw new RuntimeException("Strategy is not supported - " + targetProfile.getProvisionType().name());
151 } 146 }
152 } 147 }
153 148
@@ -193,11 +188,6 @@ public class DeviceProvisionServiceImpl implements DeviceProvisionService { @@ -193,11 +188,6 @@ public class DeviceProvisionServiceImpl implements DeviceProvisionService {
193 logAction(device.getTenantId(), device.getCustomerId(), device, success, provisionRequest); 188 logAction(device.getTenantId(), device.getCustomerId(), device, success, provisionRequest);
194 } 189 }
195 190
196 - private ProvisionRequestValidationStrategyType getStrategy(DeviceProfile profile) {  
197 - return ((ProvisionDeviceProfileConfiguration) profile.getProfileData().getConfiguration()).getStrategy();  
198 -  
199 - }  
200 -  
201 private ListenableFuture<ProvisionResponse> processCreateDevice(ProvisionRequest provisionRequest, DeviceProfile profile) { 191 private ListenableFuture<ProvisionResponse> processCreateDevice(ProvisionRequest provisionRequest, DeviceProfile profile) {
202 Device device = deviceService.findDeviceByTenantIdAndName(profile.getTenantId(), provisionRequest.getDeviceName()); 192 Device device = deviceService.findDeviceByTenantIdAndName(profile.getTenantId(), provisionRequest.getDeviceName());
203 if (device == null) { 193 if (device == null) {
@@ -226,7 +216,7 @@ public class DeviceProvisionServiceImpl implements DeviceProvisionService { @@ -226,7 +216,7 @@ public class DeviceProvisionServiceImpl implements DeviceProvisionService {
226 private Device saveDevice(ProvisionRequest provisionRequest, DeviceProfile profile) { 216 private Device saveDevice(ProvisionRequest provisionRequest, DeviceProfile profile) {
227 Device device = new Device(); 217 Device device = new Device();
228 device.setName(provisionRequest.getDeviceName()); 218 device.setName(provisionRequest.getDeviceName());
229 - device.setType(provisionRequest.getDeviceType()); 219 + device.setType(profile.getName());
230 device.setTenantId(profile.getTenantId()); 220 device.setTenantId(profile.getTenantId());
231 return deviceService.saveDevice(device); 221 return deviceService.saveDevice(device);
232 } 222 }
@@ -30,7 +30,7 @@ import org.thingsboard.server.common.data.Device; @@ -30,7 +30,7 @@ import org.thingsboard.server.common.data.Device;
30 import org.thingsboard.server.common.data.DeviceProfile; 30 import org.thingsboard.server.common.data.DeviceProfile;
31 import org.thingsboard.server.common.data.TenantProfile; 31 import org.thingsboard.server.common.data.TenantProfile;
32 import org.thingsboard.server.common.data.device.credentials.BasicMqttCredentials; 32 import org.thingsboard.server.common.data.device.credentials.BasicMqttCredentials;
33 -import org.thingsboard.server.common.data.device.profile.ProvisionDeviceProfileConfiguration; 33 +import org.thingsboard.server.common.data.device.profile.ProvisionDeviceProfileCredentials;
34 import org.thingsboard.server.common.data.id.CustomerId; 34 import org.thingsboard.server.common.data.id.CustomerId;
35 import org.thingsboard.server.common.data.id.DeviceId; 35 import org.thingsboard.server.common.data.id.DeviceId;
36 import org.thingsboard.server.common.data.id.DeviceProfileId; 36 import org.thingsboard.server.common.data.id.DeviceProfileId;
@@ -279,9 +279,8 @@ public class DefaultTransportApiService implements TransportApiService { @@ -279,9 +279,8 @@ public class DefaultTransportApiService implements TransportApiService {
279 provisionResponseFuture = deviceProvisionService.provisionDevice( 279 provisionResponseFuture = deviceProvisionService.provisionDevice(
280 new ProvisionRequest( 280 new ProvisionRequest(
281 requestMsg.getDeviceName(), 281 requestMsg.getDeviceName(),
282 - requestMsg.getDeviceType(),  
283 requestMsg.getX509CertPubKey(), 282 requestMsg.getX509CertPubKey(),
284 - new ProvisionDeviceProfileConfiguration( 283 + new ProvisionDeviceProfileCredentials(
285 requestMsg.getProvisionDeviceCredentialsMsg().getProvisionDeviceKey(), 284 requestMsg.getProvisionDeviceCredentialsMsg().getProvisionDeviceKey(),
286 requestMsg.getProvisionDeviceCredentialsMsg().getProvisionDeviceSecret()))); 285 requestMsg.getProvisionDeviceCredentialsMsg().getProvisionDeviceSecret())));
287 return Futures.transform(provisionResponseFuture, provisionResponse -> { 286 return Futures.transform(provisionResponseFuture, provisionResponse -> {
@@ -68,6 +68,7 @@ import org.thingsboard.server.common.data.User; @@ -68,6 +68,7 @@ import org.thingsboard.server.common.data.User;
68 import org.thingsboard.server.common.data.device.profile.DefaultDeviceProfileConfiguration; 68 import org.thingsboard.server.common.data.device.profile.DefaultDeviceProfileConfiguration;
69 import org.thingsboard.server.common.data.device.profile.DefaultDeviceProfileTransportConfiguration; 69 import org.thingsboard.server.common.data.device.profile.DefaultDeviceProfileTransportConfiguration;
70 import org.thingsboard.server.common.data.device.profile.DeviceProfileData; 70 import org.thingsboard.server.common.data.device.profile.DeviceProfileData;
  71 +import org.thingsboard.server.common.data.device.profile.ProvisionDeviceProfileCredentials;
71 import org.thingsboard.server.common.data.id.HasId; 72 import org.thingsboard.server.common.data.id.HasId;
72 import org.thingsboard.server.common.data.id.RuleChainId; 73 import org.thingsboard.server.common.data.id.RuleChainId;
73 import org.thingsboard.server.common.data.id.TenantId; 74 import org.thingsboard.server.common.data.id.TenantId;
@@ -28,6 +28,7 @@ import org.thingsboard.server.common.data.DeviceProfileType; @@ -28,6 +28,7 @@ import org.thingsboard.server.common.data.DeviceProfileType;
28 import org.thingsboard.server.common.data.DeviceTransportType; 28 import org.thingsboard.server.common.data.DeviceTransportType;
29 import org.thingsboard.server.common.data.Tenant; 29 import org.thingsboard.server.common.data.Tenant;
30 import org.thingsboard.server.common.data.User; 30 import org.thingsboard.server.common.data.User;
  31 +import org.thingsboard.server.common.data.device.profile.ProvisionDeviceProfileCredentials;
31 import org.thingsboard.server.common.data.page.PageData; 32 import org.thingsboard.server.common.data.page.PageData;
32 import org.thingsboard.server.common.data.page.PageLink; 33 import org.thingsboard.server.common.data.page.PageLink;
33 import org.thingsboard.server.common.data.security.Authority; 34 import org.thingsboard.server.common.data.security.Authority;
@@ -153,6 +154,17 @@ public abstract class BaseDeviceProfileControllerTest extends AbstractController @@ -153,6 +154,17 @@ public abstract class BaseDeviceProfileControllerTest extends AbstractController
153 .andExpect(statusReason(containsString("Device profile with such name already exists"))); 154 .andExpect(statusReason(containsString("Device profile with such name already exists")));
154 } 155 }
155 156
  157 + @Test
  158 + public void testSaveDeviceProfileWithSameProvisionDeviceKey() throws Exception {
  159 + DeviceProfile deviceProfile = this.createDeviceProfile("Device Profile");
  160 + deviceProfile.setProvisionDeviceKey("testProvisionDeviceKey");
  161 + doPost("/api/deviceProfile", deviceProfile).andExpect(status().isOk());
  162 + DeviceProfile deviceProfile2 = this.createDeviceProfile("Device Profile 2");
  163 + deviceProfile2.setProvisionDeviceKey("testProvisionDeviceKey");
  164 + doPost("/api/deviceProfile", deviceProfile2).andExpect(status().isBadRequest())
  165 + .andExpect(statusReason(containsString("Device profile with such provision device key already exists")));
  166 + }
  167 +
156 @Ignore 168 @Ignore
157 @Test 169 @Test
158 public void testChangeDeviceProfileTypeWithExistingDevices() throws Exception { 170 public void testChangeDeviceProfileTypeWithExistingDevices() throws Exception {
@@ -17,13 +17,12 @@ package org.thingsboard.server.dao.device.provision; @@ -17,13 +17,12 @@ package org.thingsboard.server.dao.device.provision;
17 17
18 import lombok.AllArgsConstructor; 18 import lombok.AllArgsConstructor;
19 import lombok.Data; 19 import lombok.Data;
20 -import org.thingsboard.server.common.data.device.profile.ProvisionDeviceProfileConfiguration; 20 +import org.thingsboard.server.common.data.device.profile.ProvisionDeviceProfileCredentials;
21 21
22 @Data 22 @Data
23 @AllArgsConstructor 23 @AllArgsConstructor
24 public class ProvisionRequest { 24 public class ProvisionRequest {
25 private String deviceName; 25 private String deviceName;
26 - private String deviceType;  
27 private String x509CertPubKey; 26 private String x509CertPubKey;
28 - private ProvisionDeviceProfileConfiguration credentials; 27 + private ProvisionDeviceProfileCredentials credentials;
29 } 28 }
@@ -41,10 +41,12 @@ public class DeviceProfile extends SearchTextBased<DeviceProfileId> implements H @@ -41,10 +41,12 @@ public class DeviceProfile extends SearchTextBased<DeviceProfileId> implements H
41 private boolean isDefault; 41 private boolean isDefault;
42 private DeviceProfileType type; 42 private DeviceProfileType type;
43 private DeviceTransportType transportType; 43 private DeviceTransportType transportType;
  44 + private DeviceProfileProvisionType provisionType;
44 private RuleChainId defaultRuleChainId; 45 private RuleChainId defaultRuleChainId;
45 private transient DeviceProfileData profileData; 46 private transient DeviceProfileData profileData;
46 @JsonIgnore 47 @JsonIgnore
47 private byte[] profileDataBytes; 48 private byte[] profileDataBytes;
  49 + private String provisionDeviceKey;
48 50
49 public DeviceProfile() { 51 public DeviceProfile() {
50 super(); 52 super();
@@ -62,6 +64,7 @@ public class DeviceProfile extends SearchTextBased<DeviceProfileId> implements H @@ -62,6 +64,7 @@ public class DeviceProfile extends SearchTextBased<DeviceProfileId> implements H
62 this.isDefault = deviceProfile.isDefault(); 64 this.isDefault = deviceProfile.isDefault();
63 this.defaultRuleChainId = deviceProfile.getDefaultRuleChainId(); 65 this.defaultRuleChainId = deviceProfile.getDefaultRuleChainId();
64 this.setProfileData(deviceProfile.getProfileData()); 66 this.setProfileData(deviceProfile.getProfileData());
  67 + this.provisionDeviceKey = deviceProfile.getProvisionDeviceKey();
65 } 68 }
66 69
67 @Override 70 @Override
common/data/src/main/java/org/thingsboard/server/common/data/DeviceProfileProvisionType.java renamed from common/data/src/main/java/org/thingsboard/server/common/data/device/profile/ProvisionRequestValidationStrategyType.java
@@ -13,8 +13,10 @@ @@ -13,8 +13,10 @@
13 * See the License for the specific language governing permissions and 13 * See the License for the specific language governing permissions and
14 * limitations under the License. 14 * limitations under the License.
15 */ 15 */
16 -package org.thingsboard.server.common.data.device.profile; 16 +package org.thingsboard.server.common.data;
17 17
18 -public enum ProvisionRequestValidationStrategyType {  
19 - CHECK_NEW_DEVICE, CHECK_PRE_PROVISIONED_DEVICE 18 +public enum DeviceProfileProvisionType {
  19 + DISABLED,
  20 + ALLOW_CREATE_NEW_DEVICES,
  21 + CHECK_PRE_PROVISIONED_DEVICES
20 } 22 }
@@ -16,6 +16,5 @@ @@ -16,6 +16,5 @@
16 package org.thingsboard.server.common.data; 16 package org.thingsboard.server.common.data;
17 17
18 public enum DeviceProfileType { 18 public enum DeviceProfileType {
19 - DEFAULT,  
20 - PROVISION 19 + DEFAULT
21 } 20 }
@@ -27,8 +27,7 @@ import org.thingsboard.server.common.data.DeviceProfileType; @@ -27,8 +27,7 @@ import org.thingsboard.server.common.data.DeviceProfileType;
27 include = JsonTypeInfo.As.PROPERTY, 27 include = JsonTypeInfo.As.PROPERTY,
28 property = "type") 28 property = "type")
29 @JsonSubTypes({ 29 @JsonSubTypes({
30 - @JsonSubTypes.Type(value = DefaultDeviceConfiguration.class, name = "DEFAULT"),  
31 - @JsonSubTypes.Type(value = DefaultDeviceConfiguration.class, name = "PROVISION")}) 30 + @JsonSubTypes.Type(value = DefaultDeviceConfiguration.class, name = "DEFAULT")})
32 public interface DeviceConfiguration { 31 public interface DeviceConfiguration {
33 32
34 @JsonIgnore 33 @JsonIgnore
  1 +/**
  2 + * Copyright © 2016-2020 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.common.data.device.profile;
  17 +
  18 +import lombok.Data;
  19 +import org.thingsboard.server.common.data.DeviceProfileProvisionType;
  20 +
  21 +@Data
  22 +public class AllowCreateNewDevicesDeviceProfileProvisionConfiguration implements DeviceProfileProvisionConfiguration {
  23 +
  24 + private final String provisionDeviceSecret;
  25 +
  26 + @Override
  27 + public DeviceProfileProvisionType getType() {
  28 + return DeviceProfileProvisionType.ALLOW_CREATE_NEW_DEVICES;
  29 + }
  30 +
  31 +}
common/data/src/main/java/org/thingsboard/server/common/data/device/profile/CheckPreProvisionedDevicesDeviceProfileProvisionConfiguration.java renamed from common/data/src/main/java/org/thingsboard/server/common/data/device/profile/ProvisionDeviceProfileConfiguration.java
@@ -15,43 +15,17 @@ @@ -15,43 +15,17 @@
15 */ 15 */
16 package org.thingsboard.server.common.data.device.profile; 16 package org.thingsboard.server.common.data.device.profile;
17 17
18 -import com.fasterxml.jackson.annotation.JsonCreator;  
19 -import com.fasterxml.jackson.annotation.JsonProperty;  
20 import lombok.Data; 18 import lombok.Data;
21 -import org.thingsboard.server.common.data.DeviceProfileType;  
22 -  
23 -import java.util.Objects; 19 +import org.thingsboard.server.common.data.DeviceProfileProvisionType;
24 20
25 @Data 21 @Data
26 -public class ProvisionDeviceProfileConfiguration implements DeviceProfileConfiguration {  
27 -  
28 - private String provisionDeviceKey;  
29 - private String provisionDeviceSecret; 22 +public class CheckPreProvisionedDevicesDeviceProfileProvisionConfiguration implements DeviceProfileProvisionConfiguration {
30 23
31 - private ProvisionRequestValidationStrategyType strategy; 24 + private final String provisionDeviceSecret;
32 25
33 @Override 26 @Override
34 - public DeviceProfileType getType() {  
35 - return DeviceProfileType.PROVISION; 27 + public DeviceProfileProvisionType getType() {
  28 + return DeviceProfileProvisionType.CHECK_PRE_PROVISIONED_DEVICES;
36 } 29 }
37 30
38 - @JsonCreator  
39 - public ProvisionDeviceProfileConfiguration(@JsonProperty("provisionDeviceKey") String provisionProfileKey, @JsonProperty("provisionDeviceSecret") String provisionProfileSecret) {  
40 - this.provisionDeviceKey = provisionProfileKey;  
41 - this.provisionDeviceSecret = provisionProfileSecret;  
42 - }  
43 -  
44 - @Override  
45 - public boolean equals(Object o) {  
46 - if (this == o) return true;  
47 - if (o == null || getClass() != o.getClass()) return false;  
48 - ProvisionDeviceProfileConfiguration that = (ProvisionDeviceProfileConfiguration) o;  
49 - return provisionDeviceKey.equals(that.provisionDeviceKey) &&  
50 - provisionDeviceSecret.equals(that.provisionDeviceSecret);  
51 - }  
52 -  
53 - @Override  
54 - public int hashCode() {  
55 - return Objects.hash(provisionDeviceKey, provisionDeviceSecret);  
56 - }  
57 } 31 }
@@ -27,8 +27,7 @@ import org.thingsboard.server.common.data.DeviceProfileType; @@ -27,8 +27,7 @@ import org.thingsboard.server.common.data.DeviceProfileType;
27 include = JsonTypeInfo.As.PROPERTY, 27 include = JsonTypeInfo.As.PROPERTY,
28 property = "type") 28 property = "type")
29 @JsonSubTypes({ 29 @JsonSubTypes({
30 - @JsonSubTypes.Type(value = DefaultDeviceProfileConfiguration.class, name = "DEFAULT"),  
31 - @JsonSubTypes.Type(value = ProvisionDeviceProfileConfiguration.class, name = "PROVISION")}) 30 + @JsonSubTypes.Type(value = DefaultDeviceProfileConfiguration.class, name = "DEFAULT")})
32 public interface DeviceProfileConfiguration { 31 public interface DeviceProfileConfiguration {
33 32
34 @JsonIgnore 33 @JsonIgnore
@@ -24,6 +24,7 @@ public class DeviceProfileData { @@ -24,6 +24,7 @@ public class DeviceProfileData {
24 24
25 private DeviceProfileConfiguration configuration; 25 private DeviceProfileConfiguration configuration;
26 private DeviceProfileTransportConfiguration transportConfiguration; 26 private DeviceProfileTransportConfiguration transportConfiguration;
  27 + private DeviceProfileProvisionConfiguration provisionConfiguration;
27 private List<DeviceProfileAlarm> alarms; 28 private List<DeviceProfileAlarm> alarms;
28 29
29 } 30 }
  1 +/**
  2 + * Copyright © 2016-2020 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.common.data.device.profile;
  17 +
  18 +import com.fasterxml.jackson.annotation.JsonIgnore;
  19 +import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
  20 +import com.fasterxml.jackson.annotation.JsonSubTypes;
  21 +import com.fasterxml.jackson.annotation.JsonTypeInfo;
  22 +import org.thingsboard.server.common.data.DeviceProfileProvisionType;
  23 +
  24 +
  25 +@JsonIgnoreProperties(ignoreUnknown = true)
  26 +@JsonTypeInfo(
  27 + use = JsonTypeInfo.Id.NAME,
  28 + include = JsonTypeInfo.As.PROPERTY,
  29 + property = "type")
  30 +@JsonSubTypes({
  31 + @JsonSubTypes.Type(value = DisabledDeviceProfileProvisionConfiguration.class, name = "DISABLED"),
  32 + @JsonSubTypes.Type(value = AllowCreateNewDevicesDeviceProfileProvisionConfiguration.class, name = "ALLOW_CREATE_NEW_DEVICES"),
  33 + @JsonSubTypes.Type(value = CheckPreProvisionedDevicesDeviceProfileProvisionConfiguration.class, name = "CHECK_PRE_PROVISIONED_DEVICES")})
  34 +public interface DeviceProfileProvisionConfiguration {
  35 +
  36 + @JsonIgnore
  37 + DeviceProfileProvisionType getType();
  38 +
  39 +}
  1 +/**
  2 + * Copyright © 2016-2020 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.common.data.device.profile;
  17 +
  18 +import lombok.Data;
  19 +import org.thingsboard.server.common.data.DeviceProfileProvisionType;
  20 +
  21 +@Data
  22 +public class DisabledDeviceProfileProvisionConfiguration implements DeviceProfileProvisionConfiguration {
  23 +
  24 + private final String provisionDeviceSecret;
  25 +
  26 + @Override
  27 + public DeviceProfileProvisionType getType() {
  28 + return DeviceProfileProvisionType.DISABLED;
  29 + }
  30 +
  31 +}
common/data/src/main/java/org/thingsboard/server/common/data/device/profile/ProvisionDeviceProfileCredentials.java renamed from common/data/src/main/java/org/thingsboard/server/common/data/device/profile/ProvisionRequestValidationStrategy.java
@@ -18,6 +18,7 @@ package org.thingsboard.server.common.data.device.profile; @@ -18,6 +18,7 @@ package org.thingsboard.server.common.data.device.profile;
18 import lombok.Data; 18 import lombok.Data;
19 19
20 @Data 20 @Data
21 -public class ProvisionRequestValidationStrategy {  
22 - private final ProvisionRequestValidationStrategyType validationStrategyType; 21 +public class ProvisionDeviceProfileCredentials {
  22 + private final String provisionDeviceKey;
  23 + private final String provisionDeviceSecret;
23 } 24 }
@@ -256,9 +256,8 @@ message DeviceCredentialsProto { @@ -256,9 +256,8 @@ message DeviceCredentialsProto {
256 256
257 message ProvisionDeviceRequestMsg { 257 message ProvisionDeviceRequestMsg {
258 string deviceName = 1; 258 string deviceName = 1;
259 - string deviceType = 2;  
260 - string x509CertPubKey = 3;  
261 - ProvisionDeviceCredentialsMsg provisionDeviceCredentialsMsg = 4; 259 + string x509CertPubKey = 2;
  260 + ProvisionDeviceCredentialsMsg provisionDeviceCredentialsMsg = 3;
262 } 261 }
263 262
264 message ProvisionDeviceCredentialsMsg { 263 message ProvisionDeviceCredentialsMsg {
@@ -543,7 +543,6 @@ public class JsonConverter { @@ -543,7 +543,6 @@ public class JsonConverter {
543 private static TransportProtos.ProvisionDeviceRequestMsg buildProvisionRequestMsg(JsonObject jo) { 543 private static TransportProtos.ProvisionDeviceRequestMsg buildProvisionRequestMsg(JsonObject jo) {
544 return TransportProtos.ProvisionDeviceRequestMsg.newBuilder() 544 return TransportProtos.ProvisionDeviceRequestMsg.newBuilder()
545 .setDeviceName(getStrValue(jo, DataConstants.DEVICE_NAME, true)) 545 .setDeviceName(getStrValue(jo, DataConstants.DEVICE_NAME, true))
546 - .setDeviceType(getStrValue(jo, DataConstants.DEVICE_TYPE, true))  
547 .setX509CertPubKey(getStrValue(jo, DataConstants.CERT_PUB_KEY, false)) 546 .setX509CertPubKey(getStrValue(jo, DataConstants.CERT_PUB_KEY, false))
548 .setProvisionDeviceCredentialsMsg(buildProvisionDeviceCredentialsMsg( 547 .setProvisionDeviceCredentialsMsg(buildProvisionDeviceCredentialsMsg(
549 getStrValue(jo, DataConstants.PROVISION_KEY, true), 548 getStrValue(jo, DataConstants.PROVISION_KEY, true),
@@ -38,7 +38,7 @@ public interface DeviceProfileDao extends Dao<DeviceProfile> { @@ -38,7 +38,7 @@ public interface DeviceProfileDao extends Dao<DeviceProfile> {
38 38
39 DeviceProfileInfo findDefaultDeviceProfileInfo(TenantId tenantId); 39 DeviceProfileInfo findDefaultDeviceProfileInfo(TenantId tenantId);
40 40
41 - DeviceProfile findProfileByProfileNameAndProfileDataProvisionConfigurationPair(String profileName, String provisionDeviceKey, String provisionDeviceSecret); 41 + DeviceProfile findByProvisionDeviceKeyAndProvisionDeviceSecret(String provisionDeviceKey, String provisionDeviceSecret);
42 42
43 DeviceProfile findByName(TenantId tenantId, String profileName); 43 DeviceProfile findByName(TenantId tenantId, String profileName);
44 } 44 }
@@ -26,6 +26,7 @@ import org.springframework.stereotype.Service; @@ -26,6 +26,7 @@ import org.springframework.stereotype.Service;
26 import org.thingsboard.server.common.data.Device; 26 import org.thingsboard.server.common.data.Device;
27 import org.thingsboard.server.common.data.DeviceProfile; 27 import org.thingsboard.server.common.data.DeviceProfile;
28 import org.thingsboard.server.common.data.DeviceProfileInfo; 28 import org.thingsboard.server.common.data.DeviceProfileInfo;
  29 +import org.thingsboard.server.common.data.DeviceProfileProvisionType;
29 import org.thingsboard.server.common.data.DeviceProfileType; 30 import org.thingsboard.server.common.data.DeviceProfileType;
30 import org.thingsboard.server.common.data.DeviceTransportType; 31 import org.thingsboard.server.common.data.DeviceTransportType;
31 import org.thingsboard.server.common.data.EntitySubtype; 32 import org.thingsboard.server.common.data.EntitySubtype;
@@ -33,6 +34,7 @@ import org.thingsboard.server.common.data.Tenant; @@ -33,6 +34,7 @@ import org.thingsboard.server.common.data.Tenant;
33 import org.thingsboard.server.common.data.device.profile.DefaultDeviceProfileConfiguration; 34 import org.thingsboard.server.common.data.device.profile.DefaultDeviceProfileConfiguration;
34 import org.thingsboard.server.common.data.device.profile.DefaultDeviceProfileTransportConfiguration; 35 import org.thingsboard.server.common.data.device.profile.DefaultDeviceProfileTransportConfiguration;
35 import org.thingsboard.server.common.data.device.profile.DeviceProfileData; 36 import org.thingsboard.server.common.data.device.profile.DeviceProfileData;
  37 +import org.thingsboard.server.common.data.device.profile.DisabledDeviceProfileProvisionConfiguration;
36 import org.thingsboard.server.common.data.id.DeviceProfileId; 38 import org.thingsboard.server.common.data.id.DeviceProfileId;
37 import org.thingsboard.server.common.data.id.TenantId; 39 import org.thingsboard.server.common.data.id.TenantId;
38 import org.thingsboard.server.common.data.page.PageData; 40 import org.thingsboard.server.common.data.page.PageData;
@@ -112,6 +114,8 @@ public class DeviceProfileServiceImpl extends AbstractEntityService implements D @@ -112,6 +114,8 @@ public class DeviceProfileServiceImpl extends AbstractEntityService implements D
112 ConstraintViolationException e = extractConstraintViolationException(t).orElse(null); 114 ConstraintViolationException e = extractConstraintViolationException(t).orElse(null);
113 if (e != null && e.getConstraintName() != null && e.getConstraintName().equalsIgnoreCase("device_profile_name_unq_key")) { 115 if (e != null && e.getConstraintName() != null && e.getConstraintName().equalsIgnoreCase("device_profile_name_unq_key")) {
114 throw new DataValidationException("Device profile with such name already exists!"); 116 throw new DataValidationException("Device profile with such name already exists!");
  117 + } else if (e != null && e.getConstraintName() != null && e.getConstraintName().equalsIgnoreCase("device_provision_key_unq_key")) {
  118 + throw new DataValidationException("Device profile with such provision device key already exists!");
115 } else { 119 } else {
116 throw t; 120 throw t;
117 } 121 }
@@ -210,12 +214,15 @@ public class DeviceProfileServiceImpl extends AbstractEntityService implements D @@ -210,12 +214,15 @@ public class DeviceProfileServiceImpl extends AbstractEntityService implements D
210 deviceProfile.setName(profileName); 214 deviceProfile.setName(profileName);
211 deviceProfile.setType(DeviceProfileType.DEFAULT); 215 deviceProfile.setType(DeviceProfileType.DEFAULT);
212 deviceProfile.setTransportType(DeviceTransportType.DEFAULT); 216 deviceProfile.setTransportType(DeviceTransportType.DEFAULT);
  217 + deviceProfile.setProvisionType(DeviceProfileProvisionType.DISABLED);
213 deviceProfile.setDescription("Default device profile"); 218 deviceProfile.setDescription("Default device profile");
214 DeviceProfileData deviceProfileData = new DeviceProfileData(); 219 DeviceProfileData deviceProfileData = new DeviceProfileData();
215 DefaultDeviceProfileConfiguration configuration = new DefaultDeviceProfileConfiguration(); 220 DefaultDeviceProfileConfiguration configuration = new DefaultDeviceProfileConfiguration();
216 DefaultDeviceProfileTransportConfiguration transportConfiguration = new DefaultDeviceProfileTransportConfiguration(); 221 DefaultDeviceProfileTransportConfiguration transportConfiguration = new DefaultDeviceProfileTransportConfiguration();
  222 + DisabledDeviceProfileProvisionConfiguration provisionConfiguration = new DisabledDeviceProfileProvisionConfiguration(null);
217 deviceProfileData.setConfiguration(configuration); 223 deviceProfileData.setConfiguration(configuration);
218 deviceProfileData.setTransportConfiguration(transportConfiguration); 224 deviceProfileData.setTransportConfiguration(transportConfiguration);
  225 + deviceProfileData.setProvisionConfiguration(provisionConfiguration);
219 deviceProfile.setProfileData(deviceProfileData); 226 deviceProfile.setProfileData(deviceProfileData);
220 return saveDeviceProfile(deviceProfile); 227 return saveDeviceProfile(deviceProfile);
221 } 228 }
@@ -169,10 +169,12 @@ public class ModelConstants { @@ -169,10 +169,12 @@ public class ModelConstants {
169 public static final String DEVICE_PROFILE_NAME_PROPERTY = "name"; 169 public static final String DEVICE_PROFILE_NAME_PROPERTY = "name";
170 public static final String DEVICE_PROFILE_TYPE_PROPERTY = "type"; 170 public static final String DEVICE_PROFILE_TYPE_PROPERTY = "type";
171 public static final String DEVICE_PROFILE_TRANSPORT_TYPE_PROPERTY = "transport_type"; 171 public static final String DEVICE_PROFILE_TRANSPORT_TYPE_PROPERTY = "transport_type";
  172 + public static final String DEVICE_PROFILE_PROVISION_TYPE_PROPERTY = "provision_type";
172 public static final String DEVICE_PROFILE_PROFILE_DATA_PROPERTY = "profile_data"; 173 public static final String DEVICE_PROFILE_PROFILE_DATA_PROPERTY = "profile_data";
173 public static final String DEVICE_PROFILE_DESCRIPTION_PROPERTY = "description"; 174 public static final String DEVICE_PROFILE_DESCRIPTION_PROPERTY = "description";
174 public static final String DEVICE_PROFILE_IS_DEFAULT_PROPERTY = "is_default"; 175 public static final String DEVICE_PROFILE_IS_DEFAULT_PROPERTY = "is_default";
175 public static final String DEVICE_PROFILE_DEFAULT_RULE_CHAIN_ID_PROPERTY = "default_rule_chain_id"; 176 public static final String DEVICE_PROFILE_DEFAULT_RULE_CHAIN_ID_PROPERTY = "default_rule_chain_id";
  177 + public static final String DEVICE_PROFILE_PROVISION_DEVICE_KEY = "provision_device_key";
176 178
177 /** 179 /**
178 * Cassandra entityView constants. 180 * Cassandra entityView constants.
@@ -23,6 +23,7 @@ import org.hibernate.annotations.Type; @@ -23,6 +23,7 @@ import org.hibernate.annotations.Type;
23 import org.hibernate.annotations.TypeDef; 23 import org.hibernate.annotations.TypeDef;
24 import org.thingsboard.server.common.data.DeviceProfile; 24 import org.thingsboard.server.common.data.DeviceProfile;
25 import org.thingsboard.server.common.data.DeviceProfileType; 25 import org.thingsboard.server.common.data.DeviceProfileType;
  26 +import org.thingsboard.server.common.data.DeviceProfileProvisionType;
26 import org.thingsboard.server.common.data.DeviceTransportType; 27 import org.thingsboard.server.common.data.DeviceTransportType;
27 import org.thingsboard.server.common.data.device.profile.DeviceProfileData; 28 import org.thingsboard.server.common.data.device.profile.DeviceProfileData;
28 import org.thingsboard.server.common.data.id.DeviceProfileId; 29 import org.thingsboard.server.common.data.id.DeviceProfileId;
@@ -62,6 +63,10 @@ public final class DeviceProfileEntity extends BaseSqlEntity<DeviceProfile> impl @@ -62,6 +63,10 @@ public final class DeviceProfileEntity extends BaseSqlEntity<DeviceProfile> impl
62 @Column(name = ModelConstants.DEVICE_PROFILE_TRANSPORT_TYPE_PROPERTY) 63 @Column(name = ModelConstants.DEVICE_PROFILE_TRANSPORT_TYPE_PROPERTY)
63 private DeviceTransportType transportType; 64 private DeviceTransportType transportType;
64 65
  66 + @Enumerated(EnumType.STRING)
  67 + @Column(name = ModelConstants.DEVICE_PROFILE_PROVISION_TYPE_PROPERTY)
  68 + private DeviceProfileProvisionType provisionType;
  69 +
65 @Column(name = ModelConstants.DEVICE_PROFILE_DESCRIPTION_PROPERTY) 70 @Column(name = ModelConstants.DEVICE_PROFILE_DESCRIPTION_PROPERTY)
66 private String description; 71 private String description;
67 72
@@ -78,6 +83,9 @@ public final class DeviceProfileEntity extends BaseSqlEntity<DeviceProfile> impl @@ -78,6 +83,9 @@ public final class DeviceProfileEntity extends BaseSqlEntity<DeviceProfile> impl
78 @Column(name = ModelConstants.DEVICE_PROFILE_PROFILE_DATA_PROPERTY, columnDefinition = "jsonb") 83 @Column(name = ModelConstants.DEVICE_PROFILE_PROFILE_DATA_PROPERTY, columnDefinition = "jsonb")
79 private JsonNode profileData; 84 private JsonNode profileData;
80 85
  86 + @Column(name=ModelConstants.DEVICE_PROFILE_PROVISION_DEVICE_KEY)
  87 + private String provisionDeviceKey;
  88 +
81 public DeviceProfileEntity() { 89 public DeviceProfileEntity() {
82 super(); 90 super();
83 } 91 }
@@ -93,12 +101,14 @@ public final class DeviceProfileEntity extends BaseSqlEntity<DeviceProfile> impl @@ -93,12 +101,14 @@ public final class DeviceProfileEntity extends BaseSqlEntity<DeviceProfile> impl
93 this.name = deviceProfile.getName(); 101 this.name = deviceProfile.getName();
94 this.type = deviceProfile.getType(); 102 this.type = deviceProfile.getType();
95 this.transportType = deviceProfile.getTransportType(); 103 this.transportType = deviceProfile.getTransportType();
  104 + this.provisionType = deviceProfile.getProvisionType();
96 this.description = deviceProfile.getDescription(); 105 this.description = deviceProfile.getDescription();
97 this.isDefault = deviceProfile.isDefault(); 106 this.isDefault = deviceProfile.isDefault();
98 this.profileData = JacksonUtil.convertValue(deviceProfile.getProfileData(), ObjectNode.class); 107 this.profileData = JacksonUtil.convertValue(deviceProfile.getProfileData(), ObjectNode.class);
99 if (deviceProfile.getDefaultRuleChainId() != null) { 108 if (deviceProfile.getDefaultRuleChainId() != null) {
100 this.defaultRuleChainId = deviceProfile.getDefaultRuleChainId().getId(); 109 this.defaultRuleChainId = deviceProfile.getDefaultRuleChainId().getId();
101 } 110 }
  111 + this.provisionDeviceKey = deviceProfile.getProvisionDeviceKey();
102 } 112 }
103 113
104 @Override 114 @Override
@@ -125,12 +135,14 @@ public final class DeviceProfileEntity extends BaseSqlEntity<DeviceProfile> impl @@ -125,12 +135,14 @@ public final class DeviceProfileEntity extends BaseSqlEntity<DeviceProfile> impl
125 deviceProfile.setName(name); 135 deviceProfile.setName(name);
126 deviceProfile.setType(type); 136 deviceProfile.setType(type);
127 deviceProfile.setTransportType(transportType); 137 deviceProfile.setTransportType(transportType);
  138 + deviceProfile.setProvisionType(provisionType);
128 deviceProfile.setDescription(description); 139 deviceProfile.setDescription(description);
129 deviceProfile.setDefault(isDefault); 140 deviceProfile.setDefault(isDefault);
130 deviceProfile.setProfileData(JacksonUtil.convertValue(profileData, DeviceProfileData.class)); 141 deviceProfile.setProfileData(JacksonUtil.convertValue(profileData, DeviceProfileData.class));
131 if (defaultRuleChainId != null) { 142 if (defaultRuleChainId != null) {
132 deviceProfile.setDefaultRuleChainId(new RuleChainId(defaultRuleChainId)); 143 deviceProfile.setDefaultRuleChainId(new RuleChainId(defaultRuleChainId));
133 } 144 }
  145 + deviceProfile.setProvisionDeviceKey(provisionDeviceKey);
134 return deviceProfile; 146 return deviceProfile;
135 } 147 }
136 } 148 }
@@ -56,14 +56,10 @@ public interface DeviceProfileRepository extends PagingAndSortingRepository<Devi @@ -56,14 +56,10 @@ public interface DeviceProfileRepository extends PagingAndSortingRepository<Devi
56 56
57 DeviceProfileEntity findByTenantIdAndName(UUID id, String profileName); 57 DeviceProfileEntity findByTenantIdAndName(UUID id, String profileName);
58 58
59 - @Query(value = "SELECT d.* FROM device_profile as d " +  
60 - "WHERE d.name = :profileName " +  
61 - "AND d.profile_data->'configuration'->>'provisionDeviceKey' IS NOT NULL " +  
62 - "AND d.profile_data->'configuration'->>'provisionDeviceSecret' IS NOT NULL " +  
63 - "AND d.profile_data->'configuration'->>'provisionDeviceKey' = :provisionDeviceKey " +  
64 - "AND d.profile_data->'configuration'->>'provisionDeviceSecret' = :provisionDeviceSecret", 59 + @Query(value = "SELECT d.* from device_profile d " +
  60 + "WHERE d.provision_device_key = :provisionDeviceKey " +
  61 + "AND d.profile_data->'provisionConfiguration'->>'provisionDeviceSecret' = :provisionDeviceSecret",
65 nativeQuery = true) 62 nativeQuery = true)
66 - DeviceProfileEntity findProfileByProfileNameAndProfileDataProvisionConfigurationPair(@Param("profileName") String profileName,  
67 - @Param("provisionDeviceKey") String provisionDeviceKey,  
68 - @Param("provisionDeviceSecret") String provisionDeviceSecret); 63 + DeviceProfileEntity findByProvisionDeviceKeyAndProvisionDeviceSecret(@Param("provisionDeviceKey") String provisionDeviceKey,
  64 + @Param("provisionDeviceSecret") String provisionDeviceSecret);
69 } 65 }
@@ -81,8 +81,8 @@ public class JpaDeviceProfileDao extends JpaAbstractSearchTextDao<DeviceProfileE @@ -81,8 +81,8 @@ public class JpaDeviceProfileDao extends JpaAbstractSearchTextDao<DeviceProfileE
81 } 81 }
82 82
83 @Override 83 @Override
84 - public DeviceProfile findProfileByProfileNameAndProfileDataProvisionConfigurationPair(String profileName, String provisionDeviceKey, String provisionDeviceSecret) {  
85 - return DaoUtil.getData(deviceProfileRepository.findProfileByProfileNameAndProfileDataProvisionConfigurationPair(profileName, provisionDeviceKey, provisionDeviceSecret)); 84 + public DeviceProfile findByProvisionDeviceKeyAndProvisionDeviceSecret(String provisionDeviceKey, String provisionDeviceSecret) {
  85 + return DaoUtil.getData(deviceProfileRepository.findByProvisionDeviceKeyAndProvisionDeviceSecret(provisionDeviceKey, provisionDeviceSecret));
86 } 86 }
87 87
88 @Override 88 @Override
@@ -152,13 +152,16 @@ CREATE TABLE IF NOT EXISTS device_profile ( @@ -152,13 +152,16 @@ CREATE TABLE IF NOT EXISTS device_profile (
152 name varchar(255), 152 name varchar(255),
153 type varchar(255), 153 type varchar(255),
154 transport_type varchar(255), 154 transport_type varchar(255),
  155 + provision_type varchar(255),
155 profile_data jsonb, 156 profile_data jsonb,
156 description varchar, 157 description varchar,
157 search_text varchar(255), 158 search_text varchar(255),
158 is_default boolean, 159 is_default boolean,
159 tenant_id uuid, 160 tenant_id uuid,
160 default_rule_chain_id uuid, 161 default_rule_chain_id uuid,
  162 + provision_device_key varchar,
161 CONSTRAINT device_profile_name_unq_key UNIQUE (tenant_id, name), 163 CONSTRAINT device_profile_name_unq_key UNIQUE (tenant_id, name),
  164 + CONSTRAINT device_provision_key_unq_key UNIQUE (provision_device_key),
162 CONSTRAINT fk_default_rule_chain_device_profile FOREIGN KEY (default_rule_chain_id) REFERENCES rule_chain(id) 165 CONSTRAINT fk_default_rule_chain_device_profile FOREIGN KEY (default_rule_chain_id) REFERENCES rule_chain(id)
163 ); 166 );
164 167
@@ -170,13 +170,16 @@ CREATE TABLE IF NOT EXISTS device_profile ( @@ -170,13 +170,16 @@ CREATE TABLE IF NOT EXISTS device_profile (
170 name varchar(255), 170 name varchar(255),
171 type varchar(255), 171 type varchar(255),
172 transport_type varchar(255), 172 transport_type varchar(255),
  173 + provision_type varchar(255),
173 profile_data jsonb, 174 profile_data jsonb,
174 description varchar, 175 description varchar,
175 search_text varchar(255), 176 search_text varchar(255),
176 is_default boolean, 177 is_default boolean,
177 tenant_id uuid, 178 tenant_id uuid,
178 default_rule_chain_id uuid, 179 default_rule_chain_id uuid,
  180 + provision_device_key varchar,
179 CONSTRAINT device_profile_name_unq_key UNIQUE (tenant_id, name), 181 CONSTRAINT device_profile_name_unq_key UNIQUE (tenant_id, name),
  182 + CONSTRAINT device_provision_key_unq_key UNIQUE (provision_device_key),
180 CONSTRAINT fk_default_rule_chain_device_profile FOREIGN KEY (default_rule_chain_id) REFERENCES rule_chain(id) 183 CONSTRAINT fk_default_rule_chain_device_profile FOREIGN KEY (default_rule_chain_id) REFERENCES rule_chain(id)
181 ); 184 );
182 185