Commit 3ddf14668e2692241e408e0f05a4e131c585b76b
1 parent
7d7a5062
Tenant and Device profiles DAO layer
Showing
52 changed files
with
2242 additions
and
50 deletions
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 | + | ||
17 | +ALTER TABLE device ADD COLUMN device_profile_id uuid; | ||
18 | +ALTER TABLE tenant ADD COLUMN tenant_profile_id uuid; | ||
19 | + | ||
20 | +CREATE TABLE IF NOT EXISTS device_profile ( | ||
21 | + id uuid NOT NULL CONSTRAINT device_profile_pkey PRIMARY KEY, | ||
22 | + created_time bigint NOT NULL, | ||
23 | + name varchar(255), | ||
24 | + profile_data varchar, | ||
25 | + description varchar, | ||
26 | + search_text varchar(255), | ||
27 | + default boolean, | ||
28 | + tenant_id uuid, | ||
29 | + default_rule_chain_id uuid | ||
30 | +); | ||
31 | + | ||
32 | +CREATE TABLE IF NOT EXISTS tenant_profile ( | ||
33 | + id uuid NOT NULL CONSTRAINT tenant_profile_pkey PRIMARY KEY, | ||
34 | + created_time bigint NOT NULL, | ||
35 | + name varchar(255), | ||
36 | + profile_data varchar, | ||
37 | + description varchar, | ||
38 | + search_text varchar(255), | ||
39 | + default boolean, | ||
40 | + isolated_tb_core boolean, | ||
41 | + isolated_tb_rule_engine boolean | ||
42 | +); |
@@ -58,6 +58,7 @@ import org.thingsboard.server.dao.event.EventService; | @@ -58,6 +58,7 @@ import org.thingsboard.server.dao.event.EventService; | ||
58 | import org.thingsboard.server.dao.nosql.CassandraBufferedRateExecutor; | 58 | import org.thingsboard.server.dao.nosql.CassandraBufferedRateExecutor; |
59 | import org.thingsboard.server.dao.relation.RelationService; | 59 | import org.thingsboard.server.dao.relation.RelationService; |
60 | import org.thingsboard.server.dao.rule.RuleChainService; | 60 | import org.thingsboard.server.dao.rule.RuleChainService; |
61 | +import org.thingsboard.server.dao.tenant.TenantProfileService; | ||
61 | import org.thingsboard.server.dao.tenant.TenantService; | 62 | import org.thingsboard.server.dao.tenant.TenantService; |
62 | import org.thingsboard.server.dao.timeseries.TimeseriesService; | 63 | import org.thingsboard.server.dao.timeseries.TimeseriesService; |
63 | import org.thingsboard.server.dao.user.UserService; | 64 | import org.thingsboard.server.dao.user.UserService; |
@@ -139,6 +140,10 @@ public class ActorSystemContext { | @@ -139,6 +140,10 @@ public class ActorSystemContext { | ||
139 | 140 | ||
140 | @Autowired | 141 | @Autowired |
141 | @Getter | 142 | @Getter |
143 | + private TenantProfileService tenantProfileService; | ||
144 | + | ||
145 | + @Autowired | ||
146 | + @Getter | ||
142 | private CustomerService customerService; | 147 | private CustomerService customerService; |
143 | 148 | ||
144 | @Autowired | 149 | @Autowired |
@@ -27,6 +27,7 @@ import org.thingsboard.server.actors.service.DefaultActorService; | @@ -27,6 +27,7 @@ import org.thingsboard.server.actors.service.DefaultActorService; | ||
27 | import org.thingsboard.server.actors.tenant.TenantActor; | 27 | import org.thingsboard.server.actors.tenant.TenantActor; |
28 | import org.thingsboard.server.common.data.EntityType; | 28 | import org.thingsboard.server.common.data.EntityType; |
29 | import org.thingsboard.server.common.data.Tenant; | 29 | import org.thingsboard.server.common.data.Tenant; |
30 | +import org.thingsboard.server.common.data.TenantProfile; | ||
30 | import org.thingsboard.server.common.data.id.EntityId; | 31 | import org.thingsboard.server.common.data.id.EntityId; |
31 | import org.thingsboard.server.common.data.id.TenantId; | 32 | import org.thingsboard.server.common.data.id.TenantId; |
32 | import org.thingsboard.server.common.data.page.PageDataIterable; | 33 | import org.thingsboard.server.common.data.page.PageDataIterable; |
@@ -116,7 +117,9 @@ public class AppActor extends ContextAwareActor { | @@ -116,7 +117,9 @@ public class AppActor extends ContextAwareActor { | ||
116 | boolean isRuleEngine = systemContext.getServiceInfoProvider().isService(ServiceType.TB_RULE_ENGINE); | 117 | boolean isRuleEngine = systemContext.getServiceInfoProvider().isService(ServiceType.TB_RULE_ENGINE); |
117 | boolean isCore = systemContext.getServiceInfoProvider().isService(ServiceType.TB_CORE); | 118 | boolean isCore = systemContext.getServiceInfoProvider().isService(ServiceType.TB_CORE); |
118 | for (Tenant tenant : tenantIterator) { | 119 | for (Tenant tenant : tenantIterator) { |
119 | - if (isCore || (isRuleEngine && !tenant.isIsolatedTbRuleEngine())) { | 120 | + // TODO: Tenant Profile from cache |
121 | + TenantProfile tenantProfile = systemContext.getTenantProfileService().findTenantProfileById(TenantId.SYS_TENANT_ID, tenant.getTenantProfileId()); | ||
122 | + if (isCore || (isRuleEngine && !tenantProfile.isIsolatedTbRuleEngine())) { | ||
120 | log.debug("[{}] Creating tenant actor", tenant.getId()); | 123 | log.debug("[{}] Creating tenant actor", tenant.getId()); |
121 | getOrCreateTenantActor(tenant.getId()); | 124 | getOrCreateTenantActor(tenant.getId()); |
122 | log.debug("[{}] Tenant actor created.", tenant.getId()); | 125 | log.debug("[{}] Tenant actor created.", tenant.getId()); |
@@ -31,6 +31,7 @@ import org.thingsboard.server.actors.service.ContextBasedCreator; | @@ -31,6 +31,7 @@ import org.thingsboard.server.actors.service.ContextBasedCreator; | ||
31 | import org.thingsboard.server.actors.service.DefaultActorService; | 31 | import org.thingsboard.server.actors.service.DefaultActorService; |
32 | import org.thingsboard.server.common.data.EntityType; | 32 | import org.thingsboard.server.common.data.EntityType; |
33 | import org.thingsboard.server.common.data.Tenant; | 33 | import org.thingsboard.server.common.data.Tenant; |
34 | +import org.thingsboard.server.common.data.TenantProfile; | ||
34 | import org.thingsboard.server.common.data.id.DeviceId; | 35 | import org.thingsboard.server.common.data.id.DeviceId; |
35 | import org.thingsboard.server.common.data.id.EntityId; | 36 | import org.thingsboard.server.common.data.id.EntityId; |
36 | import org.thingsboard.server.common.data.id.RuleChainId; | 37 | import org.thingsboard.server.common.data.id.RuleChainId; |
@@ -75,12 +76,16 @@ public class TenantActor extends RuleChainManagerActor { | @@ -75,12 +76,16 @@ public class TenantActor extends RuleChainManagerActor { | ||
75 | // This Service may be started for specific tenant only. | 76 | // This Service may be started for specific tenant only. |
76 | Optional<TenantId> isolatedTenantId = systemContext.getServiceInfoProvider().getIsolatedTenant(); | 77 | Optional<TenantId> isolatedTenantId = systemContext.getServiceInfoProvider().getIsolatedTenant(); |
77 | 78 | ||
79 | + // TODO: Tenant Profile from cache | ||
80 | + | ||
81 | + TenantProfile tenantProfile = systemContext.getTenantProfileService().findTenantProfileById(tenantId, tenant.getTenantProfileId()); | ||
82 | + | ||
78 | isRuleEngineForCurrentTenant = systemContext.getServiceInfoProvider().isService(ServiceType.TB_RULE_ENGINE); | 83 | isRuleEngineForCurrentTenant = systemContext.getServiceInfoProvider().isService(ServiceType.TB_RULE_ENGINE); |
79 | isCore = systemContext.getServiceInfoProvider().isService(ServiceType.TB_CORE); | 84 | isCore = systemContext.getServiceInfoProvider().isService(ServiceType.TB_CORE); |
80 | 85 | ||
81 | if (isRuleEngineForCurrentTenant) { | 86 | if (isRuleEngineForCurrentTenant) { |
82 | try { | 87 | try { |
83 | - if (isolatedTenantId.map(id -> id.equals(tenantId)).orElseGet(() -> !tenant.isIsolatedTbRuleEngine())) { | 88 | + if (isolatedTenantId.map(id -> id.equals(tenantId)).orElseGet(() -> !tenantProfile.isIsolatedTbRuleEngine())) { |
84 | log.info("[{}] Going to init rule chains", tenantId); | 89 | log.info("[{}] Going to init rule chains", tenantId); |
85 | initRuleChains(); | 90 | initRuleChains(); |
86 | } else { | 91 | } else { |
@@ -175,6 +175,9 @@ public class ThingsboardInstallService { | @@ -175,6 +175,9 @@ public class ThingsboardInstallService { | ||
175 | case "3.1.0": | 175 | case "3.1.0": |
176 | log.info("Upgrading ThingsBoard from version 3.1.0 to 3.1.1 ..."); | 176 | log.info("Upgrading ThingsBoard from version 3.1.0 to 3.1.1 ..."); |
177 | databaseEntitiesUpgradeService.upgradeDatabase("3.1.0"); | 177 | databaseEntitiesUpgradeService.upgradeDatabase("3.1.0"); |
178 | + case "3.1.1": | ||
179 | + log.info("Upgrading ThingsBoard from version 3.1.1 to 3.2.0 ..."); | ||
180 | + databaseEntitiesUpgradeService.upgradeDatabase("3.1.1"); | ||
178 | log.info("Updating system data..."); | 181 | log.info("Updating system data..."); |
179 | systemDataLoaderService.updateSystemWidgets(); | 182 | systemDataLoaderService.updateSystemWidgets(); |
180 | break; | 183 | break; |
@@ -206,6 +209,7 @@ public class ThingsboardInstallService { | @@ -206,6 +209,7 @@ public class ThingsboardInstallService { | ||
206 | componentDiscoveryService.discoverComponents(); | 209 | componentDiscoveryService.discoverComponents(); |
207 | 210 | ||
208 | systemDataLoaderService.createSysAdmin(); | 211 | systemDataLoaderService.createSysAdmin(); |
212 | + systemDataLoaderService.createDefaultTenantProfile(); | ||
209 | systemDataLoaderService.createAdminSettings(); | 213 | systemDataLoaderService.createAdminSettings(); |
210 | systemDataLoaderService.loadSystemWidgets(); | 214 | systemDataLoaderService.loadSystemWidgets(); |
211 | // systemDataLoaderService.loadSystemPlugins(); | 215 | // systemDataLoaderService.loadSystemPlugins(); |
application/src/main/java/org/thingsboard/server/service/install/DefaultSystemDataLoaderService.java
@@ -28,6 +28,7 @@ import org.thingsboard.server.common.data.Customer; | @@ -28,6 +28,7 @@ import org.thingsboard.server.common.data.Customer; | ||
28 | import org.thingsboard.server.common.data.DataConstants; | 28 | import org.thingsboard.server.common.data.DataConstants; |
29 | import org.thingsboard.server.common.data.Device; | 29 | import org.thingsboard.server.common.data.Device; |
30 | import org.thingsboard.server.common.data.Tenant; | 30 | import org.thingsboard.server.common.data.Tenant; |
31 | +import org.thingsboard.server.common.data.TenantProfile; | ||
31 | import org.thingsboard.server.common.data.User; | 32 | import org.thingsboard.server.common.data.User; |
32 | import org.thingsboard.server.common.data.asset.Asset; | 33 | import org.thingsboard.server.common.data.asset.Asset; |
33 | import org.thingsboard.server.common.data.id.CustomerId; | 34 | import org.thingsboard.server.common.data.id.CustomerId; |
@@ -49,6 +50,7 @@ import org.thingsboard.server.dao.device.DeviceCredentialsService; | @@ -49,6 +50,7 @@ import org.thingsboard.server.dao.device.DeviceCredentialsService; | ||
49 | import org.thingsboard.server.dao.device.DeviceService; | 50 | import org.thingsboard.server.dao.device.DeviceService; |
50 | import org.thingsboard.server.dao.relation.RelationService; | 51 | import org.thingsboard.server.dao.relation.RelationService; |
51 | import org.thingsboard.server.dao.settings.AdminSettingsService; | 52 | import org.thingsboard.server.dao.settings.AdminSettingsService; |
53 | +import org.thingsboard.server.dao.tenant.TenantProfileService; | ||
52 | import org.thingsboard.server.dao.tenant.TenantService; | 54 | import org.thingsboard.server.dao.tenant.TenantService; |
53 | import org.thingsboard.server.dao.user.UserService; | 55 | import org.thingsboard.server.dao.user.UserService; |
54 | import org.thingsboard.server.dao.widget.WidgetsBundleService; | 56 | import org.thingsboard.server.dao.widget.WidgetsBundleService; |
@@ -83,6 +85,9 @@ public class DefaultSystemDataLoaderService implements SystemDataLoaderService { | @@ -83,6 +85,9 @@ public class DefaultSystemDataLoaderService implements SystemDataLoaderService { | ||
83 | private TenantService tenantService; | 85 | private TenantService tenantService; |
84 | 86 | ||
85 | @Autowired | 87 | @Autowired |
88 | + private TenantProfileService tenantProfileService; | ||
89 | + | ||
90 | + @Autowired | ||
86 | private CustomerService customerService; | 91 | private CustomerService customerService; |
87 | 92 | ||
88 | @Autowired | 93 | @Autowired |
@@ -111,6 +116,11 @@ public class DefaultSystemDataLoaderService implements SystemDataLoaderService { | @@ -111,6 +116,11 @@ public class DefaultSystemDataLoaderService implements SystemDataLoaderService { | ||
111 | } | 116 | } |
112 | 117 | ||
113 | @Override | 118 | @Override |
119 | + public void createDefaultTenantProfile() throws Exception { | ||
120 | + tenantProfileService.findOrCreateDefaultTenantProfile(TenantId.SYS_TENANT_ID); | ||
121 | + } | ||
122 | + | ||
123 | + @Override | ||
114 | public void createAdminSettings() throws Exception { | 124 | public void createAdminSettings() throws Exception { |
115 | AdminSettings generalSettings = new AdminSettings(); | 125 | AdminSettings generalSettings = new AdminSettings(); |
116 | generalSettings.setKey("general"); | 126 | generalSettings.setKey("general"); |
@@ -303,6 +303,14 @@ public class SqlDatabaseUpgradeService implements DatabaseEntitiesUpgradeService | @@ -303,6 +303,14 @@ public class SqlDatabaseUpgradeService implements DatabaseEntitiesUpgradeService | ||
303 | log.info("Schema updated."); | 303 | log.info("Schema updated."); |
304 | } | 304 | } |
305 | break; | 305 | break; |
306 | + case "3.1.1": | ||
307 | + try (Connection conn = DriverManager.getConnection(dbUrl, dbUserName, dbPassword)) { | ||
308 | + log.info("Updating schema ..."); | ||
309 | + schemaUpdateFile = Paths.get(installScripts.getDataDir(), "upgrade", "3.1.1", SCHEMA_UPDATE_SQL); | ||
310 | + loadSql(schemaUpdateFile, conn); | ||
311 | + log.info("Schema updated."); | ||
312 | + } | ||
313 | + break; | ||
306 | default: | 314 | default: |
307 | throw new RuntimeException("Unable to upgrade SQL database, unsupported fromVersion: " + fromVersion); | 315 | throw new RuntimeException("Unable to upgrade SQL database, unsupported fromVersion: " + fromVersion); |
308 | } | 316 | } |
@@ -19,6 +19,8 @@ public interface SystemDataLoaderService { | @@ -19,6 +19,8 @@ public interface SystemDataLoaderService { | ||
19 | 19 | ||
20 | void createSysAdmin() throws Exception; | 20 | void createSysAdmin() throws Exception; |
21 | 21 | ||
22 | + void createDefaultTenantProfile() throws Exception; | ||
23 | + | ||
22 | void createAdminSettings() throws Exception; | 24 | void createAdminSettings() throws Exception; |
23 | 25 | ||
24 | void loadSystemWidgets() throws Exception; | 26 | void loadSystemWidgets() throws Exception; |
@@ -19,7 +19,9 @@ import lombok.extern.slf4j.Slf4j; | @@ -19,7 +19,9 @@ import lombok.extern.slf4j.Slf4j; | ||
19 | import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; | 19 | import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; |
20 | import org.springframework.stereotype.Service; | 20 | import org.springframework.stereotype.Service; |
21 | import org.thingsboard.server.common.data.Tenant; | 21 | import org.thingsboard.server.common.data.Tenant; |
22 | +import org.thingsboard.server.common.data.TenantProfile; | ||
22 | import org.thingsboard.server.common.data.id.TenantId; | 23 | import org.thingsboard.server.common.data.id.TenantId; |
24 | +import org.thingsboard.server.dao.tenant.TenantProfileService; | ||
23 | import org.thingsboard.server.dao.tenant.TenantService; | 25 | import org.thingsboard.server.dao.tenant.TenantService; |
24 | import org.thingsboard.server.queue.discovery.TenantRoutingInfo; | 26 | import org.thingsboard.server.queue.discovery.TenantRoutingInfo; |
25 | import org.thingsboard.server.queue.discovery.TenantRoutingInfoService; | 27 | import org.thingsboard.server.queue.discovery.TenantRoutingInfoService; |
@@ -31,15 +33,20 @@ public class DefaultTenantRoutingInfoService implements TenantRoutingInfoService | @@ -31,15 +33,20 @@ public class DefaultTenantRoutingInfoService implements TenantRoutingInfoService | ||
31 | 33 | ||
32 | private final TenantService tenantService; | 34 | private final TenantService tenantService; |
33 | 35 | ||
34 | - public DefaultTenantRoutingInfoService(TenantService tenantService) { | 36 | + private final TenantProfileService tenantProfileService; |
37 | + | ||
38 | + public DefaultTenantRoutingInfoService(TenantService tenantService, TenantProfileService tenantProfileService) { | ||
35 | this.tenantService = tenantService; | 39 | this.tenantService = tenantService; |
40 | + this.tenantProfileService = tenantProfileService; | ||
36 | } | 41 | } |
37 | 42 | ||
38 | @Override | 43 | @Override |
39 | public TenantRoutingInfo getRoutingInfo(TenantId tenantId) { | 44 | public TenantRoutingInfo getRoutingInfo(TenantId tenantId) { |
40 | Tenant tenant = tenantService.findTenantById(tenantId); | 45 | Tenant tenant = tenantService.findTenantById(tenantId); |
41 | if (tenant != null) { | 46 | if (tenant != null) { |
42 | - return new TenantRoutingInfo(tenantId, tenant.isIsolatedTbCore(), tenant.isIsolatedTbRuleEngine()); | 47 | + // TODO: Tenant Profile from cache |
48 | + TenantProfile tenantProfile = tenantProfileService.findTenantProfileById(tenantId, tenant.getTenantProfileId()); | ||
49 | + return new TenantRoutingInfo(tenantId, tenantProfile.isIsolatedTbCore(), tenantProfile.isIsolatedTbRuleEngine()); | ||
43 | } else { | 50 | } else { |
44 | throw new RuntimeException("Tenant not found!"); | 51 | throw new RuntimeException("Tenant not found!"); |
45 | } | 52 | } |
@@ -28,6 +28,7 @@ import org.springframework.util.StringUtils; | @@ -28,6 +28,7 @@ import org.springframework.util.StringUtils; | ||
28 | import org.thingsboard.server.common.data.DataConstants; | 28 | import org.thingsboard.server.common.data.DataConstants; |
29 | import org.thingsboard.server.common.data.Device; | 29 | import org.thingsboard.server.common.data.Device; |
30 | import org.thingsboard.server.common.data.Tenant; | 30 | import org.thingsboard.server.common.data.Tenant; |
31 | +import org.thingsboard.server.common.data.TenantProfile; | ||
31 | import org.thingsboard.server.common.data.id.CustomerId; | 32 | import org.thingsboard.server.common.data.id.CustomerId; |
32 | import org.thingsboard.server.common.data.id.DeviceId; | 33 | import org.thingsboard.server.common.data.id.DeviceId; |
33 | import org.thingsboard.server.common.data.id.TenantId; | 34 | import org.thingsboard.server.common.data.id.TenantId; |
@@ -40,6 +41,7 @@ import org.thingsboard.server.common.msg.TbMsgMetaData; | @@ -40,6 +41,7 @@ import org.thingsboard.server.common.msg.TbMsgMetaData; | ||
40 | import org.thingsboard.server.dao.device.DeviceCredentialsService; | 41 | import org.thingsboard.server.dao.device.DeviceCredentialsService; |
41 | import org.thingsboard.server.dao.device.DeviceService; | 42 | import org.thingsboard.server.dao.device.DeviceService; |
42 | import org.thingsboard.server.dao.relation.RelationService; | 43 | import org.thingsboard.server.dao.relation.RelationService; |
44 | +import org.thingsboard.server.dao.tenant.TenantProfileService; | ||
43 | import org.thingsboard.server.dao.tenant.TenantService; | 45 | import org.thingsboard.server.dao.tenant.TenantService; |
44 | import org.thingsboard.server.gen.transport.TransportProtos.DeviceInfoProto; | 46 | import org.thingsboard.server.gen.transport.TransportProtos.DeviceInfoProto; |
45 | import org.thingsboard.server.gen.transport.TransportProtos.GetOrCreateDeviceFromGatewayRequestMsg; | 47 | import org.thingsboard.server.gen.transport.TransportProtos.GetOrCreateDeviceFromGatewayRequestMsg; |
@@ -78,6 +80,9 @@ public class DefaultTransportApiService implements TransportApiService { | @@ -78,6 +80,9 @@ public class DefaultTransportApiService implements TransportApiService { | ||
78 | private TenantService tenantService; | 80 | private TenantService tenantService; |
79 | 81 | ||
80 | @Autowired | 82 | @Autowired |
83 | + private TenantProfileService tenantProfileService; | ||
84 | + | ||
85 | + @Autowired | ||
81 | private DeviceService deviceService; | 86 | private DeviceService deviceService; |
82 | 87 | ||
83 | @Autowired | 88 | @Autowired |
@@ -168,10 +173,13 @@ public class DefaultTransportApiService implements TransportApiService { | @@ -168,10 +173,13 @@ public class DefaultTransportApiService implements TransportApiService { | ||
168 | 173 | ||
169 | private ListenableFuture<TransportApiResponseMsg> handle(GetTenantRoutingInfoRequestMsg requestMsg) { | 174 | private ListenableFuture<TransportApiResponseMsg> handle(GetTenantRoutingInfoRequestMsg requestMsg) { |
170 | TenantId tenantId = new TenantId(new UUID(requestMsg.getTenantIdMSB(), requestMsg.getTenantIdLSB())); | 175 | TenantId tenantId = new TenantId(new UUID(requestMsg.getTenantIdMSB(), requestMsg.getTenantIdLSB())); |
171 | - ListenableFuture<Tenant> tenantFuture = tenantService.findTenantByIdAsync(TenantId.SYS_TENANT_ID, tenantId); | ||
172 | - return Futures.transform(tenantFuture, tenant -> TransportApiResponseMsg.newBuilder() | ||
173 | - .setGetTenantRoutingInfoResponseMsg(GetTenantRoutingInfoResponseMsg.newBuilder().setIsolatedTbCore(tenant.isIsolatedTbCore()) | ||
174 | - .setIsolatedTbRuleEngine(tenant.isIsolatedTbRuleEngine()).build()).build(), dbCallbackExecutorService); | 176 | + // TODO: Tenant Profile from cache |
177 | + ListenableFuture<TenantProfile> tenantProfileFuture = | ||
178 | + Futures.transform(tenantService.findTenantByIdAsync(TenantId.SYS_TENANT_ID, tenantId), tenant -> | ||
179 | + tenantProfileService.findTenantProfileById(TenantId.SYS_TENANT_ID, tenant.getTenantProfileId()), dbCallbackExecutorService); | ||
180 | + return Futures.transform(tenantProfileFuture, tenantProfile -> TransportApiResponseMsg.newBuilder() | ||
181 | + .setGetTenantRoutingInfoResponseMsg(GetTenantRoutingInfoResponseMsg.newBuilder().setIsolatedTbCore(tenantProfile.isIsolatedTbCore()) | ||
182 | + .setIsolatedTbRuleEngine(tenantProfile.isIsolatedTbRuleEngine()).build()).build(), dbCallbackExecutorService); | ||
175 | } | 183 | } |
176 | 184 | ||
177 | private ListenableFuture<TransportApiResponseMsg> getDeviceInfo(DeviceId deviceId, DeviceCredentials credentials) { | 185 | private ListenableFuture<TransportApiResponseMsg> getDeviceInfo(DeviceId deviceId, DeviceCredentials credentials) { |
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.dao.device; | ||
17 | + | ||
18 | +import org.thingsboard.server.common.data.DeviceProfile; | ||
19 | +import org.thingsboard.server.common.data.EntityInfo; | ||
20 | +import org.thingsboard.server.common.data.id.DeviceProfileId; | ||
21 | +import org.thingsboard.server.common.data.id.TenantId; | ||
22 | +import org.thingsboard.server.common.data.page.PageData; | ||
23 | +import org.thingsboard.server.common.data.page.PageLink; | ||
24 | + | ||
25 | +public interface DeviceProfileService { | ||
26 | + | ||
27 | + DeviceProfile findDeviceProfileById(TenantId tenantId, DeviceProfileId deviceProfileId); | ||
28 | + | ||
29 | + EntityInfo findDeviceProfileInfoById(TenantId tenantId, DeviceProfileId deviceProfileId); | ||
30 | + | ||
31 | + DeviceProfile saveDeviceProfile(DeviceProfile deviceProfile); | ||
32 | + | ||
33 | + void deleteDeviceProfile(TenantId tenantId, DeviceProfileId deviceProfileId); | ||
34 | + | ||
35 | + PageData<DeviceProfile> findDeviceProfiles(TenantId tenantId, PageLink pageLink); | ||
36 | + | ||
37 | + PageData<EntityInfo> findDeviceProfileInfos(TenantId tenantId, PageLink pageLink); | ||
38 | + | ||
39 | + DeviceProfile createDefaultDeviceProfile(TenantId tenantId); | ||
40 | + | ||
41 | + DeviceProfile findDefaultDeviceProfile(TenantId tenantId); | ||
42 | + | ||
43 | + EntityInfo findDefaultDeviceProfileInfo(TenantId tenantId); | ||
44 | + | ||
45 | + boolean setDefaultDeviceProfile(TenantId tenantId, DeviceProfileId deviceProfileId); | ||
46 | + | ||
47 | + void deleteDeviceProfilesByTenantId(TenantId tenantId); | ||
48 | + | ||
49 | +} |
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.dao.tenant; | ||
17 | + | ||
18 | +import org.thingsboard.server.common.data.EntityInfo; | ||
19 | +import org.thingsboard.server.common.data.TenantProfile; | ||
20 | +import org.thingsboard.server.common.data.id.TenantId; | ||
21 | +import org.thingsboard.server.common.data.id.TenantProfileId; | ||
22 | +import org.thingsboard.server.common.data.page.PageData; | ||
23 | +import org.thingsboard.server.common.data.page.PageLink; | ||
24 | + | ||
25 | +public interface TenantProfileService { | ||
26 | + | ||
27 | + TenantProfile findTenantProfileById(TenantId tenantId, TenantProfileId tenantProfileId); | ||
28 | + | ||
29 | + EntityInfo findTenantProfileInfoById(TenantId tenantId, TenantProfileId tenantProfileId); | ||
30 | + | ||
31 | + TenantProfile saveTenantProfile(TenantId tenantId, TenantProfile tenantProfile); | ||
32 | + | ||
33 | + void deleteTenantProfile(TenantId tenantId, TenantProfileId tenantProfileId); | ||
34 | + | ||
35 | + PageData<TenantProfile> findTenantProfiles(TenantId tenantId, PageLink pageLink); | ||
36 | + | ||
37 | + PageData<EntityInfo> findTenantProfileInfos(TenantId tenantId, PageLink pageLink); | ||
38 | + | ||
39 | + TenantProfile findOrCreateDefaultTenantProfile(TenantId tenantId); | ||
40 | + | ||
41 | + TenantProfile findDefaultTenantProfile(TenantId tenantId); | ||
42 | + | ||
43 | + EntityInfo findDefaultTenantProfileInfo(TenantId tenantId); | ||
44 | + | ||
45 | + boolean setDefaultTenantProfile(TenantId tenantId, TenantProfileId tenantProfileId); | ||
46 | + | ||
47 | + void deleteTenantProfiles(TenantId tenantId); | ||
48 | + | ||
49 | +} |
@@ -18,6 +18,7 @@ package org.thingsboard.server.common.data; | @@ -18,6 +18,7 @@ package org.thingsboard.server.common.data; | ||
18 | import lombok.EqualsAndHashCode; | 18 | import lombok.EqualsAndHashCode; |
19 | import org.thingsboard.server.common.data.id.CustomerId; | 19 | import org.thingsboard.server.common.data.id.CustomerId; |
20 | import org.thingsboard.server.common.data.id.DeviceId; | 20 | import org.thingsboard.server.common.data.id.DeviceId; |
21 | +import org.thingsboard.server.common.data.id.DeviceProfileId; | ||
21 | import org.thingsboard.server.common.data.id.TenantId; | 22 | import org.thingsboard.server.common.data.id.TenantId; |
22 | 23 | ||
23 | @EqualsAndHashCode(callSuper = true) | 24 | @EqualsAndHashCode(callSuper = true) |
@@ -30,6 +31,7 @@ public class Device extends SearchTextBasedWithAdditionalInfo<DeviceId> implemen | @@ -30,6 +31,7 @@ public class Device extends SearchTextBasedWithAdditionalInfo<DeviceId> implemen | ||
30 | private String name; | 31 | private String name; |
31 | private String type; | 32 | private String type; |
32 | private String label; | 33 | private String label; |
34 | + private DeviceProfileId deviceProfileId; | ||
33 | 35 | ||
34 | public Device() { | 36 | public Device() { |
35 | super(); | 37 | super(); |
@@ -46,6 +48,7 @@ public class Device extends SearchTextBasedWithAdditionalInfo<DeviceId> implemen | @@ -46,6 +48,7 @@ public class Device extends SearchTextBasedWithAdditionalInfo<DeviceId> implemen | ||
46 | this.name = device.getName(); | 48 | this.name = device.getName(); |
47 | this.type = device.getType(); | 49 | this.type = device.getType(); |
48 | this.label = device.getLabel(); | 50 | this.label = device.getLabel(); |
51 | + this.deviceProfileId = device.getDeviceProfileId(); | ||
49 | } | 52 | } |
50 | 53 | ||
51 | public TenantId getTenantId() { | 54 | public TenantId getTenantId() { |
@@ -89,6 +92,14 @@ public class Device extends SearchTextBasedWithAdditionalInfo<DeviceId> implemen | @@ -89,6 +92,14 @@ public class Device extends SearchTextBasedWithAdditionalInfo<DeviceId> implemen | ||
89 | this.label = label; | 92 | this.label = label; |
90 | } | 93 | } |
91 | 94 | ||
95 | + public DeviceProfileId getDeviceProfileId() { | ||
96 | + return deviceProfileId; | ||
97 | + } | ||
98 | + | ||
99 | + public void setDeviceProfileId(DeviceProfileId deviceProfileId) { | ||
100 | + this.deviceProfileId = deviceProfileId; | ||
101 | + } | ||
102 | + | ||
92 | @Override | 103 | @Override |
93 | public String getSearchText() { | 104 | public String getSearchText() { |
94 | return getName(); | 105 | return getName(); |
@@ -107,6 +118,8 @@ public class Device extends SearchTextBasedWithAdditionalInfo<DeviceId> implemen | @@ -107,6 +118,8 @@ public class Device extends SearchTextBasedWithAdditionalInfo<DeviceId> implemen | ||
107 | builder.append(type); | 118 | builder.append(type); |
108 | builder.append(", label="); | 119 | builder.append(", label="); |
109 | builder.append(label); | 120 | builder.append(label); |
121 | + builder.append(", deviceProfileId="); | ||
122 | + builder.append(deviceProfileId); | ||
110 | builder.append(", additionalInfo="); | 123 | builder.append(", additionalInfo="); |
111 | builder.append(getAdditionalInfo()); | 124 | builder.append(getAdditionalInfo()); |
112 | builder.append(", createdTime="); | 125 | builder.append(", createdTime="); |
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; | ||
17 | + | ||
18 | +import com.fasterxml.jackson.annotation.JsonIgnore; | ||
19 | +import com.fasterxml.jackson.databind.JsonNode; | ||
20 | +import lombok.Data; | ||
21 | +import lombok.EqualsAndHashCode; | ||
22 | +import org.thingsboard.server.common.data.id.DeviceProfileId; | ||
23 | +import org.thingsboard.server.common.data.id.RuleChainId; | ||
24 | +import org.thingsboard.server.common.data.id.TenantId; | ||
25 | + | ||
26 | +import static org.thingsboard.server.common.data.SearchTextBasedWithAdditionalInfo.getJson; | ||
27 | +import static org.thingsboard.server.common.data.SearchTextBasedWithAdditionalInfo.setJson; | ||
28 | + | ||
29 | +@Data | ||
30 | +@EqualsAndHashCode(callSuper = true) | ||
31 | +public class DeviceProfile extends SearchTextBased<DeviceProfileId> implements HasName { | ||
32 | + | ||
33 | + private TenantId tenantId; | ||
34 | + private String name; | ||
35 | + private String description; | ||
36 | + private boolean isDefault; | ||
37 | + private RuleChainId defaultRuleChainId; | ||
38 | + private transient JsonNode profileData; | ||
39 | + @JsonIgnore | ||
40 | + private byte[] profileDataBytes; | ||
41 | + | ||
42 | + public DeviceProfile() { | ||
43 | + super(); | ||
44 | + } | ||
45 | + | ||
46 | + public DeviceProfile(DeviceProfileId deviceProfileId) { | ||
47 | + super(deviceProfileId); | ||
48 | + } | ||
49 | + | ||
50 | + public DeviceProfile(DeviceProfile deviceProfile) { | ||
51 | + super(deviceProfile); | ||
52 | + this.tenantId = deviceProfile.getTenantId(); | ||
53 | + this.name = deviceProfile.getName(); | ||
54 | + this.description = deviceProfile.getDescription(); | ||
55 | + this.isDefault = deviceProfile.isDefault(); | ||
56 | + this.defaultRuleChainId = deviceProfile.getDefaultRuleChainId(); | ||
57 | + this.setProfileData(deviceProfile.getProfileData()); | ||
58 | + } | ||
59 | + | ||
60 | + @Override | ||
61 | + public String getSearchText() { | ||
62 | + return getName(); | ||
63 | + } | ||
64 | + | ||
65 | + @Override | ||
66 | + public String getName() { | ||
67 | + return name; | ||
68 | + } | ||
69 | + | ||
70 | + public JsonNode getProfileData() { | ||
71 | + return getJson(() -> profileData, () -> profileDataBytes); | ||
72 | + } | ||
73 | + | ||
74 | + public void setProfileData(JsonNode data) { | ||
75 | + setJson(data, json -> this.profileData = json, bytes -> this.profileDataBytes = bytes); | ||
76 | + } | ||
77 | + | ||
78 | +} |
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; | ||
17 | + | ||
18 | +import lombok.Data; | ||
19 | +import org.thingsboard.server.common.data.id.EntityId; | ||
20 | +import org.thingsboard.server.common.data.id.EntityIdFactory; | ||
21 | +import org.thingsboard.server.common.data.id.HasId; | ||
22 | + | ||
23 | +import java.util.UUID; | ||
24 | + | ||
25 | +@Data | ||
26 | +public class EntityInfo implements HasId<EntityId>, HasName { | ||
27 | + | ||
28 | + private final EntityId id; | ||
29 | + private final String name; | ||
30 | + | ||
31 | + public EntityInfo(EntityId id, String name) { | ||
32 | + this.id = id; | ||
33 | + this.name = name; | ||
34 | + } | ||
35 | + | ||
36 | + public EntityInfo(UUID uuid, String type, String name) { | ||
37 | + this.id = EntityIdFactory.getByTypeAndUuid(type, uuid); | ||
38 | + this.name = name; | ||
39 | + } | ||
40 | + | ||
41 | +} |
@@ -19,5 +19,5 @@ package org.thingsboard.server.common.data; | @@ -19,5 +19,5 @@ package org.thingsboard.server.common.data; | ||
19 | * @author Andrew Shvayka | 19 | * @author Andrew Shvayka |
20 | */ | 20 | */ |
21 | public enum EntityType { | 21 | public enum EntityType { |
22 | - TENANT, CUSTOMER, USER, DASHBOARD, ASSET, DEVICE, ALARM, RULE_CHAIN, RULE_NODE, ENTITY_VIEW, WIDGETS_BUNDLE, WIDGET_TYPE | 22 | + TENANT, TENANT_PROFILE, CUSTOMER, USER, DASHBOARD, ASSET, DEVICE, DEVICE_PROFILE, ALARM, RULE_CHAIN, RULE_NODE, ENTITY_VIEW, WIDGETS_BUNDLE, WIDGET_TYPE |
23 | } | 23 | } |
@@ -19,8 +19,7 @@ import com.fasterxml.jackson.annotation.JsonIgnore; | @@ -19,8 +19,7 @@ import com.fasterxml.jackson.annotation.JsonIgnore; | ||
19 | import com.fasterxml.jackson.annotation.JsonProperty; | 19 | import com.fasterxml.jackson.annotation.JsonProperty; |
20 | import lombok.EqualsAndHashCode; | 20 | import lombok.EqualsAndHashCode; |
21 | import org.thingsboard.server.common.data.id.TenantId; | 21 | import org.thingsboard.server.common.data.id.TenantId; |
22 | - | ||
23 | -import com.fasterxml.jackson.databind.JsonNode; | 22 | +import org.thingsboard.server.common.data.id.TenantProfileId; |
24 | 23 | ||
25 | @EqualsAndHashCode(callSuper = true) | 24 | @EqualsAndHashCode(callSuper = true) |
26 | public class Tenant extends ContactBased<TenantId> implements HasTenantId { | 25 | public class Tenant extends ContactBased<TenantId> implements HasTenantId { |
@@ -29,8 +28,7 @@ public class Tenant extends ContactBased<TenantId> implements HasTenantId { | @@ -29,8 +28,7 @@ public class Tenant extends ContactBased<TenantId> implements HasTenantId { | ||
29 | 28 | ||
30 | private String title; | 29 | private String title; |
31 | private String region; | 30 | private String region; |
32 | - private boolean isolatedTbCore; | ||
33 | - private boolean isolatedTbRuleEngine; | 31 | + private TenantProfileId tenantProfileId; |
34 | 32 | ||
35 | public Tenant() { | 33 | public Tenant() { |
36 | super(); | 34 | super(); |
@@ -44,6 +42,7 @@ public class Tenant extends ContactBased<TenantId> implements HasTenantId { | @@ -44,6 +42,7 @@ public class Tenant extends ContactBased<TenantId> implements HasTenantId { | ||
44 | super(tenant); | 42 | super(tenant); |
45 | this.title = tenant.getTitle(); | 43 | this.title = tenant.getTitle(); |
46 | this.region = tenant.getRegion(); | 44 | this.region = tenant.getRegion(); |
45 | + this.tenantProfileId = tenant.getTenantProfileId(); | ||
47 | } | 46 | } |
48 | 47 | ||
49 | public String getTitle() { | 48 | public String getTitle() { |
@@ -74,20 +73,12 @@ public class Tenant extends ContactBased<TenantId> implements HasTenantId { | @@ -74,20 +73,12 @@ public class Tenant extends ContactBased<TenantId> implements HasTenantId { | ||
74 | this.region = region; | 73 | this.region = region; |
75 | } | 74 | } |
76 | 75 | ||
77 | - public boolean isIsolatedTbCore() { | ||
78 | - return isolatedTbCore; | ||
79 | - } | ||
80 | - | ||
81 | - public void setIsolatedTbCore(boolean isolatedTbCore) { | ||
82 | - this.isolatedTbCore = isolatedTbCore; | ||
83 | - } | ||
84 | - | ||
85 | - public boolean isIsolatedTbRuleEngine() { | ||
86 | - return isolatedTbRuleEngine; | 76 | + public TenantProfileId getTenantProfileId() { |
77 | + return tenantProfileId; | ||
87 | } | 78 | } |
88 | 79 | ||
89 | - public void setIsolatedTbRuleEngine(boolean isolatedTbRuleEngine) { | ||
90 | - this.isolatedTbRuleEngine = isolatedTbRuleEngine; | 80 | + public void setTenantProfileId(TenantProfileId tenantProfileId) { |
81 | + this.tenantProfileId = tenantProfileId; | ||
91 | } | 82 | } |
92 | 83 | ||
93 | @Override | 84 | @Override |
@@ -102,10 +93,8 @@ public class Tenant extends ContactBased<TenantId> implements HasTenantId { | @@ -102,10 +93,8 @@ public class Tenant extends ContactBased<TenantId> implements HasTenantId { | ||
102 | builder.append(title); | 93 | builder.append(title); |
103 | builder.append(", region="); | 94 | builder.append(", region="); |
104 | builder.append(region); | 95 | builder.append(region); |
105 | - builder.append(", isolatedTbCore="); | ||
106 | - builder.append(isolatedTbCore); | ||
107 | - builder.append(", isolatedTbRuleEngine="); | ||
108 | - builder.append(isolatedTbRuleEngine); | 96 | + builder.append(", tenantProfileId="); |
97 | + builder.append(tenantProfileId); | ||
109 | builder.append(", additionalInfo="); | 98 | builder.append(", additionalInfo="); |
110 | builder.append(getAdditionalInfo()); | 99 | builder.append(getAdditionalInfo()); |
111 | builder.append(", country="); | 100 | builder.append(", country="); |
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; | ||
17 | + | ||
18 | +import com.fasterxml.jackson.annotation.JsonIgnore; | ||
19 | +import com.fasterxml.jackson.databind.JsonNode; | ||
20 | +import lombok.Data; | ||
21 | +import lombok.EqualsAndHashCode; | ||
22 | +import org.thingsboard.server.common.data.id.TenantProfileId; | ||
23 | + | ||
24 | +import static org.thingsboard.server.common.data.SearchTextBasedWithAdditionalInfo.getJson; | ||
25 | +import static org.thingsboard.server.common.data.SearchTextBasedWithAdditionalInfo.setJson; | ||
26 | + | ||
27 | +@Data | ||
28 | +@EqualsAndHashCode(callSuper = true) | ||
29 | +public class TenantProfile extends SearchTextBased<TenantProfileId> implements HasName { | ||
30 | + | ||
31 | + private String name; | ||
32 | + private String description; | ||
33 | + private boolean isDefault; | ||
34 | + private boolean isolatedTbCore; | ||
35 | + private boolean isolatedTbRuleEngine; | ||
36 | + private transient JsonNode profileData; | ||
37 | + @JsonIgnore | ||
38 | + private byte[] profileDataBytes; | ||
39 | + | ||
40 | + public TenantProfile() { | ||
41 | + super(); | ||
42 | + } | ||
43 | + | ||
44 | + public TenantProfile(TenantProfileId tenantProfileId) { | ||
45 | + super(tenantProfileId); | ||
46 | + } | ||
47 | + | ||
48 | + public TenantProfile(TenantProfile tenantProfile) { | ||
49 | + super(tenantProfile); | ||
50 | + this.name = tenantProfile.getName(); | ||
51 | + this.description = tenantProfile.getDescription(); | ||
52 | + this.isDefault = tenantProfile.isDefault(); | ||
53 | + this.isolatedTbCore = tenantProfile.isIsolatedTbCore(); | ||
54 | + this.isolatedTbRuleEngine = tenantProfile.isIsolatedTbRuleEngine(); | ||
55 | + this.setProfileData(tenantProfile.getProfileData()); | ||
56 | + } | ||
57 | + | ||
58 | + @Override | ||
59 | + public String getSearchText() { | ||
60 | + return getName(); | ||
61 | + } | ||
62 | + | ||
63 | + @Override | ||
64 | + public String getName() { | ||
65 | + return name; | ||
66 | + } | ||
67 | + | ||
68 | + public JsonNode getProfileData() { | ||
69 | + return getJson(() -> profileData, () -> profileDataBytes); | ||
70 | + } | ||
71 | + | ||
72 | + public void setProfileData(JsonNode data) { | ||
73 | + setJson(data, json -> this.profileData = json, bytes -> this.profileDataBytes = bytes); | ||
74 | + } | ||
75 | + | ||
76 | +} |
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.id; | ||
17 | + | ||
18 | +import java.util.UUID; | ||
19 | + | ||
20 | +import com.fasterxml.jackson.annotation.JsonCreator; | ||
21 | +import com.fasterxml.jackson.annotation.JsonIgnore; | ||
22 | +import com.fasterxml.jackson.annotation.JsonProperty; | ||
23 | +import org.thingsboard.server.common.data.EntityType; | ||
24 | + | ||
25 | +public class DeviceProfileId extends UUIDBased implements EntityId { | ||
26 | + | ||
27 | + private static final long serialVersionUID = 1L; | ||
28 | + | ||
29 | + @JsonCreator | ||
30 | + public DeviceProfileId(@JsonProperty("id") UUID id) { | ||
31 | + super(id); | ||
32 | + } | ||
33 | + | ||
34 | + public static DeviceProfileId fromString(String deviceProfileId) { | ||
35 | + return new DeviceProfileId(UUID.fromString(deviceProfileId)); | ||
36 | + } | ||
37 | + | ||
38 | + @JsonIgnore | ||
39 | + @Override | ||
40 | + public EntityType getEntityType() { | ||
41 | + return EntityType.DEVICE_PROFILE; | ||
42 | + } | ||
43 | +} |
@@ -29,7 +29,7 @@ import java.util.UUID; | @@ -29,7 +29,7 @@ import java.util.UUID; | ||
29 | 29 | ||
30 | @JsonDeserialize(using = EntityIdDeserializer.class) | 30 | @JsonDeserialize(using = EntityIdDeserializer.class) |
31 | @JsonSerialize(using = EntityIdSerializer.class) | 31 | @JsonSerialize(using = EntityIdSerializer.class) |
32 | -public interface EntityId extends Serializable { //NOSONAR, the constant is closely related to EntityId | 32 | +public interface EntityId extends HasUUID, Serializable { //NOSONAR, the constant is closely related to EntityId |
33 | 33 | ||
34 | UUID NULL_UUID = UUID.fromString("13814000-1dd2-11b2-8080-808080808080"); | 34 | UUID NULL_UUID = UUID.fromString("13814000-1dd2-11b2-8080-808080808080"); |
35 | 35 |
@@ -62,6 +62,10 @@ public class EntityIdFactory { | @@ -62,6 +62,10 @@ public class EntityIdFactory { | ||
62 | return new WidgetsBundleId(uuid); | 62 | return new WidgetsBundleId(uuid); |
63 | case WIDGET_TYPE: | 63 | case WIDGET_TYPE: |
64 | return new WidgetTypeId(uuid); | 64 | return new WidgetTypeId(uuid); |
65 | + case DEVICE_PROFILE: | ||
66 | + return new DeviceProfileId(uuid); | ||
67 | + case TENANT_PROFILE: | ||
68 | + return new TenantProfileId(uuid); | ||
65 | } | 69 | } |
66 | throw new IllegalArgumentException("EntityType " + type + " is not supported!"); | 70 | throw new IllegalArgumentException("EntityType " + type + " is not supported!"); |
67 | } | 71 | } |
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.id; | ||
17 | + | ||
18 | +import java.io.Serializable; | ||
19 | + | ||
20 | +public interface HasId<I extends HasUUID> extends Serializable { | ||
21 | + | ||
22 | + I getId(); | ||
23 | + | ||
24 | +} |
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 | + | ||
17 | +package org.thingsboard.server.common.data.id; | ||
18 | + | ||
19 | +import java.util.UUID; | ||
20 | + | ||
21 | +public interface HasUUID { | ||
22 | + | ||
23 | + UUID getId(); | ||
24 | + | ||
25 | +} |
@@ -20,7 +20,7 @@ import com.fasterxml.jackson.annotation.JsonIgnore; | @@ -20,7 +20,7 @@ import com.fasterxml.jackson.annotation.JsonIgnore; | ||
20 | import java.io.Serializable; | 20 | import java.io.Serializable; |
21 | import java.util.UUID; | 21 | import java.util.UUID; |
22 | 22 | ||
23 | -public abstract class IdBased<I extends UUIDBased> implements Serializable { | 23 | +public abstract class IdBased<I extends UUIDBased> implements HasId<I> { |
24 | 24 | ||
25 | protected I id; | 25 | protected I id; |
26 | 26 |
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.id; | ||
17 | + | ||
18 | +import java.util.UUID; | ||
19 | + | ||
20 | +import com.fasterxml.jackson.annotation.JsonCreator; | ||
21 | +import com.fasterxml.jackson.annotation.JsonIgnore; | ||
22 | +import com.fasterxml.jackson.annotation.JsonProperty; | ||
23 | +import org.thingsboard.server.common.data.EntityType; | ||
24 | + | ||
25 | +public class TenantProfileId extends UUIDBased implements EntityId { | ||
26 | + | ||
27 | + private static final long serialVersionUID = 1L; | ||
28 | + | ||
29 | + @JsonCreator | ||
30 | + public TenantProfileId(@JsonProperty("id") UUID id) { | ||
31 | + super(id); | ||
32 | + } | ||
33 | + | ||
34 | + public static TenantProfileId fromString(String tenantProfileId) { | ||
35 | + return new TenantProfileId(UUID.fromString(tenantProfileId)); | ||
36 | + } | ||
37 | + | ||
38 | + @JsonIgnore | ||
39 | + @Override | ||
40 | + public EntityType getEntityType() { | ||
41 | + return EntityType.TENANT_PROFILE; | ||
42 | + } | ||
43 | +} |
@@ -18,7 +18,7 @@ package org.thingsboard.server.common.data.id; | @@ -18,7 +18,7 @@ package org.thingsboard.server.common.data.id; | ||
18 | import java.io.Serializable; | 18 | import java.io.Serializable; |
19 | import java.util.UUID; | 19 | import java.util.UUID; |
20 | 20 | ||
21 | -public abstract class UUIDBased implements Serializable { | 21 | +public abstract class UUIDBased implements HasUUID, Serializable { |
22 | 22 | ||
23 | private static final long serialVersionUID = 1L; | 23 | private static final long serialVersionUID = 1L; |
24 | 24 |
@@ -43,6 +43,10 @@ public abstract class DaoUtil { | @@ -43,6 +43,10 @@ public abstract class DaoUtil { | ||
43 | return new PageData(data, page.getTotalPages(), page.getTotalElements(), page.hasNext()); | 43 | return new PageData(data, page.getTotalPages(), page.getTotalElements(), page.hasNext()); |
44 | } | 44 | } |
45 | 45 | ||
46 | + public static <T> PageData<T> pageToPageData(Page<T> page) { | ||
47 | + return new PageData(page.getContent(), page.getTotalPages(), page.getTotalElements(), page.hasNext()); | ||
48 | + } | ||
49 | + | ||
46 | public static Pageable toPageable(PageLink pageLink) { | 50 | public static Pageable toPageable(PageLink pageLink) { |
47 | return toPageable(pageLink, Collections.emptyMap()); | 51 | return toPageable(pageLink, Collections.emptyMap()); |
48 | } | 52 | } |
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.dao.device; | ||
17 | + | ||
18 | +import org.thingsboard.server.common.data.DeviceProfile; | ||
19 | +import org.thingsboard.server.common.data.EntityInfo; | ||
20 | +import org.thingsboard.server.common.data.id.TenantId; | ||
21 | +import org.thingsboard.server.common.data.page.PageData; | ||
22 | +import org.thingsboard.server.common.data.page.PageLink; | ||
23 | +import org.thingsboard.server.dao.Dao; | ||
24 | + | ||
25 | +import java.util.UUID; | ||
26 | + | ||
27 | +public interface DeviceProfileDao extends Dao<DeviceProfile> { | ||
28 | + | ||
29 | + EntityInfo findDeviceProfileInfoById(TenantId tenantId, UUID deviceProfileId); | ||
30 | + | ||
31 | + DeviceProfile save(TenantId tenantId, DeviceProfile deviceProfile); | ||
32 | + | ||
33 | + PageData<DeviceProfile> findDeviceProfiles(TenantId tenantId, PageLink pageLink); | ||
34 | + | ||
35 | + PageData<EntityInfo> findDeviceProfileInfos(TenantId tenantId, PageLink pageLink); | ||
36 | + | ||
37 | + DeviceProfile findDefaultDeviceProfile(TenantId tenantId); | ||
38 | + | ||
39 | + EntityInfo findDefaultDeviceProfileInfo(TenantId tenantId); | ||
40 | +} |
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.dao.device; | ||
17 | + | ||
18 | +import lombok.extern.slf4j.Slf4j; | ||
19 | +import org.apache.commons.lang3.StringUtils; | ||
20 | +import org.hibernate.exception.ConstraintViolationException; | ||
21 | +import org.springframework.beans.factory.annotation.Autowired; | ||
22 | +import org.springframework.stereotype.Service; | ||
23 | +import org.thingsboard.server.common.data.DeviceProfile; | ||
24 | +import org.thingsboard.server.common.data.EntityInfo; | ||
25 | +import org.thingsboard.server.common.data.Tenant; | ||
26 | +import org.thingsboard.server.common.data.id.DeviceProfileId; | ||
27 | +import org.thingsboard.server.common.data.id.TenantId; | ||
28 | +import org.thingsboard.server.common.data.page.PageData; | ||
29 | +import org.thingsboard.server.common.data.page.PageLink; | ||
30 | +import org.thingsboard.server.dao.entity.AbstractEntityService; | ||
31 | +import org.thingsboard.server.dao.exception.DataValidationException; | ||
32 | +import org.thingsboard.server.dao.service.DataValidator; | ||
33 | +import org.thingsboard.server.dao.service.PaginatedRemover; | ||
34 | +import org.thingsboard.server.dao.service.Validator; | ||
35 | +import org.thingsboard.server.dao.tenant.TenantDao; | ||
36 | +import org.thingsboard.server.dao.util.mapping.JacksonUtil; | ||
37 | + | ||
38 | +import static org.thingsboard.server.dao.service.Validator.validateId; | ||
39 | + | ||
40 | +@Service | ||
41 | +@Slf4j | ||
42 | +public class DeviceProfileServiceImpl extends AbstractEntityService implements DeviceProfileService { | ||
43 | + | ||
44 | + private static final String INCORRECT_TENANT_ID = "Incorrect tenantId "; | ||
45 | + private static final String INCORRECT_DEVICE_PROFILE_ID = "Incorrect deviceProfileId "; | ||
46 | + | ||
47 | + @Autowired | ||
48 | + private DeviceProfileDao deviceProfileDao; | ||
49 | + | ||
50 | + @Autowired | ||
51 | + private TenantDao tenantDao; | ||
52 | + | ||
53 | + @Override | ||
54 | + public DeviceProfile findDeviceProfileById(TenantId tenantId, DeviceProfileId deviceProfileId) { | ||
55 | + log.trace("Executing findDeviceProfileById [{}]", deviceProfileId); | ||
56 | + Validator.validateId(deviceProfileId, INCORRECT_DEVICE_PROFILE_ID + deviceProfileId); | ||
57 | + return deviceProfileDao.findById(tenantId, deviceProfileId.getId()); | ||
58 | + } | ||
59 | + | ||
60 | + @Override | ||
61 | + public EntityInfo findDeviceProfileInfoById(TenantId tenantId, DeviceProfileId deviceProfileId) { | ||
62 | + log.trace("Executing findDeviceProfileById [{}]", deviceProfileId); | ||
63 | + Validator.validateId(deviceProfileId, INCORRECT_DEVICE_PROFILE_ID + deviceProfileId); | ||
64 | + return deviceProfileDao.findDeviceProfileInfoById(tenantId, deviceProfileId.getId()); | ||
65 | + } | ||
66 | + | ||
67 | + @Override | ||
68 | + public DeviceProfile saveDeviceProfile(DeviceProfile deviceProfile) { | ||
69 | + log.trace("Executing saveDeviceProfile [{}]", deviceProfile); | ||
70 | + deviceProfileValidator.validate(deviceProfile, DeviceProfile::getTenantId); | ||
71 | + DeviceProfile savedDeviceProfile; | ||
72 | + try { | ||
73 | + savedDeviceProfile = deviceProfileDao.save(deviceProfile.getTenantId(), deviceProfile); | ||
74 | + } catch (Exception t) { | ||
75 | + ConstraintViolationException e = extractConstraintViolationException(t).orElse(null); | ||
76 | + if (e != null && e.getConstraintName() != null && e.getConstraintName().equalsIgnoreCase("device_profile_name_unq_key")) { | ||
77 | + throw new DataValidationException("Device profile with such name already exists!"); | ||
78 | + } else { | ||
79 | + throw t; | ||
80 | + } | ||
81 | + } | ||
82 | + return savedDeviceProfile; | ||
83 | + } | ||
84 | + | ||
85 | + @Override | ||
86 | + public void deleteDeviceProfile(TenantId tenantId, DeviceProfileId deviceProfileId) { | ||
87 | + log.trace("Executing deleteDeviceProfile [{}]", deviceProfileId); | ||
88 | + Validator.validateId(deviceProfileId, INCORRECT_DEVICE_PROFILE_ID + deviceProfileId); | ||
89 | + deleteEntityRelations(tenantId, deviceProfileId); | ||
90 | + deviceProfileDao.removeById(tenantId, deviceProfileId.getId()); | ||
91 | + } | ||
92 | + | ||
93 | + @Override | ||
94 | + public PageData<DeviceProfile> findDeviceProfiles(TenantId tenantId, PageLink pageLink) { | ||
95 | + log.trace("Executing findDeviceProfiles tenantId [{}], pageLink [{}]", tenantId, pageLink); | ||
96 | + validateId(tenantId, INCORRECT_TENANT_ID + tenantId); | ||
97 | + Validator.validatePageLink(pageLink); | ||
98 | + return deviceProfileDao.findDeviceProfiles(tenantId, pageLink); | ||
99 | + } | ||
100 | + | ||
101 | + @Override | ||
102 | + public PageData<EntityInfo> findDeviceProfileInfos(TenantId tenantId, PageLink pageLink) { | ||
103 | + log.trace("Executing findDeviceProfileInfos tenantId [{}], pageLink [{}]", tenantId, pageLink); | ||
104 | + validateId(tenantId, INCORRECT_TENANT_ID + tenantId); | ||
105 | + Validator.validatePageLink(pageLink); | ||
106 | + return deviceProfileDao.findDeviceProfileInfos(tenantId, pageLink); | ||
107 | + } | ||
108 | + | ||
109 | + @Override | ||
110 | + public DeviceProfile createDefaultDeviceProfile(TenantId tenantId) { | ||
111 | + log.trace("Executing createDefaultDeviceProfile tenantId [{}]", tenantId); | ||
112 | + validateId(tenantId, INCORRECT_TENANT_ID + tenantId); | ||
113 | + DeviceProfile deviceProfile = new DeviceProfile(); | ||
114 | + deviceProfile.setTenantId(tenantId); | ||
115 | + deviceProfile.setDefault(true); | ||
116 | + deviceProfile.setName("Default"); | ||
117 | + deviceProfile.setDescription("Default device profile"); | ||
118 | + deviceProfile.setProfileData(JacksonUtil.OBJECT_MAPPER.createObjectNode()); | ||
119 | + return deviceProfileDao.save(tenantId, deviceProfile); | ||
120 | + } | ||
121 | + | ||
122 | + @Override | ||
123 | + public DeviceProfile findDefaultDeviceProfile(TenantId tenantId) { | ||
124 | + log.trace("Executing findDefaultDeviceProfile tenantId [{}]", tenantId); | ||
125 | + validateId(tenantId, INCORRECT_TENANT_ID + tenantId); | ||
126 | + return deviceProfileDao.findDefaultDeviceProfile(tenantId); | ||
127 | + } | ||
128 | + | ||
129 | + @Override | ||
130 | + public EntityInfo findDefaultDeviceProfileInfo(TenantId tenantId) { | ||
131 | + log.trace("Executing findDefaultDeviceProfileInfo tenantId [{}]", tenantId); | ||
132 | + validateId(tenantId, INCORRECT_TENANT_ID + tenantId); | ||
133 | + return deviceProfileDao.findDefaultDeviceProfileInfo(tenantId); | ||
134 | + } | ||
135 | + | ||
136 | + @Override | ||
137 | + public boolean setDefaultDeviceProfile(TenantId tenantId, DeviceProfileId deviceProfileId) { | ||
138 | + log.trace("Executing setDefaultDeviceProfile [{}]", deviceProfileId); | ||
139 | + Validator.validateId(deviceProfileId, INCORRECT_DEVICE_PROFILE_ID + deviceProfileId); | ||
140 | + DeviceProfile deviceProfile = deviceProfileDao.findById(tenantId, deviceProfileId.getId()); | ||
141 | + if (!deviceProfile.isDefault()) { | ||
142 | + deviceProfile.setDefault(true); | ||
143 | + DeviceProfile previousDefaultDeviceProfile = findDefaultDeviceProfile(tenantId); | ||
144 | + if (previousDefaultDeviceProfile == null) { | ||
145 | + deviceProfileDao.save(tenantId, deviceProfile); | ||
146 | + return true; | ||
147 | + } else if (!previousDefaultDeviceProfile.getId().equals(deviceProfile.getId())) { | ||
148 | + previousDefaultDeviceProfile.setDefault(false); | ||
149 | + deviceProfileDao.save(tenantId, previousDefaultDeviceProfile); | ||
150 | + deviceProfileDao.save(tenantId, deviceProfile); | ||
151 | + return true; | ||
152 | + } | ||
153 | + } | ||
154 | + return false; | ||
155 | + } | ||
156 | + | ||
157 | + @Override | ||
158 | + public void deleteDeviceProfilesByTenantId(TenantId tenantId) { | ||
159 | + log.trace("Executing deleteDeviceProfilesByTenantId, tenantId [{}]", tenantId); | ||
160 | + validateId(tenantId, INCORRECT_TENANT_ID + tenantId); | ||
161 | + tenantDeviceProfilesRemover.removeEntities(tenantId, tenantId); | ||
162 | + } | ||
163 | + | ||
164 | + private DataValidator<DeviceProfile> deviceProfileValidator = | ||
165 | + new DataValidator<DeviceProfile>() { | ||
166 | + @Override | ||
167 | + protected void validateDataImpl(TenantId tenantId, DeviceProfile deviceProfile) { | ||
168 | + if (StringUtils.isEmpty(deviceProfile.getName())) { | ||
169 | + throw new DataValidationException("Device profile name should be specified!"); | ||
170 | + } | ||
171 | + if (deviceProfile.getTenantId() == null) { | ||
172 | + throw new DataValidationException("Device profile should be assigned to tenant!"); | ||
173 | + } else { | ||
174 | + Tenant tenant = tenantDao.findById(deviceProfile.getTenantId(), deviceProfile.getTenantId().getId()); | ||
175 | + if (tenant == null) { | ||
176 | + throw new DataValidationException("Device profile is referencing to non-existent tenant!"); | ||
177 | + } | ||
178 | + } | ||
179 | + if (deviceProfile.isDefault()) { | ||
180 | + DeviceProfile defaultDeviceProfile = findDefaultDeviceProfile(tenantId); | ||
181 | + if (defaultDeviceProfile != null && !defaultDeviceProfile.getId().equals(deviceProfile.getId())) { | ||
182 | + throw new DataValidationException("Another default device profile is present in scope of current tenant!"); | ||
183 | + } | ||
184 | + } | ||
185 | + } | ||
186 | + }; | ||
187 | + | ||
188 | + private PaginatedRemover<TenantId, DeviceProfile> tenantDeviceProfilesRemover = | ||
189 | + new PaginatedRemover<TenantId, DeviceProfile>() { | ||
190 | + | ||
191 | + @Override | ||
192 | + protected PageData<DeviceProfile> findEntities(TenantId tenantId, TenantId id, PageLink pageLink) { | ||
193 | + return deviceProfileDao.findDeviceProfiles(id, pageLink); | ||
194 | + } | ||
195 | + | ||
196 | + @Override | ||
197 | + protected void removeEntity(TenantId tenantId, DeviceProfile entity) { | ||
198 | + deleteDeviceProfile(tenantId, new DeviceProfileId(entity.getUuidId())); | ||
199 | + } | ||
200 | + }; | ||
201 | + | ||
202 | +} |
@@ -34,6 +34,8 @@ import org.springframework.util.StringUtils; | @@ -34,6 +34,8 @@ import org.springframework.util.StringUtils; | ||
34 | import org.thingsboard.server.common.data.Customer; | 34 | import org.thingsboard.server.common.data.Customer; |
35 | import org.thingsboard.server.common.data.Device; | 35 | import org.thingsboard.server.common.data.Device; |
36 | import org.thingsboard.server.common.data.DeviceInfo; | 36 | import org.thingsboard.server.common.data.DeviceInfo; |
37 | +import org.thingsboard.server.common.data.DeviceProfile; | ||
38 | +import org.thingsboard.server.common.data.EntityInfo; | ||
37 | import org.thingsboard.server.common.data.EntitySubtype; | 39 | import org.thingsboard.server.common.data.EntitySubtype; |
38 | import org.thingsboard.server.common.data.EntityType; | 40 | import org.thingsboard.server.common.data.EntityType; |
39 | import org.thingsboard.server.common.data.EntityView; | 41 | import org.thingsboard.server.common.data.EntityView; |
@@ -41,6 +43,7 @@ import org.thingsboard.server.common.data.Tenant; | @@ -41,6 +43,7 @@ import org.thingsboard.server.common.data.Tenant; | ||
41 | import org.thingsboard.server.common.data.device.DeviceSearchQuery; | 43 | import org.thingsboard.server.common.data.device.DeviceSearchQuery; |
42 | import org.thingsboard.server.common.data.id.CustomerId; | 44 | import org.thingsboard.server.common.data.id.CustomerId; |
43 | import org.thingsboard.server.common.data.id.DeviceId; | 45 | import org.thingsboard.server.common.data.id.DeviceId; |
46 | +import org.thingsboard.server.common.data.id.DeviceProfileId; | ||
44 | import org.thingsboard.server.common.data.id.EntityId; | 47 | import org.thingsboard.server.common.data.id.EntityId; |
45 | import org.thingsboard.server.common.data.id.TenantId; | 48 | import org.thingsboard.server.common.data.id.TenantId; |
46 | import org.thingsboard.server.common.data.page.PageData; | 49 | import org.thingsboard.server.common.data.page.PageData; |
@@ -96,6 +99,9 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe | @@ -96,6 +99,9 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe | ||
96 | private DeviceCredentialsService deviceCredentialsService; | 99 | private DeviceCredentialsService deviceCredentialsService; |
97 | 100 | ||
98 | @Autowired | 101 | @Autowired |
102 | + private DeviceProfileService deviceProfileService; | ||
103 | + | ||
104 | + @Autowired | ||
99 | private EntityViewService entityViewService; | 105 | private EntityViewService entityViewService; |
100 | 106 | ||
101 | @Autowired | 107 | @Autowired |
@@ -159,6 +165,10 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe | @@ -159,6 +165,10 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe | ||
159 | deviceValidator.validate(device, Device::getTenantId); | 165 | deviceValidator.validate(device, Device::getTenantId); |
160 | Device savedDevice; | 166 | Device savedDevice; |
161 | try { | 167 | try { |
168 | + if (device.getDeviceProfileId() == null) { | ||
169 | + EntityInfo deviceProfile = this.deviceProfileService.findDefaultDeviceProfileInfo(device.getTenantId()); | ||
170 | + device.setDeviceProfileId(new DeviceProfileId(deviceProfile.getId().getId())); | ||
171 | + } | ||
162 | savedDevice = deviceDao.save(device.getTenantId(), device); | 172 | savedDevice = deviceDao.save(device.getTenantId(), device); |
163 | } catch (Exception t) { | 173 | } catch (Exception t) { |
164 | ConstraintViolationException e = extractConstraintViolationException(t).orElse(null); | 174 | ConstraintViolationException e = extractConstraintViolationException(t).orElse(null); |
@@ -114,12 +114,22 @@ public class ModelConstants { | @@ -114,12 +114,22 @@ public class ModelConstants { | ||
114 | public static final String TENANT_TITLE_PROPERTY = TITLE_PROPERTY; | 114 | public static final String TENANT_TITLE_PROPERTY = TITLE_PROPERTY; |
115 | public static final String TENANT_REGION_PROPERTY = "region"; | 115 | public static final String TENANT_REGION_PROPERTY = "region"; |
116 | public static final String TENANT_ADDITIONAL_INFO_PROPERTY = ADDITIONAL_INFO_PROPERTY; | 116 | public static final String TENANT_ADDITIONAL_INFO_PROPERTY = ADDITIONAL_INFO_PROPERTY; |
117 | - public static final String TENANT_ISOLATED_TB_CORE = "isolated_tb_core"; | ||
118 | - public static final String TENANT_ISOLATED_TB_RULE_ENGINE = "isolated_tb_rule_engine"; | 117 | + public static final String TENANT_TENANT_PROFILE_ID_PROPERTY = "tenant_profile_id"; |
119 | 118 | ||
120 | public static final String TENANT_BY_REGION_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME = "tenant_by_region_and_search_text"; | 119 | public static final String TENANT_BY_REGION_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME = "tenant_by_region_and_search_text"; |
121 | 120 | ||
122 | /** | 121 | /** |
122 | + * Tenant profile constants. | ||
123 | + */ | ||
124 | + public static final String TENANT_PROFILE_COLUMN_FAMILY_NAME = "tenant_profile"; | ||
125 | + public static final String TENANT_PROFILE_NAME_PROPERTY = "name"; | ||
126 | + public static final String TENANT_PROFILE_PROFILE_DATA_PROPERTY = "profile_data"; | ||
127 | + public static final String TENANT_PROFILE_DESCRIPTION_PROPERTY = "description"; | ||
128 | + public static final String TENANT_PROFILE_IS_DEFAULT_PROPERTY = "is_default"; | ||
129 | + public static final String TENANT_PROFILE_ISOLATED_TB_CORE = "isolated_tb_core"; | ||
130 | + public static final String TENANT_PROFILE_ISOLATED_TB_RULE_ENGINE = "isolated_tb_rule_engine"; | ||
131 | + | ||
132 | + /** | ||
123 | * Cassandra customer constants. | 133 | * Cassandra customer constants. |
124 | */ | 134 | */ |
125 | public static final String CUSTOMER_COLUMN_FAMILY_NAME = "customer"; | 135 | public static final String CUSTOMER_COLUMN_FAMILY_NAME = "customer"; |
@@ -141,6 +151,7 @@ public class ModelConstants { | @@ -141,6 +151,7 @@ public class ModelConstants { | ||
141 | public static final String DEVICE_TYPE_PROPERTY = "type"; | 151 | public static final String DEVICE_TYPE_PROPERTY = "type"; |
142 | public static final String DEVICE_LABEL_PROPERTY = "label"; | 152 | public static final String DEVICE_LABEL_PROPERTY = "label"; |
143 | public static final String DEVICE_ADDITIONAL_INFO_PROPERTY = ADDITIONAL_INFO_PROPERTY; | 153 | public static final String DEVICE_ADDITIONAL_INFO_PROPERTY = ADDITIONAL_INFO_PROPERTY; |
154 | + public static final String DEVICE_DEVICE_PROFILE_ID_PROPERTY = "device_profile_id"; | ||
144 | public static final String DEVICE_BY_TENANT_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME = "device_by_tenant_and_search_text"; | 155 | public static final String DEVICE_BY_TENANT_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME = "device_by_tenant_and_search_text"; |
145 | public static final String DEVICE_BY_TENANT_BY_TYPE_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME = "device_by_tenant_by_type_and_search_text"; | 156 | public static final String DEVICE_BY_TENANT_BY_TYPE_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME = "device_by_tenant_by_type_and_search_text"; |
146 | public static final String DEVICE_BY_CUSTOMER_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME = "device_by_customer_and_search_text"; | 157 | public static final String DEVICE_BY_CUSTOMER_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME = "device_by_customer_and_search_text"; |
@@ -149,6 +160,17 @@ public class ModelConstants { | @@ -149,6 +160,17 @@ public class ModelConstants { | ||
149 | public static final String DEVICE_TYPES_BY_TENANT_VIEW_NAME = "device_types_by_tenant"; | 160 | public static final String DEVICE_TYPES_BY_TENANT_VIEW_NAME = "device_types_by_tenant"; |
150 | 161 | ||
151 | /** | 162 | /** |
163 | + * Device profile constants. | ||
164 | + */ | ||
165 | + public static final String DEVICE_PROFILE_COLUMN_FAMILY_NAME = "device_profile"; | ||
166 | + public static final String DEVICE_PROFILE_TENANT_ID_PROPERTY = TENANT_ID_PROPERTY; | ||
167 | + public static final String DEVICE_PROFILE_NAME_PROPERTY = "name"; | ||
168 | + public static final String DEVICE_PROFILE_PROFILE_DATA_PROPERTY = "profile_data"; | ||
169 | + public static final String DEVICE_PROFILE_DESCRIPTION_PROPERTY = "description"; | ||
170 | + public static final String DEVICE_PROFILE_IS_DEFAULT_PROPERTY = "is_default"; | ||
171 | + public static final String DEVICE_PROFILE_DEFAULT_RULE_CHAIN_ID_PROPERTY = "default_rule_chain_id"; | ||
172 | + | ||
173 | + /** | ||
152 | * Cassandra entityView constants. | 174 | * Cassandra entityView constants. |
153 | */ | 175 | */ |
154 | public static final String ENTITY_VIEW_TABLE_FAMILY_NAME = "entity_view"; | 176 | public static final String ENTITY_VIEW_TABLE_FAMILY_NAME = "entity_view"; |
@@ -23,6 +23,7 @@ import org.hibernate.annotations.TypeDef; | @@ -23,6 +23,7 @@ import org.hibernate.annotations.TypeDef; | ||
23 | import org.thingsboard.server.common.data.Device; | 23 | import org.thingsboard.server.common.data.Device; |
24 | import org.thingsboard.server.common.data.id.CustomerId; | 24 | import org.thingsboard.server.common.data.id.CustomerId; |
25 | import org.thingsboard.server.common.data.id.DeviceId; | 25 | import org.thingsboard.server.common.data.id.DeviceId; |
26 | +import org.thingsboard.server.common.data.id.DeviceProfileId; | ||
26 | import org.thingsboard.server.common.data.id.TenantId; | 27 | import org.thingsboard.server.common.data.id.TenantId; |
27 | import org.thingsboard.server.dao.model.BaseSqlEntity; | 28 | import org.thingsboard.server.dao.model.BaseSqlEntity; |
28 | import org.thingsboard.server.dao.model.ModelConstants; | 29 | import org.thingsboard.server.dao.model.ModelConstants; |
@@ -61,6 +62,9 @@ public abstract class AbstractDeviceEntity<T extends Device> extends BaseSqlEnti | @@ -61,6 +62,9 @@ public abstract class AbstractDeviceEntity<T extends Device> extends BaseSqlEnti | ||
61 | @Column(name = ModelConstants.DEVICE_ADDITIONAL_INFO_PROPERTY) | 62 | @Column(name = ModelConstants.DEVICE_ADDITIONAL_INFO_PROPERTY) |
62 | private JsonNode additionalInfo; | 63 | private JsonNode additionalInfo; |
63 | 64 | ||
65 | + @Column(name = ModelConstants.DEVICE_DEVICE_PROFILE_ID_PROPERTY, columnDefinition = "uuid") | ||
66 | + private UUID deviceProfileId; | ||
67 | + | ||
64 | public AbstractDeviceEntity() { | 68 | public AbstractDeviceEntity() { |
65 | super(); | 69 | super(); |
66 | } | 70 | } |
@@ -76,6 +80,9 @@ public abstract class AbstractDeviceEntity<T extends Device> extends BaseSqlEnti | @@ -76,6 +80,9 @@ public abstract class AbstractDeviceEntity<T extends Device> extends BaseSqlEnti | ||
76 | if (device.getCustomerId() != null) { | 80 | if (device.getCustomerId() != null) { |
77 | this.customerId = device.getCustomerId().getId(); | 81 | this.customerId = device.getCustomerId().getId(); |
78 | } | 82 | } |
83 | + if (device.getDeviceProfileId() != null) { | ||
84 | + this.deviceProfileId = device.getDeviceProfileId().getId(); | ||
85 | + } | ||
79 | this.name = device.getName(); | 86 | this.name = device.getName(); |
80 | this.type = device.getType(); | 87 | this.type = device.getType(); |
81 | this.label = device.getLabel(); | 88 | this.label = device.getLabel(); |
@@ -87,6 +94,7 @@ public abstract class AbstractDeviceEntity<T extends Device> extends BaseSqlEnti | @@ -87,6 +94,7 @@ public abstract class AbstractDeviceEntity<T extends Device> extends BaseSqlEnti | ||
87 | this.setCreatedTime(deviceEntity.getCreatedTime()); | 94 | this.setCreatedTime(deviceEntity.getCreatedTime()); |
88 | this.tenantId = deviceEntity.getTenantId(); | 95 | this.tenantId = deviceEntity.getTenantId(); |
89 | this.customerId = deviceEntity.getCustomerId(); | 96 | this.customerId = deviceEntity.getCustomerId(); |
97 | + this.deviceProfileId = deviceEntity.getDeviceProfileId(); | ||
90 | this.type = deviceEntity.getType(); | 98 | this.type = deviceEntity.getType(); |
91 | this.name = deviceEntity.getName(); | 99 | this.name = deviceEntity.getName(); |
92 | this.label = deviceEntity.getLabel(); | 100 | this.label = deviceEntity.getLabel(); |
@@ -113,6 +121,9 @@ public abstract class AbstractDeviceEntity<T extends Device> extends BaseSqlEnti | @@ -113,6 +121,9 @@ public abstract class AbstractDeviceEntity<T extends Device> extends BaseSqlEnti | ||
113 | if (customerId != null) { | 121 | if (customerId != null) { |
114 | device.setCustomerId(new CustomerId(customerId)); | 122 | device.setCustomerId(new CustomerId(customerId)); |
115 | } | 123 | } |
124 | + if (deviceProfileId != null) { | ||
125 | + device.setDeviceProfileId(new DeviceProfileId(deviceProfileId)); | ||
126 | + } | ||
116 | device.setName(name); | 127 | device.setName(name); |
117 | device.setType(type); | 128 | device.setType(type); |
118 | device.setLabel(label); | 129 | device.setLabel(label); |
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.dao.model.sql; | ||
17 | + | ||
18 | +import com.fasterxml.jackson.databind.JsonNode; | ||
19 | +import lombok.Data; | ||
20 | +import lombok.EqualsAndHashCode; | ||
21 | +import org.hibernate.annotations.Type; | ||
22 | +import org.hibernate.annotations.TypeDef; | ||
23 | +import org.thingsboard.server.common.data.DeviceProfile; | ||
24 | +import org.thingsboard.server.common.data.id.DeviceProfileId; | ||
25 | +import org.thingsboard.server.common.data.id.RuleChainId; | ||
26 | +import org.thingsboard.server.common.data.id.TenantId; | ||
27 | +import org.thingsboard.server.dao.model.BaseSqlEntity; | ||
28 | +import org.thingsboard.server.dao.model.ModelConstants; | ||
29 | +import org.thingsboard.server.dao.model.SearchTextEntity; | ||
30 | +import org.thingsboard.server.dao.util.mapping.JsonStringType; | ||
31 | + | ||
32 | +import javax.persistence.Column; | ||
33 | +import javax.persistence.Entity; | ||
34 | +import javax.persistence.Table; | ||
35 | +import java.util.UUID; | ||
36 | + | ||
37 | +@Data | ||
38 | +@EqualsAndHashCode(callSuper = true) | ||
39 | +@Entity | ||
40 | +@TypeDef(name = "json", typeClass = JsonStringType.class) | ||
41 | +@Table(name = ModelConstants.DEVICE_PROFILE_COLUMN_FAMILY_NAME) | ||
42 | +public final class DeviceProfileEntity extends BaseSqlEntity<DeviceProfile> implements SearchTextEntity<DeviceProfile> { | ||
43 | + | ||
44 | + @Column(name = ModelConstants.DEVICE_PROFILE_TENANT_ID_PROPERTY) | ||
45 | + private UUID tenantId; | ||
46 | + | ||
47 | + @Column(name = ModelConstants.DEVICE_PROFILE_NAME_PROPERTY) | ||
48 | + private String name; | ||
49 | + | ||
50 | + @Column(name = ModelConstants.DEVICE_PROFILE_DESCRIPTION_PROPERTY) | ||
51 | + private String description; | ||
52 | + | ||
53 | + @Column(name = ModelConstants.SEARCH_TEXT_PROPERTY) | ||
54 | + private String searchText; | ||
55 | + | ||
56 | + @Column(name = ModelConstants.DEVICE_PROFILE_IS_DEFAULT_PROPERTY) | ||
57 | + private boolean isDefault; | ||
58 | + | ||
59 | + @Column(name = ModelConstants.DEVICE_PROFILE_DEFAULT_RULE_CHAIN_ID_PROPERTY, columnDefinition = "uuid") | ||
60 | + private UUID defaultRuleChainId; | ||
61 | + | ||
62 | + @Type(type = "json") | ||
63 | + @Column(name = ModelConstants.DEVICE_PROFILE_PROFILE_DATA_PROPERTY) | ||
64 | + private JsonNode profileData; | ||
65 | + | ||
66 | + public DeviceProfileEntity() { | ||
67 | + super(); | ||
68 | + } | ||
69 | + | ||
70 | + public DeviceProfileEntity(DeviceProfile deviceProfile) { | ||
71 | + if (deviceProfile.getId() != null) { | ||
72 | + this.setUuid(deviceProfile.getId().getId()); | ||
73 | + } | ||
74 | + if (deviceProfile.getTenantId() != null) { | ||
75 | + this.tenantId = deviceProfile.getTenantId().getId(); | ||
76 | + } | ||
77 | + this.setCreatedTime(deviceProfile.getCreatedTime()); | ||
78 | + this.name = deviceProfile.getName(); | ||
79 | + this.description = deviceProfile.getDescription(); | ||
80 | + this.isDefault = deviceProfile.isDefault(); | ||
81 | + this.profileData = deviceProfile.getProfileData(); | ||
82 | + if (deviceProfile.getDefaultRuleChainId() != null) { | ||
83 | + this.defaultRuleChainId = deviceProfile.getDefaultRuleChainId().getId(); | ||
84 | + } | ||
85 | + } | ||
86 | + | ||
87 | + @Override | ||
88 | + public String getSearchTextSource() { | ||
89 | + return name; | ||
90 | + } | ||
91 | + | ||
92 | + @Override | ||
93 | + public void setSearchText(String searchText) { | ||
94 | + this.searchText = searchText; | ||
95 | + } | ||
96 | + | ||
97 | + public String getSearchText() { | ||
98 | + return searchText; | ||
99 | + } | ||
100 | + | ||
101 | + @Override | ||
102 | + public DeviceProfile toData() { | ||
103 | + DeviceProfile deviceProfile = new DeviceProfile(new DeviceProfileId(this.getUuid())); | ||
104 | + deviceProfile.setCreatedTime(createdTime); | ||
105 | + if (tenantId != null) { | ||
106 | + deviceProfile.setTenantId(new TenantId(tenantId)); | ||
107 | + } | ||
108 | + deviceProfile.setName(name); | ||
109 | + deviceProfile.setDescription(description); | ||
110 | + deviceProfile.setDefault(isDefault); | ||
111 | + deviceProfile.setProfileData(profileData); | ||
112 | + if (defaultRuleChainId != null) { | ||
113 | + deviceProfile.setDefaultRuleChainId(new RuleChainId(defaultRuleChainId)); | ||
114 | + } | ||
115 | + return deviceProfile; | ||
116 | + } | ||
117 | +} |
@@ -21,7 +21,9 @@ import lombok.EqualsAndHashCode; | @@ -21,7 +21,9 @@ import lombok.EqualsAndHashCode; | ||
21 | import org.hibernate.annotations.Type; | 21 | import org.hibernate.annotations.Type; |
22 | import org.hibernate.annotations.TypeDef; | 22 | import org.hibernate.annotations.TypeDef; |
23 | import org.thingsboard.server.common.data.Tenant; | 23 | import org.thingsboard.server.common.data.Tenant; |
24 | +import org.thingsboard.server.common.data.id.CustomerId; | ||
24 | import org.thingsboard.server.common.data.id.TenantId; | 25 | import org.thingsboard.server.common.data.id.TenantId; |
26 | +import org.thingsboard.server.common.data.id.TenantProfileId; | ||
25 | import org.thingsboard.server.dao.model.BaseSqlEntity; | 27 | import org.thingsboard.server.dao.model.BaseSqlEntity; |
26 | import org.thingsboard.server.dao.model.ModelConstants; | 28 | import org.thingsboard.server.dao.model.ModelConstants; |
27 | import org.thingsboard.server.dao.model.SearchTextEntity; | 29 | import org.thingsboard.server.dao.model.SearchTextEntity; |
@@ -30,6 +32,7 @@ import org.thingsboard.server.dao.util.mapping.JsonStringType; | @@ -30,6 +32,7 @@ import org.thingsboard.server.dao.util.mapping.JsonStringType; | ||
30 | import javax.persistence.Column; | 32 | import javax.persistence.Column; |
31 | import javax.persistence.Entity; | 33 | import javax.persistence.Entity; |
32 | import javax.persistence.Table; | 34 | import javax.persistence.Table; |
35 | +import java.util.UUID; | ||
33 | 36 | ||
34 | @Data | 37 | @Data |
35 | @EqualsAndHashCode(callSuper = true) | 38 | @EqualsAndHashCode(callSuper = true) |
@@ -71,16 +74,13 @@ public final class TenantEntity extends BaseSqlEntity<Tenant> implements SearchT | @@ -71,16 +74,13 @@ public final class TenantEntity extends BaseSqlEntity<Tenant> implements SearchT | ||
71 | @Column(name = ModelConstants.EMAIL_PROPERTY) | 74 | @Column(name = ModelConstants.EMAIL_PROPERTY) |
72 | private String email; | 75 | private String email; |
73 | 76 | ||
74 | - @Column(name = ModelConstants.TENANT_ISOLATED_TB_CORE) | ||
75 | - private boolean isolatedTbCore; | ||
76 | - | ||
77 | - @Column(name = ModelConstants.TENANT_ISOLATED_TB_RULE_ENGINE) | ||
78 | - private boolean isolatedTbRuleEngine; | ||
79 | - | ||
80 | @Type(type = "json") | 77 | @Type(type = "json") |
81 | @Column(name = ModelConstants.TENANT_ADDITIONAL_INFO_PROPERTY) | 78 | @Column(name = ModelConstants.TENANT_ADDITIONAL_INFO_PROPERTY) |
82 | private JsonNode additionalInfo; | 79 | private JsonNode additionalInfo; |
83 | 80 | ||
81 | + @Column(name = ModelConstants.TENANT_TENANT_PROFILE_ID_PROPERTY, columnDefinition = "uuid") | ||
82 | + private UUID tenantProfileId; | ||
83 | + | ||
84 | public TenantEntity() { | 84 | public TenantEntity() { |
85 | super(); | 85 | super(); |
86 | } | 86 | } |
@@ -101,8 +101,9 @@ public final class TenantEntity extends BaseSqlEntity<Tenant> implements SearchT | @@ -101,8 +101,9 @@ public final class TenantEntity extends BaseSqlEntity<Tenant> implements SearchT | ||
101 | this.phone = tenant.getPhone(); | 101 | this.phone = tenant.getPhone(); |
102 | this.email = tenant.getEmail(); | 102 | this.email = tenant.getEmail(); |
103 | this.additionalInfo = tenant.getAdditionalInfo(); | 103 | this.additionalInfo = tenant.getAdditionalInfo(); |
104 | - this.isolatedTbCore = tenant.isIsolatedTbCore(); | ||
105 | - this.isolatedTbRuleEngine = tenant.isIsolatedTbRuleEngine(); | 104 | + if (tenant.getTenantProfileId() != null) { |
105 | + this.tenantProfileId = tenant.getTenantProfileId().getId(); | ||
106 | + } | ||
106 | } | 107 | } |
107 | 108 | ||
108 | @Override | 109 | @Override |
@@ -134,8 +135,9 @@ public final class TenantEntity extends BaseSqlEntity<Tenant> implements SearchT | @@ -134,8 +135,9 @@ public final class TenantEntity extends BaseSqlEntity<Tenant> implements SearchT | ||
134 | tenant.setPhone(phone); | 135 | tenant.setPhone(phone); |
135 | tenant.setEmail(email); | 136 | tenant.setEmail(email); |
136 | tenant.setAdditionalInfo(additionalInfo); | 137 | tenant.setAdditionalInfo(additionalInfo); |
137 | - tenant.setIsolatedTbCore(isolatedTbCore); | ||
138 | - tenant.setIsolatedTbRuleEngine(isolatedTbRuleEngine); | 138 | + if (tenantProfileId != null) { |
139 | + tenant.setTenantProfileId(new TenantProfileId(tenantProfileId)); | ||
140 | + } | ||
139 | return tenant; | 141 | return tenant; |
140 | } | 142 | } |
141 | 143 |
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.dao.model.sql; | ||
17 | + | ||
18 | +import com.fasterxml.jackson.databind.JsonNode; | ||
19 | +import lombok.Data; | ||
20 | +import lombok.EqualsAndHashCode; | ||
21 | +import org.hibernate.annotations.Type; | ||
22 | +import org.hibernate.annotations.TypeDef; | ||
23 | +import org.thingsboard.server.common.data.TenantProfile; | ||
24 | +import org.thingsboard.server.common.data.id.TenantProfileId; | ||
25 | +import org.thingsboard.server.dao.model.BaseSqlEntity; | ||
26 | +import org.thingsboard.server.dao.model.ModelConstants; | ||
27 | +import org.thingsboard.server.dao.model.SearchTextEntity; | ||
28 | +import org.thingsboard.server.dao.util.mapping.JsonStringType; | ||
29 | + | ||
30 | +import javax.persistence.Column; | ||
31 | +import javax.persistence.Entity; | ||
32 | +import javax.persistence.Table; | ||
33 | + | ||
34 | +@Data | ||
35 | +@EqualsAndHashCode(callSuper = true) | ||
36 | +@Entity | ||
37 | +@TypeDef(name = "json", typeClass = JsonStringType.class) | ||
38 | +@Table(name = ModelConstants.TENANT_PROFILE_COLUMN_FAMILY_NAME) | ||
39 | +public final class TenantProfileEntity extends BaseSqlEntity<TenantProfile> implements SearchTextEntity<TenantProfile> { | ||
40 | + | ||
41 | + @Column(name = ModelConstants.TENANT_PROFILE_NAME_PROPERTY) | ||
42 | + private String name; | ||
43 | + | ||
44 | + @Column(name = ModelConstants.TENANT_PROFILE_DESCRIPTION_PROPERTY) | ||
45 | + private String description; | ||
46 | + | ||
47 | + @Column(name = ModelConstants.SEARCH_TEXT_PROPERTY) | ||
48 | + private String searchText; | ||
49 | + | ||
50 | + @Column(name = ModelConstants.TENANT_PROFILE_IS_DEFAULT_PROPERTY) | ||
51 | + private boolean isDefault; | ||
52 | + | ||
53 | + @Column(name = ModelConstants.TENANT_PROFILE_ISOLATED_TB_CORE) | ||
54 | + private boolean isolatedTbCore; | ||
55 | + | ||
56 | + @Column(name = ModelConstants.TENANT_PROFILE_ISOLATED_TB_RULE_ENGINE) | ||
57 | + private boolean isolatedTbRuleEngine; | ||
58 | + | ||
59 | + @Type(type = "json") | ||
60 | + @Column(name = ModelConstants.TENANT_PROFILE_PROFILE_DATA_PROPERTY) | ||
61 | + private JsonNode profileData; | ||
62 | + | ||
63 | + public TenantProfileEntity() { | ||
64 | + super(); | ||
65 | + } | ||
66 | + | ||
67 | + public TenantProfileEntity(TenantProfile tenantProfile) { | ||
68 | + if (tenantProfile.getId() != null) { | ||
69 | + this.setUuid(tenantProfile.getId().getId()); | ||
70 | + } | ||
71 | + this.setCreatedTime(tenantProfile.getCreatedTime()); | ||
72 | + this.name = tenantProfile.getName(); | ||
73 | + this.description = tenantProfile.getDescription(); | ||
74 | + this.isDefault = tenantProfile.isDefault(); | ||
75 | + this.isolatedTbCore = tenantProfile.isIsolatedTbCore(); | ||
76 | + this.isolatedTbRuleEngine = tenantProfile.isIsolatedTbRuleEngine(); | ||
77 | + this.profileData = tenantProfile.getProfileData(); | ||
78 | + } | ||
79 | + | ||
80 | + @Override | ||
81 | + public String getSearchTextSource() { | ||
82 | + return name; | ||
83 | + } | ||
84 | + | ||
85 | + @Override | ||
86 | + public void setSearchText(String searchText) { | ||
87 | + this.searchText = searchText; | ||
88 | + } | ||
89 | + | ||
90 | + public String getSearchText() { | ||
91 | + return searchText; | ||
92 | + } | ||
93 | + | ||
94 | + @Override | ||
95 | + public TenantProfile toData() { | ||
96 | + TenantProfile tenantProfile = new TenantProfile(new TenantProfileId(this.getUuid())); | ||
97 | + tenantProfile.setCreatedTime(createdTime); | ||
98 | + tenantProfile.setName(name); | ||
99 | + tenantProfile.setDescription(description); | ||
100 | + tenantProfile.setDefault(isDefault); | ||
101 | + tenantProfile.setIsolatedTbCore(isolatedTbCore); | ||
102 | + tenantProfile.setIsolatedTbRuleEngine(isolatedTbRuleEngine); | ||
103 | + tenantProfile.setProfileData(profileData); | ||
104 | + return tenantProfile; | ||
105 | + } | ||
106 | + | ||
107 | + | ||
108 | +} |
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.dao.sql.device; | ||
17 | + | ||
18 | +import org.springframework.data.domain.Page; | ||
19 | +import org.springframework.data.domain.Pageable; | ||
20 | +import org.springframework.data.jpa.repository.Query; | ||
21 | +import org.springframework.data.repository.PagingAndSortingRepository; | ||
22 | +import org.springframework.data.repository.query.Param; | ||
23 | +import org.thingsboard.server.common.data.EntityInfo; | ||
24 | +import org.thingsboard.server.dao.model.sql.DeviceProfileEntity; | ||
25 | + | ||
26 | +import java.util.UUID; | ||
27 | + | ||
28 | +public interface DeviceProfileRepository extends PagingAndSortingRepository<DeviceProfileEntity, UUID> { | ||
29 | + | ||
30 | + @Query("SELECT new org.thingsboard.server.common.data.EntityInfo(d.id, 'DEVICE_PROFILE', d.name) " + | ||
31 | + "FROM DeviceProfileEntity d " + | ||
32 | + "WHERE d.id = :deviceProfileId") | ||
33 | + EntityInfo findDeviceProfileInfoById(@Param("deviceProfileId") UUID deviceProfileId); | ||
34 | + | ||
35 | + @Query("SELECT d FROM DeviceProfileEntity d WHERE " + | ||
36 | + "d.tenantId = :tenantId AND LOWER(d.searchText) LIKE LOWER(CONCAT(:textSearch, '%'))") | ||
37 | + Page<DeviceProfileEntity> findDeviceProfiles(@Param("tenantId") UUID tenantId, | ||
38 | + @Param("textSearch") String textSearch, | ||
39 | + Pageable pageable); | ||
40 | + | ||
41 | + @Query("SELECT new org.thingsboard.server.common.data.EntityInfo(d.id, 'DEVICE_PROFILE', d.name) " + | ||
42 | + "FROM DeviceProfileEntity d WHERE " + | ||
43 | + "d.tenantId = :tenantId AND LOWER(d.searchText) LIKE LOWER(CONCAT(:textSearch, '%'))") | ||
44 | + Page<EntityInfo> findDeviceProfileInfos(@Param("tenantId") UUID tenantId, | ||
45 | + @Param("textSearch") String textSearch, | ||
46 | + Pageable pageable); | ||
47 | + | ||
48 | + @Query("SELECT d FROM DeviceProfileEntity d " + | ||
49 | + "WHERE d.tenantId = :tenantId AND d.isDefault = true") | ||
50 | + DeviceProfileEntity findByDefaultTrueAndTenantId(@Param("tenantId") UUID tenantId); | ||
51 | + | ||
52 | + @Query("SELECT new org.thingsboard.server.common.data.EntityInfo(d.id, 'DEVICE_PROFILE', d.name) " + | ||
53 | + "FROM DeviceProfileEntity d " + | ||
54 | + "WHERE d.tenantId = :tenantId AND d.isDefault = true") | ||
55 | + EntityInfo findDefaultDeviceProfileInfo(@Param("tenantId") UUID tenantId); | ||
56 | +} |
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.dao.sql.device; | ||
17 | + | ||
18 | +import org.springframework.beans.factory.annotation.Autowired; | ||
19 | +import org.springframework.data.repository.CrudRepository; | ||
20 | +import org.springframework.stereotype.Component; | ||
21 | +import org.thingsboard.server.common.data.DeviceProfile; | ||
22 | +import org.thingsboard.server.common.data.EntityInfo; | ||
23 | +import org.thingsboard.server.common.data.id.TenantId; | ||
24 | +import org.thingsboard.server.common.data.page.PageData; | ||
25 | +import org.thingsboard.server.common.data.page.PageLink; | ||
26 | +import org.thingsboard.server.dao.DaoUtil; | ||
27 | +import org.thingsboard.server.dao.device.DeviceProfileDao; | ||
28 | +import org.thingsboard.server.dao.model.sql.DeviceProfileEntity; | ||
29 | +import org.thingsboard.server.dao.sql.JpaAbstractSearchTextDao; | ||
30 | + | ||
31 | +import java.util.Objects; | ||
32 | +import java.util.UUID; | ||
33 | + | ||
34 | +@Component | ||
35 | +public class JpaDeviceProfileDao extends JpaAbstractSearchTextDao<DeviceProfileEntity, DeviceProfile> implements DeviceProfileDao { | ||
36 | + | ||
37 | + @Autowired | ||
38 | + private DeviceProfileRepository deviceProfileRepository; | ||
39 | + | ||
40 | + @Override | ||
41 | + protected Class<DeviceProfileEntity> getEntityClass() { | ||
42 | + return DeviceProfileEntity.class; | ||
43 | + } | ||
44 | + | ||
45 | + @Override | ||
46 | + protected CrudRepository<DeviceProfileEntity, UUID> getCrudRepository() { | ||
47 | + return deviceProfileRepository; | ||
48 | + } | ||
49 | + | ||
50 | + @Override | ||
51 | + public EntityInfo findDeviceProfileInfoById(TenantId tenantId, UUID deviceProfileId) { | ||
52 | + return deviceProfileRepository.findDeviceProfileInfoById(deviceProfileId); | ||
53 | + } | ||
54 | + | ||
55 | + @Override | ||
56 | + public PageData<DeviceProfile> findDeviceProfiles(TenantId tenantId, PageLink pageLink) { | ||
57 | + return DaoUtil.toPageData( | ||
58 | + deviceProfileRepository.findDeviceProfiles( | ||
59 | + tenantId.getId(), | ||
60 | + Objects.toString(pageLink.getTextSearch(), ""), | ||
61 | + DaoUtil.toPageable(pageLink))); | ||
62 | + } | ||
63 | + | ||
64 | + @Override | ||
65 | + public PageData<EntityInfo> findDeviceProfileInfos(TenantId tenantId, PageLink pageLink) { | ||
66 | + return DaoUtil.pageToPageData( | ||
67 | + deviceProfileRepository.findDeviceProfileInfos( | ||
68 | + tenantId.getId(), | ||
69 | + Objects.toString(pageLink.getTextSearch(), ""), | ||
70 | + DaoUtil.toPageable(pageLink))); | ||
71 | + } | ||
72 | + | ||
73 | + @Override | ||
74 | + public DeviceProfile findDefaultDeviceProfile(TenantId tenantId) { | ||
75 | + return DaoUtil.getData(deviceProfileRepository.findByDefaultTrueAndTenantId(tenantId.getId())); | ||
76 | + } | ||
77 | + | ||
78 | + @Override | ||
79 | + public EntityInfo findDefaultDeviceProfileInfo(TenantId tenantId) { | ||
80 | + return deviceProfileRepository.findDefaultDeviceProfileInfo(tenantId.getId()); | ||
81 | + } | ||
82 | + | ||
83 | +} |
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.dao.sql.tenant; | ||
17 | + | ||
18 | +import org.springframework.beans.factory.annotation.Autowired; | ||
19 | +import org.springframework.data.repository.CrudRepository; | ||
20 | +import org.springframework.stereotype.Component; | ||
21 | +import org.thingsboard.server.common.data.EntityInfo; | ||
22 | +import org.thingsboard.server.common.data.TenantProfile; | ||
23 | +import org.thingsboard.server.common.data.id.TenantId; | ||
24 | +import org.thingsboard.server.common.data.page.PageData; | ||
25 | +import org.thingsboard.server.common.data.page.PageLink; | ||
26 | +import org.thingsboard.server.dao.DaoUtil; | ||
27 | +import org.thingsboard.server.dao.model.sql.TenantProfileEntity; | ||
28 | +import org.thingsboard.server.dao.sql.JpaAbstractSearchTextDao; | ||
29 | +import org.thingsboard.server.dao.tenant.TenantProfileDao; | ||
30 | + | ||
31 | +import java.util.Objects; | ||
32 | +import java.util.UUID; | ||
33 | + | ||
34 | +@Component | ||
35 | +public class JpaTenantProfileDao extends JpaAbstractSearchTextDao<TenantProfileEntity, TenantProfile> implements TenantProfileDao { | ||
36 | + | ||
37 | + @Autowired | ||
38 | + private TenantProfileRepository tenantProfileRepository; | ||
39 | + | ||
40 | + @Override | ||
41 | + protected Class<TenantProfileEntity> getEntityClass() { | ||
42 | + return TenantProfileEntity.class; | ||
43 | + } | ||
44 | + | ||
45 | + @Override | ||
46 | + protected CrudRepository<TenantProfileEntity, UUID> getCrudRepository() { | ||
47 | + return tenantProfileRepository; | ||
48 | + } | ||
49 | + | ||
50 | + @Override | ||
51 | + public EntityInfo findTenantProfileInfoById(TenantId tenantId, UUID tenantProfileId) { | ||
52 | + return tenantProfileRepository.findTenantProfileInfoById(tenantProfileId); | ||
53 | + } | ||
54 | + | ||
55 | + @Override | ||
56 | + public PageData<TenantProfile> findTenantProfiles(TenantId tenantId, PageLink pageLink) { | ||
57 | + return DaoUtil.toPageData( | ||
58 | + tenantProfileRepository.findTenantProfiles( | ||
59 | + Objects.toString(pageLink.getTextSearch(), ""), | ||
60 | + DaoUtil.toPageable(pageLink))); | ||
61 | + } | ||
62 | + | ||
63 | + @Override | ||
64 | + public PageData<EntityInfo> findTenantProfileInfos(TenantId tenantId, PageLink pageLink) { | ||
65 | + return DaoUtil.pageToPageData( | ||
66 | + tenantProfileRepository.findTenantProfileInfos( | ||
67 | + Objects.toString(pageLink.getTextSearch(), ""), | ||
68 | + DaoUtil.toPageable(pageLink))); | ||
69 | + } | ||
70 | + | ||
71 | + @Override | ||
72 | + public TenantProfile findDefaultTenantProfile(TenantId tenantId) { | ||
73 | + return DaoUtil.getData(tenantProfileRepository.findByDefaultTrue()); | ||
74 | + } | ||
75 | + | ||
76 | + @Override | ||
77 | + public EntityInfo findDefaultTenantProfileInfo(TenantId tenantId) { | ||
78 | + return tenantProfileRepository.findDefaultTenantProfileInfo(); | ||
79 | + } | ||
80 | +} |
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.dao.sql.tenant; | ||
17 | + | ||
18 | +import org.springframework.data.domain.Page; | ||
19 | +import org.springframework.data.domain.Pageable; | ||
20 | +import org.springframework.data.jpa.repository.Query; | ||
21 | +import org.springframework.data.repository.PagingAndSortingRepository; | ||
22 | +import org.springframework.data.repository.query.Param; | ||
23 | +import org.thingsboard.server.common.data.EntityInfo; | ||
24 | +import org.thingsboard.server.dao.model.sql.TenantProfileEntity; | ||
25 | + | ||
26 | +import java.util.UUID; | ||
27 | + | ||
28 | +public interface TenantProfileRepository extends PagingAndSortingRepository<TenantProfileEntity, UUID> { | ||
29 | + | ||
30 | + @Query("SELECT new org.thingsboard.server.common.data.EntityInfo(t.id, 'TENANT_PROFILE', t.name) " + | ||
31 | + "FROM TenantProfileEntity t " + | ||
32 | + "WHERE t.id = :tenantProfileId") | ||
33 | + EntityInfo findTenantProfileInfoById(@Param("tenantProfileId") UUID tenantProfileId); | ||
34 | + | ||
35 | + @Query("SELECT t FROM TenantProfileEntity t WHERE " + | ||
36 | + "LOWER(t.searchText) LIKE LOWER(CONCAT(:textSearch, '%'))") | ||
37 | + Page<TenantProfileEntity> findTenantProfiles(@Param("textSearch") String textSearch, | ||
38 | + Pageable pageable); | ||
39 | + | ||
40 | + @Query("SELECT new org.thingsboard.server.common.data.EntityInfo(t.id, 'TENANT_PROFILE', t.name) " + | ||
41 | + "FROM TenantProfileEntity t " + | ||
42 | + "WHERE LOWER(t.searchText) LIKE LOWER(CONCAT(:textSearch, '%'))") | ||
43 | + Page<EntityInfo> findTenantProfileInfos(@Param("textSearch") String textSearch, | ||
44 | + Pageable pageable); | ||
45 | + | ||
46 | + @Query("SELECT t FROM TenantProfileEntity t " + | ||
47 | + "WHERE t.isDefault = true") | ||
48 | + TenantProfileEntity findByDefaultTrue(); | ||
49 | + | ||
50 | + @Query("SELECT new org.thingsboard.server.common.data.EntityInfo(t.id, 'TENANT_PROFILE', t.name) " + | ||
51 | + "FROM TenantProfileEntity t " + | ||
52 | + "WHERE t.isDefault = true") | ||
53 | + EntityInfo findDefaultTenantProfileInfo(); | ||
54 | +} |
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.dao.tenant; | ||
17 | + | ||
18 | +import org.thingsboard.server.common.data.EntityInfo; | ||
19 | +import org.thingsboard.server.common.data.TenantProfile; | ||
20 | +import org.thingsboard.server.common.data.id.TenantId; | ||
21 | +import org.thingsboard.server.common.data.page.PageData; | ||
22 | +import org.thingsboard.server.common.data.page.PageLink; | ||
23 | +import org.thingsboard.server.dao.Dao; | ||
24 | + | ||
25 | +import java.util.UUID; | ||
26 | + | ||
27 | +public interface TenantProfileDao extends Dao<TenantProfile> { | ||
28 | + | ||
29 | + EntityInfo findTenantProfileInfoById(TenantId tenantId, UUID tenantProfileId); | ||
30 | + | ||
31 | + TenantProfile save(TenantId tenantId, TenantProfile tenantProfile); | ||
32 | + | ||
33 | + PageData<TenantProfile> findTenantProfiles(TenantId tenantId, PageLink pageLink); | ||
34 | + | ||
35 | + PageData<EntityInfo> findTenantProfileInfos(TenantId tenantId, PageLink pageLink); | ||
36 | + | ||
37 | + TenantProfile findDefaultTenantProfile(TenantId tenantId); | ||
38 | + | ||
39 | + EntityInfo findDefaultTenantProfileInfo(TenantId tenantId); | ||
40 | +} |
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.dao.tenant; | ||
17 | + | ||
18 | +import lombok.extern.slf4j.Slf4j; | ||
19 | +import org.apache.commons.lang3.StringUtils; | ||
20 | +import org.hibernate.exception.ConstraintViolationException; | ||
21 | +import org.springframework.beans.factory.annotation.Autowired; | ||
22 | +import org.springframework.stereotype.Service; | ||
23 | +import org.thingsboard.server.common.data.EntityInfo; | ||
24 | +import org.thingsboard.server.common.data.TenantProfile; | ||
25 | +import org.thingsboard.server.common.data.id.TenantId; | ||
26 | +import org.thingsboard.server.common.data.id.TenantProfileId; | ||
27 | +import org.thingsboard.server.common.data.page.PageData; | ||
28 | +import org.thingsboard.server.common.data.page.PageLink; | ||
29 | +import org.thingsboard.server.dao.entity.AbstractEntityService; | ||
30 | +import org.thingsboard.server.dao.exception.DataValidationException; | ||
31 | +import org.thingsboard.server.dao.service.DataValidator; | ||
32 | +import org.thingsboard.server.dao.service.PaginatedRemover; | ||
33 | +import org.thingsboard.server.dao.service.Validator; | ||
34 | +import org.thingsboard.server.dao.util.mapping.JacksonUtil; | ||
35 | + | ||
36 | +import static org.thingsboard.server.dao.service.Validator.validateId; | ||
37 | + | ||
38 | +@Service | ||
39 | +@Slf4j | ||
40 | +public class TenantProfileServiceImpl extends AbstractEntityService implements TenantProfileService { | ||
41 | + | ||
42 | + private static final String INCORRECT_TENANT_PROFILE_ID = "Incorrect tenantProfileId "; | ||
43 | + | ||
44 | + @Autowired | ||
45 | + private TenantProfileDao tenantProfileDao; | ||
46 | + | ||
47 | + @Override | ||
48 | + public TenantProfile findTenantProfileById(TenantId tenantId, TenantProfileId tenantProfileId) { | ||
49 | + log.trace("Executing findTenantProfileById [{}]", tenantProfileId); | ||
50 | + Validator.validateId(tenantProfileId, INCORRECT_TENANT_PROFILE_ID + tenantProfileId); | ||
51 | + return tenantProfileDao.findById(tenantId, tenantProfileId.getId()); | ||
52 | + } | ||
53 | + | ||
54 | + @Override | ||
55 | + public EntityInfo findTenantProfileInfoById(TenantId tenantId, TenantProfileId tenantProfileId) { | ||
56 | + log.trace("Executing findTenantProfileInfoById [{}]", tenantProfileId); | ||
57 | + Validator.validateId(tenantProfileId, INCORRECT_TENANT_PROFILE_ID + tenantProfileId); | ||
58 | + return tenantProfileDao.findTenantProfileInfoById(tenantId, tenantProfileId.getId()); | ||
59 | + } | ||
60 | + | ||
61 | + @Override | ||
62 | + public TenantProfile saveTenantProfile(TenantId tenantId, TenantProfile tenantProfile) { | ||
63 | + log.trace("Executing saveTenantProfile [{}]", tenantProfile); | ||
64 | + tenantProfileValidator.validate(tenantProfile, (tenantProfile1) -> TenantId.SYS_TENANT_ID); | ||
65 | + TenantProfile savedTenantProfile; | ||
66 | + try { | ||
67 | + savedTenantProfile = tenantProfileDao.save(tenantId, tenantProfile); | ||
68 | + } catch (Exception t) { | ||
69 | + ConstraintViolationException e = extractConstraintViolationException(t).orElse(null); | ||
70 | + if (e != null && e.getConstraintName() != null && e.getConstraintName().equalsIgnoreCase("tenant_profile_name_unq_key")) { | ||
71 | + throw new DataValidationException("Tenant profile with such name already exists!"); | ||
72 | + } else { | ||
73 | + throw t; | ||
74 | + } | ||
75 | + } | ||
76 | + return savedTenantProfile; | ||
77 | + } | ||
78 | + | ||
79 | + @Override | ||
80 | + public void deleteTenantProfile(TenantId tenantId, TenantProfileId tenantProfileId) { | ||
81 | + log.trace("Executing deleteTenantProfile [{}]", tenantProfileId); | ||
82 | + validateId(tenantId, INCORRECT_TENANT_PROFILE_ID + tenantProfileId); | ||
83 | + deleteEntityRelations(tenantId, tenantProfileId); | ||
84 | + tenantProfileDao.removeById(tenantId, tenantProfileId.getId()); | ||
85 | + } | ||
86 | + | ||
87 | + @Override | ||
88 | + public PageData<TenantProfile> findTenantProfiles(TenantId tenantId, PageLink pageLink) { | ||
89 | + log.trace("Executing findTenantProfiles pageLink [{}]", pageLink); | ||
90 | + Validator.validatePageLink(pageLink); | ||
91 | + return tenantProfileDao.findTenantProfiles(tenantId, pageLink); | ||
92 | + } | ||
93 | + | ||
94 | + @Override | ||
95 | + public PageData<EntityInfo> findTenantProfileInfos(TenantId tenantId, PageLink pageLink) { | ||
96 | + log.trace("Executing findTenantProfileInfos pageLink [{}]", pageLink); | ||
97 | + Validator.validatePageLink(pageLink); | ||
98 | + return tenantProfileDao.findTenantProfileInfos(tenantId, pageLink); | ||
99 | + } | ||
100 | + | ||
101 | + @Override | ||
102 | + public TenantProfile findOrCreateDefaultTenantProfile(TenantId tenantId) { | ||
103 | + log.trace("Executing findOrCreateDefaultTenantProfile"); | ||
104 | + TenantProfile defaultTenantProfile = findDefaultTenantProfile(tenantId); | ||
105 | + if (defaultTenantProfile == null) { | ||
106 | + defaultTenantProfile = new TenantProfile(); | ||
107 | + defaultTenantProfile.setDefault(true); | ||
108 | + defaultTenantProfile.setName("Default"); | ||
109 | + defaultTenantProfile.setProfileData(JacksonUtil.OBJECT_MAPPER.createObjectNode()); | ||
110 | + defaultTenantProfile.setDescription("Default tenant profile"); | ||
111 | + defaultTenantProfile.setIsolatedTbCore(false); | ||
112 | + defaultTenantProfile.setIsolatedTbRuleEngine(false); | ||
113 | + defaultTenantProfile = saveTenantProfile(tenantId, defaultTenantProfile); | ||
114 | + } | ||
115 | + return defaultTenantProfile; | ||
116 | + } | ||
117 | + | ||
118 | + @Override | ||
119 | + public TenantProfile findDefaultTenantProfile(TenantId tenantId) { | ||
120 | + log.trace("Executing findDefaultTenantProfile"); | ||
121 | + return tenantProfileDao.findDefaultTenantProfile(tenantId); | ||
122 | + } | ||
123 | + | ||
124 | + @Override | ||
125 | + public EntityInfo findDefaultTenantProfileInfo(TenantId tenantId) { | ||
126 | + log.trace("Executing findDefaultTenantProfileInfo"); | ||
127 | + return tenantProfileDao.findDefaultTenantProfileInfo(tenantId); | ||
128 | + } | ||
129 | + | ||
130 | + @Override | ||
131 | + public boolean setDefaultTenantProfile(TenantId tenantId, TenantProfileId tenantProfileId) { | ||
132 | + log.trace("Executing setDefaultTenantProfile [{}]", tenantProfileId); | ||
133 | + validateId(tenantId, INCORRECT_TENANT_PROFILE_ID + tenantProfileId); | ||
134 | + TenantProfile tenantProfile = tenantProfileDao.findById(tenantId, tenantProfileId.getId()); | ||
135 | + if (!tenantProfile.isDefault()) { | ||
136 | + tenantProfile.setDefault(true); | ||
137 | + TenantProfile previousDefaultTenantProfile = findDefaultTenantProfile(tenantId); | ||
138 | + if (previousDefaultTenantProfile == null) { | ||
139 | + tenantProfileDao.save(tenantId, tenantProfile); | ||
140 | + return true; | ||
141 | + } else if (!previousDefaultTenantProfile.getId().equals(tenantProfile.getId())) { | ||
142 | + previousDefaultTenantProfile.setDefault(false); | ||
143 | + tenantProfileDao.save(tenantId, previousDefaultTenantProfile); | ||
144 | + tenantProfileDao.save(tenantId, tenantProfile); | ||
145 | + return true; | ||
146 | + } | ||
147 | + } | ||
148 | + return false; | ||
149 | + } | ||
150 | + | ||
151 | + @Override | ||
152 | + public void deleteTenantProfiles(TenantId tenantId) { | ||
153 | + log.trace("Executing deleteTenantProfiles"); | ||
154 | + tenantProfilesRemover.removeEntities(tenantId, null); | ||
155 | + } | ||
156 | + | ||
157 | + private DataValidator<TenantProfile> tenantProfileValidator = | ||
158 | + new DataValidator<TenantProfile>() { | ||
159 | + @Override | ||
160 | + protected void validateDataImpl(TenantId tenantId, TenantProfile tenantProfile) { | ||
161 | + if (StringUtils.isEmpty(tenantProfile.getName())) { | ||
162 | + throw new DataValidationException("Tenant profile name should be specified!"); | ||
163 | + } | ||
164 | + if (tenantProfile.isDefault()) { | ||
165 | + TenantProfile defaultTenantProfile = findDefaultTenantProfile(tenantId); | ||
166 | + if (defaultTenantProfile != null && !defaultTenantProfile.getId().equals(tenantProfile.getId())) { | ||
167 | + throw new DataValidationException("Another default tenant profile is present!"); | ||
168 | + } | ||
169 | + } | ||
170 | + } | ||
171 | + }; | ||
172 | + | ||
173 | + private PaginatedRemover<String, TenantProfile> tenantProfilesRemover = | ||
174 | + new PaginatedRemover<String, TenantProfile>() { | ||
175 | + | ||
176 | + @Override | ||
177 | + protected PageData<TenantProfile> findEntities(TenantId tenantId, String id, PageLink pageLink) { | ||
178 | + return tenantProfileDao.findTenantProfiles(tenantId, pageLink); | ||
179 | + } | ||
180 | + | ||
181 | + @Override | ||
182 | + protected void removeEntity(TenantId tenantId, TenantProfile entity) { | ||
183 | + deleteTenantProfile(tenantId, new TenantProfileId(entity.getUuidId())); | ||
184 | + } | ||
185 | + }; | ||
186 | + | ||
187 | +} |
@@ -20,14 +20,18 @@ import lombok.extern.slf4j.Slf4j; | @@ -20,14 +20,18 @@ import lombok.extern.slf4j.Slf4j; | ||
20 | import org.apache.commons.lang3.StringUtils; | 20 | import org.apache.commons.lang3.StringUtils; |
21 | import org.springframework.beans.factory.annotation.Autowired; | 21 | import org.springframework.beans.factory.annotation.Autowired; |
22 | import org.springframework.stereotype.Service; | 22 | import org.springframework.stereotype.Service; |
23 | +import org.thingsboard.server.common.data.EntityInfo; | ||
23 | import org.thingsboard.server.common.data.Tenant; | 24 | import org.thingsboard.server.common.data.Tenant; |
25 | +import org.thingsboard.server.common.data.TenantProfile; | ||
24 | import org.thingsboard.server.common.data.id.EntityId; | 26 | import org.thingsboard.server.common.data.id.EntityId; |
25 | import org.thingsboard.server.common.data.id.TenantId; | 27 | import org.thingsboard.server.common.data.id.TenantId; |
28 | +import org.thingsboard.server.common.data.id.TenantProfileId; | ||
26 | import org.thingsboard.server.common.data.page.PageData; | 29 | import org.thingsboard.server.common.data.page.PageData; |
27 | import org.thingsboard.server.common.data.page.PageLink; | 30 | import org.thingsboard.server.common.data.page.PageLink; |
28 | import org.thingsboard.server.dao.asset.AssetService; | 31 | import org.thingsboard.server.dao.asset.AssetService; |
29 | import org.thingsboard.server.dao.customer.CustomerService; | 32 | import org.thingsboard.server.dao.customer.CustomerService; |
30 | import org.thingsboard.server.dao.dashboard.DashboardService; | 33 | import org.thingsboard.server.dao.dashboard.DashboardService; |
34 | +import org.thingsboard.server.dao.device.DeviceProfileService; | ||
31 | import org.thingsboard.server.dao.device.DeviceService; | 35 | import org.thingsboard.server.dao.device.DeviceService; |
32 | import org.thingsboard.server.dao.entity.AbstractEntityService; | 36 | import org.thingsboard.server.dao.entity.AbstractEntityService; |
33 | import org.thingsboard.server.dao.entityview.EntityViewService; | 37 | import org.thingsboard.server.dao.entityview.EntityViewService; |
@@ -52,6 +56,9 @@ public class TenantServiceImpl extends AbstractEntityService implements TenantSe | @@ -52,6 +56,9 @@ public class TenantServiceImpl extends AbstractEntityService implements TenantSe | ||
52 | private TenantDao tenantDao; | 56 | private TenantDao tenantDao; |
53 | 57 | ||
54 | @Autowired | 58 | @Autowired |
59 | + private TenantProfileService tenantProfileService; | ||
60 | + | ||
61 | + @Autowired | ||
55 | private UserService userService; | 62 | private UserService userService; |
56 | 63 | ||
57 | @Autowired | 64 | @Autowired |
@@ -64,6 +71,9 @@ public class TenantServiceImpl extends AbstractEntityService implements TenantSe | @@ -64,6 +71,9 @@ public class TenantServiceImpl extends AbstractEntityService implements TenantSe | ||
64 | private DeviceService deviceService; | 71 | private DeviceService deviceService; |
65 | 72 | ||
66 | @Autowired | 73 | @Autowired |
74 | + private DeviceProfileService deviceProfileService; | ||
75 | + | ||
76 | + @Autowired | ||
67 | private EntityViewService entityViewService; | 77 | private EntityViewService entityViewService; |
68 | 78 | ||
69 | @Autowired | 79 | @Autowired |
@@ -93,8 +103,16 @@ public class TenantServiceImpl extends AbstractEntityService implements TenantSe | @@ -93,8 +103,16 @@ public class TenantServiceImpl extends AbstractEntityService implements TenantSe | ||
93 | public Tenant saveTenant(Tenant tenant) { | 103 | public Tenant saveTenant(Tenant tenant) { |
94 | log.trace("Executing saveTenant [{}]", tenant); | 104 | log.trace("Executing saveTenant [{}]", tenant); |
95 | tenant.setRegion(DEFAULT_TENANT_REGION); | 105 | tenant.setRegion(DEFAULT_TENANT_REGION); |
106 | + if (tenant.getTenantProfileId() == null) { | ||
107 | + TenantProfile tenantProfile = this.tenantProfileService.findOrCreateDefaultTenantProfile(TenantId.SYS_TENANT_ID); | ||
108 | + tenant.setTenantProfileId(tenantProfile.getId()); | ||
109 | + } | ||
96 | tenantValidator.validate(tenant, Tenant::getId); | 110 | tenantValidator.validate(tenant, Tenant::getId); |
97 | - return tenantDao.save(tenant.getId(), tenant); | 111 | + Tenant savedTenant = tenantDao.save(tenant.getId(), tenant); |
112 | + if (tenant.getId() == null) { | ||
113 | + deviceProfileService.createDefaultDeviceProfile(savedTenant.getId()); | ||
114 | + } | ||
115 | + return savedTenant; | ||
98 | } | 116 | } |
99 | 117 | ||
100 | @Override | 118 | @Override |
@@ -107,6 +125,7 @@ public class TenantServiceImpl extends AbstractEntityService implements TenantSe | @@ -107,6 +125,7 @@ public class TenantServiceImpl extends AbstractEntityService implements TenantSe | ||
107 | entityViewService.deleteEntityViewsByTenantId(tenantId); | 125 | entityViewService.deleteEntityViewsByTenantId(tenantId); |
108 | assetService.deleteAssetsByTenantId(tenantId); | 126 | assetService.deleteAssetsByTenantId(tenantId); |
109 | deviceService.deleteDevicesByTenantId(tenantId); | 127 | deviceService.deleteDevicesByTenantId(tenantId); |
128 | + deviceProfileService.deleteDeviceProfilesByTenantId(tenantId); | ||
110 | userService.deleteTenantAdmins(tenantId); | 129 | userService.deleteTenantAdmins(tenantId); |
111 | ruleChainService.deleteRuleChainsByTenantId(tenantId); | 130 | ruleChainService.deleteRuleChainsByTenantId(tenantId); |
112 | tenantDao.removeById(tenantId, tenantId.getId()); | 131 | tenantDao.removeById(tenantId, tenantId.getId()); |
@@ -143,11 +162,13 @@ public class TenantServiceImpl extends AbstractEntityService implements TenantSe | @@ -143,11 +162,13 @@ public class TenantServiceImpl extends AbstractEntityService implements TenantSe | ||
143 | Tenant old = tenantDao.findById(TenantId.SYS_TENANT_ID, tenantId.getId()); | 162 | Tenant old = tenantDao.findById(TenantId.SYS_TENANT_ID, tenantId.getId()); |
144 | if (old == null) { | 163 | if (old == null) { |
145 | throw new DataValidationException("Can't update non existing tenant!"); | 164 | throw new DataValidationException("Can't update non existing tenant!"); |
146 | - } else if (old.isIsolatedTbRuleEngine() != tenant.isIsolatedTbRuleEngine()) { | 165 | + } |
166 | + // TODO: Move validation to tenant profile | ||
167 | + /* else if (old.isIsolatedTbRuleEngine() != tenant.isIsolatedTbRuleEngine()) { | ||
147 | throw new DataValidationException("Can't update isolatedTbRuleEngine property!"); | 168 | throw new DataValidationException("Can't update isolatedTbRuleEngine property!"); |
148 | } else if (old.isIsolatedTbCore() != tenant.isIsolatedTbCore()) { | 169 | } else if (old.isIsolatedTbCore() != tenant.isIsolatedTbCore()) { |
149 | throw new DataValidationException("Can't update isolatedTbCore property!"); | 170 | throw new DataValidationException("Can't update isolatedTbCore property!"); |
150 | - } | 171 | + } */ |
151 | } | 172 | } |
152 | }; | 173 | }; |
153 | 174 |
@@ -127,6 +127,7 @@ CREATE TABLE IF NOT EXISTS device ( | @@ -127,6 +127,7 @@ CREATE TABLE IF NOT EXISTS device ( | ||
127 | created_time bigint NOT NULL, | 127 | created_time bigint NOT NULL, |
128 | additional_info varchar, | 128 | additional_info varchar, |
129 | customer_id uuid, | 129 | customer_id uuid, |
130 | + device_profile_id uuid NOT NULL, | ||
130 | type varchar(255), | 131 | type varchar(255), |
131 | name varchar(255), | 132 | name varchar(255), |
132 | label varchar(255), | 133 | label varchar(255), |
@@ -135,6 +136,19 @@ CREATE TABLE IF NOT EXISTS device ( | @@ -135,6 +136,19 @@ CREATE TABLE IF NOT EXISTS device ( | ||
135 | CONSTRAINT device_name_unq_key UNIQUE (tenant_id, name) | 136 | CONSTRAINT device_name_unq_key UNIQUE (tenant_id, name) |
136 | ); | 137 | ); |
137 | 138 | ||
139 | +CREATE TABLE IF NOT EXISTS device_profile ( | ||
140 | + id uuid NOT NULL CONSTRAINT device_profile_pkey PRIMARY KEY, | ||
141 | + created_time bigint NOT NULL, | ||
142 | + name varchar(255), | ||
143 | + profile_data varchar, | ||
144 | + description varchar, | ||
145 | + search_text varchar(255), | ||
146 | + is_default boolean, | ||
147 | + tenant_id uuid, | ||
148 | + default_rule_chain_id uuid, | ||
149 | + CONSTRAINT device_profile_name_unq_key UNIQUE (tenant_id, name) | ||
150 | +); | ||
151 | + | ||
138 | CREATE TABLE IF NOT EXISTS device_credentials ( | 152 | CREATE TABLE IF NOT EXISTS device_credentials ( |
139 | id uuid NOT NULL CONSTRAINT device_credentials_pkey PRIMARY KEY, | 153 | id uuid NOT NULL CONSTRAINT device_credentials_pkey PRIMARY KEY, |
140 | created_time bigint NOT NULL, | 154 | created_time bigint NOT NULL, |
@@ -187,6 +201,7 @@ CREATE TABLE IF NOT EXISTS tenant ( | @@ -187,6 +201,7 @@ CREATE TABLE IF NOT EXISTS tenant ( | ||
187 | id uuid NOT NULL CONSTRAINT tenant_pkey PRIMARY KEY, | 201 | id uuid NOT NULL CONSTRAINT tenant_pkey PRIMARY KEY, |
188 | created_time bigint NOT NULL, | 202 | created_time bigint NOT NULL, |
189 | additional_info varchar, | 203 | additional_info varchar, |
204 | + tenant_profile_id uuid NOT NULL, | ||
190 | address varchar, | 205 | address varchar, |
191 | address2 varchar, | 206 | address2 varchar, |
192 | city varchar(255), | 207 | city varchar(255), |
@@ -202,6 +217,19 @@ CREATE TABLE IF NOT EXISTS tenant ( | @@ -202,6 +217,19 @@ CREATE TABLE IF NOT EXISTS tenant ( | ||
202 | isolated_tb_rule_engine boolean | 217 | isolated_tb_rule_engine boolean |
203 | ); | 218 | ); |
204 | 219 | ||
220 | +CREATE TABLE IF NOT EXISTS tenant_profile ( | ||
221 | + id uuid NOT NULL CONSTRAINT tenant_profile_pkey PRIMARY KEY, | ||
222 | + created_time bigint NOT NULL, | ||
223 | + name varchar(255), | ||
224 | + profile_data varchar, | ||
225 | + description varchar, | ||
226 | + search_text varchar(255), | ||
227 | + is_default boolean, | ||
228 | + isolated_tb_core boolean, | ||
229 | + isolated_tb_rule_engine boolean, | ||
230 | + CONSTRAINT tenant_profile_name_unq_key UNIQUE (name) | ||
231 | +); | ||
232 | + | ||
205 | CREATE TABLE IF NOT EXISTS user_credentials ( | 233 | CREATE TABLE IF NOT EXISTS user_credentials ( |
206 | id uuid NOT NULL CONSTRAINT user_credentials_pkey PRIMARY KEY, | 234 | id uuid NOT NULL CONSTRAINT user_credentials_pkey PRIMARY KEY, |
207 | created_time bigint NOT NULL, | 235 | created_time bigint NOT NULL, |
@@ -144,6 +144,7 @@ CREATE TABLE IF NOT EXISTS device ( | @@ -144,6 +144,7 @@ CREATE TABLE IF NOT EXISTS device ( | ||
144 | created_time bigint NOT NULL, | 144 | created_time bigint NOT NULL, |
145 | additional_info varchar, | 145 | additional_info varchar, |
146 | customer_id uuid, | 146 | customer_id uuid, |
147 | + device_profile_id uuid NOT NULL, | ||
147 | type varchar(255), | 148 | type varchar(255), |
148 | name varchar(255), | 149 | name varchar(255), |
149 | label varchar(255), | 150 | label varchar(255), |
@@ -152,6 +153,19 @@ CREATE TABLE IF NOT EXISTS device ( | @@ -152,6 +153,19 @@ CREATE TABLE IF NOT EXISTS device ( | ||
152 | CONSTRAINT device_name_unq_key UNIQUE (tenant_id, name) | 153 | CONSTRAINT device_name_unq_key UNIQUE (tenant_id, name) |
153 | ); | 154 | ); |
154 | 155 | ||
156 | +CREATE TABLE IF NOT EXISTS device_profile ( | ||
157 | + id uuid NOT NULL CONSTRAINT device_profile_pkey PRIMARY KEY, | ||
158 | + created_time bigint NOT NULL, | ||
159 | + name varchar(255), | ||
160 | + profile_data varchar, | ||
161 | + description varchar, | ||
162 | + search_text varchar(255), | ||
163 | + is_default boolean, | ||
164 | + tenant_id uuid, | ||
165 | + default_rule_chain_id uuid, | ||
166 | + CONSTRAINT device_profile_name_unq_key UNIQUE (tenant_id, name) | ||
167 | +); | ||
168 | + | ||
155 | CREATE TABLE IF NOT EXISTS device_credentials ( | 169 | CREATE TABLE IF NOT EXISTS device_credentials ( |
156 | id uuid NOT NULL CONSTRAINT device_credentials_pkey PRIMARY KEY, | 170 | id uuid NOT NULL CONSTRAINT device_credentials_pkey PRIMARY KEY, |
157 | created_time bigint NOT NULL, | 171 | created_time bigint NOT NULL, |
@@ -211,6 +225,7 @@ CREATE TABLE IF NOT EXISTS tenant ( | @@ -211,6 +225,7 @@ CREATE TABLE IF NOT EXISTS tenant ( | ||
211 | id uuid NOT NULL CONSTRAINT tenant_pkey PRIMARY KEY, | 225 | id uuid NOT NULL CONSTRAINT tenant_pkey PRIMARY KEY, |
212 | created_time bigint NOT NULL, | 226 | created_time bigint NOT NULL, |
213 | additional_info varchar, | 227 | additional_info varchar, |
228 | + tenant_profile_id uuid NOT NULL, | ||
214 | address varchar, | 229 | address varchar, |
215 | address2 varchar, | 230 | address2 varchar, |
216 | city varchar(255), | 231 | city varchar(255), |
@@ -226,6 +241,19 @@ CREATE TABLE IF NOT EXISTS tenant ( | @@ -226,6 +241,19 @@ CREATE TABLE IF NOT EXISTS tenant ( | ||
226 | isolated_tb_rule_engine boolean | 241 | isolated_tb_rule_engine boolean |
227 | ); | 242 | ); |
228 | 243 | ||
244 | +CREATE TABLE IF NOT EXISTS tenant_profile ( | ||
245 | + id uuid NOT NULL CONSTRAINT tenant_profile_pkey PRIMARY KEY, | ||
246 | + created_time bigint NOT NULL, | ||
247 | + name varchar(255), | ||
248 | + profile_data varchar, | ||
249 | + description varchar, | ||
250 | + search_text varchar(255), | ||
251 | + is_default boolean, | ||
252 | + isolated_tb_core boolean, | ||
253 | + isolated_tb_rule_engine boolean, | ||
254 | + CONSTRAINT tenant_profile_name_unq_key UNIQUE (name) | ||
255 | +); | ||
256 | + | ||
229 | CREATE TABLE IF NOT EXISTS user_credentials ( | 257 | CREATE TABLE IF NOT EXISTS user_credentials ( |
230 | id uuid NOT NULL CONSTRAINT user_credentials_pkey PRIMARY KEY, | 258 | id uuid NOT NULL CONSTRAINT user_credentials_pkey PRIMARY KEY, |
231 | created_time bigint NOT NULL, | 259 | created_time bigint NOT NULL, |
@@ -31,6 +31,7 @@ import org.thingsboard.server.common.data.BaseData; | @@ -31,6 +31,7 @@ import org.thingsboard.server.common.data.BaseData; | ||
31 | import org.thingsboard.server.common.data.EntityType; | 31 | import org.thingsboard.server.common.data.EntityType; |
32 | import org.thingsboard.server.common.data.Event; | 32 | import org.thingsboard.server.common.data.Event; |
33 | import org.thingsboard.server.common.data.id.EntityId; | 33 | import org.thingsboard.server.common.data.id.EntityId; |
34 | +import org.thingsboard.server.common.data.id.HasId; | ||
34 | import org.thingsboard.server.common.data.id.TenantId; | 35 | import org.thingsboard.server.common.data.id.TenantId; |
35 | import org.thingsboard.server.common.data.id.UUIDBased; | 36 | import org.thingsboard.server.common.data.id.UUIDBased; |
36 | import org.thingsboard.server.dao.alarm.AlarmService; | 37 | import org.thingsboard.server.dao.alarm.AlarmService; |
@@ -41,6 +42,7 @@ import org.thingsboard.server.dao.component.ComponentDescriptorService; | @@ -41,6 +42,7 @@ import org.thingsboard.server.dao.component.ComponentDescriptorService; | ||
41 | import org.thingsboard.server.dao.customer.CustomerService; | 42 | import org.thingsboard.server.dao.customer.CustomerService; |
42 | import org.thingsboard.server.dao.dashboard.DashboardService; | 43 | import org.thingsboard.server.dao.dashboard.DashboardService; |
43 | import org.thingsboard.server.dao.device.DeviceCredentialsService; | 44 | import org.thingsboard.server.dao.device.DeviceCredentialsService; |
45 | +import org.thingsboard.server.dao.device.DeviceProfileService; | ||
44 | import org.thingsboard.server.dao.device.DeviceService; | 46 | import org.thingsboard.server.dao.device.DeviceService; |
45 | import org.thingsboard.server.dao.entity.EntityService; | 47 | import org.thingsboard.server.dao.entity.EntityService; |
46 | import org.thingsboard.server.dao.entityview.EntityViewService; | 48 | import org.thingsboard.server.dao.entityview.EntityViewService; |
@@ -48,6 +50,7 @@ import org.thingsboard.server.dao.event.EventService; | @@ -48,6 +50,7 @@ import org.thingsboard.server.dao.event.EventService; | ||
48 | import org.thingsboard.server.dao.relation.RelationService; | 50 | import org.thingsboard.server.dao.relation.RelationService; |
49 | import org.thingsboard.server.dao.rule.RuleChainService; | 51 | import org.thingsboard.server.dao.rule.RuleChainService; |
50 | import org.thingsboard.server.dao.settings.AdminSettingsService; | 52 | import org.thingsboard.server.dao.settings.AdminSettingsService; |
53 | +import org.thingsboard.server.dao.tenant.TenantProfileService; | ||
51 | import org.thingsboard.server.dao.tenant.TenantService; | 54 | import org.thingsboard.server.dao.tenant.TenantService; |
52 | import org.thingsboard.server.dao.timeseries.TimeseriesService; | 55 | import org.thingsboard.server.dao.timeseries.TimeseriesService; |
53 | import org.thingsboard.server.dao.user.UserService; | 56 | import org.thingsboard.server.dao.user.UserService; |
@@ -125,7 +128,13 @@ public abstract class AbstractServiceTest { | @@ -125,7 +128,13 @@ public abstract class AbstractServiceTest { | ||
125 | @Autowired | 128 | @Autowired |
126 | private ComponentDescriptorService componentDescriptorService; | 129 | private ComponentDescriptorService componentDescriptorService; |
127 | 130 | ||
128 | - class IdComparator<D extends BaseData<? extends UUIDBased>> implements Comparator<D> { | 131 | + @Autowired |
132 | + protected TenantProfileService tenantProfileService; | ||
133 | + | ||
134 | + @Autowired | ||
135 | + protected DeviceProfileService deviceProfileService; | ||
136 | + | ||
137 | + class IdComparator<D extends HasId> implements Comparator<D> { | ||
129 | @Override | 138 | @Override |
130 | public int compare(D o1, D o2) { | 139 | public int compare(D o1, D o2) { |
131 | return o1.getId().getId().compareTo(o2.getId().getId()); | 140 | return o1.getId().getId().compareTo(o2.getId().getId()); |
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.dao.service; | ||
17 | + | ||
18 | +import com.datastax.oss.driver.api.core.uuid.Uuids; | ||
19 | +import org.junit.After; | ||
20 | +import org.junit.Assert; | ||
21 | +import org.junit.Before; | ||
22 | +import org.junit.Test; | ||
23 | +import org.thingsboard.server.common.data.DeviceProfile; | ||
24 | +import org.thingsboard.server.common.data.EntityInfo; | ||
25 | +import org.thingsboard.server.common.data.Tenant; | ||
26 | +import org.thingsboard.server.common.data.id.RuleChainId; | ||
27 | +import org.thingsboard.server.common.data.id.TenantId; | ||
28 | +import org.thingsboard.server.common.data.page.PageData; | ||
29 | +import org.thingsboard.server.common.data.page.PageLink; | ||
30 | +import org.thingsboard.server.dao.exception.DataValidationException; | ||
31 | +import org.thingsboard.server.dao.util.mapping.JacksonUtil; | ||
32 | + | ||
33 | +import java.util.ArrayList; | ||
34 | +import java.util.Collections; | ||
35 | +import java.util.List; | ||
36 | +import java.util.stream.Collectors; | ||
37 | + | ||
38 | +public class BaseDeviceProfileServiceTest extends AbstractServiceTest { | ||
39 | + | ||
40 | + private IdComparator<DeviceProfile> idComparator = new IdComparator<>(); | ||
41 | + private IdComparator<EntityInfo> deviceProfileInfoIdComparator = new IdComparator<>(); | ||
42 | + | ||
43 | + private TenantId tenantId; | ||
44 | + | ||
45 | + @Before | ||
46 | + public void before() { | ||
47 | + Tenant tenant = new Tenant(); | ||
48 | + tenant.setTitle("My tenant"); | ||
49 | + Tenant savedTenant = tenantService.saveTenant(tenant); | ||
50 | + Assert.assertNotNull(savedTenant); | ||
51 | + tenantId = savedTenant.getId(); | ||
52 | + } | ||
53 | + | ||
54 | + @After | ||
55 | + public void after() { | ||
56 | + tenantService.deleteTenant(tenantId); | ||
57 | + } | ||
58 | + | ||
59 | + @Test | ||
60 | + public void testSaveDeviceProfile() { | ||
61 | + DeviceProfile deviceProfile = this.createDeviceProfile("Device Profile"); | ||
62 | + DeviceProfile savedDeviceProfile = deviceProfileService.saveDeviceProfile(deviceProfile); | ||
63 | + Assert.assertNotNull(savedDeviceProfile); | ||
64 | + Assert.assertNotNull(savedDeviceProfile.getId()); | ||
65 | + Assert.assertTrue(savedDeviceProfile.getCreatedTime() > 0); | ||
66 | + Assert.assertEquals(deviceProfile.getName(), savedDeviceProfile.getName()); | ||
67 | + Assert.assertEquals(deviceProfile.getDescription(), savedDeviceProfile.getDescription()); | ||
68 | + Assert.assertEquals(deviceProfile.getProfileData(), savedDeviceProfile.getProfileData()); | ||
69 | + Assert.assertEquals(deviceProfile.isDefault(), savedDeviceProfile.isDefault()); | ||
70 | + Assert.assertEquals(deviceProfile.getDefaultRuleChainId(), savedDeviceProfile.getDefaultRuleChainId()); | ||
71 | + savedDeviceProfile.setName("New device profile"); | ||
72 | + deviceProfileService.saveDeviceProfile(savedDeviceProfile); | ||
73 | + DeviceProfile foundDeviceProfile = deviceProfileService.findDeviceProfileById(tenantId, savedDeviceProfile.getId()); | ||
74 | + Assert.assertEquals(foundDeviceProfile.getName(), savedDeviceProfile.getName()); | ||
75 | + | ||
76 | + deviceProfileService.deleteDeviceProfile(tenantId, savedDeviceProfile.getId()); | ||
77 | + } | ||
78 | + | ||
79 | + @Test | ||
80 | + public void testFindDeviceProfileById() { | ||
81 | + DeviceProfile deviceProfile = this.createDeviceProfile("Device Profile"); | ||
82 | + DeviceProfile savedDeviceProfile = deviceProfileService.saveDeviceProfile(deviceProfile); | ||
83 | + DeviceProfile foundDeviceProfile = deviceProfileService.findDeviceProfileById(tenantId, savedDeviceProfile.getId()); | ||
84 | + Assert.assertNotNull(foundDeviceProfile); | ||
85 | + Assert.assertEquals(savedDeviceProfile, foundDeviceProfile); | ||
86 | + deviceProfileService.deleteDeviceProfile(tenantId, savedDeviceProfile.getId()); | ||
87 | + } | ||
88 | + | ||
89 | + @Test | ||
90 | + public void testFindDeviceProfileInfoById() { | ||
91 | + DeviceProfile deviceProfile = this.createDeviceProfile("Device Profile"); | ||
92 | + DeviceProfile savedDeviceProfile = deviceProfileService.saveDeviceProfile(deviceProfile); | ||
93 | + EntityInfo foundDeviceProfileInfo = deviceProfileService.findDeviceProfileInfoById(tenantId, savedDeviceProfile.getId()); | ||
94 | + Assert.assertNotNull(foundDeviceProfileInfo); | ||
95 | + Assert.assertEquals(savedDeviceProfile.getId(), foundDeviceProfileInfo.getId()); | ||
96 | + Assert.assertEquals(savedDeviceProfile.getName(), foundDeviceProfileInfo.getName()); | ||
97 | + deviceProfileService.deleteDeviceProfile(tenantId, savedDeviceProfile.getId()); | ||
98 | + } | ||
99 | + | ||
100 | + @Test | ||
101 | + public void testFindDefaultDeviceProfile() { | ||
102 | + DeviceProfile foundDefaultDeviceProfile = deviceProfileService.findDefaultDeviceProfile(tenantId); | ||
103 | + Assert.assertNotNull(foundDefaultDeviceProfile); | ||
104 | + Assert.assertNotNull(foundDefaultDeviceProfile.getId()); | ||
105 | + Assert.assertNotNull(foundDefaultDeviceProfile.getName()); | ||
106 | + } | ||
107 | + | ||
108 | + @Test | ||
109 | + public void testFindDefaultDeviceProfileInfo() { | ||
110 | + EntityInfo foundDefaultDeviceProfileInfo = deviceProfileService.findDefaultDeviceProfileInfo(tenantId); | ||
111 | + Assert.assertNotNull(foundDefaultDeviceProfileInfo.getId()); | ||
112 | + Assert.assertNotNull(foundDefaultDeviceProfileInfo.getName()); | ||
113 | + Assert.assertNotNull(foundDefaultDeviceProfileInfo); | ||
114 | + } | ||
115 | + | ||
116 | + @Test | ||
117 | + public void testSetDefaultDeviceProfile() { | ||
118 | + DeviceProfile deviceProfile1 = this.createDeviceProfile("Device Profile 1"); | ||
119 | + DeviceProfile deviceProfile2 = this.createDeviceProfile("Device Profile 2"); | ||
120 | + | ||
121 | + DeviceProfile savedDeviceProfile1 = deviceProfileService.saveDeviceProfile(deviceProfile1); | ||
122 | + DeviceProfile savedDeviceProfile2 = deviceProfileService.saveDeviceProfile(deviceProfile2); | ||
123 | + | ||
124 | + boolean result = deviceProfileService.setDefaultDeviceProfile(tenantId, savedDeviceProfile1.getId()); | ||
125 | + Assert.assertTrue(result); | ||
126 | + DeviceProfile defaultDeviceProfile = deviceProfileService.findDefaultDeviceProfile(tenantId); | ||
127 | + Assert.assertNotNull(defaultDeviceProfile); | ||
128 | + Assert.assertEquals(savedDeviceProfile1.getId(), defaultDeviceProfile.getId()); | ||
129 | + result = deviceProfileService.setDefaultDeviceProfile(tenantId, savedDeviceProfile2.getId()); | ||
130 | + Assert.assertTrue(result); | ||
131 | + defaultDeviceProfile = deviceProfileService.findDefaultDeviceProfile(tenantId); | ||
132 | + Assert.assertNotNull(defaultDeviceProfile); | ||
133 | + Assert.assertEquals(savedDeviceProfile2.getId(), defaultDeviceProfile.getId()); | ||
134 | + deviceProfileService.deleteDeviceProfile(tenantId, savedDeviceProfile1.getId()); | ||
135 | + deviceProfileService.deleteDeviceProfile(tenantId, savedDeviceProfile2.getId()); | ||
136 | + } | ||
137 | + | ||
138 | + @Test(expected = DataValidationException.class) | ||
139 | + public void testSaveDeviceProfileWithEmptyName() { | ||
140 | + DeviceProfile deviceProfile = new DeviceProfile(); | ||
141 | + deviceProfile.setTenantId(tenantId); | ||
142 | + deviceProfileService.saveDeviceProfile(deviceProfile); | ||
143 | + } | ||
144 | + | ||
145 | + @Test(expected = DataValidationException.class) | ||
146 | + public void testSaveDeviceProfileWithSameName() { | ||
147 | + DeviceProfile deviceProfile = this.createDeviceProfile("Device Profile"); | ||
148 | + deviceProfileService.saveDeviceProfile(deviceProfile); | ||
149 | + DeviceProfile deviceProfile2 = this.createDeviceProfile("Device Profile"); | ||
150 | + deviceProfileService.saveDeviceProfile(deviceProfile2); | ||
151 | + } | ||
152 | + | ||
153 | + @Test | ||
154 | + public void testDeleteDeviceProfile() { | ||
155 | + DeviceProfile deviceProfile = this.createDeviceProfile("Device Profile"); | ||
156 | + DeviceProfile savedDeviceProfile = deviceProfileService.saveDeviceProfile(deviceProfile); | ||
157 | + deviceProfileService.deleteDeviceProfile(tenantId, savedDeviceProfile.getId()); | ||
158 | + DeviceProfile foundDeviceProfile = deviceProfileService.findDeviceProfileById(tenantId, savedDeviceProfile.getId()); | ||
159 | + Assert.assertNull(foundDeviceProfile); | ||
160 | + } | ||
161 | + | ||
162 | + @Test | ||
163 | + public void testFindDeviceProfiles() { | ||
164 | + | ||
165 | + List<DeviceProfile> deviceProfiles = new ArrayList<>(); | ||
166 | + PageLink pageLink = new PageLink(17); | ||
167 | + PageData<DeviceProfile> pageData = deviceProfileService.findDeviceProfiles(tenantId, pageLink); | ||
168 | + Assert.assertFalse(pageData.hasNext()); | ||
169 | + Assert.assertEquals(1, pageData.getTotalElements()); | ||
170 | + deviceProfiles.addAll(pageData.getData()); | ||
171 | + | ||
172 | + for (int i=0;i<28;i++) { | ||
173 | + DeviceProfile deviceProfile = this.createDeviceProfile("Device Profile"+i); | ||
174 | + deviceProfiles.add(deviceProfileService.saveDeviceProfile(deviceProfile)); | ||
175 | + } | ||
176 | + | ||
177 | + List<DeviceProfile> loadedDeviceProfiles = new ArrayList<>(); | ||
178 | + pageLink = new PageLink(17); | ||
179 | + do { | ||
180 | + pageData = deviceProfileService.findDeviceProfiles(tenantId, pageLink); | ||
181 | + loadedDeviceProfiles.addAll(pageData.getData()); | ||
182 | + if (pageData.hasNext()) { | ||
183 | + pageLink = pageLink.nextPageLink(); | ||
184 | + } | ||
185 | + } while (pageData.hasNext()); | ||
186 | + | ||
187 | + Collections.sort(deviceProfiles, idComparator); | ||
188 | + Collections.sort(loadedDeviceProfiles, idComparator); | ||
189 | + | ||
190 | + Assert.assertEquals(deviceProfiles, loadedDeviceProfiles); | ||
191 | + | ||
192 | + for (DeviceProfile deviceProfile : loadedDeviceProfiles) { | ||
193 | + if (!deviceProfile.isDefault()) { | ||
194 | + deviceProfileService.deleteDeviceProfile(tenantId, deviceProfile.getId()); | ||
195 | + } | ||
196 | + } | ||
197 | + | ||
198 | + pageLink = new PageLink(17); | ||
199 | + pageData = deviceProfileService.findDeviceProfiles(tenantId, pageLink); | ||
200 | + Assert.assertFalse(pageData.hasNext()); | ||
201 | + Assert.assertEquals(1, pageData.getTotalElements()); | ||
202 | + } | ||
203 | + | ||
204 | + @Test | ||
205 | + public void testFindDeviceProfileInfos() { | ||
206 | + | ||
207 | + List<DeviceProfile> deviceProfiles = new ArrayList<>(); | ||
208 | + PageLink pageLink = new PageLink(17); | ||
209 | + PageData<DeviceProfile> deviceProfilePageData = deviceProfileService.findDeviceProfiles(tenantId, pageLink); | ||
210 | + Assert.assertFalse(deviceProfilePageData.hasNext()); | ||
211 | + Assert.assertEquals(1, deviceProfilePageData.getTotalElements()); | ||
212 | + deviceProfiles.addAll(deviceProfilePageData.getData()); | ||
213 | + | ||
214 | + for (int i=0;i<28;i++) { | ||
215 | + DeviceProfile deviceProfile = this.createDeviceProfile("Device Profile"+i); | ||
216 | + deviceProfiles.add(deviceProfileService.saveDeviceProfile(deviceProfile)); | ||
217 | + } | ||
218 | + | ||
219 | + List<EntityInfo> loadedDeviceProfileInfos = new ArrayList<>(); | ||
220 | + pageLink = new PageLink(17); | ||
221 | + PageData<EntityInfo> pageData; | ||
222 | + do { | ||
223 | + pageData = deviceProfileService.findDeviceProfileInfos(tenantId, pageLink); | ||
224 | + loadedDeviceProfileInfos.addAll(pageData.getData()); | ||
225 | + if (pageData.hasNext()) { | ||
226 | + pageLink = pageLink.nextPageLink(); | ||
227 | + } | ||
228 | + } while (pageData.hasNext()); | ||
229 | + | ||
230 | + | ||
231 | + Collections.sort(deviceProfiles, idComparator); | ||
232 | + Collections.sort(loadedDeviceProfileInfos, deviceProfileInfoIdComparator); | ||
233 | + | ||
234 | + List<EntityInfo> deviceProfileInfos = deviceProfiles.stream().map(deviceProfile -> new EntityInfo(deviceProfile.getId(), | ||
235 | + deviceProfile.getName())).collect(Collectors.toList()); | ||
236 | + | ||
237 | + Assert.assertEquals(deviceProfileInfos, loadedDeviceProfileInfos); | ||
238 | + | ||
239 | + for (DeviceProfile deviceProfile : deviceProfiles) { | ||
240 | + if (!deviceProfile.isDefault()) { | ||
241 | + deviceProfileService.deleteDeviceProfile(tenantId, deviceProfile.getId()); | ||
242 | + } | ||
243 | + } | ||
244 | + | ||
245 | + pageLink = new PageLink(17); | ||
246 | + pageData = deviceProfileService.findDeviceProfileInfos(tenantId, pageLink); | ||
247 | + Assert.assertFalse(pageData.hasNext()); | ||
248 | + Assert.assertEquals(1, pageData.getTotalElements()); | ||
249 | + } | ||
250 | + | ||
251 | + private DeviceProfile createDeviceProfile(String name) { | ||
252 | + DeviceProfile deviceProfile = new DeviceProfile(); | ||
253 | + deviceProfile.setTenantId(tenantId); | ||
254 | + deviceProfile.setName(name); | ||
255 | + deviceProfile.setDescription(name + " Test"); | ||
256 | + deviceProfile.setProfileData(JacksonUtil.OBJECT_MAPPER.createObjectNode()); | ||
257 | + deviceProfile.setDefault(false); | ||
258 | + deviceProfile.setDefaultRuleChainId(new RuleChainId(Uuids.timeBased())); | ||
259 | + return deviceProfile; | ||
260 | + } | ||
261 | + | ||
262 | +} |
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.dao.service; | ||
17 | + | ||
18 | +import org.junit.After; | ||
19 | +import org.junit.Assert; | ||
20 | +import org.junit.Test; | ||
21 | +import org.thingsboard.server.common.data.EntityInfo; | ||
22 | +import org.thingsboard.server.common.data.TenantProfile; | ||
23 | +import org.thingsboard.server.common.data.id.TenantId; | ||
24 | +import org.thingsboard.server.common.data.id.TenantProfileId; | ||
25 | +import org.thingsboard.server.common.data.page.PageData; | ||
26 | +import org.thingsboard.server.common.data.page.PageLink; | ||
27 | +import org.thingsboard.server.dao.exception.DataValidationException; | ||
28 | +import org.thingsboard.server.dao.util.mapping.JacksonUtil; | ||
29 | + | ||
30 | +import java.util.ArrayList; | ||
31 | +import java.util.Collections; | ||
32 | +import java.util.List; | ||
33 | +import java.util.stream.Collectors; | ||
34 | + | ||
35 | +public class BaseTenantProfileServiceTest extends AbstractServiceTest { | ||
36 | + | ||
37 | + private IdComparator<TenantProfile> idComparator = new IdComparator<>(); | ||
38 | + private IdComparator<EntityInfo> tenantProfileInfoIdComparator = new IdComparator<>(); | ||
39 | + | ||
40 | + @After | ||
41 | + public void after() { | ||
42 | + tenantProfileService.deleteTenantProfiles(TenantId.SYS_TENANT_ID); | ||
43 | + } | ||
44 | + | ||
45 | + @Test | ||
46 | + public void testSaveTenantProfile() { | ||
47 | + TenantProfile tenantProfile = this.createTenantProfile("Tenant Profile"); | ||
48 | + TenantProfile savedTenantProfile = tenantProfileService.saveTenantProfile(TenantId.SYS_TENANT_ID, tenantProfile); | ||
49 | + Assert.assertNotNull(savedTenantProfile); | ||
50 | + Assert.assertNotNull(savedTenantProfile.getId()); | ||
51 | + Assert.assertTrue(savedTenantProfile.getCreatedTime() > 0); | ||
52 | + Assert.assertEquals(tenantProfile.getName(), savedTenantProfile.getName()); | ||
53 | + Assert.assertEquals(tenantProfile.getDescription(), savedTenantProfile.getDescription()); | ||
54 | + Assert.assertEquals(tenantProfile.getProfileData(), savedTenantProfile.getProfileData()); | ||
55 | + Assert.assertEquals(tenantProfile.isDefault(), savedTenantProfile.isDefault()); | ||
56 | + Assert.assertEquals(tenantProfile.isIsolatedTbCore(), savedTenantProfile.isIsolatedTbCore()); | ||
57 | + Assert.assertEquals(tenantProfile.isIsolatedTbRuleEngine(), savedTenantProfile.isIsolatedTbRuleEngine()); | ||
58 | + | ||
59 | + savedTenantProfile.setName("New tenant profile"); | ||
60 | + tenantProfileService.saveTenantProfile(TenantId.SYS_TENANT_ID, savedTenantProfile); | ||
61 | + TenantProfile foundTenantProfile = tenantProfileService.findTenantProfileById(TenantId.SYS_TENANT_ID, savedTenantProfile.getId()); | ||
62 | + Assert.assertEquals(foundTenantProfile.getName(), savedTenantProfile.getName()); | ||
63 | + | ||
64 | + tenantProfileService.deleteTenantProfile(TenantId.SYS_TENANT_ID, savedTenantProfile.getId()); | ||
65 | + } | ||
66 | + | ||
67 | + @Test | ||
68 | + public void testFindTenantProfileById() { | ||
69 | + TenantProfile tenantProfile = this.createTenantProfile("Tenant Profile"); | ||
70 | + TenantProfile savedTenantProfile = tenantProfileService.saveTenantProfile(TenantId.SYS_TENANT_ID, tenantProfile); | ||
71 | + TenantProfile foundTenantProfile = tenantProfileService.findTenantProfileById(TenantId.SYS_TENANT_ID, savedTenantProfile.getId()); | ||
72 | + Assert.assertNotNull(foundTenantProfile); | ||
73 | + Assert.assertEquals(savedTenantProfile, foundTenantProfile); | ||
74 | + tenantProfileService.deleteTenantProfile(TenantId.SYS_TENANT_ID, savedTenantProfile.getId()); | ||
75 | + } | ||
76 | + | ||
77 | + @Test | ||
78 | + public void testFindTenantProfileInfoById() { | ||
79 | + TenantProfile tenantProfile = this.createTenantProfile("Tenant Profile"); | ||
80 | + TenantProfile savedTenantProfile = tenantProfileService.saveTenantProfile(TenantId.SYS_TENANT_ID, tenantProfile); | ||
81 | + EntityInfo foundTenantProfileInfo = tenantProfileService.findTenantProfileInfoById(TenantId.SYS_TENANT_ID, savedTenantProfile.getId()); | ||
82 | + Assert.assertNotNull(foundTenantProfileInfo); | ||
83 | + Assert.assertEquals(savedTenantProfile.getId(), foundTenantProfileInfo.getId()); | ||
84 | + Assert.assertEquals(savedTenantProfile.getName(), foundTenantProfileInfo.getName()); | ||
85 | + tenantProfileService.deleteTenantProfile(TenantId.SYS_TENANT_ID, savedTenantProfile.getId()); | ||
86 | + } | ||
87 | + | ||
88 | + @Test | ||
89 | + public void testFindDefaultTenantProfile() { | ||
90 | + TenantProfile tenantProfile = this.createTenantProfile("Default Tenant Profile"); | ||
91 | + tenantProfile.setDefault(true); | ||
92 | + TenantProfile savedTenantProfile = tenantProfileService.saveTenantProfile(TenantId.SYS_TENANT_ID, tenantProfile); | ||
93 | + TenantProfile foundDefaultTenantProfile = tenantProfileService.findDefaultTenantProfile(TenantId.SYS_TENANT_ID); | ||
94 | + Assert.assertNotNull(foundDefaultTenantProfile); | ||
95 | + Assert.assertEquals(savedTenantProfile, foundDefaultTenantProfile); | ||
96 | + tenantProfileService.deleteTenantProfile(TenantId.SYS_TENANT_ID, savedTenantProfile.getId()); | ||
97 | + } | ||
98 | + | ||
99 | + @Test | ||
100 | + public void testFindDefaultTenantProfileInfo() { | ||
101 | + TenantProfile tenantProfile = this.createTenantProfile("Default Tenant Profile"); | ||
102 | + tenantProfile.setDefault(true); | ||
103 | + TenantProfile savedTenantProfile = tenantProfileService.saveTenantProfile(TenantId.SYS_TENANT_ID, tenantProfile); | ||
104 | + EntityInfo foundDefaultTenantProfileInfo = tenantProfileService.findDefaultTenantProfileInfo(TenantId.SYS_TENANT_ID); | ||
105 | + Assert.assertNotNull(foundDefaultTenantProfileInfo); | ||
106 | + Assert.assertEquals(savedTenantProfile.getId(), foundDefaultTenantProfileInfo.getId()); | ||
107 | + Assert.assertEquals(savedTenantProfile.getName(), foundDefaultTenantProfileInfo.getName()); | ||
108 | + tenantProfileService.deleteTenantProfile(TenantId.SYS_TENANT_ID, savedTenantProfile.getId()); | ||
109 | + } | ||
110 | + | ||
111 | + @Test | ||
112 | + public void testSetDefaultTenantProfile() { | ||
113 | + TenantProfile tenantProfile1 = this.createTenantProfile("Tenant Profile 1"); | ||
114 | + TenantProfile tenantProfile2 = this.createTenantProfile("Tenant Profile 2"); | ||
115 | + | ||
116 | + TenantProfile savedTenantProfile1 = tenantProfileService.saveTenantProfile(TenantId.SYS_TENANT_ID, tenantProfile1); | ||
117 | + TenantProfile savedTenantProfile2 = tenantProfileService.saveTenantProfile(TenantId.SYS_TENANT_ID, tenantProfile2); | ||
118 | + | ||
119 | + boolean result = tenantProfileService.setDefaultTenantProfile(TenantId.SYS_TENANT_ID, savedTenantProfile1.getId()); | ||
120 | + Assert.assertTrue(result); | ||
121 | + TenantProfile defaultTenantProfile = tenantProfileService.findDefaultTenantProfile(TenantId.SYS_TENANT_ID); | ||
122 | + Assert.assertNotNull(defaultTenantProfile); | ||
123 | + Assert.assertEquals(savedTenantProfile1.getId(), defaultTenantProfile.getId()); | ||
124 | + result = tenantProfileService.setDefaultTenantProfile(TenantId.SYS_TENANT_ID, savedTenantProfile2.getId()); | ||
125 | + Assert.assertTrue(result); | ||
126 | + defaultTenantProfile = tenantProfileService.findDefaultTenantProfile(TenantId.SYS_TENANT_ID); | ||
127 | + Assert.assertNotNull(defaultTenantProfile); | ||
128 | + Assert.assertEquals(savedTenantProfile2.getId(), defaultTenantProfile.getId()); | ||
129 | + tenantProfileService.deleteTenantProfile(TenantId.SYS_TENANT_ID, savedTenantProfile1.getId()); | ||
130 | + tenantProfileService.deleteTenantProfile(TenantId.SYS_TENANT_ID, savedTenantProfile2.getId()); | ||
131 | + } | ||
132 | + | ||
133 | + @Test(expected = DataValidationException.class) | ||
134 | + public void testSaveTenantProfileWithEmptyName() { | ||
135 | + TenantProfile tenantProfile = new TenantProfile(); | ||
136 | + tenantProfileService.saveTenantProfile(TenantId.SYS_TENANT_ID, tenantProfile); | ||
137 | + } | ||
138 | + | ||
139 | + @Test(expected = DataValidationException.class) | ||
140 | + public void testSaveTenantProfileWithSameName() { | ||
141 | + TenantProfile tenantProfile = this.createTenantProfile("Tenant Profile"); | ||
142 | + tenantProfileService.saveTenantProfile(TenantId.SYS_TENANT_ID, tenantProfile); | ||
143 | + TenantProfile tenantProfile2 = this.createTenantProfile("Tenant Profile"); | ||
144 | + tenantProfileService.saveTenantProfile(TenantId.SYS_TENANT_ID, tenantProfile2); | ||
145 | + } | ||
146 | + | ||
147 | + @Test | ||
148 | + public void testDeleteTenantProfile() { | ||
149 | + TenantProfile tenantProfile = this.createTenantProfile("Tenant Profile"); | ||
150 | + TenantProfile savedTenantProfile = tenantProfileService.saveTenantProfile(TenantId.SYS_TENANT_ID, tenantProfile); | ||
151 | + tenantProfileService.deleteTenantProfile(TenantId.SYS_TENANT_ID, savedTenantProfile.getId()); | ||
152 | + TenantProfile foundTenantProfile = tenantProfileService.findTenantProfileById(TenantId.SYS_TENANT_ID, savedTenantProfile.getId()); | ||
153 | + Assert.assertNull(foundTenantProfile); | ||
154 | + } | ||
155 | + | ||
156 | + @Test | ||
157 | + public void testFindTenantProfiles() { | ||
158 | + | ||
159 | + List<TenantProfile> tenantProfiles = new ArrayList<>(); | ||
160 | + PageLink pageLink = new PageLink(17); | ||
161 | + PageData<TenantProfile> pageData = tenantProfileService.findTenantProfiles(TenantId.SYS_TENANT_ID, pageLink); | ||
162 | + Assert.assertFalse(pageData.hasNext()); | ||
163 | + Assert.assertTrue(pageData.getData().isEmpty()); | ||
164 | + tenantProfiles.addAll(pageData.getData()); | ||
165 | + | ||
166 | + for (int i=0;i<28;i++) { | ||
167 | + TenantProfile tenantProfile = this.createTenantProfile("Tenant Profile"+i); | ||
168 | + tenantProfiles.add(tenantProfileService.saveTenantProfile(TenantId.SYS_TENANT_ID, tenantProfile)); | ||
169 | + } | ||
170 | + | ||
171 | + List<TenantProfile> loadedTenantProfiles = new ArrayList<>(); | ||
172 | + pageLink = new PageLink(17); | ||
173 | + do { | ||
174 | + pageData = tenantProfileService.findTenantProfiles(TenantId.SYS_TENANT_ID, pageLink); | ||
175 | + loadedTenantProfiles.addAll(pageData.getData()); | ||
176 | + if (pageData.hasNext()) { | ||
177 | + pageLink = pageLink.nextPageLink(); | ||
178 | + } | ||
179 | + } while (pageData.hasNext()); | ||
180 | + | ||
181 | + Collections.sort(tenantProfiles, idComparator); | ||
182 | + Collections.sort(loadedTenantProfiles, idComparator); | ||
183 | + | ||
184 | + Assert.assertEquals(tenantProfiles, loadedTenantProfiles); | ||
185 | + | ||
186 | + for (TenantProfile tenantProfile : loadedTenantProfiles) { | ||
187 | + tenantProfileService.deleteTenantProfile(TenantId.SYS_TENANT_ID, tenantProfile.getId()); | ||
188 | + } | ||
189 | + | ||
190 | + pageLink = new PageLink(17); | ||
191 | + pageData = tenantProfileService.findTenantProfiles(TenantId.SYS_TENANT_ID, pageLink); | ||
192 | + Assert.assertFalse(pageData.hasNext()); | ||
193 | + Assert.assertTrue(pageData.getData().isEmpty()); | ||
194 | + | ||
195 | + } | ||
196 | + | ||
197 | + @Test | ||
198 | + public void testFindTenantProfileInfos() { | ||
199 | + | ||
200 | + List<TenantProfile> tenantProfiles = new ArrayList<>(); | ||
201 | + | ||
202 | + for (int i=0;i<28;i++) { | ||
203 | + TenantProfile tenantProfile = this.createTenantProfile("Tenant Profile"+i); | ||
204 | + tenantProfiles.add(tenantProfileService.saveTenantProfile(TenantId.SYS_TENANT_ID, tenantProfile)); | ||
205 | + } | ||
206 | + | ||
207 | + List<EntityInfo> loadedTenantProfileInfos = new ArrayList<>(); | ||
208 | + PageLink pageLink = new PageLink(17); | ||
209 | + PageData<EntityInfo> pageData; | ||
210 | + do { | ||
211 | + pageData = tenantProfileService.findTenantProfileInfos(TenantId.SYS_TENANT_ID, pageLink); | ||
212 | + loadedTenantProfileInfos.addAll(pageData.getData()); | ||
213 | + if (pageData.hasNext()) { | ||
214 | + pageLink = pageLink.nextPageLink(); | ||
215 | + } | ||
216 | + } while (pageData.hasNext()); | ||
217 | + | ||
218 | + Collections.sort(tenantProfiles, idComparator); | ||
219 | + Collections.sort(loadedTenantProfileInfos, tenantProfileInfoIdComparator); | ||
220 | + | ||
221 | + List<EntityInfo> tenantProfileInfos = tenantProfiles.stream().map(tenantProfile -> new EntityInfo(tenantProfile.getId(), | ||
222 | + tenantProfile.getName())).collect(Collectors.toList()); | ||
223 | + | ||
224 | + Assert.assertEquals(tenantProfileInfos, loadedTenantProfileInfos); | ||
225 | + | ||
226 | + for (EntityInfo tenantProfile : loadedTenantProfileInfos) { | ||
227 | + tenantProfileService.deleteTenantProfile(TenantId.SYS_TENANT_ID, new TenantProfileId(tenantProfile.getId().getId())); | ||
228 | + } | ||
229 | + | ||
230 | + pageLink = new PageLink(17); | ||
231 | + pageData = tenantProfileService.findTenantProfileInfos(TenantId.SYS_TENANT_ID, pageLink); | ||
232 | + Assert.assertFalse(pageData.hasNext()); | ||
233 | + Assert.assertTrue(pageData.getData().isEmpty()); | ||
234 | + | ||
235 | + } | ||
236 | + | ||
237 | + private TenantProfile createTenantProfile(String name) { | ||
238 | + TenantProfile tenantProfile = new TenantProfile(); | ||
239 | + tenantProfile.setName(name); | ||
240 | + tenantProfile.setDescription(name + " Test"); | ||
241 | + tenantProfile.setProfileData(JacksonUtil.OBJECT_MAPPER.createObjectNode()); | ||
242 | + tenantProfile.setDefault(false); | ||
243 | + tenantProfile.setIsolatedTbCore(false); | ||
244 | + tenantProfile.setIsolatedTbRuleEngine(false); | ||
245 | + return tenantProfile; | ||
246 | + } | ||
247 | + | ||
248 | +} |
dao/src/test/java/org/thingsboard/server/dao/service/sql/DeviceProfileServiceSqlTest.java
0 → 100644
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.dao.service.sql; | ||
17 | + | ||
18 | +import org.thingsboard.server.dao.service.BaseDeviceProfileServiceTest; | ||
19 | +import org.thingsboard.server.dao.service.DaoSqlTest; | ||
20 | + | ||
21 | +@DaoSqlTest | ||
22 | +public class DeviceProfileServiceSqlTest extends BaseDeviceProfileServiceTest { | ||
23 | +} |
dao/src/test/java/org/thingsboard/server/dao/service/sql/TenantProfileServiceSqlTest.java
0 → 100644
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.dao.service.sql; | ||
17 | + | ||
18 | +import org.thingsboard.server.dao.service.BaseTenantProfileServiceTest; | ||
19 | +import org.thingsboard.server.dao.service.DaoSqlTest; | ||
20 | + | ||
21 | +@DaoSqlTest | ||
22 | +public class TenantProfileServiceSqlTest extends BaseTenantProfileServiceTest { | ||
23 | +} |
@@ -20,4 +20,6 @@ DROP TABLE IF EXISTS widgets_bundle; | @@ -20,4 +20,6 @@ DROP TABLE IF EXISTS widgets_bundle; | ||
20 | DROP TABLE IF EXISTS rule_node; | 20 | DROP TABLE IF EXISTS rule_node; |
21 | DROP TABLE IF EXISTS rule_chain; | 21 | DROP TABLE IF EXISTS rule_chain; |
22 | DROP TABLE IF EXISTS entity_view; | 22 | DROP TABLE IF EXISTS entity_view; |
23 | +DROP TABLE IF EXISTS device_profile; | ||
24 | +DROP TABLE IF EXISTS tenant_profile; | ||
23 | DROP FUNCTION IF EXISTS to_uuid; | 25 | DROP FUNCTION IF EXISTS to_uuid; |
@@ -21,4 +21,6 @@ DROP TABLE IF EXISTS widgets_bundle; | @@ -21,4 +21,6 @@ DROP TABLE IF EXISTS widgets_bundle; | ||
21 | DROP TABLE IF EXISTS rule_node; | 21 | DROP TABLE IF EXISTS rule_node; |
22 | DROP TABLE IF EXISTS rule_chain; | 22 | DROP TABLE IF EXISTS rule_chain; |
23 | DROP TABLE IF EXISTS entity_view; | 23 | DROP TABLE IF EXISTS entity_view; |
24 | -DROP TABLE IF EXISTS tb_schema_settings; | ||
24 | +DROP TABLE IF EXISTS device_profile; | ||
25 | +DROP TABLE IF EXISTS tenant_profile; | ||
26 | +DROP TABLE IF EXISTS tb_schema_settings; |
@@ -21,4 +21,6 @@ DROP TABLE IF EXISTS widgets_bundle; | @@ -21,4 +21,6 @@ DROP TABLE IF EXISTS widgets_bundle; | ||
21 | DROP TABLE IF EXISTS rule_node; | 21 | DROP TABLE IF EXISTS rule_node; |
22 | DROP TABLE IF EXISTS rule_chain; | 22 | DROP TABLE IF EXISTS rule_chain; |
23 | DROP TABLE IF EXISTS entity_view; | 23 | DROP TABLE IF EXISTS entity_view; |
24 | -DROP TABLE IF EXISTS tb_schema_settings; | ||
24 | +DROP TABLE IF EXISTS device_profile; | ||
25 | +DROP TABLE IF EXISTS tenant_profile; | ||
26 | +DROP TABLE IF EXISTS tb_schema_settings; |