From 9b19da096f6b832567b2e9aeec9b94da2e882c23 Mon Sep 17 00:00:00 2001 From: YevhenBondarenko Date: Thu, 21 Apr 2022 09:51:25 +0200 Subject: [PATCH] removed max queues and max partitions per queue in tenant profile --- .../server/controller/QueueController.java | 14 +-- .../server/dao/queue/QueueService.java | 3 - .../server/common/data/TenantProfile.java | 6 +- .../server/dao/model/ModelConstants.java | 2 - .../dao/model/sql/TenantProfileEntity.java | 10 --- .../server/dao/queue/BaseQueueService.java | 37 -------- .../dao/tenant/TenantProfileServiceImpl.java | 85 +++++++++++++++++++ .../main/resources/sql/schema-entities.sql | 2 - .../dao/service/BaseQueueServiceTest.java | 49 ++++++----- .../service/BaseTenantProfileServiceTest.java | 28 ++++++ ui-ngx/src/app/core/http/queue.service.ts | 10 +-- .../import-export/import-export.service.ts | 4 +- .../tenant-profile-data.component.html | 5 ++ .../profile/tenant-profile.component.html | 32 ------- .../profile/tenant-profile.component.ts | 12 +-- ui-ngx/src/app/shared/models/tenant.model.ts | 2 - .../assets/locale/locale.constant-en_US.json | 8 +- 17 files changed, 159 insertions(+), 150 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/controller/QueueController.java b/application/src/main/java/org/thingsboard/server/controller/QueueController.java index c48fc8036f..dd0e023152 100644 --- a/application/src/main/java/org/thingsboard/server/controller/QueueController.java +++ b/application/src/main/java/org/thingsboard/server/controller/QueueController.java @@ -55,7 +55,7 @@ public class QueueController extends BaseController { @ApiOperation(value = "Get queue names (getTenantQueuesByServiceType)", notes = "Returns a set of unique queue names based on service type. " + TENANT_AUTHORITY_PARAGRAPH) @PreAuthorize("hasAuthority('TENANT_ADMIN')") - @RequestMapping(value = "/tenant/queues", params = {"serviceType"}, produces = MediaType.APPLICATION_JSON_VALUE, method = RequestMethod.GET) + @RequestMapping(value = "/queues", params = {"serviceType"}, produces = MediaType.APPLICATION_JSON_VALUE, method = RequestMethod.GET) @ResponseBody() public Set getTenantQueuesByServiceType(@ApiParam(value = QUEUE_SERVICE_TYPE_DESCRIPTION, allowableValues = QUEUE_SERVICE_TYPE_ALLOWABLE_VALUES) @RequestParam String serviceType) throws ThingsboardException { @@ -74,7 +74,7 @@ public class QueueController extends BaseController { } @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") - @RequestMapping(value = "/tenant/queues", params = {"serviceType", "pageSize", "page"}, method = RequestMethod.GET) + @RequestMapping(value = "/queues", params = {"serviceType", "pageSize", "page"}, method = RequestMethod.GET) @ResponseBody public PageData getTenantQueuesByServiceType(@RequestParam String serviceType, @RequestParam int pageSize, @@ -98,7 +98,7 @@ public class QueueController extends BaseController { } @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") - @RequestMapping(value = "/tenant/queues/{queueId}", method = RequestMethod.GET) + @RequestMapping(value = "/queues/{queueId}", method = RequestMethod.GET) @ResponseBody public Queue getQueueById(@PathVariable("queueId") String queueIdStr) throws ThingsboardException { checkParameter("queueId", queueIdStr); @@ -111,8 +111,8 @@ public class QueueController extends BaseController { } } - @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") - @RequestMapping(value = "/tenant/queues", params = {"serviceType"}, method = RequestMethod.POST) + @PreAuthorize("hasAnyAuthority('SYS_ADMIN')") + @RequestMapping(value = "/queues", params = {"serviceType"}, method = RequestMethod.POST) @ResponseBody public Queue saveQueue(@RequestBody Queue queue, @RequestParam String serviceType) throws ThingsboardException { @@ -137,8 +137,8 @@ public class QueueController extends BaseController { } } - @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") - @RequestMapping(value = "/tenant/queues/{queueId}", method = RequestMethod.DELETE) + @PreAuthorize("hasAnyAuthority('SYS_ADMIN')") + @RequestMapping(value = "/queues/{queueId}", method = RequestMethod.DELETE) @ResponseBody public void deleteQueue(@PathVariable("queueId") String queueIdStr) throws ThingsboardException { checkParameter("queueId", queueIdStr); diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/queue/QueueService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/queue/QueueService.java index 3fbb228f3c..bdea0ef09c 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/queue/QueueService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/queue/QueueService.java @@ -15,7 +15,6 @@ */ package org.thingsboard.server.dao.queue; -import org.thingsboard.server.common.data.TenantProfile; import org.thingsboard.server.common.data.id.QueueId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.PageData; @@ -42,7 +41,5 @@ public interface QueueService { Queue findQueueByTenantIdAndName(TenantId tenantId, String name); - Queue createDefaultMainQueue(TenantProfile tenantProfile, TenantId tenantId); - void deleteQueuesByTenantId(TenantId tenantId); } \ No newline at end of file diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/TenantProfile.java b/common/data/src/main/java/org/thingsboard/server/common/data/TenantProfile.java index 32b6ba88ba..308500a6bd 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/TenantProfile.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/TenantProfile.java @@ -57,11 +57,7 @@ public class TenantProfile extends SearchTextBased implements H @ApiModelProperty(position = 7, value = "If enabled, will push all messages related to this tenant and processed by the rule engine into separate queue. " + "Useful for complex microservices deployments, to isolate processing of the data for specific tenants", example = "true") private boolean isolatedTbRuleEngine; - @ApiModelProperty(position = 8, value = "Max amount of queues configurable by isolated tenant.", example = "5") - private Integer maxNumberOfQueues; - @ApiModelProperty(position = 9, value = "Max amount of partitions per queue configurable by isolated tenant.", example = "10") - private Integer maxNumberOfPartitionsPerQueue; - @ApiModelProperty(position = 10, value = "Complex JSON object that contains profile settings: max devices, max assets, rate limits, etc.") + @ApiModelProperty(position = 8, value = "Complex JSON object that contains profile settings: queue configs, max devices, max assets, rate limits, etc.") private transient TenantProfileData profileData; @JsonIgnore private byte[] profileDataBytes; diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java b/dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java index c9f89ccc91..d122f712ca 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java @@ -128,8 +128,6 @@ public class ModelConstants { public static final String TENANT_PROFILE_IS_DEFAULT_PROPERTY = "is_default"; public static final String TENANT_PROFILE_ISOLATED_TB_CORE = "isolated_tb_core"; public static final String TENANT_PROFILE_ISOLATED_TB_RULE_ENGINE = "isolated_tb_rule_engine"; - public static final String TENANT_PROFILE_MAX_NUMBER_OF_QUEUES = "max_number_of_queues"; - public static final String TENANT_PROFILE_MAX_NUMBER_OF_PARTITIONS_PER_QUEUE = "max_number_of_partitions_per_queue"; /** * Cassandra customer constants. diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/TenantProfileEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/TenantProfileEntity.java index 2b62588c76..6f7b094464 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/TenantProfileEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/TenantProfileEntity.java @@ -59,12 +59,6 @@ public final class TenantProfileEntity extends BaseSqlEntity impl @Column(name = ModelConstants.TENANT_PROFILE_ISOLATED_TB_RULE_ENGINE) private boolean isolatedTbRuleEngine; - @Column(name = ModelConstants.TENANT_PROFILE_MAX_NUMBER_OF_QUEUES) - private Integer maxNumberOfQueues; - - @Column(name = ModelConstants.TENANT_PROFILE_MAX_NUMBER_OF_PARTITIONS_PER_QUEUE) - private Integer maxNumberOfPartitionsPerQueue; - @Type(type = "jsonb") @Column(name = ModelConstants.TENANT_PROFILE_PROFILE_DATA_PROPERTY, columnDefinition = "jsonb") private JsonNode profileData; @@ -83,8 +77,6 @@ public final class TenantProfileEntity extends BaseSqlEntity impl this.isDefault = tenantProfile.isDefault(); this.isolatedTbCore = tenantProfile.isIsolatedTbCore(); this.isolatedTbRuleEngine = tenantProfile.isIsolatedTbRuleEngine(); - this.maxNumberOfPartitionsPerQueue = tenantProfile.getMaxNumberOfPartitionsPerQueue(); - this.maxNumberOfQueues = tenantProfile.getMaxNumberOfQueues(); this.profileData = JacksonUtil.convertValue(tenantProfile.getProfileData(), ObjectNode.class); } @@ -111,8 +103,6 @@ public final class TenantProfileEntity extends BaseSqlEntity impl tenantProfile.setDefault(isDefault); tenantProfile.setIsolatedTbCore(isolatedTbCore); tenantProfile.setIsolatedTbRuleEngine(isolatedTbRuleEngine); - tenantProfile.setMaxNumberOfPartitionsPerQueue(maxNumberOfPartitionsPerQueue); - tenantProfile.setMaxNumberOfQueues(maxNumberOfQueues); tenantProfile.setProfileData(JacksonUtil.convertValue(profileData, TenantProfileData.class)); return tenantProfile; } diff --git a/dao/src/main/java/org/thingsboard/server/dao/queue/BaseQueueService.java b/dao/src/main/java/org/thingsboard/server/dao/queue/BaseQueueService.java index 28c0330267..a0ad3c3a4a 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/queue/BaseQueueService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/queue/BaseQueueService.java @@ -21,14 +21,12 @@ 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.springframework.transaction.annotation.Transactional; import org.thingsboard.server.common.data.TenantProfile; import org.thingsboard.server.common.data.id.QueueId; 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.common.data.queue.ProcessingStrategy; -import org.thingsboard.server.common.data.queue.ProcessingStrategyType; import org.thingsboard.server.common.data.queue.Queue; import org.thingsboard.server.common.data.queue.SubmitStrategy; import org.thingsboard.server.common.data.queue.SubmitStrategyType; @@ -202,30 +200,6 @@ public class BaseQueueService extends AbstractEntityService implements QueueServ tenantQueuesRemover.removeEntities(tenantId, tenantId); } - @Override - @Transactional - public Queue createDefaultMainQueue(TenantProfile tenantProfile, TenantId tenantId) { - Queue mainQueue = new Queue(); - mainQueue.setTenantId(tenantId); - mainQueue.setName("Main"); - mainQueue.setTopic("tb_rule_engine.main"); - mainQueue.setPollInterval(25); - mainQueue.setPartitions(Math.max(tenantProfile.getMaxNumberOfPartitionsPerQueue(), 1)); - mainQueue.setPackProcessingTimeout(60000); - SubmitStrategy mainQueueSubmitStrategy = new SubmitStrategy(); - mainQueueSubmitStrategy.setType(SubmitStrategyType.BURST); - mainQueueSubmitStrategy.setBatchSize(1000); - mainQueue.setSubmitStrategy(mainQueueSubmitStrategy); - ProcessingStrategy mainQueueProcessingStrategy = new ProcessingStrategy(); - mainQueueProcessingStrategy.setType(ProcessingStrategyType.SKIP_ALL_FAILURES); - mainQueueProcessingStrategy.setRetries(3); - mainQueueProcessingStrategy.setFailurePercentage(0); - mainQueueProcessingStrategy.setPauseBetweenRetries(3); - mainQueueProcessingStrategy.setMaxPauseBetweenRetries(3); - mainQueue.setProcessingStrategy(mainQueueProcessingStrategy); - return saveQueue(mainQueue); - } - private DataValidator queueValidator = new DataValidator<>() { @@ -261,17 +235,6 @@ public class BaseQueueService extends AbstractEntityService implements QueueServ if (!tenantProfile.isIsolatedTbRuleEngine()) { throw new DataValidationException("Tenant should be isolated!"); } - - if (queue.getId() == null) { - List existingQueues = findQueuesByTenantId(tenantId); - if (existingQueues.size() >= tenantProfile.getMaxNumberOfQueues()) { - throw new DataValidationException("The limit for creating new queue has been exceeded!"); - } - } - - if (queue.getPartitions() > tenantProfile.getMaxNumberOfPartitionsPerQueue()) { - throw new DataValidationException(String.format("Queue partitions can't be more then %d", tenantProfile.getMaxNumberOfPartitionsPerQueue())); - } } if (StringUtils.isEmpty(queue.getName())) { diff --git a/dao/src/main/java/org/thingsboard/server/dao/tenant/TenantProfileServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/tenant/TenantProfileServiceImpl.java index a4f9c65807..2b8611846a 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/tenant/TenantProfileServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/tenant/TenantProfileServiceImpl.java @@ -29,8 +29,12 @@ 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.common.data.queue.ProcessingStrategy; +import org.thingsboard.server.common.data.queue.SubmitStrategy; +import org.thingsboard.server.common.data.queue.SubmitStrategyType; import org.thingsboard.server.common.data.tenant.profile.DefaultTenantProfileConfiguration; import org.thingsboard.server.common.data.tenant.profile.TenantProfileData; +import org.thingsboard.server.common.data.tenant.profile.TenantProfileQueueConfiguration; import org.thingsboard.server.dao.entity.AbstractEntityService; import org.thingsboard.server.dao.exception.DataValidationException; import org.thingsboard.server.dao.service.DataValidator; @@ -39,6 +43,10 @@ import org.thingsboard.server.dao.service.Validator; import java.util.Arrays; import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Optional; +import java.util.Set; import static org.thingsboard.server.common.data.CacheConstants.TENANT_PROFILE_CACHE; import static org.thingsboard.server.dao.service.Validator.validateId; @@ -228,6 +236,35 @@ public class TenantProfileServiceImpl extends AbstractEntityService implements T throw new DataValidationException("Another default tenant profile is present!"); } } + + if (tenantProfile.isIsolatedTbRuleEngine()) { + List queueConfiguration = tenantProfile.getProfileData().getQueueConfiguration(); + if (queueConfiguration == null) { + throw new DataValidationException("Tenant profile data queue configuration should be specified!"); + } + + Optional mainQueueConfig = + queueConfiguration + .stream() + .filter(q -> q.getName().equals("Main")) + .findAny(); + if (mainQueueConfig.isEmpty()) { + throw new DataValidationException("Main queue configuration should be specified!"); + } + + queueConfiguration.forEach(this::validateQueueConfiguration); + + Set queueNames = new HashSet<>(queueConfiguration.size()); + + queueConfiguration.forEach(q -> { + String name = q.getName(); + if (queueNames.contains(name)) { + throw new DataValidationException(String.format("Queue configuration name '%s' already present!", name)); + } else { + queueNames.add(name); + } + }); + } } @Override @@ -241,6 +278,54 @@ public class TenantProfileServiceImpl extends AbstractEntityService implements T throw new DataValidationException("Can't update isolatedTbCore property!"); } } + + private void validateQueueConfiguration(TenantProfileQueueConfiguration queue) { + if (StringUtils.isEmpty(queue.getName())) { + throw new DataValidationException("Queue name should be specified!"); + } + if (StringUtils.isBlank(queue.getTopic())) { + throw new DataValidationException("Queue topic should be non empty and without spaces!"); + } + if (queue.getPollInterval() < 1) { + throw new DataValidationException("Queue poll interval should be more then 0!"); + } + if (queue.getPartitions() < 1) { + throw new DataValidationException("Queue partitions should be more then 0!"); + } + if (queue.getPackProcessingTimeout() < 1) { + throw new DataValidationException("Queue pack processing timeout should be more then 0!"); + } + + SubmitStrategy submitStrategy = queue.getSubmitStrategy(); + if (submitStrategy == null) { + throw new DataValidationException("Queue submit strategy can't be null!"); + } + if (submitStrategy.getType() == null) { + throw new DataValidationException("Queue submit strategy type can't be null!"); + } + if (submitStrategy.getType() == SubmitStrategyType.BATCH && submitStrategy.getBatchSize() < 1) { + throw new DataValidationException("Queue submit strategy batch size should be more then 0!"); + } + ProcessingStrategy processingStrategy = queue.getProcessingStrategy(); + if (processingStrategy == null) { + throw new DataValidationException("Queue processing strategy can't be null!"); + } + if (processingStrategy.getType() == null) { + throw new DataValidationException("Queue processing strategy type can't be null!"); + } + if (processingStrategy.getRetries() < 0) { + throw new DataValidationException("Queue processing strategy retries can't be less then 0!"); + } + if (processingStrategy.getFailurePercentage() < 0 || processingStrategy.getFailurePercentage() > 100) { + throw new DataValidationException("Queue processing strategy failure percentage should be in a range from 0 to 100!"); + } + if (processingStrategy.getPauseBetweenRetries() < 0) { + throw new DataValidationException("Queue processing strategy pause between retries can't be less then 0!"); + } + if (processingStrategy.getMaxPauseBetweenRetries() < processingStrategy.getPauseBetweenRetries()) { + throw new DataValidationException("Queue processing strategy MAX pause between retries can't be less then pause between retries!"); + } + } }; private PaginatedRemover tenantProfilesRemover = diff --git a/dao/src/main/resources/sql/schema-entities.sql b/dao/src/main/resources/sql/schema-entities.sql index b85171efee..1f3717429b 100644 --- a/dao/src/main/resources/sql/schema-entities.sql +++ b/dao/src/main/resources/sql/schema-entities.sql @@ -352,8 +352,6 @@ CREATE TABLE IF NOT EXISTS tenant_profile ( is_default boolean, isolated_tb_core boolean, isolated_tb_rule_engine boolean, - max_number_of_queues int , - max_number_of_partitions_per_queue int, CONSTRAINT tenant_profile_name_unq_key UNIQUE (name) ); diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/BaseQueueServiceTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/BaseQueueServiceTest.java index 8899224bd5..577193ff94 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/BaseQueueServiceTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/BaseQueueServiceTest.java @@ -30,10 +30,10 @@ import org.thingsboard.server.common.data.queue.ProcessingStrategyType; import org.thingsboard.server.common.data.queue.Queue; import org.thingsboard.server.common.data.queue.SubmitStrategy; import org.thingsboard.server.common.data.queue.SubmitStrategyType; +import org.thingsboard.server.common.data.tenant.profile.TenantProfileData; +import org.thingsboard.server.common.data.tenant.profile.TenantProfileQueueConfiguration; import org.thingsboard.server.dao.exception.DataValidationException; -import org.thingsboard.server.dao.tenant.TenantServiceImpl; -import java.lang.reflect.Field; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -47,18 +47,34 @@ public abstract class BaseQueueServiceTest extends AbstractServiceTest { @Before public void before() throws NoSuchFieldException, IllegalAccessException { - Field zkEnabled = TenantServiceImpl.class.getDeclaredField("zkEnabled"); - zkEnabled.setAccessible(true); - zkEnabled.set(tenantService, Boolean.TRUE); - TenantProfile tenantProfile = new TenantProfile(); tenantProfile.setDefault(false); tenantProfile.setName("Isolated TB Rule Engine"); tenantProfile.setDescription("Isolated TB Rule Engine tenant profile"); tenantProfile.setIsolatedTbCore(false); tenantProfile.setIsolatedTbRuleEngine(true); - tenantProfile.setMaxNumberOfQueues(10); - tenantProfile.setMaxNumberOfPartitionsPerQueue(10); + + TenantProfileQueueConfiguration mainQueueConfiguration = new TenantProfileQueueConfiguration(); + mainQueueConfiguration.setName("Main"); + mainQueueConfiguration.setTopic("tb_rule_engine.main"); + mainQueueConfiguration.setPollInterval(25); + mainQueueConfiguration.setPartitions(10); + mainQueueConfiguration.setConsumerPerPartition(true); + mainQueueConfiguration.setPackProcessingTimeout(2000); + SubmitStrategy mainQueueSubmitStrategy = new SubmitStrategy(); + mainQueueSubmitStrategy.setType(SubmitStrategyType.BURST); + mainQueueSubmitStrategy.setBatchSize(1000); + mainQueueConfiguration.setSubmitStrategy(mainQueueSubmitStrategy); + ProcessingStrategy mainQueueProcessingStrategy = new ProcessingStrategy(); + mainQueueProcessingStrategy.setType(ProcessingStrategyType.SKIP_ALL_FAILURES); + mainQueueProcessingStrategy.setRetries(3); + mainQueueProcessingStrategy.setFailurePercentage(0); + mainQueueProcessingStrategy.setPauseBetweenRetries(3); + mainQueueProcessingStrategy.setMaxPauseBetweenRetries(3); + mainQueueConfiguration.setProcessingStrategy(mainQueueProcessingStrategy); + TenantProfileData profileData = tenantProfile.getProfileData(); + profileData.setQueueConfiguration(Collections.singletonList(mainQueueConfiguration)); + tenantProfile.setProfileData(profileData); TenantProfile savedTenantProfile = tenantProfileService.saveTenantProfile(TenantId.SYS_TENANT_ID, tenantProfile); Assert.assertNotNull(savedTenantProfile); @@ -343,23 +359,6 @@ public abstract class BaseQueueServiceTest extends AbstractServiceTest { } } - @Test(expected = DataValidationException.class) - public void testSaveQueueWithExceededLimitPerTenant() { - for (int i = 1; i <= 10; i++) { - //main queue created automatically - Queue queue = new Queue(); - queue.setTenantId(tenantId); - queue.setName("Test" + i); - queue.setTopic("tb_rule_engine.test" + i); - queue.setPollInterval(25); - queue.setPartitions(1); - queue.setPackProcessingTimeout(2000); - queue.setSubmitStrategy(createTestSubmitStrategy()); - queue.setProcessingStrategy(createTestProcessingStrategy()); - queueService.saveQueue(queue); - } - } - @Test public void testUpdateQueue() { Queue queue = new Queue(); diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/BaseTenantProfileServiceTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/BaseTenantProfileServiceTest.java index b655a8439c..ae9459ccae 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/BaseTenantProfileServiceTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/BaseTenantProfileServiceTest.java @@ -25,8 +25,13 @@ 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.common.data.queue.ProcessingStrategy; +import org.thingsboard.server.common.data.queue.ProcessingStrategyType; +import org.thingsboard.server.common.data.queue.SubmitStrategy; +import org.thingsboard.server.common.data.queue.SubmitStrategyType; import org.thingsboard.server.common.data.tenant.profile.DefaultTenantProfileConfiguration; import org.thingsboard.server.common.data.tenant.profile.TenantProfileData; +import org.thingsboard.server.common.data.tenant.profile.TenantProfileQueueConfiguration; import org.thingsboard.server.dao.exception.DataValidationException; import java.util.ArrayList; @@ -47,6 +52,29 @@ public abstract class BaseTenantProfileServiceTest extends AbstractServiceTest { @Test public void testSaveTenantProfile() { TenantProfile tenantProfile = this.createTenantProfile("Tenant Profile"); + + tenantProfile.setIsolatedTbRuleEngine(true); + + TenantProfileQueueConfiguration mainQueueConfiguration = new TenantProfileQueueConfiguration(); + mainQueueConfiguration.setName("Main"); + mainQueueConfiguration.setTopic("tb_rule_engine.main"); + mainQueueConfiguration.setPollInterval(25); + mainQueueConfiguration.setPartitions(10); + mainQueueConfiguration.setConsumerPerPartition(true); + mainQueueConfiguration.setPackProcessingTimeout(2000); + SubmitStrategy mainQueueSubmitStrategy = new SubmitStrategy(); + mainQueueSubmitStrategy.setType(SubmitStrategyType.BURST); + mainQueueSubmitStrategy.setBatchSize(1000); + mainQueueConfiguration.setSubmitStrategy(mainQueueSubmitStrategy); + ProcessingStrategy mainQueueProcessingStrategy = new ProcessingStrategy(); + mainQueueProcessingStrategy.setType(ProcessingStrategyType.SKIP_ALL_FAILURES); + mainQueueProcessingStrategy.setRetries(3); + mainQueueProcessingStrategy.setFailurePercentage(0); + mainQueueProcessingStrategy.setPauseBetweenRetries(3); + mainQueueProcessingStrategy.setMaxPauseBetweenRetries(3); + mainQueueConfiguration.setProcessingStrategy(mainQueueProcessingStrategy); + tenantProfile.getProfileData().setQueueConfiguration(Collections.singletonList(mainQueueConfiguration)); + TenantProfile savedTenantProfile = tenantProfileService.saveTenantProfile(TenantId.SYS_TENANT_ID, tenantProfile); Assert.assertNotNull(savedTenantProfile); Assert.assertNotNull(savedTenantProfile.getId()); diff --git a/ui-ngx/src/app/core/http/queue.service.ts b/ui-ngx/src/app/core/http/queue.service.ts index bf2183449d..a5967eef97 100644 --- a/ui-ngx/src/app/core/http/queue.service.ts +++ b/ui-ngx/src/app/core/http/queue.service.ts @@ -32,26 +32,26 @@ export class QueueService { ) { } public getTenantQueuesNamesByServiceType(serviceType: ServiceType, config?: RequestConfig): Observable> { - return this.http.get>(`/api/tenant/queues?serviceType=${serviceType}`, + return this.http.get>(`/api/queues?serviceType=${serviceType}`, defaultHttpOptionsFromConfig(config)); } public getQueueById(queueId: string, config?: RequestConfig): Observable { - return this.http.get(`/api/tenant/queues/${queueId}`, defaultHttpOptionsFromConfig(config)); + return this.http.get(`/api/queues/${queueId}`, defaultHttpOptionsFromConfig(config)); } public getTenantQueuesByServiceType(pageLink: PageLink, serviceType: ServiceType, config?: RequestConfig): Observable> { - return this.http.get>(`/api/tenant/queues${pageLink.toQuery()}&serviceType=${serviceType}`, + return this.http.get>(`/api/queues${pageLink.toQuery()}&serviceType=${serviceType}`, defaultHttpOptionsFromConfig(config)); } public saveQueue(queue: QueueInfo, serviceType: ServiceType, config?: RequestConfig): Observable { - return this.http.post(`/api/tenant/queues?serviceType=${serviceType}`, queue, defaultHttpOptionsFromConfig(config)); + return this.http.post(`/api/queues?serviceType=${serviceType}`, queue, defaultHttpOptionsFromConfig(config)); } public deleteQueue(queueId: string) { - return this.http.delete(`/api/tenant/queues/${queueId}`); + return this.http.delete(`/api/queues/${queueId}`); } } diff --git a/ui-ngx/src/app/modules/home/components/import-export/import-export.service.ts b/ui-ngx/src/app/modules/home/components/import-export/import-export.service.ts index 78507cb121..2bddd229bc 100644 --- a/ui-ngx/src/app/modules/home/components/import-export/import-export.service.ts +++ b/ui-ngx/src/app/modules/home/components/import-export/import-export.service.ts @@ -567,9 +567,7 @@ export class ImportExportService { return isDefined(tenantProfile.name) && isDefined(tenantProfile.profileData) && isDefined(tenantProfile.isolatedTbCore) - && isDefined(tenantProfile.isolatedTbRuleEngine) - && isDefined(tenantProfile.maxNumberOfQueues) - && isDefined(tenantProfile.maxNumberOfPartitionsPerQueue); + && isDefined(tenantProfile.isolatedTbRuleEngine); } private sumObject(obj1: any, obj2: any): any { diff --git a/ui-ngx/src/app/modules/home/components/profile/tenant-profile-data.component.html b/ui-ngx/src/app/modules/home/components/profile/tenant-profile-data.component.html index 81ca768911..115a224374 100644 --- a/ui-ngx/src/app/modules/home/components/profile/tenant-profile-data.component.html +++ b/ui-ngx/src/app/modules/home/components/profile/tenant-profile-data.component.html @@ -16,6 +16,11 @@ -->
+ + + + + diff --git a/ui-ngx/src/app/modules/home/components/profile/tenant-profile.component.html b/ui-ngx/src/app/modules/home/components/profile/tenant-profile.component.html index 6377e59a45..e2eb776e5b 100644 --- a/ui-ngx/src/app/modules/home/components/profile/tenant-profile.component.html +++ b/ui-ngx/src/app/modules/home/components/profile/tenant-profile.component.html @@ -67,38 +67,6 @@
{{ 'tenant.isolated-tb-rule-engine' | translate }}
{{'tenant.isolated-tb-rule-engine-details' | translate}}
-
- - tenant.max-number-of-queues - - - {{ 'tenant.max-number-of-queues-required' | translate }} - - - {{ 'tenant.max-number-of-queues-min-length' | translate }} - - - - tenant.max-number-of-partitions-per-queue - - - {{ 'tenant.max-number-of-partitions-per-queue-required' | translate }} - - - {{ 'tenant.max-number-of-partitions-per-queue-min-length' | translate }} - - -
{ name: [entity ? entity.name : '', [Validators.required, Validators.maxLength(255)]], isolatedTbCore: [entity ? entity.isolatedTbCore : false, []], isolatedTbRuleEngine: [entity ? entity.isolatedTbRuleEngine : false, []], - maxNumberOfQueues: [entity ? entity.maxNumberOfQueues : 1, [Validators.required, Validators.min(1)]], - maxNumberOfPartitionsPerQueue: [entity ? entity.maxNumberOfPartitionsPerQueue : 1, [Validators.required, Validators.min(1)]], profileData: [entity && !this.isAdd ? entity.profileData : { configuration: createTenantProfileConfiguration(TenantProfileType.DEFAULT) } as TenantProfileData, []], @@ -81,8 +79,6 @@ export class TenantProfileComponent extends EntityComponent { this.entityForm.patchValue({name: entity.name}); this.entityForm.patchValue({isolatedTbCore: entity.isolatedTbCore}); this.entityForm.patchValue({isolatedTbRuleEngine: entity.isolatedTbRuleEngine}); - this.entityForm.patchValue({maxNumberOfQueues: entity.maxNumberOfQueues}); - this.entityForm.patchValue({maxNumberOfPartitionsPerQueue: entity.maxNumberOfPartitionsPerQueue}); this.entityForm.patchValue({profileData: !this.isAdd ? entity.profileData : { configuration: createTenantProfileConfiguration(TenantProfileType.DEFAULT) } as TenantProfileData}); @@ -92,11 +88,9 @@ export class TenantProfileComponent extends EntityComponent { showQueueParams(): boolean { let isolatedTbRuleEngine: boolean = this.entityForm.get('isolatedTbRuleEngine').value; if (isolatedTbRuleEngine) { - this.entityForm.get('maxNumberOfQueues').enable(); - this.entityForm.get('maxNumberOfPartitionsPerQueue').enable(); +//enable } else { - this.entityForm.get('maxNumberOfQueues').disable(); - this.entityForm.get('maxNumberOfPartitionsPerQueue').disable(); +//disable } return isolatedTbRuleEngine; } @@ -108,8 +102,6 @@ export class TenantProfileComponent extends EntityComponent { if (!this.isAdd) { this.entityForm.get('isolatedTbCore').disable({emitEvent: false}); this.entityForm.get('isolatedTbRuleEngine').disable({emitEvent: false}); - this.entityForm.get('maxNumberOfQueues').disable({emitEvent: false}); - this.entityForm.get('maxNumberOfPartitionsPerQueue').disable({emitEvent: false}); } } else { this.entityForm.disable({emitEvent: false}); diff --git a/ui-ngx/src/app/shared/models/tenant.model.ts b/ui-ngx/src/app/shared/models/tenant.model.ts index 311529a42a..cceb1cc7d7 100644 --- a/ui-ngx/src/app/shared/models/tenant.model.ts +++ b/ui-ngx/src/app/shared/models/tenant.model.ts @@ -107,8 +107,6 @@ export interface TenantProfile extends BaseData { default?: boolean; isolatedTbCore?: boolean; isolatedTbRuleEngine?: boolean; - maxNumberOfQueues?: number; - maxNumberOfPartitionsPerQueue?: number; profileData?: TenantProfileData; } diff --git a/ui-ngx/src/assets/locale/locale.constant-en_US.json b/ui-ngx/src/assets/locale/locale.constant-en_US.json index 4c93854125..4414e71847 100644 --- a/ui-ngx/src/assets/locale/locale.constant-en_US.json +++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json @@ -2759,13 +2759,7 @@ "isolated-tb-core": "Processing in isolated ThingsBoard Core container", "isolated-tb-rule-engine": "Processing in isolated ThingsBoard Rule Engine container", "isolated-tb-core-details": "Requires separate microservice(s) per isolated Tenant", - "isolated-tb-rule-engine-details": "Requires separate microservice(s) per isolated Tenant", - "max-number-of-queues": "Max number of ThingsBoard Rule Engine queues", - "max-number-of-queues-required": "Max number of queues is required", - "max-number-of-queues-min-length": "Max number of queues can't be less then 1", - "max-number-of-partitions-per-queue": "Max number of partitions per ThingsBoard Rule Engine queue", - "max-number-of-partitions-per-queue-required": "Max number of partitions per queue is required", - "max-number-of-partitions-per-queue-min-length": "Max number of partitions per queue can't be less then 1" + "isolated-tb-rule-engine-details": "Requires separate microservice(s) per isolated Tenant" }, "tenant-profile": { "tenant-profile": "Tenant profile",