diff --git a/application/src/main/data/upgrade/3.1.1/schema_update.sql b/application/src/main/data/upgrade/3.1.1/schema_update.sql deleted file mode 100644 index c2e311c3dd..0000000000 --- a/application/src/main/data/upgrade/3.1.1/schema_update.sql +++ /dev/null @@ -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 -); diff --git a/application/src/main/data/upgrade/3.1.1/schema_update_after.sql b/application/src/main/data/upgrade/3.1.1/schema_update_after.sql new file mode 100644 index 0000000000..c8f9d2970e --- /dev/null +++ b/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); diff --git a/application/src/main/data/upgrade/3.1.1/schema_update_before.sql b/application/src/main/data/upgrade/3.1.1/schema_update_before.sql new file mode 100644 index 0000000000..67d7a6e01b --- /dev/null +++ b/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; +$$; diff --git a/application/src/main/java/org/thingsboard/server/controller/BaseController.java b/application/src/main/java/org/thingsboard/server/controller/BaseController.java index 38a2ef2eee..142a8520bb 100644 --- a/application/src/main/java/org/thingsboard/server/controller/BaseController.java +++ b/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); diff --git a/application/src/main/java/org/thingsboard/server/controller/DeviceProfileController.java b/application/src/main/java/org/thingsboard/server/controller/DeviceProfileController.java index 88dace797f..44509c8adf 100644 --- a/application/src/main/java/org/thingsboard/server/controller/DeviceProfileController.java +++ b/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 getDeviceProfileInfos(@RequestParam int pageSize, + public PageData getDeviceProfileInfos(@RequestParam int pageSize, @RequestParam int page, @RequestParam(required = false) String textSearch, @RequestParam(required = false) String sortProperty, diff --git a/application/src/main/java/org/thingsboard/server/controller/TenantController.java b/application/src/main/java/org/thingsboard/server/controller/TenantController.java index 0c0eefe354..ebb46778c9 100644 --- a/application/src/main/java/org/thingsboard/server/controller/TenantController.java +++ b/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 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); + } + } + } diff --git a/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java b/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java index 7dc1442390..adc295a721 100644 --- a/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java +++ b/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(); diff --git a/application/src/main/java/org/thingsboard/server/service/install/DefaultSystemDataLoaderService.java b/application/src/main/java/org/thingsboard/server/service/install/DefaultSystemDataLoaderService.java index d80adcf8c4..7ef674245b 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/DefaultSystemDataLoaderService.java +++ b/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 diff --git a/application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java b/application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java index 3f00b39da5..0c5f4da1ed 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java +++ b/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 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: diff --git a/application/src/main/java/org/thingsboard/server/service/install/SystemDataLoaderService.java b/application/src/main/java/org/thingsboard/server/service/install/SystemDataLoaderService.java index f212488a0c..b588c2dff2 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/SystemDataLoaderService.java +++ b/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; diff --git a/application/src/test/java/org/thingsboard/server/controller/BaseDeviceProfileControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/BaseDeviceProfileControllerTest.java index 033a1eef0f..d4b3ec5977 100644 --- a/application/src/test/java/org/thingsboard/server/controller/BaseDeviceProfileControllerTest.java +++ b/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 idComparator = new IdComparator<>(); - private IdComparator deviceProfileInfoIdComparator = new IdComparator<>(); + private IdComparator 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 loadedDeviceProfileInfos = new ArrayList<>(); + List loadedDeviceProfileInfos = new ArrayList<>(); pageLink = new PageLink(17); - PageData pageData; + PageData pageData; do { pageData = doGetTypedWithPageLink("/api/deviceProfileInfos?", - new TypeReference>(){}, pageLink); + new TypeReference>(){}, 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 deviceProfileInfos = deviceProfiles.stream().map(deviceProfile -> new EntityInfo(deviceProfile.getId(), - deviceProfile.getName())).collect(Collectors.toList()); + List 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>(){}, pageLink); + new TypeReference>(){}, pageLink); Assert.assertFalse(pageData.hasNext()); Assert.assertEquals(1, pageData.getTotalElements()); } diff --git a/application/src/test/java/org/thingsboard/server/controller/BaseTenantControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/BaseTenantControllerTest.java index e9641646ff..2294987668 100644 --- a/application/src/test/java/org/thingsboard/server/controller/BaseTenantControllerTest.java +++ b/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 tenants = new ArrayList<>(); + PageLink pageLink = new PageLink(17); + PageData pageData = doGetTypedWithPageLink("/api/tenantInfos?", new TypeReference>(){}, 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 loadedTenants = new ArrayList<>(); + pageLink = new PageLink(17); + do { + pageData = doGetTypedWithPageLink("/api/tenantInfos?", new TypeReference>(){}, 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>(){}, pageLink); + Assert.assertFalse(pageData.hasNext()); + Assert.assertEquals(1, pageData.getData().size()); + } } diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/device/DeviceProfileService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/device/DeviceProfileService.java index 057b14db23..b2410a807e 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/device/DeviceProfileService.java +++ b/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 findDeviceProfiles(TenantId tenantId, PageLink pageLink); - PageData findDeviceProfileInfos(TenantId tenantId, PageLink pageLink); + PageData 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); diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/tenant/TenantService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/tenant/TenantService.java index 5bf811da80..eaf835812b 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/tenant/TenantService.java +++ b/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 findTenantByIdAsync(TenantId callerId, TenantId tenantId); Tenant saveTenant(Tenant tenant); @@ -32,6 +35,8 @@ public interface TenantService { void deleteTenant(TenantId tenantId); PageData findTenants(PageLink pageLink); + + PageData findTenantInfos(PageLink pageLink); void deleteTenants(); } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/DeviceInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/DeviceInfo.java index 406fa26086..56fb4bc11c 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/DeviceInfo.java +++ b/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; } } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/DeviceProfileInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/DeviceProfileInfo.java new file mode 100644 index 0000000000..b8d157bd1d --- /dev/null +++ b/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; + } + +} diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/EntityInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/EntityInfo.java index 170d4f254d..3bb3b134d4 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/EntityInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/EntityInfo.java @@ -36,8 +36,8 @@ public class EntityInfo implements HasId, 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; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/TenantInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/TenantInfo.java new file mode 100644 index 0000000000..ee94b26f18 --- /dev/null +++ b/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; + } + +} diff --git a/dao/src/main/java/org/thingsboard/server/dao/device/DeviceProfileDao.java b/dao/src/main/java/org/thingsboard/server/dao/device/DeviceProfileDao.java index 68ad164941..34c12ab90c 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/device/DeviceProfileDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/device/DeviceProfileDao.java @@ -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 { - EntityInfo findDeviceProfileInfoById(TenantId tenantId, UUID deviceProfileId); + DeviceProfileInfo findDeviceProfileInfoById(TenantId tenantId, UUID deviceProfileId); DeviceProfile save(TenantId tenantId, DeviceProfile deviceProfile); PageData findDeviceProfiles(TenantId tenantId, PageLink pageLink); - PageData findDeviceProfileInfos(TenantId tenantId, PageLink pageLink); + PageData findDeviceProfileInfos(TenantId tenantId, PageLink pageLink); DeviceProfile findDefaultDeviceProfile(TenantId tenantId); - EntityInfo findDefaultDeviceProfileInfo(TenantId tenantId); + DeviceProfileInfo findDefaultDeviceProfileInfo(TenantId tenantId); } diff --git a/dao/src/main/java/org/thingsboard/server/dao/device/DeviceProfileServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/device/DeviceProfileServiceImpl.java index d5cdd55e3e..10f308984d 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/device/DeviceProfileServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/device/DeviceProfileServiceImpl.java @@ -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 findDeviceProfileInfos(TenantId tenantId, PageLink pageLink) { + public PageData 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); diff --git a/dao/src/main/java/org/thingsboard/server/dao/device/DeviceServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/device/DeviceServiceImpl.java index 0dd46a5ec3..b6602d1702 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/device/DeviceServiceImpl.java +++ b/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); diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/AbstractTenantEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/AbstractTenantEntity.java new file mode 100644 index 0000000000..7cd5c6778e --- /dev/null +++ b/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 extends BaseSqlEntity implements SearchTextEntity { + + @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; + } + + +} diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/DeviceInfoEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/DeviceInfoEntity.java index 83914a6a9b..b3c42945fb 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/DeviceInfoEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/DeviceInfoEntity.java @@ -30,10 +30,12 @@ public class DeviceInfoEntity extends AbstractDeviceEntity { public static final Map 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 { 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 { } 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); } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/TenantEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/TenantEntity.java index 7292c16616..2d78763f71 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/TenantEntity.java +++ b/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 implements SearchTextEntity { - - @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 { 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(); } - - } diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/TenantInfoEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/TenantInfoEntity.java new file mode 100644 index 0000000000..02e7ce9ebc --- /dev/null +++ b/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 { + + public static final Map 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); + } +} diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/device/DeviceProfileRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/device/DeviceProfileRepository.java index 559307baea..162a915d88 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/device/DeviceProfileRepository.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/device/DeviceProfileRepository.java @@ -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 { - @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 findDeviceProfileInfos(@Param("tenantId") UUID tenantId, - @Param("textSearch") String textSearch, - Pageable pageable); + Page 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); } diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/device/DeviceRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/device/DeviceRepository.java index 828a9e28f0..d74ffd2f43 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/device/DeviceRepository.java +++ b/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 { - @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 findDeviceInfosByTenantId(@Param("tenantId") UUID tenantId, @@ -83,9 +86,10 @@ public interface DeviceRepository extends PagingAndSortingRepository findDeviceProfileInfos(TenantId tenantId, PageLink pageLink) { + public PageData findDeviceProfileInfos(TenantId tenantId, PageLink pageLink) { return DaoUtil.pageToPageData( deviceProfileRepository.findDeviceProfileInfos( tenantId.getId(), @@ -76,7 +76,7 @@ public class JpaDeviceProfileDao extends JpaAbstractSearchTextDao return tenantRepository; } + @Override + public TenantInfo findTenantInfoById(TenantId tenantId, UUID id) { + return DaoUtil.getData(tenantRepository.findTenantInfoById(id)); + } + @Override public PageData findTenantsByRegion(TenantId tenantId, String region, PageLink pageLink) { return DaoUtil.toPageData(tenantRepository @@ -58,4 +65,13 @@ public class JpaTenantDao extends JpaAbstractSearchTextDao Objects.toString(pageLink.getTextSearch(), ""), DaoUtil.toPageable(pageLink))); } + + @Override + public PageData findTenantInfosByRegion(TenantId tenantId, String region, PageLink pageLink) { + return DaoUtil.toPageData(tenantRepository + .findTenantInfoByRegionNextPage( + region, + Objects.toString(pageLink.getTextSearch(), ""), + DaoUtil.toPageable(pageLink, TenantInfoEntity.tenantInfoColumnMap))); + } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/tenant/TenantRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/tenant/TenantRepository.java index 012920e187..e1ff50eb2a 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/tenant/TenantRepository.java +++ b/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 { + @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 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 findTenantInfoByRegionNextPage(@Param("region") String region, + @Param("textSearch") String textSearch, + Pageable pageable); } diff --git a/dao/src/main/java/org/thingsboard/server/dao/tenant/TenantDao.java b/dao/src/main/java/org/thingsboard/server/dao/tenant/TenantDao.java index d850694135..18fd3ff73e 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/tenant/TenantDao.java +++ b/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 { + TenantInfo findTenantInfoById(TenantId tenantId, UUID id); + /** * Save or update tenant object * @@ -39,5 +44,7 @@ public interface TenantDao extends Dao { * @return the list of tenant objects */ PageData findTenantsByRegion(TenantId tenantId, String region, PageLink pageLink); + + PageData findTenantInfosByRegion(TenantId tenantId, String region, PageLink pageLink); } diff --git a/dao/src/main/java/org/thingsboard/server/dao/tenant/TenantServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/tenant/TenantServiceImpl.java index f8b7096b98..52761184fd 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/tenant/TenantServiceImpl.java +++ b/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 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 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"); diff --git a/dao/src/main/resources/sql/schema-entities-hsql.sql b/dao/src/main/resources/sql/schema-entities-hsql.sql index 2d34f0b1ba..657c82982e 100644 --- a/dao/src/main/resources/sql/schema-entities-hsql.sql +++ b/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) ); diff --git a/dao/src/main/resources/sql/schema-entities.sql b/dao/src/main/resources/sql/schema-entities.sql index 053d7420a5..75a7fa50bb 100644 --- a/dao/src/main/resources/sql/schema-entities.sql +++ b/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) ); diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/BaseDeviceProfileServiceTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/BaseDeviceProfileServiceTest.java index ba823e8595..c53a89829c 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/BaseDeviceProfileServiceTest.java +++ b/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 idComparator = new IdComparator<>(); - private IdComparator deviceProfileInfoIdComparator = new IdComparator<>(); + private IdComparator 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 loadedDeviceProfileInfos = new ArrayList<>(); + List loadedDeviceProfileInfos = new ArrayList<>(); pageLink = new PageLink(17); - PageData pageData; + PageData 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 deviceProfileInfos = deviceProfiles.stream().map(deviceProfile -> new EntityInfo(deviceProfile.getId(), - deviceProfile.getName())).collect(Collectors.toList()); + List 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()); } - - - } diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/BaseDeviceServiceTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/BaseDeviceServiceTest.java index 1b7561467e..29da0e7f87 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/BaseDeviceServiceTest.java +++ b/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 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 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 loadedDevices = new ArrayList<>(); diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/BaseTenantServiceTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/BaseTenantServiceTest.java index 0c1cd3ffe5..e71788258b 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/BaseTenantServiceTest.java +++ b/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 tenants = new ArrayList<>(); + PageLink pageLink = new PageLink(17); + PageData 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 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()); + + } }