Commit 266af3c1a23d7d7d0c9f287dc10d6587baa1d3d4

Authored by Igor Kulikov
1 parent ad879244

Introduce DeviceProfileInfo, release 3.2 upgrade script.

Showing 36 changed files with 799 additions and 200 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 +DROP PROCEDURE IF EXISTS update_tenant_profiles;
  18 +DROP PROCEDURE IF EXISTS update_device_profiles;
  19 +
  20 +ALTER TABLE tenant ALTER COLUMN tenant_profile_id SET NOT NULL;
  21 +ALTER TABLE tenant DROP CONSTRAINT IF EXISTS fk_tenant_profile;
  22 +ALTER TABLE tenant ADD CONSTRAINT fk_tenant_profile FOREIGN KEY (tenant_profile_id) REFERENCES tenant_profile(id);
  23 +ALTER TABLE tenant DROP COLUMN IF EXISTS isolated_tb_core;
  24 +ALTER TABLE tenant DROP COLUMN IF EXISTS isolated_tb_rule_engine;
  25 +
  26 +ALTER TABLE device ALTER COLUMN device_profile_id SET NOT NULL;
  27 +ALTER TABLE device DROP CONSTRAINT IF EXISTS fk_device_profile;
  28 +ALTER TABLE device ADD CONSTRAINT fk_device_profile FOREIGN KEY (device_profile_id) REFERENCES device_profile(id);
... ...
application/src/main/data/upgrade/3.1.1/schema_update_before.sql renamed from application/src/main/data/upgrade/3.1.1/schema_update.sql
... ... @@ -14,19 +14,18 @@
14 14 -- limitations under the License.
15 15 --
16 16
17   -ALTER TABLE device ADD COLUMN device_profile_id uuid;
18   -ALTER TABLE tenant ADD COLUMN tenant_profile_id uuid;
19   -
20 17 CREATE TABLE IF NOT EXISTS device_profile (
21 18 id uuid NOT NULL CONSTRAINT device_profile_pkey PRIMARY KEY,
22 19 created_time bigint NOT NULL,
23 20 name varchar(255),
  21 + type varchar(255),
24 22 profile_data varchar,
25 23 description varchar,
26 24 search_text varchar(255),
27   - default boolean,
  25 + is_default boolean,
28 26 tenant_id uuid,
29   - default_rule_chain_id uuid
  27 + default_rule_chain_id uuid,
  28 + CONSTRAINT device_profile_name_unq_key UNIQUE (tenant_id, name)
30 29 );
31 30
32 31 CREATE TABLE IF NOT EXISTS tenant_profile (
... ... @@ -36,7 +35,45 @@ CREATE TABLE IF NOT EXISTS tenant_profile (
36 35 profile_data varchar,
37 36 description varchar,
38 37 search_text varchar(255),
39   - default boolean,
  38 + is_default boolean,
40 39 isolated_tb_core boolean,
41   - isolated_tb_rule_engine boolean
  40 + isolated_tb_rule_engine boolean,
  41 + CONSTRAINT tenant_profile_name_unq_key UNIQUE (name)
42 42 );
  43 +
  44 +CREATE OR REPLACE PROCEDURE update_tenant_profiles()
  45 + LANGUAGE plpgsql AS
  46 +$$
  47 +BEGIN
  48 + UPDATE tenant as t SET tenant_profile_id = p.id
  49 + FROM
  50 + (SELECT id from tenant_profile WHERE isolated_tb_core = false AND isolated_tb_rule_engine = false) as p
  51 + WHERE t.tenant_profile_id IS NULL AND t.isolated_tb_core = false AND t.isolated_tb_rule_engine = false;
  52 +
  53 + UPDATE tenant as t SET tenant_profile_id = p.id
  54 + FROM
  55 + (SELECT id from tenant_profile WHERE isolated_tb_core = true AND isolated_tb_rule_engine = false) as p
  56 + WHERE t.tenant_profile_id IS NULL AND t.isolated_tb_core = true AND t.isolated_tb_rule_engine = false;
  57 +
  58 + UPDATE tenant as t SET tenant_profile_id = p.id
  59 + FROM
  60 + (SELECT id from tenant_profile WHERE isolated_tb_core = false AND isolated_tb_rule_engine = true) as p
  61 + WHERE t.tenant_profile_id IS NULL AND t.isolated_tb_core = false AND t.isolated_tb_rule_engine = true;
  62 +
  63 + UPDATE tenant as t SET tenant_profile_id = p.id
  64 + FROM
  65 + (SELECT id from tenant_profile WHERE isolated_tb_core = true AND isolated_tb_rule_engine = true) as p
  66 + WHERE t.tenant_profile_id IS NULL AND t.isolated_tb_core = true AND t.isolated_tb_rule_engine = true;
  67 +END;
  68 +$$;
  69 +
  70 +CREATE OR REPLACE PROCEDURE update_device_profiles()
  71 + LANGUAGE plpgsql AS
  72 +$$
  73 +BEGIN
  74 + UPDATE device as d SET device_profile_id = p.id, device_data = '{"configuration":{"type":"DEFAULT"}}'
  75 + FROM
  76 + (SELECT id, tenant_id from device_profile WHERE is_default = true) as p
  77 + WHERE d.device_profile_id IS NULL AND p.tenant_id = d.tenant_id;
  78 +END;
  79 +$$;
... ...
... ... @@ -40,6 +40,7 @@ import org.thingsboard.server.common.data.EntityViewInfo;
40 40 import org.thingsboard.server.common.data.HasName;
41 41 import org.thingsboard.server.common.data.HasTenantId;
42 42 import org.thingsboard.server.common.data.Tenant;
  43 +import org.thingsboard.server.common.data.TenantInfo;
43 44 import org.thingsboard.server.common.data.TenantProfile;
44 45 import org.thingsboard.server.common.data.User;
45 46 import org.thingsboard.server.common.data.alarm.Alarm;
... ... @@ -324,6 +325,18 @@ public abstract class BaseController {
324 325 }
325 326 }
326 327
  328 + TenantInfo checkTenantInfoId(TenantId tenantId, Operation operation) throws ThingsboardException {
  329 + try {
  330 + validateId(tenantId, INCORRECT_TENANT_ID + tenantId);
  331 + TenantInfo tenant = tenantService.findTenantInfoById(tenantId);
  332 + checkNotNull(tenant);
  333 + accessControlService.checkPermission(getCurrentUser(), Resource.TENANT, operation, tenantId, tenant);
  334 + return tenant;
  335 + } catch (Exception e) {
  336 + throw handleException(e, false);
  337 + }
  338 + }
  339 +
