diff --git a/application/src/main/data/upgrade/3.1.2/schema_update_before.sql b/application/src/main/data/upgrade/3.1.2/schema_update_before.sql index c1591e7831..8f1d2f69a2 100644 --- a/application/src/main/data/upgrade/3.1.2/schema_update_before.sql +++ b/application/src/main/data/upgrade/3.1.2/schema_update_before.sql @@ -20,13 +20,16 @@ CREATE TABLE IF NOT EXISTS device_profile ( name varchar(255), type varchar(255), transport_type varchar(255), + provision_type varchar(255), profile_data jsonb, description varchar, search_text varchar(255), is_default boolean, tenant_id uuid, default_rule_chain_id uuid, + provision_device_key varchar, CONSTRAINT device_profile_name_unq_key UNIQUE (tenant_id, name), + CONSTRAINT device_provision_key_unq_key UNIQUE (provision_device_key), CONSTRAINT fk_default_rule_chain_device_profile FOREIGN KEY (default_rule_chain_id) REFERENCES rule_chain(id) ); diff --git a/application/src/main/java/org/thingsboard/server/service/device/DeviceProvisionServiceImpl.java b/application/src/main/java/org/thingsboard/server/service/device/DeviceProvisionServiceImpl.java index 80d4c25798..091e5099ce 100644 --- a/application/src/main/java/org/thingsboard/server/service/device/DeviceProvisionServiceImpl.java +++ b/application/src/main/java/org/thingsboard/server/service/device/DeviceProvisionServiceImpl.java @@ -27,10 +27,8 @@ import org.springframework.util.StringUtils; import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.DeviceProfile; -import org.thingsboard.server.common.data.DeviceProfileType; +import org.thingsboard.server.common.data.DeviceProfileProvisionType; import org.thingsboard.server.common.data.audit.ActionType; -import org.thingsboard.server.common.data.device.profile.ProvisionDeviceProfileConfiguration; -import org.thingsboard.server.common.data.device.profile.ProvisionRequestValidationStrategyType; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.UserId; @@ -117,21 +115,18 @@ public class DeviceProvisionServiceImpl implements DeviceProvisionService { return Futures.immediateFuture(new ProvisionResponse(null, ProvisionResponseStatus.NOT_FOUND)); } - DeviceProfile targetProfile = deviceProfileDao.findProfileByProfileNameAndProfileDataProvisionConfigurationPair( - provisionRequest.getDeviceType(), - provisionRequestKey, - provisionRequestSecret); + DeviceProfile targetProfile = deviceProfileDao.findByProvisionDeviceKeyAndProvisionDeviceSecret(provisionRequestKey, provisionRequestSecret); - if (targetProfile == null || targetProfile.getProfileData().getConfiguration().getType() != DeviceProfileType.PROVISION) { + if (targetProfile == null || + !(targetProfile.getProvisionType() != DeviceProfileProvisionType.ALLOW_CREATE_NEW_DEVICES || + targetProfile.getProvisionType() != DeviceProfileProvisionType.CHECK_PRE_PROVISIONED_DEVICES)) { return Futures.immediateFuture(new ProvisionResponse(null, ProvisionResponseStatus.NOT_FOUND)); } - ProvisionRequestValidationStrategyType validationStrategy = getStrategy(targetProfile); - Device targetDevice = deviceDao.findDeviceByTenantIdAndName(targetProfile.getTenantId().getId(), provisionRequest.getDeviceName()).orElse(null); - switch(validationStrategy) { - case CHECK_NEW_DEVICE: + switch(targetProfile.getProvisionType()) { + case ALLOW_CREATE_NEW_DEVICES: if (targetDevice != null) { log.warn("[{}] The device is present and could not be provisioned once more!", targetDevice.getName()); notify(targetDevice, provisionRequest, DataConstants.PROVISION_FAILURE, false); @@ -139,15 +134,15 @@ public class DeviceProvisionServiceImpl implements DeviceProvisionService { } else { return createDevice(provisionRequest, targetProfile); } - case CHECK_PRE_PROVISIONED_DEVICE: - if (targetDevice != null){ + case CHECK_PRE_PROVISIONED_DEVICES: + if (targetDevice != null && targetDevice.getDeviceProfileId().equals(targetProfile.getId())){ return processProvision(targetDevice, provisionRequest); } else { log.warn("[{}] Failed to find pre provisioned device!", provisionRequest.getDeviceName()); return Futures.immediateFuture(new ProvisionResponse(null, ProvisionResponseStatus.FAILURE)); } default: - throw new RuntimeException("Strategy is not supported - " + validationStrategy.name()); + throw new RuntimeException("Strategy is not supported - " + targetProfile.getProvisionType().name()); } } @@ -193,11 +188,6 @@ public class DeviceProvisionServiceImpl implements DeviceProvisionService { logAction(device.getTenantId(), device.getCustomerId(), device, success, provisionRequest); } - private ProvisionRequestValidationStrategyType getStrategy(DeviceProfile profile) { - return ((ProvisionDeviceProfileConfiguration) profile.getProfileData().getConfiguration()).getStrategy(); - - } - private ListenableFuture processCreateDevice(ProvisionRequest provisionRequest, DeviceProfile profile) { Device device = deviceService.findDeviceByTenantIdAndName(profile.getTenantId(), provisionRequest.getDeviceName()); if (device == null) { @@ -226,7 +216,7 @@ public class DeviceProvisionServiceImpl implements DeviceProvisionService { private Device saveDevice(ProvisionRequest provisionRequest, DeviceProfile profile) { Device device = new Device(); device.setName(provisionRequest.getDeviceName()); - device.setType(provisionRequest.getDeviceType()); + device.setType(profile.getName()); device.setTenantId(profile.getTenantId()); return deviceService.saveDevice(device); } diff --git a/application/src/main/java/org/thingsboard/server/service/transport/DefaultTransportApiService.java b/application/src/main/java/org/thingsboard/server/service/transport/DefaultTransportApiService.java index e2dcbe5416..927afc3c8a 100644 --- a/application/src/main/java/org/thingsboard/server/service/transport/DefaultTransportApiService.java +++ b/application/src/main/java/org/thingsboard/server/service/transport/DefaultTransportApiService.java @@ -30,7 +30,7 @@ import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.DeviceProfile; import org.thingsboard.server.common.data.TenantProfile; import org.thingsboard.server.common.data.device.credentials.BasicMqttCredentials; -import org.thingsboard.server.common.data.device.profile.ProvisionDeviceProfileConfiguration; +import org.thingsboard.server.common.data.device.profile.ProvisionDeviceProfileCredentials; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.id.DeviceProfileId; @@ -279,9 +279,8 @@ public class DefaultTransportApiService implements TransportApiService { provisionResponseFuture = deviceProvisionService.provisionDevice( new ProvisionRequest( requestMsg.getDeviceName(), - requestMsg.getDeviceType(), requestMsg.getX509CertPubKey(), - new ProvisionDeviceProfileConfiguration( + new ProvisionDeviceProfileCredentials( requestMsg.getProvisionDeviceCredentialsMsg().getProvisionDeviceKey(), requestMsg.getProvisionDeviceCredentialsMsg().getProvisionDeviceSecret()))); return Futures.transform(provisionResponseFuture, provisionResponse -> { diff --git a/application/src/test/java/org/thingsboard/server/controller/AbstractWebTest.java b/application/src/test/java/org/thingsboard/server/controller/AbstractWebTest.java index a7b796cace..da71c1e2df 100644 --- a/application/src/test/java/org/thingsboard/server/controller/AbstractWebTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/AbstractWebTest.java @@ -68,6 +68,7 @@ import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.device.profile.DefaultDeviceProfileConfiguration; import org.thingsboard.server.common.data.device.profile.DefaultDeviceProfileTransportConfiguration; import org.thingsboard.server.common.data.device.profile.DeviceProfileData; +import org.thingsboard.server.common.data.device.profile.ProvisionDeviceProfileCredentials; import org.thingsboard.server.common.data.id.HasId; import org.thingsboard.server.common.data.id.RuleChainId; import org.thingsboard.server.common.data.id.TenantId; diff --git a/application/src/test/java/org/thingsboard/server/controller/BaseDeviceProfileControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/BaseDeviceProfileControllerTest.java index b2334d7c46..3376c16573 100644 --- a/application/src/test/java/org/thingsboard/server/controller/BaseDeviceProfileControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/BaseDeviceProfileControllerTest.java @@ -28,6 +28,7 @@ import org.thingsboard.server.common.data.DeviceProfileType; import org.thingsboard.server.common.data.DeviceTransportType; import org.thingsboard.server.common.data.Tenant; import org.thingsboard.server.common.data.User; +import org.thingsboard.server.common.data.device.profile.ProvisionDeviceProfileCredentials; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.security.Authority; @@ -153,6 +154,17 @@ public abstract class BaseDeviceProfileControllerTest extends AbstractController .andExpect(statusReason(containsString("Device profile with such name already exists"))); } + @Test + public void testSaveDeviceProfileWithSameProvisionDeviceKey() throws Exception { + DeviceProfile deviceProfile = this.createDeviceProfile("Device Profile"); + deviceProfile.setProvisionDeviceKey("testProvisionDeviceKey"); + doPost("/api/deviceProfile", deviceProfile).andExpect(status().isOk()); + DeviceProfile deviceProfile2 = this.createDeviceProfile("Device Profile 2"); + deviceProfile2.setProvisionDeviceKey("testProvisionDeviceKey"); + doPost("/api/deviceProfile", deviceProfile2).andExpect(status().isBadRequest()) + .andExpect(statusReason(containsString("Device profile with such provision device key already exists"))); + } + @Ignore @Test public void testChangeDeviceProfileTypeWithExistingDevices() throws Exception { diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/device/provision/ProvisionRequest.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/device/provision/ProvisionRequest.java index 45eb7f5998..1c743fd855 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/device/provision/ProvisionRequest.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/device/provision/ProvisionRequest.java @@ -17,13 +17,12 @@ package org.thingsboard.server.dao.device.provision; import lombok.AllArgsConstructor; import lombok.Data; -import org.thingsboard.server.common.data.device.profile.ProvisionDeviceProfileConfiguration; +import org.thingsboard.server.common.data.device.profile.ProvisionDeviceProfileCredentials; @Data @AllArgsConstructor public class ProvisionRequest { private String deviceName; - private String deviceType; private String x509CertPubKey; - private ProvisionDeviceProfileConfiguration credentials; + private ProvisionDeviceProfileCredentials credentials; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/DeviceProfile.java b/common/data/src/main/java/org/thingsboard/server/common/data/DeviceProfile.java index 097d64b198..10990bc436 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/DeviceProfile.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/DeviceProfile.java @@ -41,10 +41,12 @@ public class DeviceProfile extends SearchTextBased implements H private boolean isDefault; private DeviceProfileType type; private DeviceTransportType transportType; + private DeviceProfileProvisionType provisionType; private RuleChainId defaultRuleChainId; private transient DeviceProfileData profileData; @JsonIgnore private byte[] profileDataBytes; + private String provisionDeviceKey; public DeviceProfile() { super(); @@ -62,6 +64,7 @@ public class DeviceProfile extends SearchTextBased implements H this.isDefault = deviceProfile.isDefault(); this.defaultRuleChainId = deviceProfile.getDefaultRuleChainId(); this.setProfileData(deviceProfile.getProfileData()); + this.provisionDeviceKey = deviceProfile.getProvisionDeviceKey(); } @Override diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/ProvisionRequestValidationStrategyType.java b/common/data/src/main/java/org/thingsboard/server/common/data/DeviceProfileProvisionType.java similarity index 79% rename from common/data/src/main/java/org/thingsboard/server/common/data/device/profile/ProvisionRequestValidationStrategyType.java rename to common/data/src/main/java/org/thingsboard/server/common/data/DeviceProfileProvisionType.java index 9a4005612a..f33c705d52 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/ProvisionRequestValidationStrategyType.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/DeviceProfileProvisionType.java @@ -13,8 +13,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.common.data.device.profile; +package org.thingsboard.server.common.data; -public enum ProvisionRequestValidationStrategyType { - CHECK_NEW_DEVICE, CHECK_PRE_PROVISIONED_DEVICE +public enum DeviceProfileProvisionType { + DISABLED, + ALLOW_CREATE_NEW_DEVICES, + CHECK_PRE_PROVISIONED_DEVICES } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/DeviceProfileType.java b/common/data/src/main/java/org/thingsboard/server/common/data/DeviceProfileType.java index 218a5aa5b4..93ca102082 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/DeviceProfileType.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/DeviceProfileType.java @@ -16,6 +16,5 @@ package org.thingsboard.server.common.data; public enum DeviceProfileType { - DEFAULT, - PROVISION + DEFAULT } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/device/data/DeviceConfiguration.java b/common/data/src/main/java/org/thingsboard/server/common/data/device/data/DeviceConfiguration.java index 18d233caa0..1ea2ee4f97 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/device/data/DeviceConfiguration.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/device/data/DeviceConfiguration.java @@ -27,8 +27,7 @@ import org.thingsboard.server.common.data.DeviceProfileType; include = JsonTypeInfo.As.PROPERTY, property = "type") @JsonSubTypes({ - @JsonSubTypes.Type(value = DefaultDeviceConfiguration.class, name = "DEFAULT"), - @JsonSubTypes.Type(value = DefaultDeviceConfiguration.class, name = "PROVISION")}) + @JsonSubTypes.Type(value = DefaultDeviceConfiguration.class, name = "DEFAULT")}) public interface DeviceConfiguration { @JsonIgnore diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/AllowCreateNewDevicesDeviceProfileProvisionConfiguration.java b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/AllowCreateNewDevicesDeviceProfileProvisionConfiguration.java new file mode 100644 index 0000000000..8414caa400 --- /dev/null +++ b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/AllowCreateNewDevicesDeviceProfileProvisionConfiguration.java @@ -0,0 +1,31 @@ +/** + * Copyright © 2016-2020 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.common.data.device.profile; + +import lombok.Data; +import org.thingsboard.server.common.data.DeviceProfileProvisionType; + +@Data +public class AllowCreateNewDevicesDeviceProfileProvisionConfiguration implements DeviceProfileProvisionConfiguration { + + private final String provisionDeviceSecret; + + @Override + public DeviceProfileProvisionType getType() { + return DeviceProfileProvisionType.ALLOW_CREATE_NEW_DEVICES; + } + +} diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/CheckPreProvisionedDevicesDeviceProfileProvisionConfiguration.java b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/CheckPreProvisionedDevicesDeviceProfileProvisionConfiguration.java new file mode 100644 index 0000000000..40af29ea51 --- /dev/null +++ b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/CheckPreProvisionedDevicesDeviceProfileProvisionConfiguration.java @@ -0,0 +1,31 @@ +/** + * Copyright © 2016-2020 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.common.data.device.profile; + +import lombok.Data; +import org.thingsboard.server.common.data.DeviceProfileProvisionType; + +@Data +public class CheckPreProvisionedDevicesDeviceProfileProvisionConfiguration implements DeviceProfileProvisionConfiguration { + + private final String provisionDeviceSecret; + + @Override + public DeviceProfileProvisionType getType() { + return DeviceProfileProvisionType.CHECK_PRE_PROVISIONED_DEVICES; + } + +} diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/DeviceProfileConfiguration.java b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/DeviceProfileConfiguration.java index aca6d391da..3bb3d29c34 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/DeviceProfileConfiguration.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/DeviceProfileConfiguration.java @@ -27,8 +27,7 @@ import org.thingsboard.server.common.data.DeviceProfileType; include = JsonTypeInfo.As.PROPERTY, property = "type") @JsonSubTypes({ - @JsonSubTypes.Type(value = DefaultDeviceProfileConfiguration.class, name = "DEFAULT"), - @JsonSubTypes.Type(value = ProvisionDeviceProfileConfiguration.class, name = "PROVISION")}) + @JsonSubTypes.Type(value = DefaultDeviceProfileConfiguration.class, name = "DEFAULT")}) public interface DeviceProfileConfiguration { @JsonIgnore diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/DeviceProfileData.java b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/DeviceProfileData.java index 275e6269d6..7cb3304934 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/DeviceProfileData.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/DeviceProfileData.java @@ -24,6 +24,7 @@ public class DeviceProfileData { private DeviceProfileConfiguration configuration; private DeviceProfileTransportConfiguration transportConfiguration; + private DeviceProfileProvisionConfiguration provisionConfiguration; private List alarms; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/DeviceProfileProvisionConfiguration.java b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/DeviceProfileProvisionConfiguration.java new file mode 100644 index 0000000000..140c7334ec --- /dev/null +++ b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/DeviceProfileProvisionConfiguration.java @@ -0,0 +1,39 @@ +/** + * Copyright © 2016-2020 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.common.data.device.profile; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonSubTypes; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import org.thingsboard.server.common.data.DeviceProfileProvisionType; + + +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonTypeInfo( + use = JsonTypeInfo.Id.NAME, + include = JsonTypeInfo.As.PROPERTY, + property = "type") +@JsonSubTypes({ + @JsonSubTypes.Type(value = DisabledDeviceProfileProvisionConfiguration.class, name = "DISABLED"), + @JsonSubTypes.Type(value = AllowCreateNewDevicesDeviceProfileProvisionConfiguration.class, name = "ALLOW_CREATE_NEW_DEVICES"), + @JsonSubTypes.Type(value = CheckPreProvisionedDevicesDeviceProfileProvisionConfiguration.class, name = "CHECK_PRE_PROVISIONED_DEVICES")}) +public interface DeviceProfileProvisionConfiguration { + + @JsonIgnore + DeviceProfileProvisionType getType(); + +} \ No newline at end of file diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/DisabledDeviceProfileProvisionConfiguration.java b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/DisabledDeviceProfileProvisionConfiguration.java new file mode 100644 index 0000000000..01876c810d --- /dev/null +++ b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/DisabledDeviceProfileProvisionConfiguration.java @@ -0,0 +1,31 @@ +/** + * Copyright © 2016-2020 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.common.data.device.profile; + +import lombok.Data; +import org.thingsboard.server.common.data.DeviceProfileProvisionType; + +@Data +public class DisabledDeviceProfileProvisionConfiguration implements DeviceProfileProvisionConfiguration { + + private final String provisionDeviceSecret; + + @Override + public DeviceProfileProvisionType getType() { + return DeviceProfileProvisionType.DISABLED; + } + +} diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/ProvisionDeviceProfileConfiguration.java b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/ProvisionDeviceProfileConfiguration.java deleted file mode 100644 index ee20a51628..0000000000 --- a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/ProvisionDeviceProfileConfiguration.java +++ /dev/null @@ -1,57 +0,0 @@ -/** - * Copyright © 2016-2020 The Thingsboard Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.thingsboard.server.common.data.device.profile; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.Data; -import org.thingsboard.server.common.data.DeviceProfileType; - -import java.util.Objects; - -@Data -public class ProvisionDeviceProfileConfiguration implements DeviceProfileConfiguration { - - private String provisionDeviceKey; - private String provisionDeviceSecret; - - private ProvisionRequestValidationStrategyType strategy; - - @Override - public DeviceProfileType getType() { - return DeviceProfileType.PROVISION; - } - - @JsonCreator - public ProvisionDeviceProfileConfiguration(@JsonProperty("provisionDeviceKey") String provisionProfileKey, @JsonProperty("provisionDeviceSecret") String provisionProfileSecret) { - this.provisionDeviceKey = provisionProfileKey; - this.provisionDeviceSecret = provisionProfileSecret; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - ProvisionDeviceProfileConfiguration that = (ProvisionDeviceProfileConfiguration) o; - return provisionDeviceKey.equals(that.provisionDeviceKey) && - provisionDeviceSecret.equals(that.provisionDeviceSecret); - } - - @Override - public int hashCode() { - return Objects.hash(provisionDeviceKey, provisionDeviceSecret); - } -} diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/ProvisionRequestValidationStrategy.java b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/ProvisionDeviceProfileCredentials.java similarity index 83% rename from common/data/src/main/java/org/thingsboard/server/common/data/device/profile/ProvisionRequestValidationStrategy.java rename to common/data/src/main/java/org/thingsboard/server/common/data/device/profile/ProvisionDeviceProfileCredentials.java index 759940b763..659da71488 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/ProvisionRequestValidationStrategy.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/ProvisionDeviceProfileCredentials.java @@ -18,6 +18,7 @@ package org.thingsboard.server.common.data.device.profile; import lombok.Data; @Data -public class ProvisionRequestValidationStrategy { - private final ProvisionRequestValidationStrategyType validationStrategyType; +public class ProvisionDeviceProfileCredentials { + private final String provisionDeviceKey; + private final String provisionDeviceSecret; } diff --git a/common/queue/src/main/proto/queue.proto b/common/queue/src/main/proto/queue.proto index 007c17f3d3..bf308d922e 100644 --- a/common/queue/src/main/proto/queue.proto +++ b/common/queue/src/main/proto/queue.proto @@ -256,9 +256,8 @@ message DeviceCredentialsProto { message ProvisionDeviceRequestMsg { string deviceName = 1; - string deviceType = 2; - string x509CertPubKey = 3; - ProvisionDeviceCredentialsMsg provisionDeviceCredentialsMsg = 4; + string x509CertPubKey = 2; + ProvisionDeviceCredentialsMsg provisionDeviceCredentialsMsg = 3; } message ProvisionDeviceCredentialsMsg { diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/adaptor/JsonConverter.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/adaptor/JsonConverter.java index 13dda0a10a..f710efd44a 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/adaptor/JsonConverter.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/adaptor/JsonConverter.java @@ -543,7 +543,6 @@ public class JsonConverter { private static TransportProtos.ProvisionDeviceRequestMsg buildProvisionRequestMsg(JsonObject jo) { return TransportProtos.ProvisionDeviceRequestMsg.newBuilder() .setDeviceName(getStrValue(jo, DataConstants.DEVICE_NAME, true)) - .setDeviceType(getStrValue(jo, DataConstants.DEVICE_TYPE, true)) .setX509CertPubKey(getStrValue(jo, DataConstants.CERT_PUB_KEY, false)) .setProvisionDeviceCredentialsMsg(buildProvisionDeviceCredentialsMsg( getStrValue(jo, DataConstants.PROVISION_KEY, true), diff --git a/dao/src/main/java/org/thingsboard/server/dao/device/DeviceProfileDao.java b/dao/src/main/java/org/thingsboard/server/dao/device/DeviceProfileDao.java index 2d65448d02..74a251e3ff 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/device/DeviceProfileDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/device/DeviceProfileDao.java @@ -38,7 +38,7 @@ public interface DeviceProfileDao extends Dao { DeviceProfileInfo findDefaultDeviceProfileInfo(TenantId tenantId); - DeviceProfile findProfileByProfileNameAndProfileDataProvisionConfigurationPair(String profileName, String provisionDeviceKey, String provisionDeviceSecret); + DeviceProfile findByProvisionDeviceKeyAndProvisionDeviceSecret(String provisionDeviceKey, String provisionDeviceSecret); DeviceProfile findByName(TenantId tenantId, String profileName); } diff --git a/dao/src/main/java/org/thingsboard/server/dao/device/DeviceProfileServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/device/DeviceProfileServiceImpl.java index b40ad102eb..d83408aead 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/device/DeviceProfileServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/device/DeviceProfileServiceImpl.java @@ -26,6 +26,7 @@ import org.springframework.stereotype.Service; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.DeviceProfile; import org.thingsboard.server.common.data.DeviceProfileInfo; +import org.thingsboard.server.common.data.DeviceProfileProvisionType; import org.thingsboard.server.common.data.DeviceProfileType; import org.thingsboard.server.common.data.DeviceTransportType; import org.thingsboard.server.common.data.EntitySubtype; @@ -33,6 +34,7 @@ import org.thingsboard.server.common.data.Tenant; import org.thingsboard.server.common.data.device.profile.DefaultDeviceProfileConfiguration; import org.thingsboard.server.common.data.device.profile.DefaultDeviceProfileTransportConfiguration; import org.thingsboard.server.common.data.device.profile.DeviceProfileData; +import org.thingsboard.server.common.data.device.profile.DisabledDeviceProfileProvisionConfiguration; import org.thingsboard.server.common.data.id.DeviceProfileId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.PageData; @@ -112,6 +114,8 @@ public class DeviceProfileServiceImpl extends AbstractEntityService implements D ConstraintViolationException e = extractConstraintViolationException(t).orElse(null); if (e != null && e.getConstraintName() != null && e.getConstraintName().equalsIgnoreCase("device_profile_name_unq_key")) { throw new DataValidationException("Device profile with such name already exists!"); + } else if (e != null && e.getConstraintName() != null && e.getConstraintName().equalsIgnoreCase("device_provision_key_unq_key")) { + throw new DataValidationException("Device profile with such provision device key already exists!"); } else { throw t; } @@ -210,12 +214,15 @@ public class DeviceProfileServiceImpl extends AbstractEntityService implements D deviceProfile.setName(profileName); deviceProfile.setType(DeviceProfileType.DEFAULT); deviceProfile.setTransportType(DeviceTransportType.DEFAULT); + deviceProfile.setProvisionType(DeviceProfileProvisionType.DISABLED); deviceProfile.setDescription("Default device profile"); DeviceProfileData deviceProfileData = new DeviceProfileData(); DefaultDeviceProfileConfiguration configuration = new DefaultDeviceProfileConfiguration(); DefaultDeviceProfileTransportConfiguration transportConfiguration = new DefaultDeviceProfileTransportConfiguration(); + DisabledDeviceProfileProvisionConfiguration provisionConfiguration = new DisabledDeviceProfileProvisionConfiguration(null); deviceProfileData.setConfiguration(configuration); deviceProfileData.setTransportConfiguration(transportConfiguration); + deviceProfileData.setProvisionConfiguration(provisionConfiguration); deviceProfile.setProfileData(deviceProfileData); return saveDeviceProfile(deviceProfile); } diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java b/dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java index b62dac2d44..1f5a4b34d7 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java @@ -169,10 +169,12 @@ public class ModelConstants { public static final String DEVICE_PROFILE_NAME_PROPERTY = "name"; public static final String DEVICE_PROFILE_TYPE_PROPERTY = "type"; public static final String DEVICE_PROFILE_TRANSPORT_TYPE_PROPERTY = "transport_type"; + public static final String DEVICE_PROFILE_PROVISION_TYPE_PROPERTY = "provision_type"; public static final String DEVICE_PROFILE_PROFILE_DATA_PROPERTY = "profile_data"; public static final String DEVICE_PROFILE_DESCRIPTION_PROPERTY = "description"; public static final String DEVICE_PROFILE_IS_DEFAULT_PROPERTY = "is_default"; public static final String DEVICE_PROFILE_DEFAULT_RULE_CHAIN_ID_PROPERTY = "default_rule_chain_id"; + public static final String DEVICE_PROFILE_PROVISION_DEVICE_KEY = "provision_device_key"; /** * Cassandra entityView constants. diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/DeviceProfileEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/DeviceProfileEntity.java index 27e77d4eca..264d0725ae 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/DeviceProfileEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/DeviceProfileEntity.java @@ -23,6 +23,7 @@ import org.hibernate.annotations.Type; import org.hibernate.annotations.TypeDef; import org.thingsboard.server.common.data.DeviceProfile; import org.thingsboard.server.common.data.DeviceProfileType; +import org.thingsboard.server.common.data.DeviceProfileProvisionType; import org.thingsboard.server.common.data.DeviceTransportType; import org.thingsboard.server.common.data.device.profile.DeviceProfileData; import org.thingsboard.server.common.data.id.DeviceProfileId; @@ -62,6 +63,10 @@ public final class DeviceProfileEntity extends BaseSqlEntity impl @Column(name = ModelConstants.DEVICE_PROFILE_TRANSPORT_TYPE_PROPERTY) private DeviceTransportType transportType; + @Enumerated(EnumType.STRING) + @Column(name = ModelConstants.DEVICE_PROFILE_PROVISION_TYPE_PROPERTY) + private DeviceProfileProvisionType provisionType; + @Column(name = ModelConstants.DEVICE_PROFILE_DESCRIPTION_PROPERTY) private String description; @@ -78,6 +83,9 @@ public final class DeviceProfileEntity extends BaseSqlEntity impl @Column(name = ModelConstants.DEVICE_PROFILE_PROFILE_DATA_PROPERTY, columnDefinition = "jsonb") private JsonNode profileData; + @Column(name=ModelConstants.DEVICE_PROFILE_PROVISION_DEVICE_KEY) + private String provisionDeviceKey; + public DeviceProfileEntity() { super(); } @@ -93,12 +101,14 @@ public final class DeviceProfileEntity extends BaseSqlEntity impl this.name = deviceProfile.getName(); this.type = deviceProfile.getType(); this.transportType = deviceProfile.getTransportType(); + this.provisionType = deviceProfile.getProvisionType(); this.description = deviceProfile.getDescription(); this.isDefault = deviceProfile.isDefault(); this.profileData = JacksonUtil.convertValue(deviceProfile.getProfileData(), ObjectNode.class); if (deviceProfile.getDefaultRuleChainId() != null) { this.defaultRuleChainId = deviceProfile.getDefaultRuleChainId().getId(); } + this.provisionDeviceKey = deviceProfile.getProvisionDeviceKey(); } @Override @@ -125,12 +135,14 @@ public final class DeviceProfileEntity extends BaseSqlEntity impl deviceProfile.setName(name); deviceProfile.setType(type); deviceProfile.setTransportType(transportType); + deviceProfile.setProvisionType(provisionType); deviceProfile.setDescription(description); deviceProfile.setDefault(isDefault); deviceProfile.setProfileData(JacksonUtil.convertValue(profileData, DeviceProfileData.class)); if (defaultRuleChainId != null) { deviceProfile.setDefaultRuleChainId(new RuleChainId(defaultRuleChainId)); } + deviceProfile.setProvisionDeviceKey(provisionDeviceKey); return deviceProfile; } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/device/DeviceProfileRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/device/DeviceProfileRepository.java index d528650c10..43b6d68efe 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/device/DeviceProfileRepository.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/device/DeviceProfileRepository.java @@ -56,14 +56,10 @@ public interface DeviceProfileRepository extends PagingAndSortingRepository'configuration'->>'provisionDeviceKey' IS NOT NULL " + - "AND d.profile_data->'configuration'->>'provisionDeviceSecret' IS NOT NULL " + - "AND d.profile_data->'configuration'->>'provisionDeviceKey' = :provisionDeviceKey " + - "AND d.profile_data->'configuration'->>'provisionDeviceSecret' = :provisionDeviceSecret", + @Query(value = "SELECT d.* from device_profile d " + + "WHERE d.provision_device_key = :provisionDeviceKey " + + "AND d.profile_data->'provisionConfiguration'->>'provisionDeviceSecret' = :provisionDeviceSecret", nativeQuery = true) - DeviceProfileEntity findProfileByProfileNameAndProfileDataProvisionConfigurationPair(@Param("profileName") String profileName, - @Param("provisionDeviceKey") String provisionDeviceKey, - @Param("provisionDeviceSecret") String provisionDeviceSecret); + DeviceProfileEntity findByProvisionDeviceKeyAndProvisionDeviceSecret(@Param("provisionDeviceKey") String provisionDeviceKey, + @Param("provisionDeviceSecret") String provisionDeviceSecret); } diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/device/JpaDeviceProfileDao.java b/dao/src/main/java/org/thingsboard/server/dao/sql/device/JpaDeviceProfileDao.java index 3a812e78da..2d7c011a87 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/device/JpaDeviceProfileDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/device/JpaDeviceProfileDao.java @@ -81,8 +81,8 @@ public class JpaDeviceProfileDao extends JpaAbstractSearchTextDao