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 | 58 | import org.thingsboard.server.dao.nosql.CassandraBufferedRateExecutor; |
59 | 59 | import org.thingsboard.server.dao.relation.RelationService; |
60 | 60 | import org.thingsboard.server.dao.rule.RuleChainService; |
61 | +import org.thingsboard.server.dao.tenant.TenantProfileService; | |
61 | 62 | import org.thingsboard.server.dao.tenant.TenantService; |
62 | 63 | import org.thingsboard.server.dao.timeseries.TimeseriesService; |
63 | 64 | import org.thingsboard.server.dao.user.UserService; |
... | ... | @@ -139,6 +140,10 @@ public class ActorSystemContext { |
139 | 140 | |
140 | 141 | @Autowired |
141 | 142 | @Getter |
143 | + private TenantProfileService tenantProfileService; | |
144 | + | |
145 | + @Autowired | |
146 | + @Getter | |
142 | 147 | private CustomerService customerService; |
143 | 148 | |
144 | 149 | @Autowired | ... | ... |
... | ... | @@ -27,6 +27,7 @@ import org.thingsboard.server.actors.service.DefaultActorService; |
27 | 27 | import org.thingsboard.server.actors.tenant.TenantActor; |
28 | 28 | import org.thingsboard.server.common.data.EntityType; |
29 | 29 | import org.thingsboard.server.common.data.Tenant; |
30 | +import org.thingsboard.server.common.data.TenantProfile; | |
30 | 31 | import org.thingsboard.server.common.data.id.EntityId; |
31 | 32 | import org.thingsboard.server.common.data.id.TenantId; |
32 | 33 | import org.thingsboard.server.common.data.page.PageDataIterable; |
... | ... | @@ -116,7 +117,9 @@ public class AppActor extends ContextAwareActor { |
116 | 117 | boolean isRuleEngine = systemContext.getServiceInfoProvider().isService(ServiceType.TB_RULE_ENGINE); |
117 | 118 | boolean isCore = systemContext.getServiceInfoProvider().isService(ServiceType.TB_CORE); |
118 | 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 | 123 | log.debug("[{}] Creating tenant actor", tenant.getId()); |
121 | 124 | getOrCreateTenantActor(tenant.getId()); |
122 | 125 | log.debug("[{}] Tenant actor created.", tenant.getId()); | ... | ... |
... | ... | @@ -31,6 +31,7 @@ import org.thingsboard.server.actors.service.ContextBasedCreator; |
31 | 31 | import org.thingsboard.server.actors.service.DefaultActorService; |
32 | 32 | import org.thingsboard.server.common.data.EntityType; |
33 | 33 | import org.thingsboard.server.common.data.Tenant; |
34 | +import org.thingsboard.server.common.data.TenantProfile; | |
34 | 35 | import org.thingsboard.server.common.data.id.DeviceId; |
35 | 36 | import org.thingsboard.server.common.data.id.EntityId; |
36 | 37 | import org.thingsboard.server.common.data.id.RuleChainId; |
... | ... | @@ -75,12 +76,16 @@ public class TenantActor extends RuleChainManagerActor { |
75 | 76 | // This Service may be started for specific tenant only. |
76 | 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 | 83 | isRuleEngineForCurrentTenant = systemContext.getServiceInfoProvider().isService(ServiceType.TB_RULE_ENGINE); |
79 | 84 | isCore = systemContext.getServiceInfoProvider().isService(ServiceType.TB_CORE); |
80 | 85 | |
81 | 86 | if (isRuleEngineForCurrentTenant) { |
82 | 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 | 89 | log.info("[{}] Going to init rule chains", tenantId); |
85 | 90 | initRuleChains(); |
86 | 91 | } else { | ... | ... |
... | ... | @@ -175,6 +175,9 @@ public class ThingsboardInstallService { |
175 | 175 | case "3.1.0": |
176 | 176 | log.info("Upgrading ThingsBoard from version 3.1.0 to 3.1.1 ..."); |
177 | 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 | 181 | log.info("Updating system data..."); |
179 | 182 | systemDataLoaderService.updateSystemWidgets(); |
180 | 183 | break; |
... | ... | @@ -206,6 +209,7 @@ public class ThingsboardInstallService { |
206 | 209 | componentDiscoveryService.discoverComponents(); |
207 | 210 | |
208 | 211 | systemDataLoaderService.createSysAdmin(); |
212 | + systemDataLoaderService.createDefaultTenantProfile(); | |
209 | 213 | systemDataLoaderService.createAdminSettings(); |
210 | 214 | systemDataLoaderService.loadSystemWidgets(); |
211 | 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 | 28 | import org.thingsboard.server.common.data.DataConstants; |
29 | 29 | import org.thingsboard.server.common.data.Device; |
30 | 30 | import org.thingsboard.server.common.data.Tenant; |
31 | +import org.thingsboard.server.common.data.TenantProfile; | |
31 | 32 | import org.thingsboard.server.common.data.User; |
32 | 33 | import org.thingsboard.server.common.data.asset.Asset; |
33 | 34 | import org.thingsboard.server.common.data.id.CustomerId; |
... | ... | @@ -49,6 +50,7 @@ import org.thingsboard.server.dao.device.DeviceCredentialsService; |
49 | 50 | import org.thingsboard.server.dao.device.DeviceService; |
50 | 51 | import org.thingsboard.server.dao.relation.RelationService; |
51 | 52 | import org.thingsboard.server.dao.settings.AdminSettingsService; |
53 | +import org.thingsboard.server.dao.tenant.TenantProfileService; | |
52 | 54 | import org.thingsboard.server.dao.tenant.TenantService; |
53 | 55 | import org.thingsboard.server.dao.user.UserService; |
54 | 56 | import org.thingsboard.server.dao.widget.WidgetsBundleService; |
... | ... | @@ -83,6 +85,9 @@ public class DefaultSystemDataLoaderService implements SystemDataLoaderService { |
83 | 85 | private TenantService tenantService; |
84 | 86 | |
85 | 87 | @Autowired |
88 | + private TenantProfileService tenantProfileService; | |
89 | + | |
90 | + @Autowired | |
86 | 91 | private CustomerService customerService; |
87 | 92 | |
88 | 93 | @Autowired |
... | ... | @@ -111,6 +116,11 @@ public class DefaultSystemDataLoaderService implements SystemDataLoaderService { |
111 | 116 | } |
112 | 117 | |
113 | 118 | @Override |
119 | + public void createDefaultTenantProfile() throws Exception { | |
120 | + tenantProfileService.findOrCreateDefaultTenantProfile(TenantId.SYS_TENANT_ID); | |
121 | + } | |
122 | + | |
123 | + @Override | |
114 | 124 | public void createAdminSettings() throws Exception { |
115 | 125 | AdminSettings generalSettings = new AdminSettings(); |
116 | 126 | generalSettings.setKey("general"); | ... | ... |
... | ... | @@ -303,6 +303,14 @@ public class SqlDatabaseUpgradeService implements DatabaseEntitiesUpgradeService |
303 | 303 | log.info("Schema updated."); |
304 | 304 | } |
305 | 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 | 314 | default: |
307 | 315 | throw new RuntimeException("Unable to upgrade SQL database, unsupported fromVersion: " + fromVersion); |
308 | 316 | } | ... | ... |
... | ... | @@ -19,6 +19,8 @@ public interface SystemDataLoaderService { |
19 | 19 | |
20 | 20 | void createSysAdmin() throws Exception; |
21 | 21 | |
22 | + void createDefaultTenantProfile() throws Exception; | |
23 | + | |
22 | 24 | void createAdminSettings() throws Exception; |
23 | 25 | |
24 | 26 | void loadSystemWidgets() throws Exception; | ... | ... |
... | ... | @@ -19,7 +19,9 @@ import lombok.extern.slf4j.Slf4j; |
19 | 19 | import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; |
20 | 20 | import org.springframework.stereotype.Service; |
21 | 21 | import org.thingsboard.server.common.data.Tenant; |
22 | +import org.thingsboard.server.common.data.TenantProfile; | |
22 | 23 | import org.thingsboard.server.common.data.id.TenantId; |
24 | +import org.thingsboard.server.dao.tenant.TenantProfileService; | |
23 | 25 | import org.thingsboard.server.dao.tenant.TenantService; |
24 | 26 | import org.thingsboard.server.queue.discovery.TenantRoutingInfo; |
25 | 27 | import org.thingsboard.server.queue.discovery.TenantRoutingInfoService; |
... | ... | @@ -31,15 +33,20 @@ public class DefaultTenantRoutingInfoService implements TenantRoutingInfoService |
31 | 33 | |
32 | 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 | 39 | this.tenantService = tenantService; |
40 | + this.tenantProfileService = tenantProfileService; | |
36 | 41 | } |
37 | 42 | |
38 | 43 | @Override |
39 | 44 | public TenantRoutingInfo getRoutingInfo(TenantId tenantId) { |
40 | 45 | Tenant tenant = tenantService.findTenantById(tenantId); |
41 | 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 | 50 | } else { |
44 | 51 | throw new RuntimeException("Tenant not found!"); |
45 | 52 | } | ... | ... |
... | ... | @@ -28,6 +28,7 @@ import org.springframework.util.StringUtils; |
28 | 28 | import org.thingsboard.server.common.data.DataConstants; |
29 | 29 | import org.thingsboard.server.common.data.Device; |
30 | 30 | import org.thingsboard.server.common.data.Tenant; |
31 | +import org.thingsboard.server.common.data.TenantProfile; | |
31 | 32 | import org.thingsboard.server.common.data.id.CustomerId; |
32 | 33 | import org.thingsboard.server.common.data.id.DeviceId; |
33 | 34 | import org.thingsboard.server.common.data.id.TenantId; |
... | ... | @@ -40,6 +41,7 @@ import org.thingsboard.server.common.msg.TbMsgMetaData; |
40 | 41 | import org.thingsboard.server.dao.device.DeviceCredentialsService; |
41 | 42 | import org.thingsboard.server.dao.device.DeviceService; |
42 | 43 | import org.thingsboard.server.dao.relation.RelationService; |
44 | +import org.thingsboard.server.dao.tenant.TenantProfileService; | |
43 | 45 | import org.thingsboard.server.dao.tenant.TenantService; |
44 | 46 | import org.thingsboard.server.gen.transport.TransportProtos.DeviceInfoProto; |
45 | 47 | import org.thingsboard.server.gen.transport.TransportProtos.GetOrCreateDeviceFromGatewayRequestMsg; |
... | ... | @@ -78,6 +80,9 @@ public class DefaultTransportApiService implements TransportApiService { |
78 | 80 | private TenantService tenantService; |
79 | 81 | |
80 | 82 | @Autowired |
83 | + private TenantProfileService tenantProfileService; | |
84 | + | |
85 | + @Autowired | |
81 | 86 | private DeviceService deviceService; |
82 | 87 | |
83 | 88 | @Autowired |
... | ... | @@ -168,10 +173,13 @@ public class DefaultTransportApiService implements TransportApiService { |
168 | 173 | |
169 | 174 | private ListenableFuture<TransportApiResponseMsg> handle(GetTenantRoutingInfoRequestMsg requestMsg) { |
170 | 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 | 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 | 18 | import lombok.EqualsAndHashCode; |
19 | 19 | import org.thingsboard.server.common.data.id.CustomerId; |
20 | 20 | import org.thingsboard.server.common.data.id.DeviceId; |
21 | +import org.thingsboard.server.common.data.id.DeviceProfileId; | |
21 | 22 | import org.thingsboard.server.common.data.id.TenantId; |
22 | 23 | |
23 | 24 | @EqualsAndHashCode(callSuper = true) |
... | ... | @@ -30,6 +31,7 @@ public class Device extends SearchTextBasedWithAdditionalInfo<DeviceId> implemen |
30 | 31 | private String name; |
31 | 32 | private String type; |
32 | 33 | private String label; |
34 | + private DeviceProfileId deviceProfileId; | |
33 | 35 | |
34 | 36 | public Device() { |
35 | 37 | super(); |
... | ... | @@ -46,6 +48,7 @@ public class Device extends SearchTextBasedWithAdditionalInfo<DeviceId> implemen |
46 | 48 | this.name = device.getName(); |
47 | 49 | this.type = device.getType(); |
48 | 50 | this.label = device.getLabel(); |
51 | + this.deviceProfileId = device.getDeviceProfileId(); | |
49 | 52 | } |
50 | 53 | |
51 | 54 | public TenantId getTenantId() { |
... | ... | @@ -89,6 +92,14 @@ public class Device extends SearchTextBasedWithAdditionalInfo<DeviceId> implemen |
89 | 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 | 103 | @Override |
93 | 104 | public String getSearchText() { |
94 | 105 | return getName(); |
... | ... | @@ -107,6 +118,8 @@ public class Device extends SearchTextBasedWithAdditionalInfo<DeviceId> implemen |
107 | 118 | builder.append(type); |
108 | 119 | builder.append(", label="); |
109 | 120 | builder.append(label); |
121 | + builder.append(", deviceProfileId="); | |
122 | + builder.append(deviceProfileId); | |
110 | 123 | builder.append(", additionalInfo="); |
111 | 124 | builder.append(getAdditionalInfo()); |
112 | 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 | 19 | * @author Andrew Shvayka |
20 | 20 | */ |
21 | 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 | 19 | import com.fasterxml.jackson.annotation.JsonProperty; |
20 | 20 | import lombok.EqualsAndHashCode; |
21 | 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 | 24 | @EqualsAndHashCode(callSuper = true) |
26 | 25 | public class Tenant extends ContactBased<TenantId> implements HasTenantId { |
... | ... | @@ -29,8 +28,7 @@ public class Tenant extends ContactBased<TenantId> implements HasTenantId { |
29 | 28 | |
30 | 29 | private String title; |
31 | 30 | private String region; |
32 | - private boolean isolatedTbCore; | |
33 | - private boolean isolatedTbRuleEngine; | |
31 | + private TenantProfileId tenantProfileId; | |
34 | 32 | |
35 | 33 | public Tenant() { |
36 | 34 | super(); |
... | ... | @@ -44,6 +42,7 @@ public class Tenant extends ContactBased<TenantId> implements HasTenantId { |
44 | 42 | super(tenant); |
45 | 43 | this.title = tenant.getTitle(); |
46 | 44 | this.region = tenant.getRegion(); |
45 | + this.tenantProfileId = tenant.getTenantProfileId(); | |
47 | 46 | } |
48 | 47 | |
49 | 48 | public String getTitle() { |
... | ... | @@ -74,20 +73,12 @@ public class Tenant extends ContactBased<TenantId> implements HasTenantId { |
74 | 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 | 84 | @Override |
... | ... | @@ -102,10 +93,8 @@ public class Tenant extends ContactBased<TenantId> implements HasTenantId { |
102 | 93 | builder.append(title); |
103 | 94 | builder.append(", region="); |
104 | 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 | 98 | builder.append(", additionalInfo="); |
110 | 99 | builder.append(getAdditionalInfo()); |
111 | 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 | 29 | |
30 | 30 | @JsonDeserialize(using = EntityIdDeserializer.class) |
31 | 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 | 34 | UUID NULL_UUID = UUID.fromString("13814000-1dd2-11b2-8080-808080808080"); |
35 | 35 | ... | ... |
... | ... | @@ -62,6 +62,10 @@ public class EntityIdFactory { |
62 | 62 | return new WidgetsBundleId(uuid); |
63 | 63 | case WIDGET_TYPE: |
64 | 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 | 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 | 20 | import java.io.Serializable; |
21 | 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 | 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 | 18 | import java.io.Serializable; |
19 | 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 | 23 | private static final long serialVersionUID = 1L; |
24 | 24 | ... | ... |
... | ... | @@ -43,6 +43,10 @@ public abstract class DaoUtil { |
43 | 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 | 50 | public static Pageable toPageable(PageLink pageLink) { |
47 | 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 | 34 | import org.thingsboard.server.common.data.Customer; |
35 | 35 | import org.thingsboard.server.common.data.Device; |
36 | 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 | 39 | import org.thingsboard.server.common.data.EntitySubtype; |
38 | 40 | import org.thingsboard.server.common.data.EntityType; |
39 | 41 | import org.thingsboard.server.common.data.EntityView; |
... | ... | @@ -41,6 +43,7 @@ import org.thingsboard.server.common.data.Tenant; |
41 | 43 | import org.thingsboard.server.common.data.device.DeviceSearchQuery; |
42 | 44 | import org.thingsboard.server.common.data.id.CustomerId; |
43 | 45 | import org.thingsboard.server.common.data.id.DeviceId; |
46 | +import org.thingsboard.server.common.data.id.DeviceProfileId; | |
44 | 47 | import org.thingsboard.server.common.data.id.EntityId; |
45 | 48 | import org.thingsboard.server.common.data.id.TenantId; |
46 | 49 | import org.thingsboard.server.common.data.page.PageData; |
... | ... | @@ -96,6 +99,9 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe |
96 | 99 | private DeviceCredentialsService deviceCredentialsService; |
97 | 100 | |
98 | 101 | @Autowired |
102 | + private DeviceProfileService deviceProfileService; | |
103 | + | |
104 | + @Autowired | |
99 | 105 | private EntityViewService entityViewService; |
100 | 106 | |
101 | 107 | @Autowired |
... | ... | @@ -159,6 +165,10 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe |
159 | 165 | deviceValidator.validate(device, Device::getTenantId); |
160 | 166 | Device savedDevice; |
161 | 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 | 172 | savedDevice = deviceDao.save(device.getTenantId(), device); |
163 | 173 | } catch (Exception t) { |
164 | 174 | ConstraintViolationException e = extractConstraintViolationException(t).orElse(null); | ... | ... |
... | ... | @@ -114,12 +114,22 @@ public class ModelConstants { |
114 | 114 | public static final String TENANT_TITLE_PROPERTY = TITLE_PROPERTY; |
115 | 115 | public static final String TENANT_REGION_PROPERTY = "region"; |
116 | 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 | 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 | 133 | * Cassandra customer constants. |
124 | 134 | */ |
125 | 135 | public static final String CUSTOMER_COLUMN_FAMILY_NAME = "customer"; |
... | ... | @@ -141,6 +151,7 @@ public class ModelConstants { |
141 | 151 | public static final String DEVICE_TYPE_PROPERTY = "type"; |
142 | 152 | public static final String DEVICE_LABEL_PROPERTY = "label"; |
143 | 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 | 155 | public static final String DEVICE_BY_TENANT_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME = "device_by_tenant_and_search_text"; |
145 | 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 | 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 | 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 | 174 | * Cassandra entityView constants. |
153 | 175 | */ |
154 | 176 | public static final String ENTITY_VIEW_TABLE_FAMILY_NAME = "entity_view"; | ... | ... |
... | ... | @@ -23,6 +23,7 @@ import org.hibernate.annotations.TypeDef; |
23 | 23 | import org.thingsboard.server.common.data.Device; |
24 | 24 | import org.thingsboard.server.common.data.id.CustomerId; |
25 | 25 | import org.thingsboard.server.common.data.id.DeviceId; |
26 | +import org.thingsboard.server.common.data.id.DeviceProfileId; | |
26 | 27 | import org.thingsboard.server.common.data.id.TenantId; |
27 | 28 | import org.thingsboard.server.dao.model.BaseSqlEntity; |
28 | 29 | import org.thingsboard.server.dao.model.ModelConstants; |
... | ... | @@ -61,6 +62,9 @@ public abstract class AbstractDeviceEntity<T extends Device> extends BaseSqlEnti |
61 | 62 | @Column(name = ModelConstants.DEVICE_ADDITIONAL_INFO_PROPERTY) |
62 | 63 | private JsonNode additionalInfo; |
63 | 64 | |
65 | + @Column(name = ModelConstants.DEVICE_DEVICE_PROFILE_ID_PROPERTY, columnDefinition = "uuid") | |
66 | + private UUID deviceProfileId; | |
67 | + | |
64 | 68 | public AbstractDeviceEntity() { |
65 | 69 | super(); |
66 | 70 | } |
... | ... | @@ -76,6 +80,9 @@ public abstract class AbstractDeviceEntity<T extends Device> extends BaseSqlEnti |
76 | 80 | if (device.getCustomerId() != null) { |
77 | 81 | this.customerId = device.getCustomerId().getId(); |
78 | 82 | } |
83 | + if (device.getDeviceProfileId() != null) { | |
84 | + this.deviceProfileId = device.getDeviceProfileId().getId(); | |
85 | + } | |
79 | 86 | this.name = device.getName(); |
80 | 87 | this.type = device.getType(); |
81 | 88 | this.label = device.getLabel(); |
... | ... | @@ -87,6 +94,7 @@ public abstract class AbstractDeviceEntity<T extends Device> extends BaseSqlEnti |
87 | 94 | this.setCreatedTime(deviceEntity.getCreatedTime()); |
88 | 95 | this.tenantId = deviceEntity.getTenantId(); |
89 | 96 | this.customerId = deviceEntity.getCustomerId(); |
97 | + this.deviceProfileId = deviceEntity.getDeviceProfileId(); | |
90 | 98 | this.type = deviceEntity.getType(); |
91 | 99 | this.name = deviceEntity.getName(); |
92 | 100 | this.label = deviceEntity.getLabel(); |
... | ... | @@ -113,6 +121,9 @@ public abstract class AbstractDeviceEntity<T extends Device> extends BaseSqlEnti |
113 | 121 | if (customerId != null) { |
114 | 122 | device.setCustomerId(new CustomerId(customerId)); |
115 | 123 | } |
124 | + if (deviceProfileId != null) { | |
125 | + device.setDeviceProfileId(new DeviceProfileId(deviceProfileId)); | |
126 | + } | |
116 | 127 | device.setName(name); |
117 | 128 | device.setType(type); |
118 | 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 | 21 | import org.hibernate.annotations.Type; |
22 | 22 | import org.hibernate.annotations.TypeDef; |
23 | 23 | import org.thingsboard.server.common.data.Tenant; |
24 | +import org.thingsboard.server.common.data.id.CustomerId; | |
24 | 25 | import org.thingsboard.server.common.data.id.TenantId; |
26 | +import org.thingsboard.server.common.data.id.TenantProfileId; | |
25 | 27 | import org.thingsboard.server.dao.model.BaseSqlEntity; |
26 | 28 | import org.thingsboard.server.dao.model.ModelConstants; |
27 | 29 | import org.thingsboard.server.dao.model.SearchTextEntity; |
... | ... | @@ -30,6 +32,7 @@ import org.thingsboard.server.dao.util.mapping.JsonStringType; |
30 | 32 | import javax.persistence.Column; |
31 | 33 | import javax.persistence.Entity; |
32 | 34 | import javax.persistence.Table; |
35 | +import java.util.UUID; | |
33 | 36 | |
34 | 37 | @Data |
35 | 38 | @EqualsAndHashCode(callSuper = true) |
... | ... | @@ -71,16 +74,13 @@ public final class TenantEntity extends BaseSqlEntity<Tenant> implements SearchT |
71 | 74 | @Column(name = ModelConstants.EMAIL_PROPERTY) |
72 | 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 | 77 | @Type(type = "json") |
81 | 78 | @Column(name = ModelConstants.TENANT_ADDITIONAL_INFO_PROPERTY) |
82 | 79 | private JsonNode additionalInfo; |
83 | 80 | |
81 | + @Column(name = ModelConstants.TENANT_TENANT_PROFILE_ID_PROPERTY, columnDefinition = "uuid") | |
82 | + private UUID tenantProfileId; | |
83 | + | |
84 | 84 | public TenantEntity() { |
85 | 85 | super(); |
86 | 86 | } |
... | ... | @@ -101,8 +101,9 @@ public final class TenantEntity extends BaseSqlEntity<Tenant> implements SearchT |
101 | 101 | this.phone = tenant.getPhone(); |
102 | 102 | this.email = tenant.getEmail(); |
103 | 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 | 109 | @Override |
... | ... | @@ -134,8 +135,9 @@ public final class TenantEntity extends BaseSqlEntity<Tenant> implements SearchT |
134 | 135 | tenant.setPhone(phone); |
135 | 136 | tenant.setEmail(email); |
136 | 137 | tenant.setAdditionalInfo(additionalInfo); |
137 | - tenant.setIsolatedTbCore(isolatedTbCore); | |
138 | - tenant.setIsolatedTbRuleEngine(isolatedTbRuleEngine); | |
138 | + if (tenantProfileId != null) { | |
139 | + tenant.setTenantProfileId(new TenantProfileId(tenantProfileId)); | |
140 | + } | |
139 | 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 | 20 | import org.apache.commons.lang3.StringUtils; |
21 | 21 | import org.springframework.beans.factory.annotation.Autowired; |
22 | 22 | import org.springframework.stereotype.Service; |
23 | +import org.thingsboard.server.common.data.EntityInfo; | |
23 | 24 | import org.thingsboard.server.common.data.Tenant; |
25 | +import org.thingsboard.server.common.data.TenantProfile; | |
24 | 26 | import org.thingsboard.server.common.data.id.EntityId; |
25 | 27 | import org.thingsboard.server.common.data.id.TenantId; |
28 | +import org.thingsboard.server.common.data.id.TenantProfileId; | |
26 | 29 | import org.thingsboard.server.common.data.page.PageData; |
27 | 30 | import org.thingsboard.server.common.data.page.PageLink; |
28 | 31 | import org.thingsboard.server.dao.asset.AssetService; |
29 | 32 | import org.thingsboard.server.dao.customer.CustomerService; |
30 | 33 | import org.thingsboard.server.dao.dashboard.DashboardService; |
34 | +import org.thingsboard.server.dao.device.DeviceProfileService; | |
31 | 35 | import org.thingsboard.server.dao.device.DeviceService; |
32 | 36 | import org.thingsboard.server.dao.entity.AbstractEntityService; |
33 | 37 | import org.thingsboard.server.dao.entityview.EntityViewService; |
... | ... | @@ -52,6 +56,9 @@ public class TenantServiceImpl extends AbstractEntityService implements TenantSe |
52 | 56 | private TenantDao tenantDao; |
53 | 57 | |
54 | 58 | @Autowired |
59 | + private TenantProfileService tenantProfileService; | |
60 | + | |
61 | + @Autowired | |
55 | 62 | private UserService userService; |
56 | 63 | |
57 | 64 | @Autowired |
... | ... | @@ -64,6 +71,9 @@ public class TenantServiceImpl extends AbstractEntityService implements TenantSe |
64 | 71 | private DeviceService deviceService; |
65 | 72 | |
66 | 73 | @Autowired |
74 | + private DeviceProfileService deviceProfileService; | |
75 | + | |
76 | + @Autowired | |
67 | 77 | private EntityViewService entityViewService; |
68 | 78 | |
69 | 79 | @Autowired |
... | ... | @@ -93,8 +103,16 @@ public class TenantServiceImpl extends AbstractEntityService implements TenantSe |
93 | 103 | public Tenant saveTenant(Tenant tenant) { |
94 | 104 | log.trace("Executing saveTenant [{}]", tenant); |
95 | 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 | 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 | 118 | @Override |
... | ... | @@ -107,6 +125,7 @@ public class TenantServiceImpl extends AbstractEntityService implements TenantSe |
107 | 125 | entityViewService.deleteEntityViewsByTenantId(tenantId); |
108 | 126 | assetService.deleteAssetsByTenantId(tenantId); |
109 | 127 | deviceService.deleteDevicesByTenantId(tenantId); |
128 | + deviceProfileService.deleteDeviceProfilesByTenantId(tenantId); | |
110 | 129 | userService.deleteTenantAdmins(tenantId); |
111 | 130 | ruleChainService.deleteRuleChainsByTenantId(tenantId); |
112 | 131 | tenantDao.removeById(tenantId, tenantId.getId()); |
... | ... | @@ -143,11 +162,13 @@ public class TenantServiceImpl extends AbstractEntityService implements TenantSe |
143 | 162 | Tenant old = tenantDao.findById(TenantId.SYS_TENANT_ID, tenantId.getId()); |
144 | 163 | if (old == null) { |
145 | 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 | 168 | throw new DataValidationException("Can't update isolatedTbRuleEngine property!"); |
148 | 169 | } else if (old.isIsolatedTbCore() != tenant.isIsolatedTbCore()) { |
149 | 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 | 127 | created_time bigint NOT NULL, |
128 | 128 | additional_info varchar, |
129 | 129 | customer_id uuid, |
130 | + device_profile_id uuid NOT NULL, | |
130 | 131 | type varchar(255), |
131 | 132 | name varchar(255), |
132 | 133 | label varchar(255), |
... | ... | @@ -135,6 +136,19 @@ CREATE TABLE IF NOT EXISTS device ( |
135 | 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 | 152 | CREATE TABLE IF NOT EXISTS device_credentials ( |
139 | 153 | id uuid NOT NULL CONSTRAINT device_credentials_pkey PRIMARY KEY, |
140 | 154 | created_time bigint NOT NULL, |
... | ... | @@ -187,6 +201,7 @@ CREATE TABLE IF NOT EXISTS tenant ( |
187 | 201 | id uuid NOT NULL CONSTRAINT tenant_pkey PRIMARY KEY, |
188 | 202 | created_time bigint NOT NULL, |
189 | 203 | additional_info varchar, |
204 | + tenant_profile_id uuid NOT NULL, | |
190 | 205 | address varchar, |
191 | 206 | address2 varchar, |
192 | 207 | city varchar(255), |
... | ... | @@ -202,6 +217,19 @@ CREATE TABLE IF NOT EXISTS tenant ( |
202 | 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 | 233 | CREATE TABLE IF NOT EXISTS user_credentials ( |
206 | 234 | id uuid NOT NULL CONSTRAINT user_credentials_pkey PRIMARY KEY, |
207 | 235 | created_time bigint NOT NULL, | ... | ... |
... | ... | @@ -144,6 +144,7 @@ CREATE TABLE IF NOT EXISTS device ( |
144 | 144 | created_time bigint NOT NULL, |
145 | 145 | additional_info varchar, |
146 | 146 | customer_id uuid, |
147 | + device_profile_id uuid NOT NULL, | |
147 | 148 | type varchar(255), |
148 | 149 | name varchar(255), |
149 | 150 | label varchar(255), |
... | ... | @@ -152,6 +153,19 @@ CREATE TABLE IF NOT EXISTS device ( |
152 | 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 | 169 | CREATE TABLE IF NOT EXISTS device_credentials ( |
156 | 170 | id uuid NOT NULL CONSTRAINT device_credentials_pkey PRIMARY KEY, |
157 | 171 | created_time bigint NOT NULL, |
... | ... | @@ -211,6 +225,7 @@ CREATE TABLE IF NOT EXISTS tenant ( |
211 | 225 | id uuid NOT NULL CONSTRAINT tenant_pkey PRIMARY KEY, |
212 | 226 | created_time bigint NOT NULL, |
213 | 227 | additional_info varchar, |
228 | + tenant_profile_id uuid NOT NULL, | |
214 | 229 | address varchar, |
215 | 230 | address2 varchar, |
216 | 231 | city varchar(255), |
... | ... | @@ -226,6 +241,19 @@ CREATE TABLE IF NOT EXISTS tenant ( |
226 | 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 | 257 | CREATE TABLE IF NOT EXISTS user_credentials ( |
230 | 258 | id uuid NOT NULL CONSTRAINT user_credentials_pkey PRIMARY KEY, |
231 | 259 | created_time bigint NOT NULL, | ... | ... |
... | ... | @@ -31,6 +31,7 @@ import org.thingsboard.server.common.data.BaseData; |
31 | 31 | import org.thingsboard.server.common.data.EntityType; |
32 | 32 | import org.thingsboard.server.common.data.Event; |
33 | 33 | import org.thingsboard.server.common.data.id.EntityId; |
34 | +import org.thingsboard.server.common.data.id.HasId; | |
34 | 35 | import org.thingsboard.server.common.data.id.TenantId; |
35 | 36 | import org.thingsboard.server.common.data.id.UUIDBased; |
36 | 37 | import org.thingsboard.server.dao.alarm.AlarmService; |
... | ... | @@ -41,6 +42,7 @@ import org.thingsboard.server.dao.component.ComponentDescriptorService; |
41 | 42 | import org.thingsboard.server.dao.customer.CustomerService; |
42 | 43 | import org.thingsboard.server.dao.dashboard.DashboardService; |
43 | 44 | import org.thingsboard.server.dao.device.DeviceCredentialsService; |
45 | +import org.thingsboard.server.dao.device.DeviceProfileService; | |
44 | 46 | import org.thingsboard.server.dao.device.DeviceService; |
45 | 47 | import org.thingsboard.server.dao.entity.EntityService; |
46 | 48 | import org.thingsboard.server.dao.entityview.EntityViewService; |
... | ... | @@ -48,6 +50,7 @@ import org.thingsboard.server.dao.event.EventService; |
48 | 50 | import org.thingsboard.server.dao.relation.RelationService; |
49 | 51 | import org.thingsboard.server.dao.rule.RuleChainService; |
50 | 52 | import org.thingsboard.server.dao.settings.AdminSettingsService; |
53 | +import org.thingsboard.server.dao.tenant.TenantProfileService; | |
51 | 54 | import org.thingsboard.server.dao.tenant.TenantService; |
52 | 55 | import org.thingsboard.server.dao.timeseries.TimeseriesService; |
53 | 56 | import org.thingsboard.server.dao.user.UserService; |
... | ... | @@ -125,7 +128,13 @@ public abstract class AbstractServiceTest { |
125 | 128 | @Autowired |
126 | 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 | 138 | @Override |
130 | 139 | public int compare(D o1, D o2) { |
131 | 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 | 20 | DROP TABLE IF EXISTS rule_node; |
21 | 21 | DROP TABLE IF EXISTS rule_chain; |
22 | 22 | DROP TABLE IF EXISTS entity_view; |
23 | +DROP TABLE IF EXISTS device_profile; | |
24 | +DROP TABLE IF EXISTS tenant_profile; | |
23 | 25 | DROP FUNCTION IF EXISTS to_uuid; | ... | ... |
... | ... | @@ -21,4 +21,6 @@ DROP TABLE IF EXISTS widgets_bundle; |
21 | 21 | DROP TABLE IF EXISTS rule_node; |
22 | 22 | DROP TABLE IF EXISTS rule_chain; |
23 | 23 | DROP TABLE IF EXISTS entity_view; |
24 | -DROP TABLE IF EXISTS tb_schema_settings; | |
\ No newline at end of file | ||
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 | 21 | DROP TABLE IF EXISTS rule_node; |
22 | 22 | DROP TABLE IF EXISTS rule_chain; |
23 | 23 | DROP TABLE IF EXISTS entity_view; |
24 | -DROP TABLE IF EXISTS tb_schema_settings; | |
\ No newline at end of file | ||
24 | +DROP TABLE IF EXISTS device_profile; | |
25 | +DROP TABLE IF EXISTS tenant_profile; | |
26 | +DROP TABLE IF EXISTS tb_schema_settings; | ... | ... |