Browse Source

Introduce DeviceProfileInfo, release 3.2 upgrade script.

pull/3477/head
Igor Kulikov 6 years ago
parent
commit
266af3c1a2
  1. 42
      application/src/main/data/upgrade/3.1.1/schema_update.sql
  2. 28
      application/src/main/data/upgrade/3.1.1/schema_update_after.sql
  3. 79
      application/src/main/data/upgrade/3.1.1/schema_update_before.sql
  4. 13
      application/src/main/java/org/thingsboard/server/controller/BaseController.java
  5. 8
      application/src/main/java/org/thingsboard/server/controller/DeviceProfileController.java
  6. 30
      application/src/main/java/org/thingsboard/server/controller/TenantController.java
  7. 2
      application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java
  8. 43
      application/src/main/java/org/thingsboard/server/service/install/DefaultSystemDataLoaderService.java
  9. 59
      application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java
  10. 2
      application/src/main/java/org/thingsboard/server/service/install/SystemDataLoaderService.java
  11. 26
      application/src/test/java/org/thingsboard/server/controller/BaseDeviceProfileControllerTest.java
  12. 77
      application/src/test/java/org/thingsboard/server/controller/BaseTenantControllerTest.java
  13. 9
      common/dao-api/src/main/java/org/thingsboard/server/dao/device/DeviceProfileService.java
  14. 5
      common/dao-api/src/main/java/org/thingsboard/server/dao/tenant/TenantService.java
  15. 4
      common/data/src/main/java/org/thingsboard/server/common/data/DeviceInfo.java
  16. 48
      common/data/src/main/java/org/thingsboard/server/common/data/DeviceProfileInfo.java
  17. 4
      common/data/src/main/java/org/thingsboard/server/common/data/EntityInfo.java
  18. 39
      common/data/src/main/java/org/thingsboard/server/common/data/TenantInfo.java
  19. 8
      dao/src/main/java/org/thingsboard/server/dao/device/DeviceProfileDao.java
  20. 19
      dao/src/main/java/org/thingsboard/server/dao/device/DeviceProfileServiceImpl.java
  21. 13
      dao/src/main/java/org/thingsboard/server/dao/device/DeviceServiceImpl.java
  22. 161
      dao/src/main/java/org/thingsboard/server/dao/model/sql/AbstractTenantEntity.java
  23. 8
      dao/src/main/java/org/thingsboard/server/dao/model/sql/DeviceInfoEntity.java
  24. 104
      dao/src/main/java/org/thingsboard/server/dao/model/sql/TenantEntity.java
  25. 49
      dao/src/main/java/org/thingsboard/server/dao/model/sql/TenantInfoEntity.java
  26. 18
      dao/src/main/java/org/thingsboard/server/dao/sql/device/DeviceProfileRepository.java
  27. 15
      dao/src/main/java/org/thingsboard/server/dao/sql/device/DeviceRepository.java
  28. 8
      dao/src/main/java/org/thingsboard/server/dao/sql/device/JpaDeviceProfileDao.java
  29. 16
      dao/src/main/java/org/thingsboard/server/dao/sql/tenant/JpaTenantDao.java
  30. 16
      dao/src/main/java/org/thingsboard/server/dao/sql/tenant/TenantRepository.java
  31. 7
      dao/src/main/java/org/thingsboard/server/dao/tenant/TenantDao.java
  32. 17
      dao/src/main/java/org/thingsboard/server/dao/tenant/TenantServiceImpl.java
  33. 2
      dao/src/main/resources/sql/schema-entities-hsql.sql
  34. 4
      dao/src/main/resources/sql/schema-entities.sql
  35. 21
      dao/src/test/java/org/thingsboard/server/dao/service/BaseDeviceProfileServiceTest.java
  36. 6
      dao/src/test/java/org/thingsboard/server/dao/service/BaseDeviceServiceTest.java
  37. 59
      dao/src/test/java/org/thingsboard/server/dao/service/BaseTenantServiceTest.java

42
application/src/main/data/upgrade/3.1.1/schema_update.sql

@ -1,42 +0,0 @@
--
-- Copyright © 2016-2020 The Thingsboard Authors
--
-- Licensed under the Apache License, Version 2.0 (the "License");
-- you may not use this file except in compliance with the License.
-- You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.
--
ALTER TABLE device ADD COLUMN device_profile_id uuid;
ALTER TABLE tenant ADD COLUMN tenant_profile_id uuid;
CREATE TABLE IF NOT EXISTS device_profile (
id uuid NOT NULL CONSTRAINT device_profile_pkey PRIMARY KEY,
created_time bigint NOT NULL,
name varchar(255),
profile_data varchar,
description varchar,
search_text varchar(255),
default boolean,
tenant_id uuid,
default_rule_chain_id uuid
);
CREATE TABLE IF NOT EXISTS tenant_profile (
id uuid NOT NULL CONSTRAINT tenant_profile_pkey PRIMARY KEY,
created_time bigint NOT NULL,
name varchar(255),
profile_data varchar,
description varchar,
search_text varchar(255),
default boolean,
isolated_tb_core boolean,
isolated_tb_rule_engine boolean
);

28
application/src/main/data/upgrade/3.1.1/schema_update_after.sql

@ -0,0 +1,28 @@
--
-- Copyright © 2016-2020 The Thingsboard Authors
--
-- Licensed under the Apache License, Version 2.0 (the "License");
-- you may not use this file except in compliance with the License.
-- You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.
--
DROP PROCEDURE IF EXISTS update_tenant_profiles;
DROP PROCEDURE IF EXISTS update_device_profiles;
ALTER TABLE tenant ALTER COLUMN tenant_profile_id SET NOT NULL;
ALTER TABLE tenant DROP CONSTRAINT IF EXISTS fk_tenant_profile;
ALTER TABLE tenant ADD CONSTRAINT fk_tenant_profile FOREIGN KEY (tenant_profile_id) REFERENCES tenant_profile(id);
ALTER TABLE tenant DROP COLUMN IF EXISTS isolated_tb_core;
ALTER TABLE tenant DROP COLUMN IF EXISTS isolated_tb_rule_engine;
ALTER TABLE device ALTER COLUMN device_profile_id SET NOT NULL;
ALTER TABLE device DROP CONSTRAINT IF EXISTS fk_device_profile;
ALTER TABLE device ADD CONSTRAINT fk_device_profile FOREIGN KEY (device_profile_id) REFERENCES device_profile(id);

79
application/src/main/data/upgrade/3.1.1/schema_update_before.sql

@ -0,0 +1,79 @@
--
-- Copyright © 2016-2020 The Thingsboard Authors
--
-- Licensed under the Apache License, Version 2.0 (the "License");
-- you may not use this file except in compliance with the License.
-- You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.
--
CREATE TABLE IF NOT EXISTS device_profile (
id uuid NOT NULL CONSTRAINT device_profile_pkey PRIMARY KEY,
created_time bigint NOT NULL,
name varchar(255),
type varchar(255),
profile_data varchar,
description varchar,
search_text varchar(255),
is_default boolean,
tenant_id uuid,
default_rule_chain_id uuid,
CONSTRAINT device_profile_name_unq_key UNIQUE (tenant_id, name)
);
CREATE TABLE IF NOT EXISTS tenant_profile (
id uuid NOT NULL CONSTRAINT tenant_profile_pkey PRIMARY KEY,
created_time bigint NOT NULL,
name varchar(255),
profile_data varchar,
description varchar,
search_text varchar(255),
is_default boolean,
isolated_tb_core boolean,
isolated_tb_rule_engine boolean,
CONSTRAINT tenant_profile_name_unq_key UNIQUE (name)
);
CREATE OR REPLACE PROCEDURE update_tenant_profiles()
LANGUAGE plpgsql AS
$$
BEGIN
UPDATE tenant as t SET tenant_profile_id = p.id
FROM
(SELECT id from tenant_profile WHERE isolated_tb_core = false AND isolated_tb_rule_engine = false) as p
WHERE t.tenant_profile_id IS NULL AND t.isolated_tb_core = false AND t.isolated_tb_rule_engine = false;
UPDATE tenant as t SET tenant_profile_id = p.id
FROM
(SELECT id from tenant_profile WHERE isolated_tb_core = true AND isolated_tb_rule_engine = false) as p
WHERE t.tenant_profile_id IS NULL AND t.isolated_tb_core = true AND t.isolated_tb_rule_engine = false;
UPDATE tenant as t SET tenant_profile_id = p.id
FROM
(SELECT id from tenant_profile WHERE isolated_tb_core = false AND isolated_tb_rule_engine = true) as p
WHERE t.tenant_profile_id IS NULL AND t.isolated_tb_core = false AND t.isolated_tb_rule_engine = true;
UPDATE tenant as t SET tenant_profile_id = p.id
FROM
(SELECT id from tenant_profile WHERE isolated_tb_core = true AND isolated_tb_rule_engine = true) as p
WHERE t.tenant_profile_id IS NULL AND t.isolated_tb_core = true AND t.isolated_tb_rule_engine = true;
END;
$$;
CREATE OR REPLACE PROCEDURE update_device_profiles()
LANGUAGE plpgsql AS
$$
BEGIN
UPDATE device as d SET device_profile_id = p.id, device_data = '{"configuration":{"type":"DEFAULT"}}'
FROM
(SELECT id, tenant_id from device_profile WHERE is_default = true) as p
WHERE d.device_profile_id IS NULL AND p.tenant_id = d.tenant_id;
END;
$$;

13
application/src/main/java/org/thingsboard/server/controller/BaseController.java

