added maxCustomers, maxUsers, maxDashboards, maxRuleChains for TenantProfile
This commit is contained in:
parent
627c0577b0
commit
ba1b000adb
@ -24,6 +24,10 @@ public class DefaultTenantProfileConfiguration implements TenantProfileConfigura
|
|||||||
|
|
||||||
private long maxDevices;
|
private long maxDevices;
|
||||||
private long maxAssets;
|
private long maxAssets;
|
||||||
|
private long maxCustomers;
|
||||||
|
private long maxUsers;
|
||||||
|
private long maxDashboards;
|
||||||
|
private long maxRuleChains;
|
||||||
|
|
||||||
private String transportTenantMsgRateLimit;
|
private String transportTenantMsgRateLimit;
|
||||||
private String transportTenantTelemetryMsgRateLimit;
|
private String transportTenantTelemetryMsgRateLimit;
|
||||||
|
|||||||
@ -332,7 +332,7 @@ public class BaseAssetService extends AbstractEntityService implements AssetServ
|
|||||||
long maxAssets = profileConfiguration.getMaxAssets();
|
long maxAssets = profileConfiguration.getMaxAssets();
|
||||||
if (maxAssets > 0) {
|
if (maxAssets > 0) {
|
||||||
long currentAssetsCount = assetDao.countAssetsByTenantId(tenantId);
|
long currentAssetsCount = assetDao.countAssetsByTenantId(tenantId);
|
||||||
if (maxAssets >= currentAssetsCount) {
|
if (currentAssetsCount >= maxAssets) {
|
||||||
throw new DataValidationException("Can't create assets more then " + maxAssets);
|
throw new DataValidationException("Can't create assets more then " + maxAssets);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -55,4 +55,6 @@ public interface CustomerDao extends Dao<Customer> {
|
|||||||
*/
|
*/
|
||||||
Optional<Customer> findCustomersByTenantIdAndTitle(UUID tenantId, String title);
|
Optional<Customer> findCustomersByTenantIdAndTitle(UUID tenantId, String title);
|
||||||
|
|
||||||
|
Long countCustomersByTenantId(TenantId tenantId);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -21,6 +21,7 @@ import com.google.common.util.concurrent.ListenableFuture;
|
|||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.thingsboard.server.common.data.Customer;
|
import org.thingsboard.server.common.data.Customer;
|
||||||
import org.thingsboard.server.common.data.Tenant;
|
import org.thingsboard.server.common.data.Tenant;
|
||||||
@ -28,6 +29,7 @@ import org.thingsboard.server.common.data.id.CustomerId;
|
|||||||
import org.thingsboard.server.common.data.id.TenantId;
|
import org.thingsboard.server.common.data.id.TenantId;
|
||||||
import org.thingsboard.server.common.data.page.PageData;
|
import org.thingsboard.server.common.data.page.PageData;
|
||||||
import org.thingsboard.server.common.data.page.PageLink;
|
import org.thingsboard.server.common.data.page.PageLink;
|
||||||
|
import org.thingsboard.server.common.data.tenant.profile.DefaultTenantProfileConfiguration;
|
||||||
import org.thingsboard.server.dao.asset.AssetService;
|
import org.thingsboard.server.dao.asset.AssetService;
|
||||||
import org.thingsboard.server.dao.dashboard.DashboardService;
|
import org.thingsboard.server.dao.dashboard.DashboardService;
|
||||||
import org.thingsboard.server.dao.device.DeviceService;
|
import org.thingsboard.server.dao.device.DeviceService;
|
||||||
@ -38,6 +40,7 @@ import org.thingsboard.server.dao.exception.IncorrectParameterException;
|
|||||||
import org.thingsboard.server.dao.service.DataValidator;
|
import org.thingsboard.server.dao.service.DataValidator;
|
||||||
import org.thingsboard.server.dao.service.PaginatedRemover;
|
import org.thingsboard.server.dao.service.PaginatedRemover;
|
||||||
import org.thingsboard.server.dao.service.Validator;
|
import org.thingsboard.server.dao.service.Validator;
|
||||||
|
import org.thingsboard.server.dao.tenant.TbTenantProfileCache;
|
||||||
import org.thingsboard.server.dao.tenant.TenantDao;
|
import org.thingsboard.server.dao.tenant.TenantDao;
|
||||||
import org.thingsboard.server.dao.user.UserService;
|
import org.thingsboard.server.dao.user.UserService;
|
||||||
|
|
||||||
@ -75,6 +78,10 @@ public class CustomerServiceImpl extends AbstractEntityService implements Custom
|
|||||||
@Autowired
|
@Autowired
|
||||||
private DashboardService dashboardService;
|
private DashboardService dashboardService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
@Lazy
|
||||||
|
private TbTenantProfileCache tenantProfileCache;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Customer findCustomerById(TenantId tenantId, CustomerId customerId) {
|
public Customer findCustomerById(TenantId tenantId, CustomerId customerId) {
|
||||||
log.trace("Executing findCustomerById [{}]", customerId);
|
log.trace("Executing findCustomerById [{}]", customerId);
|
||||||
@ -162,6 +169,15 @@ public class CustomerServiceImpl extends AbstractEntityService implements Custom
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void validateCreate(TenantId tenantId, Customer customer) {
|
protected void validateCreate(TenantId tenantId, Customer customer) {
|
||||||
|
DefaultTenantProfileConfiguration profileConfiguration =
|
||||||
|
(DefaultTenantProfileConfiguration)tenantProfileCache.get(tenantId).getProfileData().getConfiguration();
|
||||||
|
long maxCustomers = profileConfiguration.getMaxCustomers();
|
||||||
|
if (maxCustomers > 0) {
|
||||||
|
long currentCustomersCount = customerDao.countCustomersByTenantId(tenantId);
|
||||||
|
if (currentCustomersCount >= maxCustomers) {
|
||||||
|
throw new DataValidationException("Can't create customers more then " + maxCustomers);
|
||||||
|
}
|
||||||
|
}
|
||||||
customerDao.findCustomersByTenantIdAndTitle(customer.getTenantId().getId(), customer.getTitle()).ifPresent(
|
customerDao.findCustomersByTenantIdAndTitle(customer.getTenantId().getId(), customer.getTitle()).ifPresent(
|
||||||
c -> {
|
c -> {
|
||||||
throw new DataValidationException("Customer with such title already exists!");
|
throw new DataValidationException("Customer with such title already exists!");
|
||||||
|
|||||||
@ -32,4 +32,5 @@ public interface DashboardDao extends Dao<Dashboard> {
|
|||||||
*/
|
*/
|
||||||
Dashboard save(TenantId tenantId, Dashboard dashboard);
|
Dashboard save(TenantId tenantId, Dashboard dashboard);
|
||||||
|
|
||||||
|
Long countDashboardsByTenantId(TenantId tenantId);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -19,6 +19,7 @@ import com.google.common.util.concurrent.ListenableFuture;
|
|||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.thingsboard.server.common.data.Customer;
|
import org.thingsboard.server.common.data.Customer;
|
||||||
import org.thingsboard.server.common.data.Dashboard;
|
import org.thingsboard.server.common.data.Dashboard;
|
||||||
@ -31,12 +32,14 @@ import org.thingsboard.server.common.data.page.PageData;
|
|||||||
import org.thingsboard.server.common.data.page.PageLink;
|
import org.thingsboard.server.common.data.page.PageLink;
|
||||||
import org.thingsboard.server.common.data.relation.EntityRelation;
|
import org.thingsboard.server.common.data.relation.EntityRelation;
|
||||||
import org.thingsboard.server.common.data.relation.RelationTypeGroup;
|
import org.thingsboard.server.common.data.relation.RelationTypeGroup;
|
||||||
|
import org.thingsboard.server.common.data.tenant.profile.DefaultTenantProfileConfiguration;
|
||||||
import org.thingsboard.server.dao.customer.CustomerDao;
|
import org.thingsboard.server.dao.customer.CustomerDao;
|
||||||
import org.thingsboard.server.dao.entity.AbstractEntityService;
|
import org.thingsboard.server.dao.entity.AbstractEntityService;
|
||||||
import org.thingsboard.server.dao.exception.DataValidationException;
|
import org.thingsboard.server.dao.exception.DataValidationException;
|
||||||
import org.thingsboard.server.dao.service.DataValidator;
|
import org.thingsboard.server.dao.service.DataValidator;
|
||||||
import org.thingsboard.server.dao.service.PaginatedRemover;
|
import org.thingsboard.server.dao.service.PaginatedRemover;
|
||||||
import org.thingsboard.server.dao.service.Validator;
|
import org.thingsboard.server.dao.service.Validator;
|
||||||
|
import org.thingsboard.server.dao.tenant.TbTenantProfileCache;
|
||||||
import org.thingsboard.server.dao.tenant.TenantDao;
|
import org.thingsboard.server.dao.tenant.TenantDao;
|
||||||
|
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
@ -61,6 +64,10 @@ public class DashboardServiceImpl extends AbstractEntityService implements Dashb
|
|||||||
@Autowired
|
@Autowired
|
||||||
private CustomerDao customerDao;
|
private CustomerDao customerDao;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
@Lazy
|
||||||
|
private TbTenantProfileCache tenantProfileCache;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Dashboard findDashboardById(TenantId tenantId, DashboardId dashboardId) {
|
public Dashboard findDashboardById(TenantId tenantId, DashboardId dashboardId) {
|
||||||
log.trace("Executing findDashboardById [{}]", dashboardId);
|
log.trace("Executing findDashboardById [{}]", dashboardId);
|
||||||
@ -214,6 +221,19 @@ public class DashboardServiceImpl extends AbstractEntityService implements Dashb
|
|||||||
|
|
||||||
private DataValidator<Dashboard> dashboardValidator =
|
private DataValidator<Dashboard> dashboardValidator =
|
||||||
new DataValidator<Dashboard>() {
|
new DataValidator<Dashboard>() {
|
||||||
|
@Override
|
||||||
|
protected void validateCreate(TenantId tenantId, Dashboard data) {
|
||||||
|
DefaultTenantProfileConfiguration profileConfiguration =
|
||||||
|
(DefaultTenantProfileConfiguration)tenantProfileCache.get(tenantId).getProfileData().getConfiguration();
|
||||||
|
long maxDashboards = profileConfiguration.getMaxDashboards();
|
||||||
|
if (maxDashboards > 0) {
|
||||||
|
long currentDashboardsCount = dashboardDao.countDashboardsByTenantId(tenantId);
|
||||||
|
if (currentDashboardsCount >= maxDashboards) {
|
||||||
|
throw new DataValidationException("Can't create dashboards more then " + maxDashboards);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void validateDataImpl(TenantId tenantId, Dashboard dashboard) {
|
protected void validateDataImpl(TenantId tenantId, Dashboard dashboard) {
|
||||||
if (StringUtils.isEmpty(dashboard.getTitle())) {
|
if (StringUtils.isEmpty(dashboard.getTitle())) {
|
||||||
|
|||||||
@ -532,7 +532,7 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe
|
|||||||
long maxDevices = profileConfiguration.getMaxDevices();
|
long maxDevices = profileConfiguration.getMaxDevices();
|
||||||
if (maxDevices > 0) {
|
if (maxDevices > 0) {
|
||||||
long currentDevicesCount = deviceDao.countDevicesByTenantId(tenantId);
|
long currentDevicesCount = deviceDao.countDevicesByTenantId(tenantId);
|
||||||
if (maxDevices >= currentDevicesCount) {
|
if (currentDevicesCount >= maxDevices) {
|
||||||
throw new DataValidationException("Can't create devices more then " + maxDevices);
|
throw new DataValidationException("Can't create devices more then " + maxDevices);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -24,6 +24,7 @@ import org.apache.commons.collections.CollectionUtils;
|
|||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.hibernate.exception.ConstraintViolationException;
|
import org.hibernate.exception.ConstraintViolationException;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.thingsboard.server.common.data.BaseData;
|
import org.thingsboard.server.common.data.BaseData;
|
||||||
import org.thingsboard.server.common.data.EntityType;
|
import org.thingsboard.server.common.data.EntityType;
|
||||||
@ -44,11 +45,13 @@ import org.thingsboard.server.common.data.rule.RuleChainData;
|
|||||||
import org.thingsboard.server.common.data.rule.RuleChainImportResult;
|
import org.thingsboard.server.common.data.rule.RuleChainImportResult;
|
||||||
import org.thingsboard.server.common.data.rule.RuleChainMetaData;
|
import org.thingsboard.server.common.data.rule.RuleChainMetaData;
|
||||||
import org.thingsboard.server.common.data.rule.RuleNode;
|
import org.thingsboard.server.common.data.rule.RuleNode;
|
||||||
|
import org.thingsboard.server.common.data.tenant.profile.DefaultTenantProfileConfiguration;
|
||||||
import org.thingsboard.server.dao.entity.AbstractEntityService;
|
import org.thingsboard.server.dao.entity.AbstractEntityService;
|
||||||
import org.thingsboard.server.dao.exception.DataValidationException;
|
import org.thingsboard.server.dao.exception.DataValidationException;
|
||||||
import org.thingsboard.server.dao.service.DataValidator;
|
import org.thingsboard.server.dao.service.DataValidator;
|
||||||
import org.thingsboard.server.dao.service.PaginatedRemover;
|
import org.thingsboard.server.dao.service.PaginatedRemover;
|
||||||
import org.thingsboard.server.dao.service.Validator;
|
import org.thingsboard.server.dao.service.Validator;
|
||||||
|
import org.thingsboard.server.dao.tenant.TbTenantProfileCache;
|
||||||
import org.thingsboard.server.dao.tenant.TenantDao;
|
import org.thingsboard.server.dao.tenant.TenantDao;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -81,6 +84,10 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC
|
|||||||
@Autowired
|
@Autowired
|
||||||
private TenantDao tenantDao;
|
private TenantDao tenantDao;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
@Lazy
|
||||||
|
private TbTenantProfileCache tenantProfileCache;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public RuleChain saveRuleChain(RuleChain ruleChain) {
|
public RuleChain saveRuleChain(RuleChain ruleChain) {
|
||||||
ruleChainValidator.validate(ruleChain, RuleChain::getTenantId);
|
ruleChainValidator.validate(ruleChain, RuleChain::getTenantId);
|
||||||
@ -580,6 +587,19 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC
|
|||||||
|
|
||||||
private DataValidator<RuleChain> ruleChainValidator =
|
private DataValidator<RuleChain> ruleChainValidator =
|
||||||
new DataValidator<RuleChain>() {
|
new DataValidator<RuleChain>() {
|
||||||
|
@Override
|
||||||
|
protected void validateCreate(TenantId tenantId, RuleChain data) {
|
||||||
|
DefaultTenantProfileConfiguration profileConfiguration =
|
||||||
|
(DefaultTenantProfileConfiguration)tenantProfileCache.get(tenantId).getProfileData().getConfiguration();
|
||||||
|
long maxRuleChains = profileConfiguration.getMaxRuleChains();
|
||||||
|
if (maxRuleChains > 0) {
|
||||||
|
long currentRuleChainsCount = ruleChainDao.countRuleChainsByTenantId(tenantId);
|
||||||
|
if (currentRuleChainsCount >= maxRuleChains) {
|
||||||
|
throw new DataValidationException("Can't create rule chains more then " + maxRuleChains);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void validateDataImpl(TenantId tenantId, RuleChain ruleChain) {
|
protected void validateDataImpl(TenantId tenantId, RuleChain ruleChain) {
|
||||||
if (StringUtils.isEmpty(ruleChain.getName())) {
|
if (StringUtils.isEmpty(ruleChain.getName())) {
|
||||||
|
|||||||
@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.thingsboard.server.dao.rule;
|
package org.thingsboard.server.dao.rule;
|
||||||
|
|
||||||
|
import org.thingsboard.server.common.data.id.TenantId;
|
||||||
import org.thingsboard.server.common.data.page.PageData;
|
import org.thingsboard.server.common.data.page.PageData;
|
||||||
import org.thingsboard.server.common.data.page.PageLink;
|
import org.thingsboard.server.common.data.page.PageLink;
|
||||||
import org.thingsboard.server.common.data.rule.RuleChain;
|
import org.thingsboard.server.common.data.rule.RuleChain;
|
||||||
@ -36,4 +37,5 @@ public interface RuleChainDao extends Dao<RuleChain> {
|
|||||||
*/
|
*/
|
||||||
PageData<RuleChain> findRuleChainsByTenantId(UUID tenantId, PageLink pageLink);
|
PageData<RuleChain> findRuleChainsByTenantId(UUID tenantId, PageLink pageLink);
|
||||||
|
|
||||||
|
Long countRuleChainsByTenantId(TenantId tenantId);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -37,4 +37,5 @@ public interface CustomerRepository extends PagingAndSortingRepository<CustomerE
|
|||||||
|
|
||||||
CustomerEntity findByTenantIdAndTitle(UUID tenantId, String title);
|
CustomerEntity findByTenantIdAndTitle(UUID tenantId, String title);
|
||||||
|
|
||||||
|
Long countByTenantId(UUID tenantId);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -19,6 +19,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|||||||
import org.springframework.data.repository.CrudRepository;
|
import org.springframework.data.repository.CrudRepository;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import org.thingsboard.server.common.data.Customer;
|
import org.thingsboard.server.common.data.Customer;
|
||||||
|
import org.thingsboard.server.common.data.id.TenantId;
|
||||||
import org.thingsboard.server.common.data.page.PageData;
|
import org.thingsboard.server.common.data.page.PageData;
|
||||||
import org.thingsboard.server.common.data.page.PageLink;
|
import org.thingsboard.server.common.data.page.PageLink;
|
||||||
import org.thingsboard.server.dao.DaoUtil;
|
import org.thingsboard.server.dao.DaoUtil;
|
||||||
@ -62,4 +63,9 @@ public class JpaCustomerDao extends JpaAbstractSearchTextDao<CustomerEntity, Cus
|
|||||||
Customer customer = DaoUtil.getData(customerRepository.findByTenantIdAndTitle(tenantId, title));
|
Customer customer = DaoUtil.getData(customerRepository.findByTenantIdAndTitle(tenantId, title));
|
||||||
return Optional.ofNullable(customer);
|
return Optional.ofNullable(customer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Long countCustomersByTenantId(TenantId tenantId) {
|
||||||
|
return customerRepository.countByTenantId(tenantId.getId());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -24,4 +24,6 @@ import java.util.UUID;
|
|||||||
* Created by Valerii Sosliuk on 5/6/2017.
|
* Created by Valerii Sosliuk on 5/6/2017.
|
||||||
*/
|
*/
|
||||||
public interface DashboardRepository extends CrudRepository<DashboardEntity, UUID> {
|
public interface DashboardRepository extends CrudRepository<DashboardEntity, UUID> {
|
||||||
|
|
||||||
|
Long countByTenantId(UUID tenantId);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -19,6 +19,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|||||||
import org.springframework.data.repository.CrudRepository;
|
import org.springframework.data.repository.CrudRepository;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import org.thingsboard.server.common.data.Dashboard;
|
import org.thingsboard.server.common.data.Dashboard;
|
||||||
|
import org.thingsboard.server.common.data.id.TenantId;
|
||||||
import org.thingsboard.server.dao.dashboard.DashboardDao;
|
import org.thingsboard.server.dao.dashboard.DashboardDao;
|
||||||
import org.thingsboard.server.dao.model.sql.DashboardEntity;
|
import org.thingsboard.server.dao.model.sql.DashboardEntity;
|
||||||
import org.thingsboard.server.dao.sql.JpaAbstractSearchTextDao;
|
import org.thingsboard.server.dao.sql.JpaAbstractSearchTextDao;
|
||||||
@ -43,4 +44,9 @@ public class JpaDashboardDao extends JpaAbstractSearchTextDao<DashboardEntity, D
|
|||||||
protected CrudRepository<DashboardEntity, UUID> getCrudRepository() {
|
protected CrudRepository<DashboardEntity, UUID> getCrudRepository() {
|
||||||
return dashboardRepository;
|
return dashboardRepository;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Long countDashboardsByTenantId(TenantId tenantId) {
|
||||||
|
return dashboardRepository.countByTenantId(tenantId.getId());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -19,6 +19,7 @@ import lombok.extern.slf4j.Slf4j;
|
|||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.data.repository.CrudRepository;
|
import org.springframework.data.repository.CrudRepository;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.thingsboard.server.common.data.id.TenantId;
|
||||||
import org.thingsboard.server.common.data.page.PageData;
|
import org.thingsboard.server.common.data.page.PageData;
|
||||||
import org.thingsboard.server.common.data.page.PageLink;
|
import org.thingsboard.server.common.data.page.PageLink;
|
||||||
import org.thingsboard.server.common.data.rule.RuleChain;
|
import org.thingsboard.server.common.data.rule.RuleChain;
|
||||||
@ -56,4 +57,8 @@ public class JpaRuleChainDao extends JpaAbstractSearchTextDao<RuleChainEntity, R
|
|||||||
DaoUtil.toPageable(pageLink)));
|
DaoUtil.toPageable(pageLink)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Long countRuleChainsByTenantId(TenantId tenantId) {
|
||||||
|
return ruleChainRepository.countByTenantId(tenantId.getId());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -32,4 +32,5 @@ public interface RuleChainRepository extends PagingAndSortingRepository<RuleChai
|
|||||||
@Param("searchText") String searchText,
|
@Param("searchText") String searchText,
|
||||||
Pageable pageable);
|
Pageable pageable);
|
||||||
|
|
||||||
|
Long countByTenantId(UUID tenantId);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -91,4 +91,9 @@ public class JpaUserDao extends JpaAbstractSearchTextDao<UserEntity, User> imple
|
|||||||
DaoUtil.toPageable(pageLink)));
|
DaoUtil.toPageable(pageLink)));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Long countUsersByTenantId(TenantId tenantId) {
|
||||||
|
return userRepository.countByTenantId(tenantId.getId());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -47,4 +47,5 @@ public interface UserRepository extends PagingAndSortingRepository<UserEntity, U
|
|||||||
@Param("searchText") String searchText,
|
@Param("searchText") String searchText,
|
||||||
Pageable pageable);
|
Pageable pageable);
|
||||||
|
|
||||||
|
Long countByTenantId(UUID tenantId);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -69,4 +69,5 @@ public interface UserDao extends Dao<User> {
|
|||||||
*/
|
*/
|
||||||
PageData<User> findCustomerUsers(UUID tenantId, UUID customerId, PageLink pageLink);
|
PageData<User> findCustomerUsers(UUID tenantId, UUID customerId, PageLink pageLink);
|
||||||
|
|
||||||
|
Long countUsersByTenantId(TenantId tenantId);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -24,6 +24,7 @@ import org.apache.commons.lang3.RandomStringUtils;
|
|||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.thingsboard.server.common.data.Customer;
|
import org.thingsboard.server.common.data.Customer;
|
||||||
import org.thingsboard.server.common.data.Tenant;
|
import org.thingsboard.server.common.data.Tenant;
|
||||||
@ -36,6 +37,7 @@ import org.thingsboard.server.common.data.page.PageData;
|
|||||||
import org.thingsboard.server.common.data.page.PageLink;
|
import org.thingsboard.server.common.data.page.PageLink;
|
||||||
import org.thingsboard.server.common.data.security.Authority;
|
import org.thingsboard.server.common.data.security.Authority;
|
||||||
import org.thingsboard.server.common.data.security.UserCredentials;
|
import org.thingsboard.server.common.data.security.UserCredentials;
|
||||||
|
import org.thingsboard.server.common.data.tenant.profile.DefaultTenantProfileConfiguration;
|
||||||
import org.thingsboard.server.dao.customer.CustomerDao;
|
import org.thingsboard.server.dao.customer.CustomerDao;
|
||||||
import org.thingsboard.server.dao.entity.AbstractEntityService;
|
import org.thingsboard.server.dao.entity.AbstractEntityService;
|
||||||
import org.thingsboard.server.dao.exception.DataValidationException;
|
import org.thingsboard.server.dao.exception.DataValidationException;
|
||||||
@ -43,6 +45,7 @@ import org.thingsboard.server.dao.exception.IncorrectParameterException;
|
|||||||
import org.thingsboard.server.dao.model.ModelConstants;
|
import org.thingsboard.server.dao.model.ModelConstants;
|
||||||
import org.thingsboard.server.dao.service.DataValidator;
|
import org.thingsboard.server.dao.service.DataValidator;
|
||||||
import org.thingsboard.server.dao.service.PaginatedRemover;
|
import org.thingsboard.server.dao.service.PaginatedRemover;
|
||||||
|
import org.thingsboard.server.dao.tenant.TbTenantProfileCache;
|
||||||
import org.thingsboard.server.dao.tenant.TenantDao;
|
import org.thingsboard.server.dao.tenant.TenantDao;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@ -84,6 +87,10 @@ public class UserServiceImpl extends AbstractEntityService implements UserServic
|
|||||||
@Autowired
|
@Autowired
|
||||||
private CustomerDao customerDao;
|
private CustomerDao customerDao;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
@Lazy
|
||||||
|
private TbTenantProfileCache tenantProfileCache;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public User findUserByEmail(TenantId tenantId, String email) {
|
public User findUserByEmail(TenantId tenantId, String email) {
|
||||||
log.trace("Executing findUserByEmail [{}]", email);
|
log.trace("Executing findUserByEmail [{}]", email);
|
||||||
@ -364,6 +371,19 @@ public class UserServiceImpl extends AbstractEntityService implements UserServic
|
|||||||
|
|
||||||
private DataValidator<User> userValidator =
|
private DataValidator<User> userValidator =
|
||||||
new DataValidator<User>() {
|
new DataValidator<User>() {
|
||||||
|
@Override
|
||||||
|
protected void validateCreate(TenantId tenantId, User data) {
|
||||||
|
DefaultTenantProfileConfiguration profileConfiguration =
|
||||||
|
(DefaultTenantProfileConfiguration)tenantProfileCache.get(tenantId).getProfileData().getConfiguration();
|
||||||
|
long maxUsers = profileConfiguration.getMaxUsers();
|
||||||
|
if (maxUsers > 0) {
|
||||||
|
long currentUsersCount = userDao.countUsersByTenantId(tenantId);
|
||||||
|
if (currentUsersCount >= maxUsers) {
|
||||||
|
throw new DataValidationException("Can't create users more then " + maxUsers);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void validateDataImpl(TenantId requestTenantId, User user) {
|
protected void validateDataImpl(TenantId requestTenantId, User user) {
|
||||||
if (StringUtils.isEmpty(user.getEmail())) {
|
if (StringUtils.isEmpty(user.getEmail())) {
|
||||||
|
|||||||
@ -40,6 +40,54 @@
|
|||||||
{{ 'tenant-profile.maximum-assets-range' | translate}}
|
{{ 'tenant-profile.maximum-assets-range' | translate}}
|
||||||
</mat-error>
|
</mat-error>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
<mat-form-field class="mat-block">
|
||||||
|
<mat-label translate>tenant-profile.maximum-customers</mat-label>
|
||||||
|
<input matInput required min="0" step="1"
|
||||||
|
formControlName="maxCustomers"
|
||||||
|
type="number">
|
||||||
|
<mat-error *ngIf="defaultTenantProfileConfigurationFormGroup.get('maxCustomers').hasError('required')">
|
||||||
|
{{ 'tenant-profile.maximum-customers-required' | translate}}
|
||||||
|
</mat-error>
|
||||||
|
<mat-error *ngIf="defaultTenantProfileConfigurationFormGroup.get('maxCustomers').hasError('min')">
|
||||||
|
{{ 'tenant-profile.maximum-customers-range' | translate}}
|
||||||
|
</mat-error>
|
||||||
|
</mat-form-field>
|
||||||
|
<mat-form-field class="mat-block">
|
||||||
|
<mat-label translate>tenant-profile.maximum-users</mat-label>
|
||||||
|
<input matInput required min="0" step="1"
|
||||||
|
formControlName="maxUsers"
|
||||||
|
type="number">
|
||||||
|
<mat-error *ngIf="defaultTenantProfileConfigurationFormGroup.get('maxUsers').hasError('required')">
|
||||||
|
{{ 'tenant-profile.maximum-users-required' | translate}}
|
||||||
|
</mat-error>
|
||||||
|
<mat-error *ngIf="defaultTenantProfileConfigurationFormGroup.get('maxUsers').hasError('min')">
|
||||||
|
{{ 'tenant-profile.maximum-users-range' | translate}}
|
||||||
|
</mat-error>
|
||||||
|
</mat-form-field>
|
||||||
|
<mat-form-field class="mat-block">
|
||||||
|
<mat-label translate>tenant-profile.maximum-dashboards</mat-label>
|
||||||
|
<input matInput required min="0" step="1"
|
||||||
|
formControlName="maxDashboards"
|
||||||
|
type="number">
|
||||||
|
<mat-error *ngIf="defaultTenantProfileConfigurationFormGroup.get('maxDashboards').hasError('required')">
|
||||||
|
{{ 'tenant-profile.maximum-dashboards-required' | translate}}
|
||||||
|
</mat-error>
|
||||||
|
<mat-error *ngIf="defaultTenantProfileConfigurationFormGroup.get('maxDashboards').hasError('min')">
|
||||||
|
{{ 'tenant-profile.maximum-dashboards-range' | translate}}
|
||||||
|
</mat-error>
|
||||||
|
</mat-form-field>
|
||||||
|
<mat-form-field class="mat-block">
|
||||||
|
<mat-label translate>tenant-profile.maximum-rule-chains</mat-label>
|
||||||
|
<input matInput required min="0" step="1"
|
||||||
|
formControlName="maxRuleChains"
|
||||||
|
type="number">
|
||||||
|
<mat-error *ngIf="defaultTenantProfileConfigurationFormGroup.get('maxRuleChains').hasError('required')">
|
||||||
|
{{ 'tenant-profile.maximum-rule-chains-required' | translate}}
|
||||||
|
</mat-error>
|
||||||
|
<mat-error *ngIf="defaultTenantProfileConfigurationFormGroup.get('maxRuleChains').hasError('min')">
|
||||||
|
{{ 'tenant-profile.maximum-rule-chains-range' | translate}}
|
||||||
|
</mat-error>
|
||||||
|
</mat-form-field>
|
||||||
<mat-form-field class="mat-block">
|
<mat-form-field class="mat-block">
|
||||||
<mat-label translate>tenant-profile.max-transport-messages</mat-label>
|
<mat-label translate>tenant-profile.max-transport-messages</mat-label>
|
||||||
<input matInput required min="0" step="1"
|
<input matInput required min="0" step="1"
|
||||||
|
|||||||
@ -55,6 +55,10 @@ export class DefaultTenantProfileConfigurationComponent implements ControlValueA
|
|||||||
this.defaultTenantProfileConfigurationFormGroup = this.fb.group({
|
this.defaultTenantProfileConfigurationFormGroup = this.fb.group({
|
||||||
maxDevices: [null, [Validators.required, Validators.min(0)]],
|
maxDevices: [null, [Validators.required, Validators.min(0)]],
|
||||||
maxAssets: [null, [Validators.required, Validators.min(0)]],
|
maxAssets: [null, [Validators.required, Validators.min(0)]],
|
||||||
|
maxCustomers: [null, [Validators.required, Validators.min(0)]],
|
||||||
|
maxUsers: [null, [Validators.required, Validators.min(0)]],
|
||||||
|
maxDashboards: [null, [Validators.required, Validators.min(0)]],
|
||||||
|
maxRuleChains: [null, [Validators.required, Validators.min(0)]],
|
||||||
transportTenantMsgRateLimit: [null, []],
|
transportTenantMsgRateLimit: [null, []],
|
||||||
transportTenantTelemetryMsgRateLimit: [null, []],
|
transportTenantTelemetryMsgRateLimit: [null, []],
|
||||||
transportTenantTelemetryDataPointsRateLimit: [null, []],
|
transportTenantTelemetryDataPointsRateLimit: [null, []],
|
||||||
|
|||||||
@ -1946,6 +1946,18 @@
|
|||||||
"maximum-assets": "Maximum number of assets (0 - unlimited)",
|
"maximum-assets": "Maximum number of assets (0 - unlimited)",
|
||||||
"maximum-assets-required": "Maximum number of assets is required.",
|
"maximum-assets-required": "Maximum number of assets is required.",
|
||||||
"maximum-assets-range": "Maximum number of assets can't be negative",
|
"maximum-assets-range": "Maximum number of assets can't be negative",
|
||||||
|
"maximum-customers": "Maximum number of customers (0 - unlimited)",
|
||||||
|
"maximum-customers-required": "Maximum number of customers is required.",
|
||||||
|
"maximum-customers-range": "Maximum number of customers can't be negative",
|
||||||
|
"maximum-users": "Maximum number of users (0 - unlimited)",
|
||||||
|
"maximum-users-required": "Maximum number of users is required.",
|
||||||
|
"maximum-users-range": "Maximum number of users can't be negative",
|
||||||
|
"maximum-dashboards": "Maximum number of dashboards (0 - unlimited)",
|
||||||
|
"maximum-dashboards-required": "Maximum number of dashboards is required.",
|
||||||
|
"maximum-dashboards-range": "Maximum number of dashboards can't be negative",
|
||||||
|
"maximum-rule-chains": "Maximum number of rule chains (0 - unlimited)",
|
||||||
|
"maximum-rule-chains-required": "Maximum number of rule chains is required.",
|
||||||
|
"maximum-rule-chains-range": "Maximum number of rule chains can't be negative",
|
||||||
"transport-tenant-msg-rate-limit": "Transport tenant messages rate limit.",
|
"transport-tenant-msg-rate-limit": "Transport tenant messages rate limit.",
|
||||||
"transport-tenant-telemetry-msg-rate-limit": "Transport tenant telemetry messages rate limit.",
|
"transport-tenant-telemetry-msg-rate-limit": "Transport tenant telemetry messages rate limit.",
|
||||||
"transport-tenant-telemetry-data-points-rate-limit": "Transport tenant telemetry data points rate limit.",
|
"transport-tenant-telemetry-data-points-rate-limit": "Transport tenant telemetry data points rate limit.",
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user