327 340 TenantProfile checkTenantProfileId(TenantProfileId tenantProfileId, Operation operation) throws ThingsboardException {
328 341 try {
329 342 validateId(tenantProfileId, "Incorrect tenantProfileId " + tenantProfileId);
... ...
... ... @@ -27,7 +27,7 @@ import org.springframework.web.bind.annotation.ResponseBody;
27 27 import org.springframework.web.bind.annotation.ResponseStatus;
28 28 import org.springframework.web.bind.annotation.RestController;
29 29 import org.thingsboard.server.common.data.DeviceProfile;
30   -import org.thingsboard.server.common.data.EntityInfo;
  30 +import org.thingsboard.server.common.data.DeviceProfileInfo;
31 31 import org.thingsboard.server.common.data.EntityType;
32 32 import org.thingsboard.server.common.data.audit.ActionType;
33 33 import org.thingsboard.server.common.data.exception.ThingsboardException;
... ... @@ -60,7 +60,7 @@ public class DeviceProfileController extends BaseController {
60 60 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
61 61 @RequestMapping(value = "/deviceProfileInfo/{deviceProfileId}", method = RequestMethod.GET)
62 62 @ResponseBody
63   - public EntityInfo getDeviceProfileInfoById(@PathVariable("deviceProfileId") String strDeviceProfileId) throws ThingsboardException {
  63 + public DeviceProfileInfo getDeviceProfileInfoById(@PathVariable("deviceProfileId") String strDeviceProfileId) throws ThingsboardException {
64 64 checkParameter("deviceProfileId", strDeviceProfileId);
65 65 try {
66 66 DeviceProfileId deviceProfileId = new DeviceProfileId(toUUID(strDeviceProfileId));
... ... @@ -73,7 +73,7 @@ public class DeviceProfileController extends BaseController {
73 73 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
74 74 @RequestMapping(value = "/deviceProfileInfo/default", method = RequestMethod.GET)
75 75 @ResponseBody
76   - public EntityInfo getDefaultDeviceProfileInfo() throws ThingsboardException {
  76 + public DeviceProfileInfo getDefaultDeviceProfileInfo() throws ThingsboardException {
77 77 try {
78 78 return checkNotNull(deviceProfileService.findDefaultDeviceProfileInfo(getTenantId()));
79 79 } catch (Exception e) {
... ... @@ -177,7 +177,7 @@ public class DeviceProfileController extends BaseController {
177 177 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
178 178 @RequestMapping(value = "/deviceProfileInfos", params = {"pageSize", "page"}, method = RequestMethod.GET)
179 179 @ResponseBody
180   - public PageData<EntityInfo> getDeviceProfileInfos(@RequestParam int pageSize,
  180 + public PageData<DeviceProfileInfo> getDeviceProfileInfos(@RequestParam int pageSize,
181 181 @RequestParam int page,
182 182 @RequestParam(required = false) String textSearch,
183 183 @RequestParam(required = false) String sortProperty,
... ...
... ... @@ -28,6 +28,7 @@ import org.springframework.web.bind.annotation.ResponseBody;
28 28 import org.springframework.web.bind.annotation.ResponseStatus;
29 29 import org.springframework.web.bind.annotation.RestController;
30 30 import org.thingsboard.server.common.data.Tenant;
  31 +import org.thingsboard.server.common.data.TenantInfo;
31 32 import org.thingsboard.server.common.data.exception.ThingsboardException;
32 33 import org.thingsboard.server.common.data.id.TenantId;
33 34 import org.thingsboard.server.common.data.page.PageData;
... ... @@ -64,6 +65,19 @@ public class TenantController extends BaseController {
64 65 }
65 66 }
66 67
  68 + @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')")
  69 + @RequestMapping(value = "/tenant/info/{tenantId}", method = RequestMethod.GET)
  70 + @ResponseBody
  71 + public TenantInfo getTenantInfoById(@PathVariable("tenantId") String strTenantId) throws ThingsboardException {
  72 + checkParameter("tenantId", strTenantId);
  73 + try {
  74 + TenantId tenantId = new TenantId(toUUID(strTenantId));
  75 + return checkTenantInfoId(tenantId, Operation.READ);
  76 + } catch (Exception e) {
  77 + throw handleException(e);
  78 + }
  79 + }
  80 +
67 81 @PreAuthorize("hasAuthority('SYS_ADMIN')")
68 82 @RequestMapping(value = "/tenant", method = RequestMethod.POST)
69 83 @ResponseBody
... ... @@ -114,4 +128,20 @@ public class TenantController extends BaseController {
114 128 }
115 129 }
116 130
  131 + @PreAuthorize("hasAuthority('SYS_ADMIN')")
  132 + @RequestMapping(value = "/tenantInfos", params = {"pageSize", "page"}, method = RequestMethod.GET)
  133 + @ResponseBody
  134 + public PageData<TenantInfo> getTenantInfos(@RequestParam int pageSize,
  135 + @RequestParam int page,
  136 + @RequestParam(required = false) String textSearch,
  137 + @RequestParam(required = false) String sortProperty,
  138 + @RequestParam(required = false) String sortOrder) throws ThingsboardException {
  139 + try {
  140 + PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder);
  141 + return checkNotNull(tenantService.findTenantInfos(pageLink));
  142 + } catch (Exception e) {
  143 + throw handleException(e);
  144 + }
  145 + }
  146 +
117 147 }
... ...
... ... @@ -209,7 +209,7 @@ public class ThingsboardInstallService {
209 209 componentDiscoveryService.discoverComponents();
210 210
211 211 systemDataLoaderService.createSysAdmin();
212   - systemDataLoaderService.createDefaultTenantProfile();
  212 + systemDataLoaderService.createDefaultTenantProfiles();
213 213 systemDataLoaderService.createAdminSettings();
214 214 systemDataLoaderService.loadSystemWidgets();
215 215 // systemDataLoaderService.loadSystemPlugins();
... ...
... ... @@ -29,6 +29,7 @@ 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 31 import org.thingsboard.server.common.data.TenantProfile;
  32 +import org.thingsboard.server.common.data.TenantProfileData;
32 33 import org.thingsboard.server.common.data.User;
33 34 import org.thingsboard.server.common.data.asset.Asset;
34 35 import org.thingsboard.server.common.data.id.CustomerId;
... ... @@ -48,6 +49,7 @@ import org.thingsboard.server.dao.attributes.AttributesService;
48 49 import org.thingsboard.server.dao.customer.CustomerService;
49 50 import org.thingsboard.server.dao.device.DeviceCredentialsService;
50 51 import org.thingsboard.server.dao.device.DeviceService;
  52 +import org.thingsboard.server.dao.exception.DataValidationException;
51 53 import org.thingsboard.server.dao.relation.RelationService;
52 54 import org.thingsboard.server.dao.settings.AdminSettingsService;
53 55 import org.thingsboard.server.dao.tenant.TenantProfileService;
... ... @@ -116,8 +118,47 @@ public class DefaultSystemDataLoaderService implements SystemDataLoaderService {
116 118 }
117 119
118 120 @Override
119   - public void createDefaultTenantProfile() throws Exception {
  121 + public void createDefaultTenantProfiles() throws Exception {
120 122 tenantProfileService.findOrCreateDefaultTenantProfile(TenantId.SYS_TENANT_ID);
  123 +
  124 + TenantProfile isolatedTbCoreProfile = new TenantProfile();
  125 + isolatedTbCoreProfile.setDefault(false);
  126 + isolatedTbCoreProfile.setName("Isolated TB Core");
  127 + isolatedTbCoreProfile.setProfileData(new TenantProfileData());
  128 + isolatedTbCoreProfile.setDescription("Isolated TB Core tenant profile");
  129 + isolatedTbCoreProfile.setIsolatedTbCore(true);
  130 + isolatedTbCoreProfile.setIsolatedTbRuleEngine(false);
  131 + try {
  132 + tenantProfileService.saveTenantProfile(TenantId.SYS_TENANT_ID, isolatedTbCoreProfile);
  133 + } catch (DataValidationException e) {
  134 + log.warn(e.getMessage());
  135 + }
  136 +
  137 + TenantProfile isolatedTbRuleEngineProfile = new TenantProfile();
  138 + isolatedTbRuleEngineProfile.setDefault(false);
  139 + isolatedTbRuleEngineProfile.setName("Isolated TB Rule Engine");
  140 + isolatedTbRuleEngineProfile.setProfileData(new TenantProfileData());
  141 + isolatedTbRuleEngineProfile.setDescription("Isolated TB Rule Engine tenant profile");
  142 + isolatedTbRuleEngineProfile.setIsolatedTbCore(false);
  143 + isolatedTbRuleEngineProfile.setIsolatedTbRuleEngine(true);
  144 + try {
  145 + tenantProfileService.saveTenantProfile(TenantId.SYS_TENANT_ID, isolatedTbRuleEngineProfile);
  146 + } catch (DataValidationException e) {
  147 + log.warn(e.getMessage());
  148 + }
  149 +
  150 + TenantProfile isolatedTbCoreAndTbRuleEngineProfile = new TenantProfile();
  151 + isolatedTbCoreAndTbRuleEngineProfile.setDefault(false);
  152 + isolatedTbCoreAndTbRuleEngineProfile.setName("Isolated TB Core and TB Rule Engine");
  153 + isolatedTbCoreAndTbRuleEngineProfile.setProfileData(new TenantProfileData());
  154 + isolatedTbCoreAndTbRuleEngineProfile.setDescription("Isolated TB Core and TB Rule Engine tenant profile");
  155 + isolatedTbCoreAndTbRuleEngineProfile.setIsolatedTbCore(true);
  156 + isolatedTbCoreAndTbRuleEngineProfile.setIsolatedTbRuleEngine(true);
  157 + try {
  158 + tenantProfileService.saveTenantProfile(TenantId.SYS_TENANT_ID, isolatedTbCoreAndTbRuleEngineProfile);
  159 + } catch (DataValidationException e) {
  160 + log.warn(e.getMessage());
  161 + }
121 162 }
122 163
123 164 @Override
... ...
... ... @@ -20,7 +20,12 @@ import org.springframework.beans.factory.annotation.Autowired;
20 20 import org.springframework.beans.factory.annotation.Value;
21 21 import org.springframework.context.annotation.Profile;
22 22 import org.springframework.stereotype.Service;
  23 +import org.thingsboard.server.common.data.Tenant;
  24 +import org.thingsboard.server.common.data.page.PageData;
  25 +import org.thingsboard.server.common.data.page.PageLink;
23 26 import org.thingsboard.server.dao.dashboard.DashboardService;
  27 +import org.thingsboard.server.dao.device.DeviceProfileService;
  28 +import org.thingsboard.server.dao.tenant.TenantService;
24 29 import org.thingsboard.server.service.install.sql.SqlDbHelper;
25 30
26 31 import java.nio.charset.Charset;
... ... @@ -76,6 +81,16 @@ public class SqlDatabaseUpgradeService implements DatabaseEntitiesUpgradeService
76 81 @Autowired
77 82 private InstallScripts installScripts;
78 83
  84 + @Autowired
  85 + private SystemDataLoaderService systemDataLoaderService;
  86 +
  87 + @Autowired
  88 + private TenantService tenantService;
  89 +
  90 + @Autowired
  91 + private DeviceProfileService deviceProfileService;
  92 +
  93 +
79 94 @Override
80 95 public void upgradeDatabase(String fromVersion) throws Exception {
81 96 switch (fromVersion) {
... ... @@ -306,9 +321,49 @@ public class SqlDatabaseUpgradeService implements DatabaseEntitiesUpgradeService
306 321 case "3.1.1":
307 322 try (Connection conn = DriverManager.getConnection(dbUrl, dbUserName, dbPassword)) {
308 323 log.info("Updating schema ...");
309   - schemaUpdateFile = Paths.get(installScripts.getDataDir(), "upgrade", "3.1.1", SCHEMA_UPDATE_SQL);
310   - loadSql(schemaUpdateFile, conn);
  324 + if (isOldSchema(conn, 3001000)) {
  325 +
  326 + try {
  327 + conn.createStatement().execute("ALTER TABLE device ADD COLUMN device_profile_id uuid, ADD COLUMN device_data varchar");
  328 + } catch (Exception e) {
  329 + }
  330 +
  331 + try {
  332 + conn.createStatement().execute("ALTER TABLE tenant ADD COLUMN tenant_profile_id uuid");
  333 + } catch (Exception e) {
  334 + }
  335 +
  336 + schemaUpdateFile = Paths.get(installScripts.getDataDir(), "upgrade", "3.1.1", "schema_update_before.sql");
  337 + loadSql(schemaUpdateFile, conn);
  338 +
  339 + log.info("Creating default tenant profiles...");
  340 + systemDataLoaderService.createDefaultTenantProfiles();
  341 +
  342 + log.info("Updating tenant profiles...");
  343 + conn.createStatement().execute("call update_tenant_profiles()");
  344 +
  345 + log.info("Creating default device profiles...");
  346 + PageLink pageLink = new PageLink(100);
  347 + PageData<Tenant> pageData;
  348 + do {
  349 + pageData = tenantService.findTenants(pageLink);
  350 + for (Tenant tenant : pageData.getData()) {
  351 + deviceProfileService.findOrCreateDefaultDeviceProfile(tenant.getId());
  352 + }
  353 + pageLink = pageLink.nextPageLink();
  354 + } while (pageData.hasNext());
  355 +
  356 + log.info("Updating device profiles...");
  357 + conn.createStatement().execute("call update_device_profiles()");
  358 +
  359 + schemaUpdateFile = Paths.get(installScripts.getDataDir(), "upgrade", "3.1.1", "schema_update_after.sql");
  360 + loadSql(schemaUpdateFile, conn);
  361 +
  362 + conn.createStatement().execute("UPDATE tb_schema_settings SET schema_version = 3002000;");
  363 + }
311 364 log.info("Schema updated.");
  365 + } catch (Exception e) {
  366 + log.error("Failed updating schema!!!", e);
312 367 }
313 368 break;
314 369 default:
... ...
... ... @@ -19,7 +19,7 @@ public interface SystemDataLoaderService {
19 19
20 20 void createSysAdmin() throws Exception;
21 21
22   - void createDefaultTenantProfile() throws Exception;
  22 + void createDefaultTenantProfiles() throws Exception;
23 23
24 24 void createAdminSettings() throws Exception;
25 25
... ...
... ... @@ -22,8 +22,8 @@ import org.junit.Before;
22 22 import org.junit.Test;
23 23 import org.thingsboard.server.common.data.Device;
24 24 import org.thingsboard.server.common.data.DeviceProfile;
  25 +import org.thingsboard.server.common.data.DeviceProfileInfo;
25 26 import org.thingsboard.server.common.data.DeviceProfileType;
26   -import org.thingsboard.server.common.data.EntityInfo;
27 27 import org.thingsboard.server.common.data.Tenant;
28 28 import org.thingsboard.server.common.data.User;
29 29 import org.thingsboard.server.common.data.page.PageData;
... ... @@ -41,7 +41,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
41 41 public abstract class BaseDeviceProfileControllerTest extends AbstractControllerTest {
42 42
43 43 private IdComparator<DeviceProfile> idComparator = new IdComparator<>();
44   - private IdComparator<EntityInfo> deviceProfileInfoIdComparator = new IdComparator<>();
  44 + private IdComparator<DeviceProfileInfo> deviceProfileInfoIdComparator = new IdComparator<>();
45 45
46 46 private Tenant savedTenant;
47 47 private User tenantAdmin;
... ... @@ -104,18 +104,21 @@ public abstract class BaseDeviceProfileControllerTest extends AbstractController
104 104 public void testFindDeviceProfileInfoById() throws Exception {
105 105 DeviceProfile deviceProfile = this.createDeviceProfile("Device Profile");
106 106 DeviceProfile savedDeviceProfile = doPost("/api/deviceProfile", deviceProfile, DeviceProfile.class);
107   - EntityInfo foundDeviceProfileInfo = doGet("/api/deviceProfileInfo/"+savedDeviceProfile.getId().getId().toString(), EntityInfo.class);
  107 + DeviceProfileInfo foundDeviceProfileInfo = doGet("/api/deviceProfileInfo/"+savedDeviceProfile.getId().getId().toString(), DeviceProfileInfo.class);
108 108 Assert.assertNotNull(foundDeviceProfileInfo);
109 109 Assert.assertEquals(savedDeviceProfile.getId(), foundDeviceProfileInfo.getId());
110 110 Assert.assertEquals(savedDeviceProfile.getName(), foundDeviceProfileInfo.getName());
  111 + Assert.assertEquals(savedDeviceProfile.getType(), foundDeviceProfileInfo.getType());
111 112 }
112 113
113 114 @Test
114 115 public void testFindDefaultDeviceProfileInfo() throws Exception {
115   - EntityInfo foundDefaultDeviceProfileInfo = doGet("/api/deviceProfileInfo/default", EntityInfo.class);
  116 + DeviceProfileInfo foundDefaultDeviceProfileInfo = doGet("/api/deviceProfileInfo/default", DeviceProfileInfo.class);
116 117 Assert.assertNotNull(foundDefaultDeviceProfileInfo);
117 118 Assert.assertNotNull(foundDefaultDeviceProfileInfo.getId());
118 119 Assert.assertNotNull(foundDefaultDeviceProfileInfo.getName());
  120 + Assert.assertNotNull(foundDefaultDeviceProfileInfo.getType());
  121 + Assert.assertEquals(DeviceProfileType.DEFAULT, foundDefaultDeviceProfileInfo.getType());
119 122 Assert.assertEquals("Default", foundDefaultDeviceProfileInfo.getName());
120 123 }
121 124
... ... @@ -125,10 +128,11 @@ public abstract class BaseDeviceProfileControllerTest extends AbstractController
125 128 DeviceProfile savedDeviceProfile = doPost("/api/deviceProfile", deviceProfile, DeviceProfile.class);
126 129 DeviceProfile defaultDeviceProfile = doPost("/api/deviceProfile/"+savedDeviceProfile.getId().getId().toString()+"/default", null, DeviceProfile.class);
127 130 Assert.assertNotNull(defaultDeviceProfile);
128   - EntityInfo foundDefaultDeviceProfile = doGet("/api/deviceProfileInfo/default", EntityInfo.class);
  131 + DeviceProfileInfo foundDefaultDeviceProfile = doGet("/api/deviceProfileInfo/default", DeviceProfileInfo.class);
129 132 Assert.assertNotNull(foundDefaultDeviceProfile);
130 133 Assert.assertEquals(savedDeviceProfile.getName(), foundDefaultDeviceProfile.getName());
131 134 Assert.assertEquals(savedDeviceProfile.getId(), foundDefaultDeviceProfile.getId());
  135 + Assert.assertEquals(savedDeviceProfile.getType(), foundDefaultDeviceProfile.getType());
132 136 }
133 137
134 138 @Test
... ... @@ -245,12 +249,12 @@ public abstract class BaseDeviceProfileControllerTest extends AbstractController
245 249 deviceProfiles.add(doPost("/api/deviceProfile", deviceProfile, DeviceProfile.class));
246 250 }
247 251
248   - List<EntityInfo> loadedDeviceProfileInfos = new ArrayList<>();
  252 + List<DeviceProfileInfo> loadedDeviceProfileInfos = new ArrayList<>();
249 253 pageLink = new PageLink(17);
250   - PageData<EntityInfo> pageData;
  254 + PageData<DeviceProfileInfo> pageData;
251 255 do {
252 256 pageData = doGetTypedWithPageLink("/api/deviceProfileInfos?",
253   - new TypeReference<PageData<EntityInfo>>(){}, pageLink);
  257 + new TypeReference<PageData<DeviceProfileInfo>>(){}, pageLink);
254 258 loadedDeviceProfileInfos.addAll(pageData.getData());
255 259 if (pageData.hasNext()) {
256 260 pageLink = pageLink.nextPageLink();
... ... @@ -260,8 +264,8 @@ public abstract class BaseDeviceProfileControllerTest extends AbstractController
260 264 Collections.sort(deviceProfiles, idComparator);
261 265 Collections.sort(loadedDeviceProfileInfos, deviceProfileInfoIdComparator);
262 266
263   - List<EntityInfo> deviceProfileInfos = deviceProfiles.stream().map(deviceProfile -> new EntityInfo(deviceProfile.getId(),
264   - deviceProfile.getName())).collect(Collectors.toList());
  267 + List<DeviceProfileInfo> deviceProfileInfos = deviceProfiles.stream().map(deviceProfile -> new DeviceProfileInfo(deviceProfile.getId(),
  268 + deviceProfile.getName(), deviceProfile.getType())).collect(Collectors.toList());
265 269
266 270 Assert.assertEquals(deviceProfileInfos, loadedDeviceProfileInfos);
267 271
... ... @@ -274,7 +278,7 @@ public abstract class BaseDeviceProfileControllerTest extends AbstractController
274 278
275 279 pageLink = new PageLink(17);
276 280 pageData = doGetTypedWithPageLink("/api/deviceProfileInfos?",
277   - new TypeReference<PageData<EntityInfo>>(){}, pageLink);
  281 + new TypeReference<PageData<DeviceProfileInfo>>(){}, pageLink);
278 282 Assert.assertFalse(pageData.hasNext());
279 283 Assert.assertEquals(1, pageData.getTotalElements());
280 284 }
... ...
... ... @@ -15,21 +15,21 @@
15 15 */
16 16 package org.thingsboard.server.controller;
17 17
18   -import static org.hamcrest.Matchers.containsString;
19   -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
20   -
21   -import java.util.ArrayList;
22   -import java.util.Collections;
23   -import java.util.List;
24   -
  18 +import com.fasterxml.jackson.core.type.TypeReference;
25 19 import org.apache.commons.lang3.RandomStringUtils;
  20 +import org.junit.Assert;
  21 +import org.junit.Test;
26 22 import org.thingsboard.server.common.data.Tenant;
  23 +import org.thingsboard.server.common.data.TenantInfo;
27 24 import org.thingsboard.server.common.data.page.PageData;
28 25 import org.thingsboard.server.common.data.page.PageLink;
29   -import org.junit.Assert;
30   -import org.junit.Test;
31 26
32   -import com.fasterxml.jackson.core.type.TypeReference;
  27 +import java.util.ArrayList;
  28 +import java.util.Collections;
  29 +import java.util.List;
  30 +
  31 +import static org.hamcrest.Matchers.containsString;
  32 +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
33 33
34 34 public abstract class BaseTenantControllerTest extends AbstractControllerTest {
35 35
... ... @@ -65,6 +65,19 @@ public abstract class BaseTenantControllerTest extends AbstractControllerTest {
65 65 doDelete("/api/tenant/"+savedTenant.getId().getId().toString())
66 66 .andExpect(status().isOk());
67 67 }
  68 +
  69 + @Test
  70 + public void testFindTenantInfoById() throws Exception {
  71 + loginSysAdmin();
  72 + Tenant tenant = new Tenant();
  73 + tenant.setTitle("My tenant");
  74 + Tenant savedTenant = doPost("/api/tenant", tenant, Tenant.class);
  75 + TenantInfo foundTenant = doGet("/api/tenant/info/"+savedTenant.getId().getId().toString(), TenantInfo.class);
  76 + Assert.assertNotNull(foundTenant);
  77 + Assert.assertEquals(new TenantInfo(savedTenant, "Default"), foundTenant);
  78 + doDelete("/api/tenant/"+savedTenant.getId().getId().toString())
  79 + .andExpect(status().isOk());
  80 + }
68 81
69 82 @Test
70 83 public void testSaveTenantWithEmptyTitle() throws Exception {
... ... @@ -217,4 +230,48 @@ public abstract class BaseTenantControllerTest extends AbstractControllerTest {
217 230 Assert.assertFalse(pageData.hasNext());
218 231 Assert.assertEquals(0, pageData.getData().size());
219 232 }
  233 +
  234 + @Test
  235 + public void testFindTenantInfos() throws Exception {
  236 + loginSysAdmin();
  237 + List<TenantInfo> tenants = new ArrayList<>();
  238 + PageLink pageLink = new PageLink(17);
  239 + PageData<TenantInfo> pageData = doGetTypedWithPageLink("/api/tenantInfos?", new TypeReference<PageData<TenantInfo>>(){}, pageLink);
  240 + Assert.assertFalse(pageData.hasNext());
  241 + Assert.assertEquals(1, pageData.getData().size());
  242 + tenants.addAll(pageData.getData());
  243 +
  244 + for (int i=0;i<56;i++) {
  245 + Tenant tenant = new Tenant();
  246 + tenant.setTitle("Tenant"+i);
  247 + tenants.add(new TenantInfo(doPost("/api/tenant", tenant, Tenant.class), "Default"));
  248 + }
  249 +
  250 + List<TenantInfo> loadedTenants = new ArrayList<>();
  251 + pageLink = new PageLink(17);
  252 + do {
  253 + pageData = doGetTypedWithPageLink("/api/tenantInfos?", new TypeReference<PageData<TenantInfo>>(){}, pageLink);
  254 + loadedTenants.addAll(pageData.getData());
  255 + if (pageData.hasNext()) {
  256 + pageLink = pageLink.nextPageLink();
  257 + }
  258 + } while (pageData.hasNext());
  259 +
  260 + Collections.sort(tenants, idComparator);
  261 + Collections.sort(loadedTenants, idComparator);
  262 +
  263 + Assert.assertEquals(tenants, loadedTenants);
  264 +
  265 + for (TenantInfo tenant : loadedTenants) {
  266 + if (!tenant.getTitle().equals(TEST_TENANT_NAME)) {
  267 + doDelete("/api/tenant/"+tenant.getId().getId().toString())
  268 + .andExpect(status().isOk());
  269 + }
  270 + }
  271 +
  272 + pageLink = new PageLink(17);
  273 + pageData = doGetTypedWithPageLink("/api/tenantInfos?", new TypeReference<PageData<TenantInfo>>(){}, pageLink);
  274 + Assert.assertFalse(pageData.hasNext());
  275 + Assert.assertEquals(1, pageData.getData().size());
  276 + }
220 277 }
... ...
... ... @@ -16,6 +16,7 @@
16 16 package org.thingsboard.server.dao.device;
17 17
18 18 import org.thingsboard.server.common.data.DeviceProfile;
  19 +import org.thingsboard.server.common.data.DeviceProfileInfo;
19 20 import org.thingsboard.server.common.data.EntityInfo;
20 21 import org.thingsboard.server.common.data.id.DeviceProfileId;
21 22 import org.thingsboard.server.common.data.id.TenantId;
... ... @@ -26,7 +27,7 @@ public interface DeviceProfileService {
26 27
27 28 DeviceProfile findDeviceProfileById(TenantId tenantId, DeviceProfileId deviceProfileId);
28 29
29   - EntityInfo findDeviceProfileInfoById(TenantId tenantId, DeviceProfileId deviceProfileId);
  30 + DeviceProfileInfo findDeviceProfileInfoById(TenantId tenantId, DeviceProfileId deviceProfileId);
30 31
31 32 DeviceProfile saveDeviceProfile(DeviceProfile deviceProfile);
32 33
... ... @@ -34,13 +35,15 @@ public interface DeviceProfileService {
34 35
35 36 PageData<DeviceProfile> findDeviceProfiles(TenantId tenantId, PageLink pageLink);
36 37
37   - PageData<EntityInfo> findDeviceProfileInfos(TenantId tenantId, PageLink pageLink);
  38 + PageData<DeviceProfileInfo> findDeviceProfileInfos(TenantId tenantId, PageLink pageLink);
  39 +
  40 + DeviceProfile findOrCreateDefaultDeviceProfile(TenantId tenantId);
38 41
39 42 DeviceProfile createDefaultDeviceProfile(TenantId tenantId);
40 43
41 44 DeviceProfile findDefaultDeviceProfile(TenantId tenantId);
42 45
43   - EntityInfo findDefaultDeviceProfileInfo(TenantId tenantId);
  46 + DeviceProfileInfo findDefaultDeviceProfileInfo(TenantId tenantId);
44 47
45 48 boolean setDefaultDeviceProfile(TenantId tenantId, DeviceProfileId deviceProfileId);
46 49
... ...
... ... @@ -17,6 +17,7 @@ package org.thingsboard.server.dao.tenant;
17 17
18 18 import com.google.common.util.concurrent.ListenableFuture;
19 19 import org.thingsboard.server.common.data.Tenant;
  20 +import org.thingsboard.server.common.data.TenantInfo;
20 21 import org.thingsboard.server.common.data.id.TenantId;
21 22 import org.thingsboard.server.common.data.page.PageData;
22 23 import org.thingsboard.server.common.data.page.PageLink;
... ... @@ -25,6 +26,8 @@ public interface TenantService {
25 26
26 27 Tenant findTenantById(TenantId tenantId);
27 28
  29 + TenantInfo findTenantInfoById(TenantId tenantId);
  30 +
28 31 ListenableFuture<Tenant> findTenantByIdAsync(TenantId callerId, TenantId tenantId);
29 32
30 33 Tenant saveTenant(Tenant tenant);
... ... @@ -32,6 +35,8 @@ public interface TenantService {
32 35 void deleteTenant(TenantId tenantId);
33 36
34 37 PageData<Tenant> findTenants(PageLink pageLink);
  38 +
  39 + PageData<TenantInfo> findTenantInfos(PageLink pageLink);
35 40
36 41 void deleteTenants();
37 42 }
... ...
... ... @@ -23,6 +23,7 @@ public class DeviceInfo extends Device {
23 23
24 24 private String customerTitle;
25 25 private boolean customerIsPublic;
  26 + private String deviceProfileName;
26 27
27 28 public DeviceInfo() {
28 29 super();
... ... @@ -32,9 +33,10 @@ public class DeviceInfo extends Device {
32 33 super(deviceId);
33 34 }
34 35
35   - public DeviceInfo(Device device, String customerTitle, boolean customerIsPublic) {
  36 + public DeviceInfo(Device device, String customerTitle, boolean customerIsPublic, String deviceProfileName) {
36 37 super(device);
37 38 this.customerTitle = customerTitle;
38 39 this.customerIsPublic = customerIsPublic;
  40 + this.deviceProfileName = deviceProfileName;
39 41 }
40 42 }
... ...
  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.JsonCreator;
  19 +import com.fasterxml.jackson.annotation.JsonProperty;
  20 +import lombok.EqualsAndHashCode;
  21 +import lombok.ToString;
  22 +import lombok.Value;
  23 +import org.thingsboard.server.common.data.id.EntityId;
  24 +import org.thingsboard.server.common.data.id.EntityIdFactory;
  25 +
  26 +import java.util.UUID;
  27 +
  28 +@Value
  29 +@EqualsAndHashCode(callSuper = true)
  30 +@ToString(callSuper = true)
  31 +public class DeviceProfileInfo extends EntityInfo {
  32 +
  33 + private final DeviceProfileType type;
  34 +
  35 + @JsonCreator
  36 + public DeviceProfileInfo(@JsonProperty("id") EntityId id,
  37 + @JsonProperty("name") String name,
  38 + @JsonProperty("type") DeviceProfileType type) {
  39 + super(id, name);
  40 + this.type = type;
  41 + }
  42 +
  43 + public DeviceProfileInfo(UUID uuid, String name, DeviceProfileType type) {
  44 + super(EntityIdFactory.getByTypeAndUuid(EntityType.DEVICE_PROFILE, uuid), name);
  45 + this.type = type;
  46 + }
  47 +
  48 +}
... ...
... ... @@ -36,8 +36,8 @@ public class EntityInfo implements HasId<EntityId>, HasName {
36 36 this.name = name;
37 37 }
38 38
39   - public EntityInfo(UUID uuid, String type, String name) {
40   - this.id = EntityIdFactory.getByTypeAndUuid(type, uuid);
  39 + public EntityInfo(UUID uuid, String entityType, String name) {
  40 + this.id = EntityIdFactory.getByTypeAndUuid(entityType, uuid);
41 41 this.name = name;
42 42 }
43 43
... ...
  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.TenantId;
  20 +
  21 +@Data
  22 +public class TenantInfo extends Tenant {
  23 +
  24 + private String tenantProfileName;
  25 +
  26 + public TenantInfo() {
  27 + super();
  28 + }
  29 +
  30 + public TenantInfo(TenantId tenantId) {
  31 + super(tenantId);
  32 + }
  33 +
  34 + public TenantInfo(Tenant tenant, String tenantProfileName) {
  35 + super(tenant);
  36 + this.tenantProfileName = tenantProfileName;
  37 + }
  38 +
  39 +}
... ...
... ... @@ -16,7 +16,7 @@
16 16 package org.thingsboard.server.dao.device;
17 17
18 18 import org.thingsboard.server.common.data.DeviceProfile;
19   -import org.thingsboard.server.common.data.EntityInfo;
  19 +import org.thingsboard.server.common.data.DeviceProfileInfo;
20 20 import org.thingsboard.server.common.data.id.TenantId;
21 21 import org.thingsboard.server.common.data.page.PageData;
22 22 import org.thingsboard.server.common.data.page.PageLink;
... ... @@ -26,15 +26,15 @@ import java.util.UUID;
26 26
27 27 public interface DeviceProfileDao extends Dao<DeviceProfile> {
28 28
29   - EntityInfo findDeviceProfileInfoById(TenantId tenantId, UUID deviceProfileId);
  29 + DeviceProfileInfo findDeviceProfileInfoById(TenantId tenantId, UUID deviceProfileId);
30 30
31 31 DeviceProfile save(TenantId tenantId, DeviceProfile deviceProfile);
32 32
33 33 PageData<DeviceProfile> findDeviceProfiles(TenantId tenantId, PageLink pageLink);
34 34
35   - PageData<EntityInfo> findDeviceProfileInfos(TenantId tenantId, PageLink pageLink);
  35 + PageData<DeviceProfileInfo> findDeviceProfileInfos(TenantId tenantId, PageLink pageLink);
36 36
37 37 DeviceProfile findDefaultDeviceProfile(TenantId tenantId);
38 38
39   - EntityInfo findDefaultDeviceProfileInfo(TenantId tenantId);
  39 + DeviceProfileInfo findDefaultDeviceProfileInfo(TenantId tenantId);
40 40 }
... ...
... ... @@ -24,8 +24,8 @@ import org.springframework.cache.CacheManager;
24 24 import org.springframework.cache.annotation.Cacheable;
25 25 import org.springframework.stereotype.Service;
26 26 import org.thingsboard.server.common.data.DeviceProfile;
  27 +import org.thingsboard.server.common.data.DeviceProfileInfo;
27 28 import org.thingsboard.server.common.data.DeviceProfileType;
28   -import org.thingsboard.server.common.data.EntityInfo;
29 29 import org.thingsboard.server.common.data.Tenant;
30 30 import org.thingsboard.server.common.data.device.profile.DefaultDeviceProfileConfiguration;
31 31 import org.thingsboard.server.common.data.device.profile.DeviceProfileData;
... ... @@ -39,7 +39,6 @@ import org.thingsboard.server.dao.service.DataValidator;
39 39 import org.thingsboard.server.dao.service.PaginatedRemover;
40 40 import org.thingsboard.server.dao.service.Validator;
41 41 import org.thingsboard.server.dao.tenant.TenantDao;
42   -import org.thingsboard.server.dao.util.mapping.JacksonUtil;
43 42
44 43 import java.util.Arrays;
45 44 import java.util.Collections;
... ... @@ -73,7 +72,7 @@ public class DeviceProfileServiceImpl extends AbstractEntityService implements D
73 72
74 73 @Cacheable(cacheNames = DEVICE_PROFILE_CACHE, key = "{'info', #deviceProfileId.id}")
75 74 @Override
76   - public EntityInfo findDeviceProfileInfoById(TenantId tenantId, DeviceProfileId deviceProfileId) {
  75 + public DeviceProfileInfo findDeviceProfileInfoById(TenantId tenantId, DeviceProfileId deviceProfileId) {
77 76 log.trace("Executing findDeviceProfileById [{}]", deviceProfileId);
78 77 Validator.validateId(deviceProfileId, INCORRECT_DEVICE_PROFILE_ID + deviceProfileId);
79 78 return deviceProfileDao.findDeviceProfileInfoById(tenantId, deviceProfileId.getId());
... ... @@ -141,7 +140,7 @@ public class DeviceProfileServiceImpl extends AbstractEntityService implements D
141 140 }
142 141
143 142 @Override
144   - public PageData<EntityInfo> findDeviceProfileInfos(TenantId tenantId, PageLink pageLink) {
  143 + public PageData<DeviceProfileInfo> findDeviceProfileInfos(TenantId tenantId, PageLink pageLink) {
145 144 log.trace("Executing findDeviceProfileInfos tenantId [{}], pageLink [{}]", tenantId, pageLink);
146 145 validateId(tenantId, INCORRECT_TENANT_ID + tenantId);
147 146 Validator.validatePageLink(pageLink);
... ... @@ -149,6 +148,16 @@ public class DeviceProfileServiceImpl extends AbstractEntityService implements D
149 148 }
150 149
151 150 @Override
  151 + public DeviceProfile findOrCreateDefaultDeviceProfile(TenantId tenantId) {
  152 + log.trace("Executing findOrCreateDefaultDeviceProfile");
  153 + DeviceProfile deviceProfile = findDefaultDeviceProfile(tenantId);
  154 + if (deviceProfile == null) {
  155 + deviceProfile = this.createDefaultDeviceProfile(tenantId);
  156 + }
  157 + return deviceProfile;
  158 + }
  159 +
  160 + @Override
152 161 public DeviceProfile createDefaultDeviceProfile(TenantId tenantId) {
153 162 log.trace("Executing createDefaultDeviceProfile tenantId [{}]", tenantId);
154 163 validateId(tenantId, INCORRECT_TENANT_ID + tenantId);
... ... @@ -175,7 +184,7 @@ public class DeviceProfileServiceImpl extends AbstractEntityService implements D
175 184
176 185 @Cacheable(cacheNames = DEVICE_PROFILE_CACHE, key = "{'default', 'info', #tenantId.id}")
177 186 @Override
178   - public EntityInfo findDefaultDeviceProfileInfo(TenantId tenantId) {
  187 + public DeviceProfileInfo findDefaultDeviceProfileInfo(TenantId tenantId) {
179 188 log.trace("Executing findDefaultDeviceProfileInfo tenantId [{}]", tenantId);
180 189 validateId(tenantId, INCORRECT_TENANT_ID + tenantId);
181 190 return deviceProfileDao.findDefaultDeviceProfileInfo(tenantId);
... ...
... ... @@ -35,7 +35,6 @@ 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 37 import org.thingsboard.server.common.data.DeviceProfile;
38   -import org.thingsboard.server.common.data.EntityInfo;
39 38 import org.thingsboard.server.common.data.EntitySubtype;
40 39 import org.thingsboard.server.common.data.EntityType;
41 40 import org.thingsboard.server.common.data.EntityView;
... ... @@ -43,6 +42,7 @@ import org.thingsboard.server.common.data.Tenant;
43 42 import org.thingsboard.server.common.data.device.DeviceSearchQuery;
44 43 import org.thingsboard.server.common.data.device.data.DefaultDeviceConfiguration;
45 44 import org.thingsboard.server.common.data.device.data.DeviceData;
  45 +import org.thingsboard.server.common.data.device.data.Lwm2mDeviceConfiguration;
46 46 import org.thingsboard.server.common.data.id.CustomerId;
47 47 import org.thingsboard.server.common.data.id.DeviceId;
48 48 import org.thingsboard.server.common.data.id.DeviceProfileId;
... ... @@ -168,10 +168,17 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe
168 168 Device savedDevice;
169 169 try {
170 170 if (device.getDeviceProfileId() == null) {
171   - EntityInfo deviceProfile = this.deviceProfileService.findDefaultDeviceProfileInfo(device.getTenantId());
  171 + DeviceProfile deviceProfile = this.deviceProfileService.findOrCreateDefaultDeviceProfile(device.getTenantId());
172 172 device.setDeviceProfileId(new DeviceProfileId(deviceProfile.getId().getId()));
173 173 DeviceData deviceData = new DeviceData();
174   - deviceData.setConfiguration(new DefaultDeviceConfiguration());
  174 + switch (deviceProfile.getType()) {
  175 + case DEFAULT:
  176 + deviceData.setConfiguration(new DefaultDeviceConfiguration());
  177 + break;
  178 + case LWM2M:
  179 + deviceData.setConfiguration(new Lwm2mDeviceConfiguration());
  180 + break;
  181 + }
175 182 device.setDeviceData(deviceData);
176 183 }
177 184 savedDevice = deviceDao.save(device.getTenantId(), device);
... ...
  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.Tenant;
  24 +import org.thingsboard.server.common.data.id.CustomerId;
  25 +import org.thingsboard.server.common.data.id.TenantId;
  26 +import org.thingsboard.server.common.data.id.TenantProfileId;
  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.MappedSuperclass;
  35 +import javax.persistence.Table;
  36 +import java.util.UUID;
  37 +
  38 +@Data
  39 +@EqualsAndHashCode(callSuper = true)
  40 +@TypeDef(name = "json", typeClass = JsonStringType.class)
  41 +@MappedSuperclass
  42 +public abstract class AbstractTenantEntity<T extends Tenant> extends BaseSqlEntity<T> implements SearchTextEntity<T> {
  43 +
  44 + @Column(name = ModelConstants.TENANT_TITLE_PROPERTY)
  45 + private String title;
  46 +
  47 + @Column(name = ModelConstants.SEARCH_TEXT_PROPERTY)
  48 + private String searchText;
  49 +
  50 + @Column(name = ModelConstants.TENANT_REGION_PROPERTY)
  51 + private String region;
  52 +
  53 + @Column(name = ModelConstants.COUNTRY_PROPERTY)
  54 + private String country;
  55 +
  56 + @Column(name = ModelConstants.STATE_PROPERTY)
  57 + private String state;
  58 +
  59 + @Column(name = ModelConstants.CITY_PROPERTY)
  60 + private String city;
  61 +
  62 + @Column(name = ModelConstants.ADDRESS_PROPERTY)
  63 + private String address;
  64 +
  65 + @Column(name = ModelConstants.ADDRESS2_PROPERTY)
  66 + private String address2;
  67 +
  68 + @Column(name = ModelConstants.ZIP_PROPERTY)
  69 + private String zip;
  70 +
  71 + @Column(name = ModelConstants.PHONE_PROPERTY)
  72 + private String phone;
  73 +
  74 + @Column(name = ModelConstants.EMAIL_PROPERTY)
  75 + private String email;
  76 +
  77 + @Type(type = "json")
  78 + @Column(name = ModelConstants.TENANT_ADDITIONAL_INFO_PROPERTY)
  79 + private JsonNode additionalInfo;
  80 +
  81 + @Column(name = ModelConstants.TENANT_TENANT_PROFILE_ID_PROPERTY, columnDefinition = "uuid")
  82 + private UUID tenantProfileId;
  83 +
  84 + public AbstractTenantEntity() {
  85 + super();
  86 + }
  87 +
  88 + public AbstractTenantEntity(Tenant tenant) {
  89 + if (tenant.getId() != null) {
  90 + this.setUuid(tenant.getId().getId());
  91 + }
  92 + this.setCreatedTime(tenant.getCreatedTime());
  93 + this.title = tenant.getTitle();
  94 + this.region = tenant.getRegion();
  95 + this.country = tenant.getCountry();
  96 + this.state = tenant.getState();
  97 + this.city = tenant.getCity();
  98 + this.address = tenant.getAddress();
  99 + this.address2 = tenant.getAddress2();
  100 + this.zip = tenant.getZip();
  101 + this.phone = tenant.getPhone();
  102 + this.email = tenant.getEmail();
  103 + this.additionalInfo = tenant.getAdditionalInfo();
  104 + if (tenant.getTenantProfileId() != null) {
  105 + this.tenantProfileId = tenant.getTenantProfileId().getId();
  106 + }
  107 + }
  108 +
  109 + public AbstractTenantEntity(TenantEntity tenantEntity) {
  110 + this.setId(tenantEntity.getId());
  111 + this.setCreatedTime(tenantEntity.getCreatedTime());
  112 + this.title = tenantEntity.getTitle();
  113 + this.region = tenantEntity.getRegion();
  114 + this.country = tenantEntity.getCountry();
  115 + this.state = tenantEntity.getState();
  116 + this.city = tenantEntity.getCity();
  117 + this.address = tenantEntity.getAddress();
  118 + this.address2 = tenantEntity.getAddress2();
  119 + this.zip = tenantEntity.getZip();
  120 + this.phone = tenantEntity.getPhone();
  121 + this.email = tenantEntity.getEmail();
  122 + this.additionalInfo = tenantEntity.getAdditionalInfo();
  123 + this.tenantProfileId = tenantEntity.getTenantProfileId();
  124 + }
  125 +
  126 + @Override
  127 + public String getSearchTextSource() {
  128 + return title;
  129 + }
  130 +
  131 + @Override
  132 + public void setSearchText(String searchText) {
  133 + this.searchText = searchText;
  134 + }
  135 +
  136 + public String getSearchText() {
  137 + return searchText;
  138 + }
  139 +
  140 + protected Tenant toTenant() {
  141 + Tenant tenant = new Tenant(new TenantId(this.getUuid()));
  142 + tenant.setCreatedTime(createdTime);
  143 + tenant.setTitle(title);
  144 + tenant.setRegion(region);
  145 + tenant.setCountry(country);
  146 + tenant.setState(state);
  147 + tenant.setCity(city);
  148 + tenant.setAddress(address);
  149 + tenant.setAddress2(address2);
  150 + tenant.setZip(zip);
  151 + tenant.setPhone(phone);
  152 + tenant.setEmail(email);
  153 + tenant.setAdditionalInfo(additionalInfo);
  154 + if (tenantProfileId != null) {
  155 + tenant.setTenantProfileId(new TenantProfileId(tenantProfileId));
  156 + }
  157 + return tenant;
  158 + }
  159 +
  160 +
  161 +}
... ...
... ... @@ -30,10 +30,12 @@ public class DeviceInfoEntity extends AbstractDeviceEntity<DeviceInfo> {
30 30 public static final Map<String,String> deviceInfoColumnMap = new HashMap<>();
31 31 static {
32 32 deviceInfoColumnMap.put("customerTitle", "c.title");
  33 + deviceInfoColumnMap.put("deviceProfileName", "p.name");
33 34 }
34 35
35 36 private String customerTitle;
36 37 private boolean customerIsPublic;
  38 + private String deviceProfileName;
37 39
38 40 public DeviceInfoEntity() {
39 41 super();
... ... @@ -41,7 +43,8 @@ public class DeviceInfoEntity extends AbstractDeviceEntity<DeviceInfo> {
41 43
42 44 public DeviceInfoEntity(DeviceEntity deviceEntity,
43 45 String customerTitle,
44   - Object customerAdditionalInfo) {
  46 + Object customerAdditionalInfo,
  47 + String deviceProfileName) {
45 48 super(deviceEntity);
46 49 this.customerTitle = customerTitle;
47 50 if (customerAdditionalInfo != null && ((JsonNode)customerAdditionalInfo).has("isPublic")) {
... ... @@ -49,10 +52,11 @@ public class DeviceInfoEntity extends AbstractDeviceEntity<DeviceInfo> {
49 52 } else {
50 53 this.customerIsPublic = false;
51 54 }
  55 + this.deviceProfileName = deviceProfileName;
52 56 }
53 57
54 58 @Override
55 59 public DeviceInfo toData() {
56   - return new DeviceInfo(super.toDevice(), customerTitle, customerIsPublic);
  60 + return new DeviceInfo(super.toDevice(), customerTitle, customerIsPublic, deviceProfileName);
57 61 }
58 62 }
... ...
... ... @@ -15,131 +15,33 @@
15 15 */
16 16 package org.thingsboard.server.dao.model.sql;
17 17
18   -import com.fasterxml.jackson.databind.JsonNode;
19 18 import lombok.Data;
20 19 import lombok.EqualsAndHashCode;
21   -import org.hibernate.annotations.Type;
22 20 import org.hibernate.annotations.TypeDef;
23 21 import org.thingsboard.server.common.data.Tenant;
24   -import org.thingsboard.server.common.data.id.CustomerId;
25   -import org.thingsboard.server.common.data.id.TenantId;
26   -import org.thingsboard.server.common.data.id.TenantProfileId;
27   -import org.thingsboard.server.dao.model.BaseSqlEntity;
28 22 import org.thingsboard.server.dao.model.ModelConstants;
29   -import org.thingsboard.server.dao.model.SearchTextEntity;
30 23 import org.thingsboard.server.dao.util.mapping.JsonStringType;
31 24
32   -import javax.persistence.Column;
33 25 import javax.persistence.Entity;
34 26 import javax.persistence.Table;
35   -import java.util.UUID;
36 27
37 28 @Data
38 29 @EqualsAndHashCode(callSuper = true)
39 30 @Entity
40 31 @TypeDef(name = "json", typeClass = JsonStringType.class)
41 32 @Table(name = ModelConstants.TENANT_COLUMN_FAMILY_NAME)
42   -public final class TenantEntity extends BaseSqlEntity<Tenant> implements SearchTextEntity<Tenant> {
43   -
44   - @Column(name = ModelConstants.TENANT_TITLE_PROPERTY)
45   - private String title;
46   -
47   - @Column(name = ModelConstants.SEARCH_TEXT_PROPERTY)
48   - private String searchText;
49   -
50   - @Column(name = ModelConstants.TENANT_REGION_PROPERTY)
51   - private String region;
52   -
53   - @Column(name = ModelConstants.COUNTRY_PROPERTY)
54   - private String country;
55   -
56   - @Column(name = ModelConstants.STATE_PROPERTY)
57   - private String state;
58   -
59   - @Column(name = ModelConstants.CITY_PROPERTY)
60   - private String city;
61   -
62   - @Column(name = ModelConstants.ADDRESS_PROPERTY)
63   - private String address;
64   -
65   - @Column(name = ModelConstants.ADDRESS2_PROPERTY)
66   - private String address2;
67   -
68   - @Column(name = ModelConstants.ZIP_PROPERTY)
69   - private String zip;
70   -
71   - @Column(name = ModelConstants.PHONE_PROPERTY)
72   - private String phone;
73   -
74   - @Column(name = ModelConstants.EMAIL_PROPERTY)
75   - private String email;
76   -
77   - @Type(type = "json")
78   - @Column(name = ModelConstants.TENANT_ADDITIONAL_INFO_PROPERTY)
79   - private JsonNode additionalInfo;
80   -
81   - @Column(name = ModelConstants.TENANT_TENANT_PROFILE_ID_PROPERTY, columnDefinition = "uuid")
82   - private UUID tenantProfileId;
  33 +public final class TenantEntity extends AbstractTenantEntity<Tenant> {
83 34
84 35 public TenantEntity() {
85 36 super();
86 37 }
87 38
88 39 public TenantEntity(Tenant tenant) {
89   - if (tenant.getId() != null) {
90   - this.setUuid(tenant.getId().getId());
91   - }
92   - this.setCreatedTime(tenant.getCreatedTime());
93   - this.title = tenant.getTitle();
94   - this.region = tenant.getRegion();
95   - this.country = tenant.getCountry();
96   - this.state = tenant.getState();
97   - this.city = tenant.getCity();
98   - this.address = tenant.getAddress();
99   - this.address2 = tenant.getAddress2();
100   - this.zip = tenant.getZip();
101   - this.phone = tenant.getPhone();
102   - this.email = tenant.getEmail();
103   - this.additionalInfo = tenant.getAdditionalInfo();
104   - if (tenant.getTenantProfileId() != null) {
105   - this.tenantProfileId = tenant.getTenantProfileId().getId();
106   - }
107   - }
108   -
109   - @Override
110   - public String getSearchTextSource() {
111   - return title;
112   - }
113   -
114   - @Override
115   - public void setSearchText(String searchText) {
116   - this.searchText = searchText;
117   - }
118   -
119   - public String getSearchText() {
120   - return searchText;
  40 + super(tenant);
121 41 }
122 42
123 43 @Override
124 44 public Tenant toData() {
125   - Tenant tenant = new Tenant(new TenantId(this.getUuid()));
126   - tenant.setCreatedTime(createdTime);
127   - tenant.setTitle(title);
128   - tenant.setRegion(region);
129   - tenant.setCountry(country);
130   - tenant.setState(state);
131   - tenant.setCity(city);
132   - tenant.setAddress(address);
133   - tenant.setAddress2(address2);
134   - tenant.setZip(zip);
135   - tenant.setPhone(phone);
136   - tenant.setEmail(email);
137   - tenant.setAdditionalInfo(additionalInfo);
138   - if (tenantProfileId != null) {
139   - tenant.setTenantProfileId(new TenantProfileId(tenantProfileId));
140   - }
141   - return tenant;
  45 + return super.toTenant();
142 46 }
143   -
144   -
145 47 }
... ...
  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 lombok.Data;
  19 +import lombok.EqualsAndHashCode;
  20 +import org.thingsboard.server.common.data.TenantInfo;
  21 +
  22 +import java.util.HashMap;
  23 +import java.util.Map;
  24 +
  25 +@Data
  26 +@EqualsAndHashCode(callSuper = true)
  27 +public class TenantInfoEntity extends AbstractTenantEntity<TenantInfo> {
  28 +
  29 + public static final Map<String,String> tenantInfoColumnMap = new HashMap<>();
  30 + static {
  31 + tenantInfoColumnMap.put("tenantProfileName", "p.name");
  32 + }
  33 +
  34 + private String tenantProfileName;
  35 +
  36 + public TenantInfoEntity() {
  37 + super();
  38 + }
  39 +
  40 + public TenantInfoEntity(TenantEntity tenantEntity, String tenantProfileName) {
  41 + super(tenantEntity);
  42 + this.tenantProfileName = tenantProfileName;
  43 + }
  44 +
  45 + @Override
  46 + public TenantInfo toData() {
  47 + return new TenantInfo(super.toTenant(), this.tenantProfileName);
  48 + }
  49 +}
... ...
... ... @@ -20,17 +20,17 @@ import org.springframework.data.domain.Pageable;
20 20 import org.springframework.data.jpa.repository.Query;
21 21 import org.springframework.data.repository.PagingAndSortingRepository;
22 22 import org.springframework.data.repository.query.Param;
23   -import org.thingsboard.server.common.data.EntityInfo;
  23 +import org.thingsboard.server.common.data.DeviceProfileInfo;
24 24 import org.thingsboard.server.dao.model.sql.DeviceProfileEntity;
25 25
26 26 import java.util.UUID;
27 27
28 28 public interface DeviceProfileRepository extends PagingAndSortingRepository<DeviceProfileEntity, UUID> {
29 29
30   - @Query("SELECT new org.thingsboard.server.common.data.EntityInfo(d.id, 'DEVICE_PROFILE', d.name) " +
  30 + @Query("SELECT new org.thingsboard.server.common.data.DeviceProfileInfo(d.id, d.name, d.type) " +
31 31 "FROM DeviceProfileEntity d " +
32 32 "WHERE d.id = :deviceProfileId")
33   - EntityInfo findDeviceProfileInfoById(@Param("deviceProfileId") UUID deviceProfileId);
  33 + DeviceProfileInfo findDeviceProfileInfoById(@Param("deviceProfileId") UUID deviceProfileId);
34 34
35 35 @Query("SELECT d FROM DeviceProfileEntity d WHERE " +
36 36 "d.tenantId = :tenantId AND LOWER(d.searchText) LIKE LOWER(CONCAT(:textSearch, '%'))")
... ... @@ -38,19 +38,19 @@ public interface DeviceProfileRepository extends PagingAndSortingRepository<Devi
38 38 @Param("textSearch") String textSearch,
39 39 Pageable pageable);
40 40
41   - @Query("SELECT new org.thingsboard.server.common.data.EntityInfo(d.id, 'DEVICE_PROFILE', d.name) " +
  41 + @Query("SELECT new org.thingsboard.server.common.data.DeviceProfileInfo(d.id, d.name, d.type) " +
42 42 "FROM DeviceProfileEntity d WHERE " +
43 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);
  44 + Page<DeviceProfileInfo> findDeviceProfileInfos(@Param("tenantId") UUID tenantId,
  45 + @Param("textSearch") String textSearch,
  46 + Pageable pageable);
47 47
48 48 @Query("SELECT d FROM DeviceProfileEntity d " +
49 49 "WHERE d.tenantId = :tenantId AND d.isDefault = true")
50 50 DeviceProfileEntity findByDefaultTrueAndTenantId(@Param("tenantId") UUID tenantId);
51 51
52   - @Query("SELECT new org.thingsboard.server.common.data.EntityInfo(d.id, 'DEVICE_PROFILE', d.name) " +
  52 + @Query("SELECT new org.thingsboard.server.common.data.DeviceProfileInfo(d.id, d.name, d.type) " +
53 53 "FROM DeviceProfileEntity d " +
54 54 "WHERE d.tenantId = :tenantId AND d.isDefault = true")
55   - EntityInfo findDefaultDeviceProfileInfo(@Param("tenantId") UUID tenantId);
  55 + DeviceProfileInfo findDefaultDeviceProfileInfo(@Param("tenantId") UUID tenantId);
56 56 }
... ...
... ... @@ -31,9 +31,10 @@ import java.util.UUID;
31 31 */
32 32 public interface DeviceRepository extends PagingAndSortingRepository<DeviceEntity, UUID> {
33 33
34   - @Query("SELECT new org.thingsboard.server.dao.model.sql.DeviceInfoEntity(d, c.title, c.additionalInfo) " +
  34 + @Query("SELECT new org.thingsboard.server.dao.model.sql.DeviceInfoEntity(d, c.title, c.additionalInfo, p.name) " +
35 35 "FROM DeviceEntity d " +
36 36 "LEFT JOIN CustomerEntity c on c.id = d.customerId " +
  37 + "LEFT JOIN DeviceProfileEntity p on p.id = d.deviceProfileId " +
37 38 "WHERE d.id = :deviceId")
38 39 DeviceInfoEntity findDeviceInfoById(@Param("deviceId") UUID deviceId);
39 40
... ... @@ -45,9 +46,10 @@ public interface DeviceRepository extends PagingAndSortingRepository<DeviceEntit
45 46 @Param("searchText") String searchText,
46 47 Pageable pageable);
47 48
48   - @Query("SELECT new org.thingsboard.server.dao.model.sql.DeviceInfoEntity(d, c.title, c.additionalInfo) " +
  49 + @Query("SELECT new org.thingsboard.server.dao.model.sql.DeviceInfoEntity(d, c.title, c.additionalInfo, p.name) " +
49 50 "FROM DeviceEntity d " +
50 51 "LEFT JOIN CustomerEntity c on c.id = d.customerId " +
  52 + "LEFT JOIN DeviceProfileEntity p on p.id = d.deviceProfileId " +
51 53 "WHERE d.tenantId = :tenantId " +
52 54 "AND d.customerId = :customerId " +
53 55 "AND LOWER(d.searchText) LIKE LOWER(CONCAT(:searchText, '%'))")
... ... @@ -66,9 +68,10 @@ public interface DeviceRepository extends PagingAndSortingRepository<DeviceEntit
66 68 @Param("textSearch") String textSearch,
67 69 Pageable pageable);
68 70
69   - @Query("SELECT new org.thingsboard.server.dao.model.sql.DeviceInfoEntity(d, c.title, c.additionalInfo) " +
  71 + @Query("SELECT new org.thingsboard.server.dao.model.sql.DeviceInfoEntity(d, c.title, c.additionalInfo, p.name) " +
70 72 "FROM DeviceEntity d " +
71 73 "LEFT JOIN CustomerEntity c on c.id = d.customerId " +
  74 + "LEFT JOIN DeviceProfileEntity p on p.id = d.deviceProfileId " +
72 75 "WHERE d.tenantId = :tenantId " +
73 76 "AND LOWER(d.searchText) LIKE LOWER(CONCAT(:textSearch, '%'))")
74 77 Page<DeviceInfoEntity> findDeviceInfosByTenantId(@Param("tenantId") UUID tenantId,
... ... @@ -83,9 +86,10 @@ public interface DeviceRepository extends PagingAndSortingRepository<DeviceEntit
83 86 @Param("textSearch") String textSearch,
84 87 Pageable pageable);
85 88
86   - @Query("SELECT new org.thingsboard.server.dao.model.sql.DeviceInfoEntity(d, c.title, c.additionalInfo) " +
  89 + @Query("SELECT new org.thingsboard.server.dao.model.sql.DeviceInfoEntity(d, c.title, c.additionalInfo, p.name) " +
87 90 "FROM DeviceEntity d " +
88 91 "LEFT JOIN CustomerEntity c on c.id = d.customerId " +
  92 + "LEFT JOIN DeviceProfileEntity p on p.id = d.deviceProfileId " +
89 93 "WHERE d.tenantId = :tenantId " +
90 94 "AND d.type = :type " +
91 95 "AND LOWER(d.searchText) LIKE LOWER(CONCAT(:textSearch, '%'))")
... ... @@ -104,9 +108,10 @@ public interface DeviceRepository extends PagingAndSortingRepository<DeviceEntit
104 108 @Param("textSearch") String textSearch,
105 109 Pageable pageable);
106 110
107   - @Query("SELECT new org.thingsboard.server.dao.model.sql.DeviceInfoEntity(d, c.title, c.additionalInfo) " +
  111 + @Query("SELECT new org.thingsboard.server.dao.model.sql.DeviceInfoEntity(d, c.title, c.additionalInfo, p.name) " +
108 112 "FROM DeviceEntity d " +
109 113 "LEFT JOIN CustomerEntity c on c.id = d.customerId " +
  114 + "LEFT JOIN DeviceProfileEntity p on p.id = d.deviceProfileId " +
110 115 "WHERE d.tenantId = :tenantId " +
111 116 "AND d.customerId = :customerId " +
112 117 "AND d.type = :type " +
... ...
... ... @@ -19,7 +19,7 @@ import org.springframework.beans.factory.annotation.Autowired;
19 19 import org.springframework.data.repository.CrudRepository;
20 20 import org.springframework.stereotype.Component;
21 21 import org.thingsboard.server.common.data.DeviceProfile;
22   -import org.thingsboard.server.common.data.EntityInfo;
  22 +import org.thingsboard.server.common.data.DeviceProfileInfo;
23 23 import org.thingsboard.server.common.data.id.TenantId;
24 24 import org.thingsboard.server.common.data.page.PageData;
25 25 import org.thingsboard.server.common.data.page.PageLink;
... ... @@ -48,7 +48,7 @@ public class JpaDeviceProfileDao extends JpaAbstractSearchTextDao<DeviceProfileE
48 48 }
49 49
50 50 @Override
51   - public EntityInfo findDeviceProfileInfoById(TenantId tenantId, UUID deviceProfileId) {
  51 + public DeviceProfileInfo findDeviceProfileInfoById(TenantId tenantId, UUID deviceProfileId) {
52 52 return deviceProfileRepository.findDeviceProfileInfoById(deviceProfileId);
53 53 }
54 54
... ... @@ -62,7 +62,7 @@ public class JpaDeviceProfileDao extends JpaAbstractSearchTextDao<DeviceProfileE
62 62 }
63 63
64 64 @Override
65   - public PageData<EntityInfo> findDeviceProfileInfos(TenantId tenantId, PageLink pageLink) {
  65 + public PageData<DeviceProfileInfo> findDeviceProfileInfos(TenantId tenantId, PageLink pageLink) {
66 66 return DaoUtil.pageToPageData(
67 67 deviceProfileRepository.findDeviceProfileInfos(
68 68 tenantId.getId(),
... ... @@ -76,7 +76,7 @@ public class JpaDeviceProfileDao extends JpaAbstractSearchTextDao<DeviceProfileE
76 76 }
77 77
78 78 @Override
79   - public EntityInfo findDefaultDeviceProfileInfo(TenantId tenantId) {
  79 + public DeviceProfileInfo findDefaultDeviceProfileInfo(TenantId tenantId) {
80 80 return deviceProfileRepository.findDefaultDeviceProfileInfo(tenantId.getId());
81 81 }
82 82
... ...
... ... @@ -19,11 +19,13 @@ import org.springframework.beans.factory.annotation.Autowired;
19 19 import org.springframework.data.repository.CrudRepository;
20 20 import org.springframework.stereotype.Component;
21 21 import org.thingsboard.server.common.data.Tenant;
  22 +import org.thingsboard.server.common.data.TenantInfo;
22 23 import org.thingsboard.server.common.data.id.TenantId;
23 24 import org.thingsboard.server.common.data.page.PageData;
24 25 import org.thingsboard.server.common.data.page.PageLink;
25 26 import org.thingsboard.server.dao.DaoUtil;
26 27 import org.thingsboard.server.dao.model.sql.TenantEntity;
  28 +import org.thingsboard.server.dao.model.sql.TenantInfoEntity;
27 29 import org.thingsboard.server.dao.sql.JpaAbstractSearchTextDao;
28 30 import org.thingsboard.server.dao.tenant.TenantDao;
29 31
... ... @@ -51,6 +53,11 @@ public class JpaTenantDao extends JpaAbstractSearchTextDao<TenantEntity, Tenant>
51 53 }
52 54
53 55 @Override
  56 + public TenantInfo findTenantInfoById(TenantId tenantId, UUID id) {
  57 + return DaoUtil.getData(tenantRepository.findTenantInfoById(id));
  58 + }
  59 +
  60 + @Override
54 61 public PageData<Tenant> findTenantsByRegion(TenantId tenantId, String region, PageLink pageLink) {
55 62 return DaoUtil.toPageData(tenantRepository
56 63 .findByRegionNextPage(
... ... @@ -58,4 +65,13 @@ public class JpaTenantDao extends JpaAbstractSearchTextDao<TenantEntity, Tenant>
58 65 Objects.toString(pageLink.getTextSearch(), ""),
59 66 DaoUtil.toPageable(pageLink)));
60 67 }
  68 +
  69 + @Override
  70 + public PageData<TenantInfo> findTenantInfosByRegion(TenantId tenantId, String region, PageLink pageLink) {
  71 + return DaoUtil.toPageData(tenantRepository
  72 + .findTenantInfoByRegionNextPage(
  73 + region,
  74 + Objects.toString(pageLink.getTextSearch(), ""),
  75 + DaoUtil.toPageable(pageLink, TenantInfoEntity.tenantInfoColumnMap)));
  76 + }
61 77 }
... ...
... ... @@ -21,6 +21,7 @@ import org.springframework.data.jpa.repository.Query;
21 21 import org.springframework.data.repository.PagingAndSortingRepository;
22 22 import org.springframework.data.repository.query.Param;
23 23 import org.thingsboard.server.dao.model.sql.TenantEntity;
  24 +import org.thingsboard.server.dao.model.sql.TenantInfoEntity;
24 25
25 26 import java.util.UUID;
26 27
... ... @@ -29,9 +30,24 @@ import java.util.UUID;
29 30 */
30 31 public interface TenantRepository extends PagingAndSortingRepository<TenantEntity, UUID> {
31 32
  33 + @Query("SELECT new org.thingsboard.server.dao.model.sql.TenantInfoEntity(t, p.name) " +
  34 + "FROM TenantEntity t " +
  35 + "LEFT JOIN TenantProfileEntity p on p.id = t.tenantProfileId " +
  36 + "WHERE t.id = :tenantId")
  37 + TenantInfoEntity findTenantInfoById(@Param("tenantId") UUID tenantId);
  38 +
32 39 @Query("SELECT t FROM TenantEntity t WHERE t.region = :region " +
33 40 "AND LOWER(t.searchText) LIKE LOWER(CONCAT(:textSearch, '%'))")
34 41 Page<TenantEntity> findByRegionNextPage(@Param("region") String region,
35 42 @Param("textSearch") String textSearch,
36 43 Pageable pageable);
  44 +
  45 + @Query("SELECT new org.thingsboard.server.dao.model.sql.TenantInfoEntity(t, p.name) " +
  46 + "FROM TenantEntity t " +
  47 + "LEFT JOIN TenantProfileEntity p on p.id = t.tenantProfileId " +
  48 + "WHERE t.region = :region " +
  49 + "AND LOWER(t.searchText) LIKE LOWER(CONCAT(:textSearch, '%'))")
  50 + Page<TenantInfoEntity> findTenantInfoByRegionNextPage(@Param("region") String region,
  51 + @Param("textSearch") String textSearch,
  52 + Pageable pageable);
37 53 }
... ...
... ... @@ -16,13 +16,18 @@
16 16 package org.thingsboard.server.dao.tenant;
17 17
18 18 import org.thingsboard.server.common.data.Tenant;
  19 +import org.thingsboard.server.common.data.TenantInfo;
19 20 import org.thingsboard.server.common.data.id.TenantId;
20 21 import org.thingsboard.server.common.data.page.PageData;
21 22 import org.thingsboard.server.common.data.page.PageLink;
22 23 import org.thingsboard.server.dao.Dao;
23 24
  25 +import java.util.UUID;
  26 +
24 27 public interface TenantDao extends Dao<Tenant> {
25 28
  29 + TenantInfo findTenantInfoById(TenantId tenantId, UUID id);
  30 +
26 31 /**
27 32 * Save or update tenant object
28 33 *
... ... @@ -39,5 +44,7 @@ public interface TenantDao extends Dao<Tenant> {
39 44 * @return the list of tenant objects
40 45 */
41 46 PageData<Tenant> findTenantsByRegion(TenantId tenantId, String region, PageLink pageLink);
  47 +
  48 + PageData<TenantInfo> findTenantInfosByRegion(TenantId tenantId, String region, PageLink pageLink);
42 49
43 50 }
... ...
... ... @@ -20,12 +20,11 @@ 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;
24 23 import org.thingsboard.server.common.data.Tenant;
  24 +import org.thingsboard.server.common.data.TenantInfo;
25 25 import org.thingsboard.server.common.data.TenantProfile;
26 26 import org.thingsboard.server.common.data.id.EntityId;
27 27 import org.thingsboard.server.common.data.id.TenantId;
28   -import org.thingsboard.server.common.data.id.TenantProfileId;
29 28 import org.thingsboard.server.common.data.page.PageData;
30 29 import org.thingsboard.server.common.data.page.PageLink;
31 30 import org.thingsboard.server.dao.asset.AssetService;
... ... @@ -93,6 +92,13 @@ public class TenantServiceImpl extends AbstractEntityService implements TenantSe
93 92 }
94 93
95 94 @Override
  95 + public TenantInfo findTenantInfoById(TenantId tenantId) {
  96 + log.trace("Executing findTenantInfoById [{}]", tenantId);
  97 + validateId(tenantId, INCORRECT_TENANT_ID + tenantId);
  98 + return tenantDao.findTenantInfoById(tenantId, tenantId.getId());
  99 + }
  100 +
  101 + @Override
96 102 public ListenableFuture<Tenant> findTenantByIdAsync(TenantId callerId, TenantId tenantId) {
97 103 log.trace("Executing TenantIdAsync [{}]", tenantId);
98 104 validateId(tenantId, INCORRECT_TENANT_ID + tenantId);
... ... @@ -140,6 +146,13 @@ public class TenantServiceImpl extends AbstractEntityService implements TenantSe
140 146 }
141 147
142 148 @Override
  149 + public PageData<TenantInfo> findTenantInfos(PageLink pageLink) {
  150 + log.trace("Executing findTenantInfos pageLink [{}]", pageLink);
  151 + Validator.validatePageLink(pageLink);
  152 + return tenantDao.findTenantInfosByRegion(new TenantId(EntityId.NULL_UUID), DEFAULT_TENANT_REGION, pageLink);
  153 + }
  154 +
  155 + @Override
143 156 public void deleteTenants() {
144 157 log.trace("Executing deleteTenants");
145 158 tenantsRemover.removeEntities(new TenantId(EntityId.NULL_UUID), DEFAULT_TENANT_REGION);
... ...
... ... @@ -230,8 +230,6 @@ CREATE TABLE IF NOT EXISTS tenant (
230 230 state varchar(255),
231 231 title varchar(255),
232 232 zip varchar(255),
233   - isolated_tb_core boolean,
234   - isolated_tb_rule_engine boolean,
235 233 CONSTRAINT fk_tenant_profile FOREIGN KEY (tenant_profile_id) REFERENCES tenant_profile(id)
236 234 );
237 235
... ...
... ... @@ -25,7 +25,7 @@ CREATE OR REPLACE PROCEDURE insert_tb_schema_settings()
25 25 $$
26 26 BEGIN
27 27 IF (SELECT COUNT(*) FROM tb_schema_settings) = 0 THEN
28   - INSERT INTO tb_schema_settings (schema_version) VALUES (3001000);
  28 + INSERT INTO tb_schema_settings (schema_version) VALUES (3002000);
29 29 END IF;
30 30 END;
31 31 $$;
... ... @@ -254,8 +254,6 @@ CREATE TABLE IF NOT EXISTS tenant (
254 254 state varchar(255),
255 255 title varchar(255),
256 256 zip varchar(255),
257   - isolated_tb_core boolean,
258   - isolated_tb_rule_engine boolean,
259 257 CONSTRAINT fk_tenant_profile FOREIGN KEY (tenant_profile_id) REFERENCES tenant_profile(id)
260 258 );
261 259
... ...
... ... @@ -21,8 +21,8 @@ import org.junit.Before;
21 21 import org.junit.Test;
22 22 import org.thingsboard.server.common.data.Device;
23 23 import org.thingsboard.server.common.data.DeviceProfile;
  24 +import org.thingsboard.server.common.data.DeviceProfileInfo;
24 25 import org.thingsboard.server.common.data.DeviceProfileType;
25   -import org.thingsboard.server.common.data.EntityInfo;
26 26 import org.thingsboard.server.common.data.Tenant;
27 27 import org.thingsboard.server.common.data.id.TenantId;
28 28 import org.thingsboard.server.common.data.page.PageData;
... ... @@ -37,7 +37,7 @@ import java.util.stream.Collectors;
37 37 public class BaseDeviceProfileServiceTest extends AbstractServiceTest {
38 38
39 39 private IdComparator<DeviceProfile> idComparator = new IdComparator<>();
40   - private IdComparator<EntityInfo> deviceProfileInfoIdComparator = new IdComparator<>();
  40 + private IdComparator<DeviceProfileInfo> deviceProfileInfoIdComparator = new IdComparator<>();
41 41
42 42 private TenantId tenantId;
43 43
... ... @@ -86,10 +86,11 @@ public class BaseDeviceProfileServiceTest extends AbstractServiceTest {
86 86 public void testFindDeviceProfileInfoById() {
87 87 DeviceProfile deviceProfile = this.createDeviceProfile(tenantId,"Device Profile");
88 88 DeviceProfile savedDeviceProfile = deviceProfileService.saveDeviceProfile(deviceProfile);
89   - EntityInfo foundDeviceProfileInfo = deviceProfileService.findDeviceProfileInfoById(tenantId, savedDeviceProfile.getId());
  89 + DeviceProfileInfo foundDeviceProfileInfo = deviceProfileService.findDeviceProfileInfoById(tenantId, savedDeviceProfile.getId());
90 90 Assert.assertNotNull(foundDeviceProfileInfo);
91 91 Assert.assertEquals(savedDeviceProfile.getId(), foundDeviceProfileInfo.getId());
92 92 Assert.assertEquals(savedDeviceProfile.getName(), foundDeviceProfileInfo.getName());
  93 + Assert.assertEquals(savedDeviceProfile.getType(), foundDeviceProfileInfo.getType());
93 94 }
94 95
95 96 @Test
... ... @@ -102,10 +103,11 @@ public class BaseDeviceProfileServiceTest extends AbstractServiceTest {
102 103
103 104 @Test
104 105 public void testFindDefaultDeviceProfileInfo() {
105   - EntityInfo foundDefaultDeviceProfileInfo = deviceProfileService.findDefaultDeviceProfileInfo(tenantId);
  106 + DeviceProfileInfo foundDefaultDeviceProfileInfo = deviceProfileService.findDefaultDeviceProfileInfo(tenantId);
106 107 Assert.assertNotNull(foundDefaultDeviceProfileInfo);
107 108 Assert.assertNotNull(foundDefaultDeviceProfileInfo.getId());
108 109 Assert.assertNotNull(foundDefaultDeviceProfileInfo.getName());
  110 + Assert.assertNotNull(foundDefaultDeviceProfileInfo.getType());
109 111 }
110 112
111 113 @Test
... ... @@ -230,9 +232,9 @@ public class BaseDeviceProfileServiceTest extends AbstractServiceTest {
230 232 deviceProfiles.add(deviceProfileService.saveDeviceProfile(deviceProfile));
231 233 }
232 234
233   - List<EntityInfo> loadedDeviceProfileInfos = new ArrayList<>();
  235 + List<DeviceProfileInfo> loadedDeviceProfileInfos = new ArrayList<>();
234 236 pageLink = new PageLink(17);
235   - PageData<EntityInfo> pageData;
  237 + PageData<DeviceProfileInfo> pageData;
236 238 do {
237 239 pageData = deviceProfileService.findDeviceProfileInfos(tenantId, pageLink);
238 240 loadedDeviceProfileInfos.addAll(pageData.getData());
... ... @@ -245,8 +247,8 @@ public class BaseDeviceProfileServiceTest extends AbstractServiceTest {
245 247 Collections.sort(deviceProfiles, idComparator);
246 248 Collections.sort(loadedDeviceProfileInfos, deviceProfileInfoIdComparator);
247 249
248   - List<EntityInfo> deviceProfileInfos = deviceProfiles.stream().map(deviceProfile -> new EntityInfo(deviceProfile.getId(),
249   - deviceProfile.getName())).collect(Collectors.toList());
  250 + List<DeviceProfileInfo> deviceProfileInfos = deviceProfiles.stream().map(deviceProfile -> new DeviceProfileInfo(deviceProfile.getId(),
  251 + deviceProfile.getName(), deviceProfile.getType())).collect(Collectors.toList());
250 252
251 253 Assert.assertEquals(deviceProfileInfos, loadedDeviceProfileInfos);
252 254
... ... @@ -261,7 +263,4 @@ public class BaseDeviceProfileServiceTest extends AbstractServiceTest {
261 263 Assert.assertFalse(pageData.hasNext());
262 264 Assert.assertEquals(1, pageData.getTotalElements());
263 265 }
264   -
265   -
266   -
267 266 }
... ...
... ... @@ -287,7 +287,7 @@ public abstract class BaseDeviceServiceTest extends AbstractServiceTest {
287 287 name = i % 2 == 0 ? name.toLowerCase() : name.toUpperCase();
288 288 device.setName(name);
289 289 device.setType("default");
290   - devicesTitle1.add(new DeviceInfo(deviceService.saveDevice(device), null, false));
  290 + devicesTitle1.add(new DeviceInfo(deviceService.saveDevice(device), null, false, "Default"));
291 291 }
292 292 String title2 = "Device title 2";
293 293 List<DeviceInfo> devicesTitle2 = new ArrayList<>();
... ... @@ -299,7 +299,7 @@ public abstract class BaseDeviceServiceTest extends AbstractServiceTest {
299 299 name = i % 2 == 0 ? name.toLowerCase() : name.toUpperCase();
300 300 device.setName(name);
301 301 device.setType("default");
302   - devicesTitle2.add(new DeviceInfo(deviceService.saveDevice(device), null, false));
  302 + devicesTitle2.add(new DeviceInfo(deviceService.saveDevice(device), null, false, "Default"));
303 303 }
304 304
305 305 List<DeviceInfo> loadedDevicesTitle1 = new ArrayList<>();
... ... @@ -452,7 +452,7 @@ public abstract class BaseDeviceServiceTest extends AbstractServiceTest {
452 452 device.setName("Device"+i);
453 453 device.setType("default");
454 454 device = deviceService.saveDevice(device);
455   - devices.add(new DeviceInfo(deviceService.assignDeviceToCustomer(tenantId, device.getId(), customerId), customer.getTitle(), customer.isPublic()));
  455 + devices.add(new DeviceInfo(deviceService.assignDeviceToCustomer(tenantId, device.getId(), customerId), customer.getTitle(), customer.isPublic(), "Default"));
456 456 }
457 457
458 458 List<DeviceInfo> loadedDevices = new ArrayList<>();
... ...
... ... @@ -19,6 +19,7 @@ import org.apache.commons.lang3.RandomStringUtils;
19 19 import org.junit.Assert;
20 20 import org.junit.Test;
21 21 import org.thingsboard.server.common.data.Tenant;
  22 +import org.thingsboard.server.common.data.TenantInfo;
22 23 import org.thingsboard.server.common.data.page.PageData;
23 24 import org.thingsboard.server.common.data.page.PageLink;
24 25 import org.thingsboard.server.dao.exception.DataValidationException;
... ... @@ -26,6 +27,7 @@ import org.thingsboard.server.dao.exception.DataValidationException;
26 27 import java.util.ArrayList;
27 28 import java.util.Collections;
28 29 import java.util.List;
  30 +import java.util.stream.Collectors;
29 31
30 32 public abstract class BaseTenantServiceTest extends AbstractServiceTest {
31 33
... ... @@ -59,6 +61,17 @@ public abstract class BaseTenantServiceTest extends AbstractServiceTest {
59 61 Assert.assertEquals(savedTenant, foundTenant);
60 62 tenantService.deleteTenant(savedTenant.getId());
61 63 }
  64 +
  65 + @Test
  66 + public void testFindTenantInfoById() {
  67 + Tenant tenant = new Tenant();
  68 + tenant.setTitle("My tenant");
  69 + Tenant savedTenant = tenantService.saveTenant(tenant);
  70 + TenantInfo foundTenant = tenantService.findTenantInfoById(savedTenant.getId());
  71 + Assert.assertNotNull(foundTenant);
  72 + Assert.assertEquals(new TenantInfo(savedTenant, "Default"), foundTenant);
  73 + tenantService.deleteTenant(savedTenant.getId());
  74 + }
62 75
63 76 @Test(expected = DataValidationException.class)
64 77 public void testSaveTenantWithEmptyTitle() {
... ... @@ -116,9 +129,7 @@ public abstract class BaseTenantServiceTest extends AbstractServiceTest {
116 129 Assert.assertEquals(tenants, loadedTenants);
117 130
118 131 for (Tenant tenant : loadedTenants) {
119   - if (!tenant.getTitle().equals("Tenant")) {
120   - tenantService.deleteTenant(tenant.getId());
121   - }
  132 + tenantService.deleteTenant(tenant.getId());
122 133 }
123 134
124 135 pageLink = new PageLink(17);
... ... @@ -200,4 +211,46 @@ public abstract class BaseTenantServiceTest extends AbstractServiceTest {
200 211 Assert.assertFalse(pageData.hasNext());
201 212 Assert.assertEquals(0, pageData.getData().size());
202 213 }
  214 +
  215 + @Test
  216 + public void testFindTenantInfos() {
  217 +
  218 + List<TenantInfo> tenants = new ArrayList<>();
  219 + PageLink pageLink = new PageLink(17);
  220 + PageData<TenantInfo> pageData = tenantService.findTenantInfos(pageLink);
  221 + Assert.assertFalse(pageData.hasNext());
  222 + Assert.assertTrue(pageData.getData().isEmpty());
  223 + tenants.addAll(pageData.getData());
  224 +
  225 + for (int i=0;i<156;i++) {
  226 + Tenant tenant = new Tenant();
  227 + tenant.setTitle("Tenant"+i);
  228 + tenants.add(new TenantInfo(tenantService.saveTenant(tenant), "Default"));
  229 + }
  230 +
  231 + List<TenantInfo> loadedTenants = new ArrayList<>();
  232 + pageLink = new PageLink(17);
  233 + do {
  234 + pageData = tenantService.findTenantInfos(pageLink);
  235 + loadedTenants.addAll(pageData.getData());
  236 + if (pageData.hasNext()) {
  237 + pageLink = pageLink.nextPageLink();
  238 + }
  239 + } while (pageData.hasNext());
  240 +
  241 + Collections.sort(tenants, idComparator);
  242 + Collections.sort(loadedTenants, idComparator);
  243 +
  244 + Assert.assertEquals(tenants, loadedTenants);
  245 +
  246 + for (TenantInfo tenant : loadedTenants) {
  247 + tenantService.deleteTenant(tenant.getId());
  248 + }
  249 +
  250 + pageLink = new PageLink(17);
  251 + pageData = tenantService.findTenantInfos(pageLink);
  252 + Assert.assertFalse(pageData.hasNext());
  253 + Assert.assertTrue(pageData.getData().isEmpty());
  254 +
  255 + }
203 256 }
... ...