@ -40,6 +40,7 @@ import org.thingsboard.server.common.data.EntityViewInfo;
import org.thingsboard.server.common.data.HasName;
import org.thingsboard.server.common.data.HasTenantId;
import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.TenantInfo;
import org.thingsboard.server.common.data.TenantProfile;
import org.thingsboard.server.common.data.User;
import org.thingsboard.server.common.data.alarm.Alarm;
@ -324,6 +325,18 @@ public abstract class BaseController {
}
}
TenantInfo checkTenantInfoId(TenantId tenantId, Operation operation) throws ThingsboardException {
try {
validateId(tenantId, INCORRECT_TENANT_ID + tenantId);
TenantInfo tenant = tenantService.findTenantInfoById(tenantId);
checkNotNull(tenant);
accessControlService.checkPermission(getCurrentUser(), Resource.TENANT, operation, tenantId, tenant);
return tenant;
} catch (Exception e) {
throw handleException(e, false);
}
}
TenantProfile checkTenantProfileId(TenantProfileId tenantProfileId, Operation operation) throws ThingsboardException {
try {
validateId(tenantProfileId, "Incorrect tenantProfileId " + tenantProfileId);

8
application/src/main/java/org/thingsboard/server/controller/DeviceProfileController.java

@ -27,7 +27,7 @@ import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import org.thingsboard.server.common.data.DeviceProfile;
import org.thingsboard.server.common.data.EntityInfo;
import org.thingsboard.server.common.data.DeviceProfileInfo;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.audit.ActionType;
import org.thingsboard.server.common.data.exception.ThingsboardException;
@ -60,7 +60,7 @@ public class DeviceProfileController extends BaseController {
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
@RequestMapping(value = "/deviceProfileInfo/{deviceProfileId}", method = RequestMethod.GET)
@ResponseBody
public EntityInfo getDeviceProfileInfoById(@PathVariable("deviceProfileId") String strDeviceProfileId) throws ThingsboardException {
public DeviceProfileInfo getDeviceProfileInfoById(@PathVariable("deviceProfileId") String strDeviceProfileId) throws ThingsboardException {
checkParameter("deviceProfileId", strDeviceProfileId);
try {
DeviceProfileId deviceProfileId = new DeviceProfileId(toUUID(strDeviceProfileId));
@ -73,7 +73,7 @@ public class DeviceProfileController extends BaseController {
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
@RequestMapping(value = "/deviceProfileInfo/default", method = RequestMethod.GET)
@ResponseBody
public EntityInfo getDefaultDeviceProfileInfo() throws ThingsboardException {
public DeviceProfileInfo getDefaultDeviceProfileInfo() throws ThingsboardException {
try {
return checkNotNull(deviceProfileService.findDefaultDeviceProfileInfo(getTenantId()));
} catch (Exception e) {
@ -177,7 +177,7 @@ public class DeviceProfileController extends BaseController {
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
@RequestMapping(value = "/deviceProfileInfos", params = {"pageSize", "page"}, method = RequestMethod.GET)
@ResponseBody
public PageData<EntityInfo> getDeviceProfileInfos(@RequestParam int pageSize,
public PageData<DeviceProfileInfo> getDeviceProfileInfos(@RequestParam int pageSize,
@RequestParam int page,
@RequestParam(required = false) String textSearch,
@RequestParam(required = false) String sortProperty,

30
application/src/main/java/org/thingsboard/server/controller/TenantController.java

@ -28,6 +28,7 @@ import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.TenantInfo;
import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.page.PageData;
@ -64,6 +65,19 @@ public class TenantController extends BaseController {
}
}
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')")
@RequestMapping(value = "/tenant/info/{tenantId}", method = RequestMethod.GET)
@ResponseBody
public TenantInfo getTenantInfoById(@PathVariable("tenantId") String strTenantId) throws ThingsboardException {
checkParameter("tenantId", strTenantId);
try {
TenantId tenantId = new TenantId(toUUID(strTenantId));
return checkTenantInfoId(tenantId, Operation.READ);
} catch (Exception e) {
throw handleException(e);
}
}
@PreAuthorize("hasAuthority('SYS_ADMIN')")
@RequestMapping(value = "/tenant", method = RequestMethod.POST)
@ResponseBody
@ -114,4 +128,20 @@ public class TenantController extends BaseController {
}
}
@PreAuthorize("hasAuthority('SYS_ADMIN')")
@RequestMapping(value = "/tenantInfos", params = {"pageSize", "page"}, method = RequestMethod.GET)
@ResponseBody
public PageData<TenantInfo> getTenantInfos(@RequestParam int pageSize,
@RequestParam int page,
@RequestParam(required = false) String textSearch,
@RequestParam(required = false) String sortProperty,
@RequestParam(required = false) String sortOrder) throws ThingsboardException {
try {
PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder);
return checkNotNull(tenantService.findTenantInfos(pageLink));
} catch (Exception e) {
throw handleException(e);
}
}
}

2
application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java

@ -209,7 +209,7 @@ public class ThingsboardInstallService {
componentDiscoveryService.discoverComponents();
systemDataLoaderService.createSysAdmin();
systemDataLoaderService.createDefaultTenantProfile();
systemDataLoaderService.createDefaultTenantProfiles();
systemDataLoaderService.createAdminSettings();
systemDataLoaderService.loadSystemWidgets();
// systemDataLoaderService.loadSystemPlugins();

43
application/src/main/java/org/thingsboard/server/service/install/DefaultSystemDataLoaderService.java

@ -29,6 +29,7 @@ import org.thingsboard.server.common.data.DataConstants;
import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.TenantProfile;
import org.thingsboard.server.common.data.TenantProfileData;
import org.thingsboard.server.common.data.User;
import org.thingsboard.server.common.data.asset.Asset;
import org.thingsboard.server.common.data.id.CustomerId;
@ -48,6 +49,7 @@ import org.thingsboard.server.dao.attributes.AttributesService;
import org.thingsboard.server.dao.customer.CustomerService;
import org.thingsboard.server.dao.device.DeviceCredentialsService;
import org.thingsboard.server.dao.device.DeviceService;
import org.thingsboard.server.dao.exception.DataValidationException;
import org.thingsboard.server.dao.relation.RelationService;
import org.thingsboard.server.dao.settings.AdminSettingsService;
import org.thingsboard.server.dao.tenant.TenantProfileService;
@ -116,8 +118,47 @@ public class DefaultSystemDataLoaderService implements SystemDataLoaderService {
}
@Override
public void createDefaultTenantProfile() throws Exception {
public void createDefaultTenantProfiles() throws Exception {
tenantProfileService.findOrCreateDefaultTenantProfile(TenantId.SYS_TENANT_ID);
TenantProfile isolatedTbCoreProfile = new TenantProfile();
isolatedTbCoreProfile.setDefault(false);
isolatedTbCoreProfile.setName("Isolated TB Core");
isolatedTbCoreProfile.setProfileData(new TenantProfileData());
isolatedTbCoreProfile.setDescription("Isolated TB Core tenant profile");
isolatedTbCoreProfile.setIsolatedTbCore(true);
isolatedTbCoreProfile.setIsolatedTbRuleEngine(false);
try {
tenantProfileService.saveTenantProfile(TenantId.SYS_TENANT_ID, isolatedTbCoreProfile);
} catch (DataValidationException e) {
log.warn(e.getMessage());
}
TenantProfile isolatedTbRuleEngineProfile = new TenantProfile();
isolatedTbRuleEngineProfile.setDefault(false);
isolatedTbRuleEngineProfile.setName("Isolated TB Rule Engine");
isolatedTbRuleEngineProfile.setProfileData(new TenantProfileData());
isolatedTbRuleEngineProfile.setDescription("Isolated TB Rule Engine tenant profile");
isolatedTbRuleEngineProfile.setIsolatedTbCore(false);
isolatedTbRuleEngineProfile.setIsolatedTbRuleEngine(true);
try {
tenantProfileService.saveTenantProfile(TenantId.SYS_TENANT_ID, isolatedTbRuleEngineProfile);
} catch (DataValidationException e) {
log.warn(e.getMessage());
}
TenantProfile isolatedTbCoreAndTbRuleEngineProfile = new TenantProfile();
isolatedTbCoreAndTbRuleEngineProfile.setDefault(false);
isolatedTbCoreAndTbRuleEngineProfile.setName("Isolated TB Core and TB Rule Engine");
isolatedTbCoreAndTbRuleEngineProfile.setProfileData(new TenantProfileData());
isolatedTbCoreAndTbRuleEngineProfile.setDescription("Isolated TB Core and TB Rule Engine tenant profile");
isolatedTbCoreAndTbRuleEngineProfile.setIsolatedTbCore(true);
isolatedTbCoreAndTbRuleEngineProfile.setIsolatedTbRuleEngine(true);
try {
tenantProfileService.saveTenantProfile(TenantId.SYS_TENANT_ID, isolatedTbCoreAndTbRuleEngineProfile);
} catch (DataValidationException e) {
log.warn(e.getMessage());
}
}
@Override

59
application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java

@ -20,7 +20,12 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Service;
import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.dao.dashboard.DashboardService;
import org.thingsboard.server.dao.device.DeviceProfileService;
import org.thingsboard.server.dao.tenant.TenantService;
import org.thingsboard.server.service.install.sql.SqlDbHelper;
import java.nio.charset.Charset;
@ -76,6 +81,16 @@ public class SqlDatabaseUpgradeService implements DatabaseEntitiesUpgradeService
@Autowired
private InstallScripts installScripts;
@Autowired
private SystemDataLoaderService systemDataLoaderService;
@Autowired
private TenantService tenantService;
@Autowired
private DeviceProfileService deviceProfileService;
@Override
public void upgradeDatabase(String fromVersion) throws Exception {
switch (fromVersion) {
@ -306,9 +321,49 @@ public class SqlDatabaseUpgradeService implements DatabaseEntitiesUpgradeService
case "3.1.1":
try (Connection conn = DriverManager.getConnection(dbUrl, dbUserName, dbPassword)) {
log.info("Updating schema ...");
schemaUpdateFile = Paths.get(installScripts.getDataDir(), "upgrade", "3.1.1", SCHEMA_UPDATE_SQL);
loadSql(schemaUpdateFile, conn);
if (isOldSchema(conn, 3001000)) {
try {
conn.createStatement().execute("ALTER TABLE device ADD COLUMN device_profile_id uuid, ADD COLUMN device_data varchar");
} catch (Exception e) {
}
try {
conn.createStatement().execute("ALTER TABLE tenant ADD COLUMN tenant_profile_id uuid");
} catch (Exception e) {
}
schemaUpdateFile = Paths.get(installScripts.getDataDir(), "upgrade", "3.1.1", "schema_update_before.sql");
loadSql(schemaUpdateFile, conn);
log.info("Creating default tenant profiles...");
systemDataLoaderService.createDefaultTenantProfiles();
log.info("Updating tenant profiles...");
conn.createStatement().execute("call update_tenant_profiles()");
log.info("Creating default device profiles...");
PageLink pageLink = new PageLink(100);
PageData<Tenant> pageData;
do {
pageData = tenantService.findTenants(pageLink);
for (Tenant tenant : pageData.getData()) {
deviceProfileService.findOrCreateDefaultDeviceProfile(tenant.getId());
}
pageLink = pageLink.nextPageLink();
} while (pageData.hasNext());
log.info("Updating device profiles...");
conn.createStatement().execute("call update_device_profiles()");
schemaUpdateFile = Paths.get(installScripts.getDataDir(), "upgrade", "3.1.1", "schema_update_after.sql");
loadSql(schemaUpdateFile, conn);
conn.createStatement().execute("UPDATE tb_schema_settings SET schema_version = 3002000;");
}
log.info("Schema updated.");
} catch (Exception e) {
log.error("Failed updating schema!!!", e);
}
break;
default:

2
application/src/main/java/org/thingsboard/server/service/install/SystemDataLoaderService.java

@ -19,7 +19,7 @@ public interface SystemDataLoaderService {
void createSysAdmin() throws Exception;
void createDefaultTenantProfile() throws Exception;
void createDefaultTenantProfiles() throws Exception;
void createAdminSettings() throws Exception;

26
application/src/test/java/org/thingsboard/server/controller/BaseDeviceProfileControllerTest.java

@ -22,8 +22,8 @@ import org.junit.Before;
import org.junit.Test;
import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.DeviceProfile;
import org.thingsboard.server.common.data.DeviceProfileInfo;
import org.thingsboard.server.common.data.DeviceProfileType;
import org.thingsboard.server.common.data.EntityInfo;
import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.User;
import org.thingsboard.server.common.data.page.PageData;
@ -41,7 +41,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
public abstract class BaseDeviceProfileControllerTest extends AbstractControllerTest {
private IdComparator<DeviceProfile> idComparator = new IdComparator<>();
private IdComparator<EntityInfo> deviceProfileInfoIdComparator = new IdComparator<>();
private IdComparator<DeviceProfileInfo> deviceProfileInfoIdComparator = new IdComparator<>();
private Tenant savedTenant;
private User tenantAdmin;
@ -104,18 +104,21 @@ public abstract class BaseDeviceProfileControllerTest extends AbstractController
public void testFindDeviceProfileInfoById() throws Exception {
DeviceProfile deviceProfile = this.createDeviceProfile("Device Profile");
DeviceProfile savedDeviceProfile = doPost("/api/deviceProfile", deviceProfile, DeviceProfile.class);
EntityInfo foundDeviceProfileInfo = doGet("/api/deviceProfileInfo/"+savedDeviceProfile.getId().getId().toString(), EntityInfo.class);
DeviceProfileInfo foundDeviceProfileInfo = doGet("/api/deviceProfileInfo/"+savedDeviceProfile.getId().getId().toString(), DeviceProfileInfo.class);
Assert.assertNotNull(foundDeviceProfileInfo);
Assert.assertEquals(savedDeviceProfile.getId(), foundDeviceProfileInfo.getId());
Assert.assertEquals(savedDeviceProfile.getName(), foundDeviceProfileInfo.getName());
Assert.assertEquals(savedDeviceProfile.getType(), foundDeviceProfileInfo.getType());
}
@Test
public void testFindDefaultDeviceProfileInfo() throws Exception {
EntityInfo foundDefaultDeviceProfileInfo = doGet("/api/deviceProfileInfo/default", EntityInfo.class);
DeviceProfileInfo foundDefaultDeviceProfileInfo = doGet("/api/deviceProfileInfo/default", DeviceProfileInfo.class);
Assert.assertNotNull(foundDefaultDeviceProfileInfo);
Assert.assertNotNull(foundDefaultDeviceProfileInfo.getId());
Assert.assertNotNull(foundDefaultDeviceProfileInfo.getName());
Assert.assertNotNull(foundDefaultDeviceProfileInfo.getType());
Assert.assertEquals(DeviceProfileType.DEFAULT, foundDefaultDeviceProfileInfo.getType());
Assert.assertEquals("Default", foundDefaultDeviceProfileInfo.getName());
}
@ -125,10 +128,11 @@ public abstract class BaseDeviceProfileControllerTest extends AbstractController
DeviceProfile savedDeviceProfile = doPost("/api/deviceProfile", deviceProfile, DeviceProfile.class);
DeviceProfile defaultDeviceProfile = doPost("/api/deviceProfile/"+savedDeviceProfile.getId().getId().toString()+"/default", null, DeviceProfile.class);
Assert.assertNotNull(defaultDeviceProfile);
EntityInfo foundDefaultDeviceProfile = doGet("/api/deviceProfileInfo/default", EntityInfo.class);
DeviceProfileInfo foundDefaultDeviceProfile = doGet("/api/deviceProfileInfo/default", DeviceProfileInfo.class);
Assert.assertNotNull(foundDefaultDeviceProfile);
Assert.assertEquals(savedDeviceProfile.getName(), foundDefaultDeviceProfile.getName());
Assert.assertEquals(savedDeviceProfile.getId(), foundDefaultDeviceProfile.getId());
Assert.assertEquals(savedDeviceProfile.getType(), foundDefaultDeviceProfile.getType());
}
@Test
@ -245,12 +249,12 @@ public abstract class BaseDeviceProfileControllerTest extends AbstractController
deviceProfiles.add(doPost("/api/deviceProfile", deviceProfile, DeviceProfile.class));
}
List<EntityInfo> loadedDeviceProfileInfos = new ArrayList<>();
List<DeviceProfileInfo> loadedDeviceProfileInfos = new ArrayList<>();
pageLink = new PageLink(17);
PageData<EntityInfo> pageData;
PageData<DeviceProfileInfo> pageData;
do {
pageData = doGetTypedWithPageLink("/api/deviceProfileInfos?",
new TypeReference<PageData<EntityInfo>>(){}, pageLink);
new TypeReference<PageData<DeviceProfileInfo>>(){}, pageLink);
loadedDeviceProfileInfos.addAll(pageData.getData());
if (pageData.hasNext()) {
pageLink = pageLink.nextPageLink();
@ -260,8 +264,8 @@ public abstract class BaseDeviceProfileControllerTest extends AbstractController
Collections.sort(deviceProfiles, idComparator);
Collections.sort(loadedDeviceProfileInfos, deviceProfileInfoIdComparator);
List<EntityInfo> deviceProfileInfos = deviceProfiles.stream().map(deviceProfile -> new EntityInfo(deviceProfile.getId(),
deviceProfile.getName())).collect(Collectors.toList());
List<DeviceProfileInfo> deviceProfileInfos = deviceProfiles.stream().map(deviceProfile -> new DeviceProfileInfo(deviceProfile.getId(),
deviceProfile.getName(), deviceProfile.getType())).collect(Collectors.toList());
Assert.assertEquals(deviceProfileInfos, loadedDeviceProfileInfos);
@ -274,7 +278,7 @@ public abstract class BaseDeviceProfileControllerTest extends AbstractController
pageLink = new PageLink(17);
pageData = doGetTypedWithPageLink("/api/deviceProfileInfos?",
new TypeReference<PageData<EntityInfo>>(){}, pageLink);
new TypeReference<PageData<DeviceProfileInfo>>(){}, pageLink);
Assert.assertFalse(pageData.hasNext());
Assert.assertEquals(1, pageData.getTotalElements());
}

77
application/src/test/java/org/thingsboard/server/controller/BaseTenantControllerTest.java

@ -15,21 +15,21 @@
*/
package org.thingsboard.server.controller;
import static org.hamcrest.Matchers.containsString;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import com.fasterxml.jackson.core.type.TypeReference;
import org.apache.commons.lang3.RandomStringUtils;
import org.junit.Assert;
import org.junit.Test;
import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.TenantInfo;
import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink;
import org.junit.Assert;
import org.junit.Test;
import com.fasterxml.jackson.core.type.TypeReference;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import static org.hamcrest.Matchers.containsString;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
public abstract class BaseTenantControllerTest extends AbstractControllerTest {
@ -65,6 +65,19 @@ public abstract class BaseTenantControllerTest extends AbstractControllerTest {
doDelete("/api/tenant/"+savedTenant.getId().getId().toString())
.andExpect(status().isOk());
}
@Test
public void testFindTenantInfoById() throws Exception {
loginSysAdmin();
Tenant tenant = new Tenant();
tenant.setTitle("My tenant");
Tenant savedTenant = doPost("/api/tenant", tenant, Tenant.class);
TenantInfo foundTenant = doGet("/api/tenant/info/"+savedTenant.getId().getId().toString(), TenantInfo.class);
Assert.assertNotNull(foundTenant);
Assert.assertEquals(new TenantInfo(savedTenant, "Default"), foundTenant);
doDelete("/api/tenant/"+savedTenant.getId().getId().toString())
.andExpect(status().isOk());
}
@Test
public void testSaveTenantWithEmptyTitle() throws Exception {
@ -217,4 +230,48 @@ public abstract class BaseTenantControllerTest extends AbstractControllerTest {
Assert.assertFalse(pageData.hasNext());
Assert.assertEquals(0, pageData.getData().size());
}
@Test
public void testFindTenantInfos() throws Exception {
loginSysAdmin();
List<TenantInfo> tenants = new ArrayList<>();
PageLink pageLink = new PageLink(17);
PageData<TenantInfo> pageData = doGetTypedWithPageLink("/api/tenantInfos?", new TypeReference<PageData<TenantInfo>>(){}, pageLink);
Assert.assertFalse(pageData.hasNext());
Assert.assertEquals(1, pageData.getData().size());
tenants.addAll(pageData.getData());
for (int i=0;i<56;i++) {
Tenant tenant = new Tenant();
tenant.setTitle("Tenant"+i);
tenants.add(new TenantInfo(doPost("/api/tenant", tenant, Tenant.class), "Default"));
}
List<TenantInfo> loadedTenants = new ArrayList<>();
pageLink = new PageLink(17);
do {
pageData = doGetTypedWithPageLink("/api/tenantInfos?", new TypeReference<PageData<TenantInfo>>(){}, pageLink);
loadedTenants.addAll(pageData.getData());
if (pageData.hasNext()) {
pageLink = pageLink.nextPageLink();
}
} while (pageData.hasNext());
Collections.sort(tenants, idComparator);
Collections.sort(loadedTenants, idComparator);
Assert.assertEquals(tenants, loadedTenants);
for (TenantInfo tenant : loadedTenants) {
if (!tenant.getTitle().equals(TEST_TENANT_NAME)) {
doDelete("/api/tenant/"+tenant.getId().getId().toString())
.andExpect(status().isOk());
}
}
pageLink = new PageLink(17);
pageData = doGetTypedWithPageLink("/api/tenantInfos?", new TypeReference<PageData<TenantInfo>>(){}, pageLink);
Assert.assertFalse(pageData.hasNext());
Assert.assertEquals(1, pageData.getData().size());
}
}

9
common/dao-api/src/main/java/org/thingsboard/server/dao/device/DeviceProfileService.java

@ -16,6 +16,7 @@
package org.thingsboard.server.dao.device;
import org.thingsboard.server.common.data.DeviceProfile;
import org.thingsboard.server.common.data.DeviceProfileInfo;
import org.thingsboard.server.common.data.EntityInfo;
import org.thingsboard.server.common.data.id.DeviceProfileId;
import org.thingsboard.server.common.data.id.TenantId;
@ -26,7 +27,7 @@ public interface DeviceProfileService {
DeviceProfile findDeviceProfileById(TenantId tenantId, DeviceProfileId deviceProfileId);
EntityInfo findDeviceProfileInfoById(TenantId tenantId, DeviceProfileId deviceProfileId);
DeviceProfileInfo findDeviceProfileInfoById(TenantId tenantId, DeviceProfileId deviceProfileId);
DeviceProfile saveDeviceProfile(DeviceProfile deviceProfile);
@ -34,13 +35,15 @@ public interface DeviceProfileService {
PageData<DeviceProfile> findDeviceProfiles(TenantId tenantId, PageLink pageLink);
PageData<EntityInfo> findDeviceProfileInfos(TenantId tenantId, PageLink pageLink);
PageData<DeviceProfileInfo> findDeviceProfileInfos(TenantId tenantId, PageLink pageLink);
DeviceProfile findOrCreateDefaultDeviceProfile(TenantId tenantId);
DeviceProfile createDefaultDeviceProfile(TenantId tenantId);
DeviceProfile findDefaultDeviceProfile(TenantId tenantId);
EntityInfo findDefaultDeviceProfileInfo(TenantId tenantId);
DeviceProfileInfo findDefaultDeviceProfileInfo(TenantId tenantId);
boolean setDefaultDeviceProfile(TenantId tenantId, DeviceProfileId deviceProfileId);

5
common/dao-api/src/main/java/org/thingsboard/server/dao/tenant/TenantService.java

@ -17,6 +17,7 @@ package org.thingsboard.server.dao.tenant;
import com.google.common.util.concurrent.ListenableFuture;
import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.TenantInfo;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink;
@ -25,6 +26,8 @@ public interface TenantService {
Tenant findTenantById(TenantId tenantId);
TenantInfo findTenantInfoById(TenantId tenantId);
ListenableFuture<Tenant> findTenantByIdAsync(TenantId callerId, TenantId tenantId);
Tenant saveTenant(Tenant tenant);
@ -32,6 +35,8 @@ public interface TenantService {
void deleteTenant(TenantId tenantId);
PageData<Tenant> findTenants(PageLink pageLink);
PageData<TenantInfo> findTenantInfos(PageLink pageLink);
void deleteTenants();
}

4
common/data/src/main/java/org/thingsboard/server/common/data/DeviceInfo.java

@ -23,6 +23,7 @@ public class DeviceInfo extends Device {
private String customerTitle;
private boolean customerIsPublic;
private String deviceProfileName;
public DeviceInfo() {
super();
@ -32,9 +33,10 @@ public class DeviceInfo extends Device {
super(deviceId);
}
public DeviceInfo(Device device, String customerTitle, boolean customerIsPublic) {
public DeviceInfo(Device device, String customerTitle, boolean customerIsPublic, String deviceProfileName) {
super(device);
this.customerTitle = customerTitle;
this.customerIsPublic = customerIsPublic;
this.deviceProfileName = deviceProfileName;
}
}

48
common/data/src/main/java/org/thingsboard/server/common/data/DeviceProfileInfo.java

@ -0,0 +1,48 @@
/**
* Copyright © 2016-2020 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.common.data;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import lombok.Value;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.EntityIdFactory;
import java.util.UUID;
@Value
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class DeviceProfileInfo extends EntityInfo {
private final DeviceProfileType type;
@JsonCreator
public DeviceProfileInfo(@JsonProperty("id") EntityId id,
@JsonProperty("name") String name,
@JsonProperty("type") DeviceProfileType type) {
super(id, name);
this.type = type;
}
public DeviceProfileInfo(UUID uuid, String name, DeviceProfileType type) {
super(EntityIdFactory.getByTypeAndUuid(EntityType.DEVICE_PROFILE, uuid), name);
this.type = type;
}
}

4
common/data/src/main/java/org/thingsboard/server/common/data/EntityInfo.java

@ -36,8 +36,8 @@ public class EntityInfo implements HasId<EntityId>, HasName {
this.name = name;
}
public EntityInfo(UUID uuid, String type, String name) {
this.id = EntityIdFactory.getByTypeAndUuid(type, uuid);
public EntityInfo(UUID uuid, String entityType, String name) {
this.id = EntityIdFactory.getByTypeAndUuid(entityType, uuid);
this.name = name;
}

39
common/data/src/main/java/org/thingsboard/server/common/data/TenantInfo.java

@ -0,0 +1,39 @@
/**
* Copyright © 2016-2020 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.common.data;
import lombok.Data;
import org.thingsboard.server.common.data.id.TenantId;
@Data
public class TenantInfo extends Tenant {
private String tenantProfileName;
public TenantInfo() {
super();
}
public TenantInfo(TenantId tenantId) {
super(tenantId);
}
public TenantInfo(Tenant tenant, String tenantProfileName) {
super(tenant);
this.tenantProfileName = tenantProfileName;
}
}

8
dao/src/main/java/org/thingsboard/server/dao/device/DeviceProfileDao.java

@ -16,7 +16,7 @@
package org.thingsboard.server.dao.device;
import org.thingsboard.server.common.data.DeviceProfile;
import org.thingsboard.server.common.data.EntityInfo;
import org.thingsboard.server.common.data.DeviceProfileInfo;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink;
@ -26,15 +26,15 @@ import java.util.UUID;
public interface DeviceProfileDao extends Dao<DeviceProfile> {
EntityInfo findDeviceProfileInfoById(TenantId tenantId, UUID deviceProfileId);
DeviceProfileInfo findDeviceProfileInfoById(TenantId tenantId, UUID deviceProfileId);
DeviceProfile save(TenantId tenantId, DeviceProfile deviceProfile);
PageData<DeviceProfile> findDeviceProfiles(TenantId tenantId, PageLink pageLink);
PageData<EntityInfo> findDeviceProfileInfos(TenantId tenantId, PageLink pageLink);
PageData<DeviceProfileInfo> findDeviceProfileInfos(TenantId tenantId, PageLink pageLink);
DeviceProfile findDefaultDeviceProfile(TenantId tenantId);
EntityInfo findDefaultDeviceProfileInfo(TenantId tenantId);
DeviceProfileInfo findDefaultDeviceProfileInfo(TenantId tenantId);
}

19
dao/src/main/java/org/thingsboard/server/dao/device/DeviceProfileServiceImpl.java

@ -24,8 +24,8 @@ import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.thingsboard.server.common.data.DeviceProfile;
import org.thingsboard.server.common.data.DeviceProfileInfo;
import org.thingsboard.server.common.data.DeviceProfileType;
import org.thingsboard.server.common.data.EntityInfo;
import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.device.profile.DefaultDeviceProfileConfiguration;
import org.thingsboard.server.common.data.device.profile.DeviceProfileData;
@ -39,7 +39,6 @@ import org.thingsboard.server.dao.service.DataValidator;
import org.thingsboard.server.dao.service.PaginatedRemover;
import org.thingsboard.server.dao.service.Validator;
import org.thingsboard.server.dao.tenant.TenantDao;
import org.thingsboard.server.dao.util.mapping.JacksonUtil;
import java.util.Arrays;
import java.util.Collections;
@ -73,7 +72,7 @@ public class DeviceProfileServiceImpl extends AbstractEntityService implements D
@Cacheable(cacheNames = DEVICE_PROFILE_CACHE, key = "{'info', #deviceProfileId.id}")
@Override
public EntityInfo findDeviceProfileInfoById(TenantId tenantId, DeviceProfileId deviceProfileId) {
public DeviceProfileInfo findDeviceProfileInfoById(TenantId tenantId, DeviceProfileId deviceProfileId) {
log.trace("Executing findDeviceProfileById [{}]", deviceProfileId);
Validator.validateId(deviceProfileId, INCORRECT_DEVICE_PROFILE_ID + deviceProfileId);
return deviceProfileDao.findDeviceProfileInfoById(tenantId, deviceProfileId.getId());
@ -141,13 +140,23 @@ public class DeviceProfileServiceImpl extends AbstractEntityService implements D
}
@Override
public PageData<EntityInfo> findDeviceProfileInfos(TenantId tenantId, PageLink pageLink) {
public PageData<DeviceProfileInfo> findDeviceProfileInfos(TenantId tenantId, PageLink pageLink) {
log.trace("Executing findDeviceProfileInfos tenantId [{}], pageLink [{}]", tenantId, pageLink);
validateId(tenantId, INCORRECT_TENANT_ID + tenantId);
Validator.validatePageLink(pageLink);
return deviceProfileDao.findDeviceProfileInfos(tenantId, pageLink);
}
@Override
public DeviceProfile findOrCreateDefaultDeviceProfile(TenantId tenantId) {
log.trace("Executing findOrCreateDefaultDeviceProfile");
DeviceProfile deviceProfile = findDefaultDeviceProfile(tenantId);
if (deviceProfile == null) {
deviceProfile = this.createDefaultDeviceProfile(tenantId);
}
return deviceProfile;
}
@Override
public DeviceProfile createDefaultDeviceProfile(TenantId tenantId) {
log.trace("Executing createDefaultDeviceProfile tenantId [{}]", tenantId);
@ -175,7 +184,7 @@ public class DeviceProfileServiceImpl extends AbstractEntityService implements D
@Cacheable(cacheNames = DEVICE_PROFILE_CACHE, key = "{'default', 'info', #tenantId.id}")
@Override
public EntityInfo findDefaultDeviceProfileInfo(TenantId tenantId) {
public DeviceProfileInfo findDefaultDeviceProfileInfo(TenantId tenantId) {
log.trace("Executing findDefaultDeviceProfileInfo tenantId [{}]", tenantId);
validateId(tenantId, INCORRECT_TENANT_ID + tenantId);
return deviceProfileDao.findDefaultDeviceProfileInfo(tenantId);

13
dao/src/main/java/org/thingsboard/server/dao/device/DeviceServiceImpl.java

@ -35,7 +35,6 @@ import org.thingsboard.server.common.data.Customer;
import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.DeviceInfo;
import org.thingsboard.server.common.data.DeviceProfile;
import org.thingsboard.server.common.data.EntityInfo;
import org.thingsboard.server.common.data.EntitySubtype;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.EntityView;
@ -43,6 +42,7 @@ import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.device.DeviceSearchQuery;
import org.thingsboard.server.common.data.device.data.DefaultDeviceConfiguration;
import org.thingsboard.server.common.data.device.data.DeviceData;
import org.thingsboard.server.common.data.device.data.Lwm2mDeviceConfiguration;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.id.DeviceProfileId;
@ -168,10 +168,17 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe
Device savedDevice;
try {
if (device.getDeviceProfileId() == null) {
EntityInfo deviceProfile = this.deviceProfileService.findDefaultDeviceProfileInfo(device.getTenantId());
DeviceProfile deviceProfile = this.deviceProfileService.findOrCreateDefaultDeviceProfile(device.getTenantId());
device.setDeviceProfileId(new DeviceProfileId(deviceProfile.getId().getId()));
DeviceData deviceData = new DeviceData();
deviceData.setConfiguration(new DefaultDeviceConfiguration());
switch (deviceProfile.getType()) {
case DEFAULT:
deviceData.setConfiguration(new DefaultDeviceConfiguration());
break;
case LWM2M:
deviceData.setConfiguration(new Lwm2mDeviceConfiguration());
break;
}
device.setDeviceData(deviceData);
}
savedDevice = deviceDao.save(device.getTenantId(), device);

161
dao/src/main/java/org/thingsboard/server/dao/model/sql/AbstractTenantEntity.java

@ -0,0 +1,161 @@
/**
* Copyright © 2016-2020 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.dao.model.sql;
import com.fasterxml.jackson.databind.JsonNode;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.hibernate.annotations.Type;
import org.hibernate.annotations.TypeDef;
import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.id.TenantProfileId;
import org.thingsboard.server.dao.model.BaseSqlEntity;
import org.thingsboard.server.dao.model.ModelConstants;
import org.thingsboard.server.dao.model.SearchTextEntity;
import org.thingsboard.server.dao.util.mapping.JsonStringType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.MappedSuperclass;
import javax.persistence.Table;
import java.util.UUID;
@Data
@EqualsAndHashCode(callSuper = true)
@TypeDef(name = "json", typeClass = JsonStringType.class)
@MappedSuperclass
public abstract class AbstractTenantEntity<T extends Tenant> extends BaseSqlEntity<T> implements SearchTextEntity<T> {
@Column(name = ModelConstants.TENANT_TITLE_PROPERTY)
private String title;
@Column(name = ModelConstants.SEARCH_TEXT_PROPERTY)
private String searchText;
@Column(name = ModelConstants.TENANT_REGION_PROPERTY)
private String region;
@Column(name = ModelConstants.COUNTRY_PROPERTY)
private String country;
@Column(name = ModelConstants.STATE_PROPERTY)
private String state;
@Column(name = ModelConstants.CITY_PROPERTY)
private String city;
@Column(name = ModelConstants.ADDRESS_PROPERTY)
private String address;
@Column(name = ModelConstants.ADDRESS2_PROPERTY)
private String address2;
@Column(name = ModelConstants.ZIP_PROPERTY)
private String zip;
@Column(name = ModelConstants.PHONE_PROPERTY)
private String phone;
@Column(name = ModelConstants.EMAIL_PROPERTY)
private String email;
@Type(type = "json")
@Column(name = ModelConstants.TENANT_ADDITIONAL_INFO_PROPERTY)
private JsonNode additionalInfo;
@Column(name = ModelConstants.TENANT_TENANT_PROFILE_ID_PROPERTY, columnDefinition = "uuid")
private UUID tenantProfileId;
public AbstractTenantEntity() {
super();
}
public AbstractTenantEntity(Tenant tenant) {
if (tenant.getId() != null) {
this.setUuid(tenant.getId().getId());
}
this.setCreatedTime(tenant.getCreatedTime());
this.title = tenant.getTitle();
this.region = tenant.getRegion();
this.country = tenant.getCountry();
this.state = tenant.getState();
this.city = tenant.getCity();
this.address = tenant.getAddress();
this.address2 = tenant.getAddress2();
this.zip = tenant.getZip();
this.phone = tenant.getPhone();
this.email = tenant.getEmail();
this.additionalInfo = tenant.getAdditionalInfo();
if (tenant.getTenantProfileId() != null) {
this.tenantProfileId = tenant.getTenantProfileId().getId();
}
}
public AbstractTenantEntity(TenantEntity tenantEntity) {
this.setId(tenantEntity.getId());
this.setCreatedTime(tenantEntity.getCreatedTime());
this.title = tenantEntity.getTitle();
this.region = tenantEntity.getRegion();
this.country = tenantEntity.getCountry();
this.state = tenantEntity.getState();
this.city = tenantEntity.getCity();
this.address = tenantEntity.getAddress();
this.address2 = tenantEntity.getAddress2();
this.zip = tenantEntity.getZip();
this.phone = tenantEntity.getPhone();
this.email = tenantEntity.getEmail();
this.additionalInfo = tenantEntity.getAdditionalInfo();
this.tenantProfileId = tenantEntity.getTenantProfileId();
}
@Override
public String getSearchTextSource() {
return title;
}
@Override
public void setSearchText(String searchText) {
this.searchText = searchText;
}
public String getSearchText() {
return searchText;
}
protected Tenant toTenant() {
Tenant tenant = new Tenant(new TenantId(this.getUuid()));
tenant.setCreatedTime(createdTime);
tenant.setTitle(title);
tenant.setRegion(region);
tenant.setCountry(country);
tenant.setState(state);
tenant.setCity(city);
tenant.setAddress(address);
tenant.setAddress2(address2);
tenant.setZip(zip);
tenant.setPhone(phone);
tenant.setEmail(email);
tenant.setAdditionalInfo(additionalInfo);
if (tenantProfileId != null) {
tenant.setTenantProfileId(new TenantProfileId(tenantProfileId));
}
return tenant;
}
}

8
dao/src/main/java/org/thingsboard/server/dao/model/sql/DeviceInfoEntity.java

@ -30,10 +30,12 @@ public class DeviceInfoEntity extends AbstractDeviceEntity<DeviceInfo> {
public static final Map<String,String> deviceInfoColumnMap = new HashMap<>();
static {
deviceInfoColumnMap.put("customerTitle", "c.title");
deviceInfoColumnMap.put("deviceProfileName", "p.name");
}
private String customerTitle;
private boolean customerIsPublic;
private String deviceProfileName;
public DeviceInfoEntity() {
super();
@ -41,7 +43,8 @@ public class DeviceInfoEntity extends AbstractDeviceEntity<DeviceInfo> {
public DeviceInfoEntity(DeviceEntity deviceEntity,
String customerTitle,
Object customerAdditionalInfo) {
Object customerAdditionalInfo,
String deviceProfileName) {
super(deviceEntity);
this.customerTitle = customerTitle;
if (customerAdditionalInfo != null && ((JsonNode)customerAdditionalInfo).has("isPublic")) {
@ -49,10 +52,11 @@ public class DeviceInfoEntity extends AbstractDeviceEntity<DeviceInfo> {
} else {
this.customerIsPublic = false;
}
this.deviceProfileName = deviceProfileName;
}
@Override
public DeviceInfo toData() {
return new DeviceInfo(super.toDevice(), customerTitle, customerIsPublic);
return new DeviceInfo(super.toDevice(), customerTitle, customerIsPublic, deviceProfileName);
}
}

104
dao/src/main/java/org/thingsboard/server/dao/model/sql/TenantEntity.java

@ -15,131 +15,33 @@
*/
package org.thingsboard.server.dao.model.sql;
import com.fasterxml.jackson.databind.JsonNode;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.hibernate.annotations.Type;
import org.hibernate.annotations.TypeDef;
import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.id.TenantProfileId;
import org.thingsboard.server.dao.model.BaseSqlEntity;
import org.thingsboard.server.dao.model.ModelConstants;
import org.thingsboard.server.dao.model.SearchTextEntity;
import org.thingsboard.server.dao.util.mapping.JsonStringType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
import java.util.UUID;
@Data
@EqualsAndHashCode(callSuper = true)
@Entity
@TypeDef(name = "json", typeClass = JsonStringType.class)
@Table(name = ModelConstants.TENANT_COLUMN_FAMILY_NAME)
public final class TenantEntity extends BaseSqlEntity<Tenant> implements SearchTextEntity<Tenant> {
@Column(name = ModelConstants.TENANT_TITLE_PROPERTY)
private String title;
@Column(name = ModelConstants.SEARCH_TEXT_PROPERTY)
private String searchText;
@Column(name = ModelConstants.TENANT_REGION_PROPERTY)
private String region;
@Column(name = ModelConstants.COUNTRY_PROPERTY)
private String country;
@Column(name = ModelConstants.STATE_PROPERTY)
private String state;
@Column(name = ModelConstants.CITY_PROPERTY)
private String city;
@Column(name = ModelConstants.ADDRESS_PROPERTY)
private String address;
@Column(name = ModelConstants.ADDRESS2_PROPERTY)
private String address2;
@Column(name = ModelConstants.ZIP_PROPERTY)
private String zip;
@Column(name = ModelConstants.PHONE_PROPERTY)
private String phone;
@Column(name = ModelConstants.EMAIL_PROPERTY)
private String email;
@Type(type = "json")
@Column(name = ModelConstants.TENANT_ADDITIONAL_INFO_PROPERTY)
private JsonNode additionalInfo;
@Column(name = ModelConstants.TENANT_TENANT_PROFILE_ID_PROPERTY, columnDefinition = "uuid")
private UUID tenantProfileId;
public final class TenantEntity extends AbstractTenantEntity<Tenant> {
public TenantEntity() {
super();
}
public TenantEntity(Tenant tenant) {
if (tenant.getId() != null) {
this.setUuid(tenant.getId().getId());
}
this.setCreatedTime(tenant.getCreatedTime());
this.title = tenant.getTitle();
this.region = tenant.getRegion();
this.country = tenant.getCountry();
this.state = tenant.getState();
this.city = tenant.getCity();
this.address = tenant.getAddress();
this.address2 = tenant.getAddress2();
this.zip = tenant.getZip();
this.phone = tenant.getPhone();
this.email = tenant.getEmail();
this.additionalInfo = tenant.getAdditionalInfo();
if (tenant.getTenantProfileId() != null) {
this.tenantProfileId = tenant.getTenantProfileId().getId();
}
}
@Override
public String getSearchTextSource() {
return title;
}
@Override
public void setSearchText(String searchText) {
this.searchText = searchText;
}
public String getSearchText() {
return searchText;
super(tenant);
}
@Override
public Tenant toData() {
Tenant tenant = new Tenant(new TenantId(this.getUuid()));
tenant.setCreatedTime(createdTime);
tenant.setTitle(title);
tenant.setRegion(region);
tenant.setCountry(country);
tenant.setState(state);
tenant.setCity(city);
tenant.setAddress(address);
tenant.setAddress2(address2);
tenant.setZip(zip);
tenant.setPhone(phone);
tenant.setEmail(email);
tenant.setAdditionalInfo(additionalInfo);
if (tenantProfileId != null) {
tenant.setTenantProfileId(new TenantProfileId(tenantProfileId));
}
return tenant;
return super.toTenant();
}
}

49
dao/src/main/java/org/thingsboard/server/dao/model/sql/TenantInfoEntity.java

@ -0,0 +1,49 @@
/**
* Copyright © 2016-2020 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.dao.model.sql;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.thingsboard.server.common.data.TenantInfo;
import java.util.HashMap;
import java.util.Map;
@Data
@EqualsAndHashCode(callSuper = true)
public class TenantInfoEntity extends AbstractTenantEntity<TenantInfo> {
public static final Map<String,String> tenantInfoColumnMap = new HashMap<>();
static {
tenantInfoColumnMap.put("tenantProfileName", "p.name");
}
private String tenantProfileName;
public TenantInfoEntity() {
super();
}
public TenantInfoEntity(TenantEntity tenantEntity, String tenantProfileName) {
super(tenantEntity);
this.tenantProfileName = tenantProfileName;
}
@Override
public TenantInfo toData() {
return new TenantInfo(super.toTenant(), this.tenantProfileName);
}
}

18
dao/src/main/java/org/thingsboard/server/dao/sql/device/DeviceProfileRepository.java

@ -20,17 +20,17 @@ import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.data.repository.query.Param;
import org.thingsboard.server.common.data.EntityInfo;
import org.thingsboard.server.common.data.DeviceProfileInfo;
import org.thingsboard.server.dao.model.sql.DeviceProfileEntity;
import java.util.UUID;
public interface DeviceProfileRepository extends PagingAndSortingRepository<DeviceProfileEntity, UUID> {
@Query("SELECT new org.thingsboard.server.common.data.EntityInfo(d.id, 'DEVICE_PROFILE', d.name) " +
@Query("SELECT new org.thingsboard.server.common.data.DeviceProfileInfo(d.id, d.name, d.type) " +
"FROM DeviceProfileEntity d " +
"WHERE d.id = :deviceProfileId")
EntityInfo findDeviceProfileInfoById(@Param("deviceProfileId") UUID deviceProfileId);
DeviceProfileInfo findDeviceProfileInfoById(@Param("deviceProfileId") UUID deviceProfileId);
@Query("SELECT d FROM DeviceProfileEntity d WHERE " +
"d.tenantId = :tenantId AND LOWER(d.searchText) LIKE LOWER(CONCAT(:textSearch, '%'))")
@ -38,19 +38,19 @@ public interface DeviceProfileRepository extends PagingAndSortingRepository<Devi
@Param("textSearch") String textSearch,
Pageable pageable);
@Query("SELECT new org.thingsboard.server.common.data.EntityInfo(d.id, 'DEVICE_PROFILE', d.name) " +
@Query("SELECT new org.thingsboard.server.common.data.DeviceProfileInfo(d.id, d.name, d.type) " +
"FROM DeviceProfileEntity d WHERE " +
"d.tenantId = :tenantId AND LOWER(d.searchText) LIKE LOWER(CONCAT(:textSearch, '%'))")
Page<EntityInfo> findDeviceProfileInfos(@Param("tenantId") UUID tenantId,
@Param("textSearch") String textSearch,
Pageable pageable);
Page<DeviceProfileInfo> findDeviceProfileInfos(@Param("tenantId") UUID tenantId,
@Param("textSearch") String textSearch,
Pageable pageable);
@Query("SELECT d FROM DeviceProfileEntity d " +
"WHERE d.tenantId = :tenantId AND d.isDefault = true")
DeviceProfileEntity findByDefaultTrueAndTenantId(@Param("tenantId") UUID tenantId);
@Query("SELECT new org.thingsboard.server.common.data.EntityInfo(d.id, 'DEVICE_PROFILE', d.name) " +
@Query("SELECT new org.thingsboard.server.common.data.DeviceProfileInfo(d.id, d.name, d.type) " +
"FROM DeviceProfileEntity d " +
"WHERE d.tenantId = :tenantId AND d.isDefault = true")
EntityInfo findDefaultDeviceProfileInfo(@Param("tenantId") UUID tenantId);
DeviceProfileInfo findDefaultDeviceProfileInfo(@Param("tenantId") UUID tenantId);
}

15
dao/src/main/java/org/thingsboard/server/dao/sql/device/DeviceRepository.java

@ -31,9 +31,10 @@ import java.util.UUID;
*/
public interface DeviceRepository extends PagingAndSortingRepository<DeviceEntity, UUID> {
@Query("SELECT new org.thingsboard.server.dao.model.sql.DeviceInfoEntity(d, c.title, c.additionalInfo) " +
@Query("SELECT new org.thingsboard.server.dao.model.sql.DeviceInfoEntity(d, c.title, c.additionalInfo, p.name) " +
"FROM DeviceEntity d " +
"LEFT JOIN CustomerEntity c on c.id = d.customerId " +
"LEFT JOIN DeviceProfileEntity p on p.id = d.deviceProfileId " +
"WHERE d.id = :deviceId")
DeviceInfoEntity findDeviceInfoById(@Param("deviceId") UUID deviceId);
@ -45,9 +46,10 @@ public interface DeviceRepository extends PagingAndSortingRepository<DeviceEntit
@Param("searchText") String searchText,
Pageable pageable);
@Query("SELECT new org.thingsboard.server.dao.model.sql.DeviceInfoEntity(d, c.title, c.additionalInfo) " +
@Query("SELECT new org.thingsboard.server.dao.model.sql.DeviceInfoEntity(d, c.title, c.additionalInfo, p.name) " +
"FROM DeviceEntity d " +
"LEFT JOIN CustomerEntity c on c.id = d.customerId " +
"LEFT JOIN DeviceProfileEntity p on p.id = d.deviceProfileId " +
"WHERE d.tenantId = :tenantId " +
"AND d.customerId = :customerId " +
"AND LOWER(d.searchText) LIKE LOWER(CONCAT(:searchText, '%'))")
@ -66,9 +68,10 @@ public interface DeviceRepository extends PagingAndSortingRepository<DeviceEntit
@Param("textSearch") String textSearch,
Pageable pageable);
@Query("SELECT new org.thingsboard.server.dao.model.sql.DeviceInfoEntity(d, c.title, c.additionalInfo) " +
@Query("SELECT new org.thingsboard.server.dao.model.sql.DeviceInfoEntity(d, c.title, c.additionalInfo, p.name) " +
"FROM DeviceEntity d " +
"LEFT JOIN CustomerEntity c on c.id = d.customerId " +
"LEFT JOIN DeviceProfileEntity p on p.id = d.deviceProfileId " +
"WHERE d.tenantId = :tenantId " +
"AND LOWER(d.searchText) LIKE LOWER(CONCAT(:textSearch, '%'))")
Page<DeviceInfoEntity> findDeviceInfosByTenantId(@Param("tenantId") UUID tenantId,
@ -83,9 +86,10 @@ public interface DeviceRepository extends PagingAndSortingRepository<DeviceEntit
@Param("textSearch") String textSearch,
Pageable pageable);
@Query("SELECT new org.thingsboard.server.dao.model.sql.DeviceInfoEntity(d, c.title, c.additionalInfo) " +
@Query("SELECT new org.thingsboard.server.dao.model.sql.DeviceInfoEntity(d, c.title, c.additionalInfo, p.name) " +
"FROM DeviceEntity d " +
"LEFT JOIN CustomerEntity c on c.id = d.customerId " +
"LEFT JOIN DeviceProfileEntity p on p.id = d.deviceProfileId " +
"WHERE d.tenantId = :tenantId " +
"AND d.type = :type " +
"AND LOWER(d.searchText) LIKE LOWER(CONCAT(:textSearch, '%'))")
@ -104,9 +108,10 @@ public interface DeviceRepository extends PagingAndSortingRepository<DeviceEntit
@Param("textSearch") String textSearch,
Pageable pageable);
@Query("SELECT new org.thingsboard.server.dao.model.sql.DeviceInfoEntity(d, c.title, c.additionalInfo) " +
@Query("SELECT new org.thingsboard.server.dao.model.sql.DeviceInfoEntity(d, c.title, c.additionalInfo, p.name) " +
"FROM DeviceEntity d " +
"LEFT JOIN CustomerEntity c on c.id = d.customerId " +
"LEFT JOIN DeviceProfileEntity p on p.id = d.deviceProfileId " +
"WHERE d.tenantId = :tenantId " +
"AND d.customerId = :customerId " +
"AND d.type = :type " +

8
dao/src/main/java/org/thingsboard/server/dao/sql/device/JpaDeviceProfileDao.java

@ -19,7 +19,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Component;
import org.thingsboard.server.common.data.DeviceProfile;
import org.thingsboard.server.common.data.EntityInfo;
import org.thingsboard.server.common.data.DeviceProfileInfo;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink;
@ -48,7 +48,7 @@ public class JpaDeviceProfileDao extends JpaAbstractSearchTextDao<DeviceProfileE
}
@Override
public EntityInfo findDeviceProfileInfoById(TenantId tenantId, UUID deviceProfileId) {
public DeviceProfileInfo findDeviceProfileInfoById(TenantId tenantId, UUID deviceProfileId) {
return deviceProfileRepository.findDeviceProfileInfoById(deviceProfileId);
}
@ -62,7 +62,7 @@ public class JpaDeviceProfileDao extends JpaAbstractSearchTextDao<DeviceProfileE
}
@Override
public PageData<EntityInfo> findDeviceProfileInfos(TenantId tenantId, PageLink pageLink) {
public PageData<DeviceProfileInfo> findDeviceProfileInfos(TenantId tenantId, PageLink pageLink) {
return DaoUtil.pageToPageData(
deviceProfileRepository.findDeviceProfileInfos(
tenantId.getId(),
@ -76,7 +76,7 @@ public class JpaDeviceProfileDao extends JpaAbstractSearchTextDao<DeviceProfileE
}
@Override
public EntityInfo findDefaultDeviceProfileInfo(TenantId tenantId) {
public DeviceProfileInfo findDefaultDeviceProfileInfo(TenantId tenantId) {
return deviceProfileRepository.findDefaultDeviceProfileInfo(tenantId.getId());
}

16
dao/src/main/java/org/thingsboard/server/dao/sql/tenant/JpaTenantDao.java

@ -19,11 +19,13 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Component;
import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.TenantInfo;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.dao.DaoUtil;
import org.thingsboard.server.dao.model.sql.TenantEntity;
import org.thingsboard.server.dao.model.sql.TenantInfoEntity;
import org.thingsboard.server.dao.sql.JpaAbstractSearchTextDao;
import org.thingsboard.server.dao.tenant.TenantDao;
@ -50,6 +52,11 @@ public class JpaTenantDao extends JpaAbstractSearchTextDao<TenantEntity, Tenant>
return tenantRepository;
}
@Override
public TenantInfo findTenantInfoById(TenantId tenantId, UUID id) {
return DaoUtil.getData(tenantRepository.findTenantInfoById(id));
}
@Override
public PageData<Tenant> findTenantsByRegion(TenantId tenantId, String region, PageLink pageLink) {
return DaoUtil.toPageData(tenantRepository
@ -58,4 +65,13 @@ public class JpaTenantDao extends JpaAbstractSearchTextDao<TenantEntity, Tenant>
Objects.toString(pageLink.getTextSearch(), ""),
DaoUtil.toPageable(pageLink)));
}
@Override
public PageData<TenantInfo> findTenantInfosByRegion(TenantId tenantId, String region, PageLink pageLink) {
return DaoUtil.toPageData(tenantRepository
.findTenantInfoByRegionNextPage(
region,
Objects.toString(pageLink.getTextSearch(), ""),
DaoUtil.toPageable(pageLink, TenantInfoEntity.tenantInfoColumnMap)));
}
}

16
dao/src/main/java/org/thingsboard/server/dao/sql/tenant/TenantRepository.java

@ -21,6 +21,7 @@ import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.data.repository.query.Param;
import org.thingsboard.server.dao.model.sql.TenantEntity;
import org.thingsboard.server.dao.model.sql.TenantInfoEntity;
import java.util.UUID;
@ -29,9 +30,24 @@ import java.util.UUID;
*/
public interface TenantRepository extends PagingAndSortingRepository<TenantEntity, UUID> {
@Query("SELECT new org.thingsboard.server.dao.model.sql.TenantInfoEntity(t, p.name) " +
"FROM TenantEntity t " +
"LEFT JOIN TenantProfileEntity p on p.id = t.tenantProfileId " +
"WHERE t.id = :tenantId")
TenantInfoEntity findTenantInfoById(@Param("tenantId") UUID tenantId);
@Query("SELECT t FROM TenantEntity t WHERE t.region = :region " +
"AND LOWER(t.searchText) LIKE LOWER(CONCAT(:textSearch, '%'))")
Page<TenantEntity> findByRegionNextPage(@Param("region") String region,
@Param("textSearch") String textSearch,
Pageable pageable);
@Query("SELECT new org.thingsboard.server.dao.model.sql.TenantInfoEntity(t, p.name) " +
"FROM TenantEntity t " +
"LEFT JOIN TenantProfileEntity p on p.id = t.tenantProfileId " +
"WHERE t.region = :region " +
"AND LOWER(t.searchText) LIKE LOWER(CONCAT(:textSearch, '%'))")
Page<TenantInfoEntity> findTenantInfoByRegionNextPage(@Param("region") String region,
@Param("textSearch") String textSearch,
Pageable pageable);
}

7
dao/src/main/java/org/thingsboard/server/dao/tenant/TenantDao.java

@ -16,13 +16,18 @@
package org.thingsboard.server.dao.tenant;
import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.TenantInfo;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.dao.Dao;
import java.util.UUID;
public interface TenantDao extends Dao<Tenant> {
TenantInfo findTenantInfoById(TenantId tenantId, UUID id);
/**
* Save or update tenant object
*
@ -39,5 +44,7 @@ public interface TenantDao extends Dao<Tenant> {
* @return the list of tenant objects
*/
PageData<Tenant> findTenantsByRegion(TenantId tenantId, String region, PageLink pageLink);
PageData<TenantInfo> findTenantInfosByRegion(TenantId tenantId, String region, PageLink pageLink);
}

17
dao/src/main/java/org/thingsboard/server/dao/tenant/TenantServiceImpl.java

@ -20,12 +20,11 @@ import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.thingsboard.server.common.data.EntityInfo;
import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.TenantInfo;
import org.thingsboard.server.common.data.TenantProfile;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.id.TenantProfileId;
import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.dao.asset.AssetService;
@ -92,6 +91,13 @@ public class TenantServiceImpl extends AbstractEntityService implements TenantSe
return tenantDao.findById(tenantId, tenantId.getId());
}
@Override
public TenantInfo findTenantInfoById(TenantId tenantId) {
log.trace("Executing findTenantInfoById [{}]", tenantId);
validateId(tenantId, INCORRECT_TENANT_ID + tenantId);
return tenantDao.findTenantInfoById(tenantId, tenantId.getId());
}
@Override
public ListenableFuture<Tenant> findTenantByIdAsync(TenantId callerId, TenantId tenantId) {
log.trace("Executing TenantIdAsync [{}]", tenantId);
@ -139,6 +145,13 @@ public class TenantServiceImpl extends AbstractEntityService implements TenantSe
return tenantDao.findTenantsByRegion(new TenantId(EntityId.NULL_UUID), DEFAULT_TENANT_REGION, pageLink);
}
@Override
public PageData<TenantInfo> findTenantInfos(PageLink pageLink) {
log.trace("Executing findTenantInfos pageLink [{}]", pageLink);
Validator.validatePageLink(pageLink);
return tenantDao.findTenantInfosByRegion(new TenantId(EntityId.NULL_UUID), DEFAULT_TENANT_REGION, pageLink);
}
@Override
public void deleteTenants() {
log.trace("Executing deleteTenants");

2
dao/src/main/resources/sql/schema-entities-hsql.sql

@ -230,8 +230,6 @@ CREATE TABLE IF NOT EXISTS tenant (
state varchar(255),
title varchar(255),
zip varchar(255),
isolated_tb_core boolean,
isolated_tb_rule_engine boolean,
CONSTRAINT fk_tenant_profile FOREIGN KEY (tenant_profile_id) REFERENCES tenant_profile(id)
);

4
dao/src/main/resources/sql/schema-entities.sql

@ -25,7 +25,7 @@ CREATE OR REPLACE PROCEDURE insert_tb_schema_settings()
$$
BEGIN
IF (SELECT COUNT(*) FROM tb_schema_settings) = 0 THEN
INSERT INTO tb_schema_settings (schema_version) VALUES (3001000);
INSERT INTO tb_schema_settings (schema_version) VALUES (3002000);
END IF;
END;
$$;
@ -254,8 +254,6 @@ CREATE TABLE IF NOT EXISTS tenant (
state varchar(255),
title varchar(255),
zip varchar(255),
isolated_tb_core boolean,
isolated_tb_rule_engine boolean,
CONSTRAINT fk_tenant_profile FOREIGN KEY (tenant_profile_id) REFERENCES tenant_profile(id)
);

21
dao/src/test/java/org/thingsboard/server/dao/service/BaseDeviceProfileServiceTest.java

@ -21,8 +21,8 @@ import org.junit.Before;
import org.junit.Test;
import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.DeviceProfile;
import org.thingsboard.server.common.data.DeviceProfileInfo;
import org.thingsboard.server.common.data.DeviceProfileType;
import org.thingsboard.server.common.data.EntityInfo;
import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.page.PageData;
@ -37,7 +37,7 @@ import java.util.stream.Collectors;
public class BaseDeviceProfileServiceTest extends AbstractServiceTest {
private IdComparator<DeviceProfile> idComparator = new IdComparator<>();
private IdComparator<EntityInfo> deviceProfileInfoIdComparator = new IdComparator<>();
private IdComparator<DeviceProfileInfo> deviceProfileInfoIdComparator = new IdComparator<>();
private TenantId tenantId;
@ -86,10 +86,11 @@ public class BaseDeviceProfileServiceTest extends AbstractServiceTest {
public void testFindDeviceProfileInfoById() {
DeviceProfile deviceProfile = this.createDeviceProfile(tenantId,"Device Profile");
DeviceProfile savedDeviceProfile = deviceProfileService.saveDeviceProfile(deviceProfile);
EntityInfo foundDeviceProfileInfo = deviceProfileService.findDeviceProfileInfoById(tenantId, savedDeviceProfile.getId());
DeviceProfileInfo foundDeviceProfileInfo = deviceProfileService.findDeviceProfileInfoById(tenantId, savedDeviceProfile.getId());
Assert.assertNotNull(foundDeviceProfileInfo);
Assert.assertEquals(savedDeviceProfile.getId(), foundDeviceProfileInfo.getId());
Assert.assertEquals(savedDeviceProfile.getName(), foundDeviceProfileInfo.getName());
Assert.assertEquals(savedDeviceProfile.getType(), foundDeviceProfileInfo.getType());
}
@Test
@ -102,10 +103,11 @@ public class BaseDeviceProfileServiceTest extends AbstractServiceTest {
@Test
public void testFindDefaultDeviceProfileInfo() {
EntityInfo foundDefaultDeviceProfileInfo = deviceProfileService.findDefaultDeviceProfileInfo(tenantId);
DeviceProfileInfo foundDefaultDeviceProfileInfo = deviceProfileService.findDefaultDeviceProfileInfo(tenantId);
Assert.assertNotNull(foundDefaultDeviceProfileInfo);
Assert.assertNotNull(foundDefaultDeviceProfileInfo.getId());
Assert.assertNotNull(foundDefaultDeviceProfileInfo.getName());
Assert.assertNotNull(foundDefaultDeviceProfileInfo.getType());
}
@Test
@ -230,9 +232,9 @@ public class BaseDeviceProfileServiceTest extends AbstractServiceTest {
deviceProfiles.add(deviceProfileService.saveDeviceProfile(deviceProfile));
}
List<EntityInfo> loadedDeviceProfileInfos = new ArrayList<>();
List<DeviceProfileInfo> loadedDeviceProfileInfos = new ArrayList<>();
pageLink = new PageLink(17);
PageData<EntityInfo> pageData;
PageData<DeviceProfileInfo> pageData;
do {
pageData = deviceProfileService.findDeviceProfileInfos(tenantId, pageLink);
loadedDeviceProfileInfos.addAll(pageData.getData());
@ -245,8 +247,8 @@ public class BaseDeviceProfileServiceTest extends AbstractServiceTest {
Collections.sort(deviceProfiles, idComparator);
Collections.sort(loadedDeviceProfileInfos, deviceProfileInfoIdComparator);
List<EntityInfo> deviceProfileInfos = deviceProfiles.stream().map(deviceProfile -> new EntityInfo(deviceProfile.getId(),
deviceProfile.getName())).collect(Collectors.toList());
List<DeviceProfileInfo> deviceProfileInfos = deviceProfiles.stream().map(deviceProfile -> new DeviceProfileInfo(deviceProfile.getId(),
deviceProfile.getName(), deviceProfile.getType())).collect(Collectors.toList());
Assert.assertEquals(deviceProfileInfos, loadedDeviceProfileInfos);
@ -261,7 +263,4 @@ public class BaseDeviceProfileServiceTest extends AbstractServiceTest {
Assert.assertFalse(pageData.hasNext());
Assert.assertEquals(1, pageData.getTotalElements());
}
}

6
dao/src/test/java/org/thingsboard/server/dao/service/BaseDeviceServiceTest.java

@ -287,7 +287,7 @@ public abstract class BaseDeviceServiceTest extends AbstractServiceTest {
name = i % 2 == 0 ? name.toLowerCase() : name.toUpperCase();
device.setName(name);
device.setType("default");
devicesTitle1.add(new DeviceInfo(deviceService.saveDevice(device), null, false));
devicesTitle1.add(new DeviceInfo(deviceService.saveDevice(device), null, false, "Default"));
}
String title2 = "Device title 2";
List<DeviceInfo> devicesTitle2 = new ArrayList<>();
@ -299,7 +299,7 @@ public abstract class BaseDeviceServiceTest extends AbstractServiceTest {
name = i % 2 == 0 ? name.toLowerCase() : name.toUpperCase();
device.setName(name);
device.setType("default");
devicesTitle2.add(new DeviceInfo(deviceService.saveDevice(device), null, false));
devicesTitle2.add(new DeviceInfo(deviceService.saveDevice(device), null, false, "Default"));
}
List<DeviceInfo> loadedDevicesTitle1 = new ArrayList<>();
@ -452,7 +452,7 @@ public abstract class BaseDeviceServiceTest extends AbstractServiceTest {
device.setName("Device"+i);
device.setType("default");
device = deviceService.saveDevice(device);
devices.add(new DeviceInfo(deviceService.assignDeviceToCustomer(tenantId, device.getId(), customerId), customer.getTitle(), customer.isPublic()));
devices.add(new DeviceInfo(deviceService.assignDeviceToCustomer(tenantId, device.getId(), customerId), customer.getTitle(), customer.isPublic(), "Default"));
}
List<DeviceInfo> loadedDevices = new ArrayList<>();

59
dao/src/test/java/org/thingsboard/server/dao/service/BaseTenantServiceTest.java

@ -19,6 +19,7 @@ import org.apache.commons.lang3.RandomStringUtils;
import org.junit.Assert;
import org.junit.Test;
import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.TenantInfo;
import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.dao.exception.DataValidationException;
@ -26,6 +27,7 @@ import org.thingsboard.server.dao.exception.DataValidationException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
public abstract class BaseTenantServiceTest extends AbstractServiceTest {
@ -59,6 +61,17 @@ public abstract class BaseTenantServiceTest extends AbstractServiceTest {
Assert.assertEquals(savedTenant, foundTenant);
tenantService.deleteTenant(savedTenant.getId());
}
@Test
public void testFindTenantInfoById() {
Tenant tenant = new Tenant();
tenant.setTitle("My tenant");
Tenant savedTenant = tenantService.saveTenant(tenant);
TenantInfo foundTenant = tenantService.findTenantInfoById(savedTenant.getId());
Assert.assertNotNull(foundTenant);
Assert.assertEquals(new TenantInfo(savedTenant, "Default"), foundTenant);
tenantService.deleteTenant(savedTenant.getId());
}
@Test(expected = DataValidationException.class)
public void testSaveTenantWithEmptyTitle() {
@ -116,9 +129,7 @@ public abstract class BaseTenantServiceTest extends AbstractServiceTest {
Assert.assertEquals(tenants, loadedTenants);
for (Tenant tenant : loadedTenants) {
if (!tenant.getTitle().equals("Tenant")) {
tenantService.deleteTenant(tenant.getId());
}
tenantService.deleteTenant(tenant.getId());
}
pageLink = new PageLink(17);
@ -200,4 +211,46 @@ public abstract class BaseTenantServiceTest extends AbstractServiceTest {
Assert.assertFalse(pageData.hasNext());
Assert.assertEquals(0, pageData.getData().size());
}
@Test
public void testFindTenantInfos() {
List<TenantInfo> tenants = new ArrayList<>();
PageLink pageLink = new PageLink(17);
PageData<TenantInfo> pageData = tenantService.findTenantInfos(pageLink);
Assert.assertFalse(pageData.hasNext());
Assert.assertTrue(pageData.getData().isEmpty());
tenants.addAll(pageData.getData());
for (int i=0;i<156;i++) {
Tenant tenant = new Tenant();
tenant.setTitle("Tenant"+i);
tenants.add(new TenantInfo(tenantService.saveTenant(tenant), "Default"));
}
List<TenantInfo> loadedTenants = new ArrayList<>();
pageLink = new PageLink(17);
do {
pageData = tenantService.findTenantInfos(pageLink);
loadedTenants.addAll(pageData.getData());
if (pageData.hasNext()) {
pageLink = pageLink.nextPageLink();
}
} while (pageData.hasNext());
Collections.sort(tenants, idComparator);
Collections.sort(loadedTenants, idComparator);
Assert.assertEquals(tenants, loadedTenants);
for (TenantInfo tenant : loadedTenants) {
tenantService.deleteTenant(tenant.getId());
}
pageLink = new PageLink(17);
pageData = tenantService.findTenantInfos(pageLink);
Assert.assertFalse(pageData.hasNext());
Assert.assertTrue(pageData.getData().isEmpty());
}
}

Loading…
Cancel
Save