From 0d8a2549d959b59fb4053195d1e57eb0cbd8f848 Mon Sep 17 00:00:00 2001 From: ViacheslavKlimov Date: Thu, 14 Sep 2023 15:22:53 +0300 Subject: [PATCH 1/9] Single PartitionChangeEvent after recalculatePartitions --- .../actors/service/DefaultActorService.java | 2 +- .../DefaultTbRuleEngineConsumerService.java | 28 ++++++++++--------- .../discovery/HashPartitionServiceTest.java | 22 ++++++--------- .../state/DefaultDeviceStateServiceTest.java | 4 ++- .../common/msg/queue/PartitionChangeMsg.java | 4 --- .../queue/discovery/HashPartitionService.java | 16 +++++++++-- .../discovery/event/PartitionChangeEvent.java | 18 +++++++----- 7 files changed, 52 insertions(+), 42 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/actors/service/DefaultActorService.java b/application/src/main/java/org/thingsboard/server/actors/service/DefaultActorService.java index dd5bd4f1ed..380da71443 100644 --- a/application/src/main/java/org/thingsboard/server/actors/service/DefaultActorService.java +++ b/application/src/main/java/org/thingsboard/server/actors/service/DefaultActorService.java @@ -121,7 +121,7 @@ public class DefaultActorService extends TbApplicationEventListener { + String serviceQueue = queueKey.getQueueName(); + log.info("[{}] Subscribing to partitions: {}", serviceQueue, partitions); + Queue configuration = consumerConfigurations.get(queueKey); + if (configuration == null) { + log.warn("Received invalid partition change event for {} that is not managed by this service", queueKey); + return; + } + if (!configuration.isConsumerPerPartition()) { + consumers.get(queueKey).subscribe(partitions); + } else { + log.info("[{}] Subscribing consumer per partition: {}", serviceQueue, partitions); + subscribeConsumerPerPartition(queueKey, partitions); + } + }); } } diff --git a/application/src/test/java/org/thingsboard/server/queue/discovery/HashPartitionServiceTest.java b/application/src/test/java/org/thingsboard/server/queue/discovery/HashPartitionServiceTest.java index 5e800d52a5..49008ab559 100644 --- a/application/src/test/java/org/thingsboard/server/queue/discovery/HashPartitionServiceTest.java +++ b/application/src/test/java/org/thingsboard/server/queue/discovery/HashPartitionServiceTest.java @@ -286,10 +286,8 @@ public class HashPartitionServiceTest { HashPartitionService partitionService_common = createPartitionService(); partitionService_common.recalculatePartitions(commonRuleEngine, List.of(dedicatedRuleEngine)); verifyPartitionChangeEvent(event -> { - return event.getQueueKey().getTenantId().isSysTenantId() && - event.getQueueKey().getQueueName().equals(DataConstants.MAIN_QUEUE_NAME) && - event.getPartitions().stream().map(TopicPartitionInfo::getPartition).collect(Collectors.toSet()) - .size() == systemQueue.getPartitions(); + QueueKey queueKey = new QueueKey(ServiceType.TB_RULE_ENGINE, DataConstants.MAIN_QUEUE_NAME, TenantId.SYS_TENANT_ID); + return event.getPartitionsMap().get(queueKey).size() == systemQueue.getPartitions(); }); Mockito.reset(applicationEventPublisher); @@ -316,18 +314,15 @@ public class HashPartitionServiceTest { partitionService_common.recalculatePartitions(commonRuleEngine, List.of(dedicatedRuleEngine)); // expecting event about no partitions for isolated queue key verifyPartitionChangeEvent(event -> { - return event.getQueueKey().getTenantId().equals(tenantId) && - event.getQueueKey().getQueueName().equals(DataConstants.MAIN_QUEUE_NAME) && - event.getPartitions().isEmpty(); + QueueKey queueKey = new QueueKey(ServiceType.TB_RULE_ENGINE, DataConstants.MAIN_QUEUE_NAME, tenantId); + return event.getPartitionsMap().get(queueKey).isEmpty(); }); partitionService_dedicated.updateQueue(queueUpdateMsg); partitionService_dedicated.recalculatePartitions(dedicatedRuleEngine, List.of(commonRuleEngine)); verifyPartitionChangeEvent(event -> { - return event.getQueueKey().getTenantId().equals(tenantId) && - event.getQueueKey().getQueueName().equals(DataConstants.MAIN_QUEUE_NAME) && - event.getPartitions().stream().map(TopicPartitionInfo::getPartition).collect(Collectors.toSet()) - .size() == isolatedQueue.getPartitions(); + QueueKey queueKey = new QueueKey(ServiceType.TB_RULE_ENGINE, DataConstants.MAIN_QUEUE_NAME, tenantId); + return event.getPartitionsMap().get(queueKey).size() == isolatedQueue.getPartitions(); }); @@ -345,9 +340,8 @@ public class HashPartitionServiceTest { partitionService_dedicated.removeQueue(queueDeleteMsg); partitionService_dedicated.recalculatePartitions(dedicatedRuleEngine, List.of(commonRuleEngine)); verifyPartitionChangeEvent(event -> { - return event.getQueueKey().getTenantId().equals(tenantId) && - event.getQueueKey().getQueueName().equals(DataConstants.MAIN_QUEUE_NAME) && - event.getPartitions().isEmpty(); + QueueKey queueKey = new QueueKey(ServiceType.TB_RULE_ENGINE, DataConstants.MAIN_QUEUE_NAME, tenantId); + return event.getPartitionsMap().get(queueKey).isEmpty(); }); } diff --git a/application/src/test/java/org/thingsboard/server/service/state/DefaultDeviceStateServiceTest.java b/application/src/test/java/org/thingsboard/server/service/state/DefaultDeviceStateServiceTest.java index ccb0b5e26c..adb46affe8 100644 --- a/application/src/test/java/org/thingsboard/server/service/state/DefaultDeviceStateServiceTest.java +++ b/application/src/test/java/org/thingsboard/server/service/state/DefaultDeviceStateServiceTest.java @@ -160,7 +160,9 @@ public class DefaultDeviceStateServiceTest { Mockito.reset(service, telemetrySubscriptionService); ReflectionTestUtils.setField(service, "defaultInactivityTimeoutMs", timeout); service.init(); - PartitionChangeEvent event = new PartitionChangeEvent(this, new QueueKey(ServiceType.TB_CORE), Collections.singleton(tpi)); + PartitionChangeEvent event = new PartitionChangeEvent(this, ServiceType.TB_CORE, Map.of( + new QueueKey(ServiceType.TB_CORE), Collections.singleton(tpi) + )); service.onApplicationEvent(event); Thread.sleep(100); } diff --git a/common/message/src/main/java/org/thingsboard/server/common/msg/queue/PartitionChangeMsg.java b/common/message/src/main/java/org/thingsboard/server/common/msg/queue/PartitionChangeMsg.java index 39d7dad2db..fd48b36e67 100644 --- a/common/message/src/main/java/org/thingsboard/server/common/msg/queue/PartitionChangeMsg.java +++ b/common/message/src/main/java/org/thingsboard/server/common/msg/queue/PartitionChangeMsg.java @@ -20,8 +20,6 @@ import lombok.Getter; import org.thingsboard.server.common.msg.MsgType; import org.thingsboard.server.common.msg.TbActorMsg; -import java.util.Set; - /** * @author Andrew Shvayka */ @@ -30,8 +28,6 @@ public final class PartitionChangeMsg implements TbActorMsg { @Getter private final ServiceType serviceType; - @Getter - private final Set partitions; @Override public MsgType getMsgType() { diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/discovery/HashPartitionService.java b/common/queue/src/main/java/org/thingsboard/server/queue/discovery/HashPartitionService.java index 33fb350292..1974c82ec4 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/discovery/HashPartitionService.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/discovery/HashPartitionService.java @@ -271,6 +271,8 @@ public class HashPartitionService implements PartitionService { final ConcurrentMap> oldPartitions = myPartitions; myPartitions = newPartitions; + Map> changedPartitionsMap = new HashMap<>(); + Set removed = new HashSet<>(); oldPartitions.forEach((queueKey, partitions) -> { if (!newPartitions.containsKey(queueKey)) { @@ -286,7 +288,7 @@ public class HashPartitionService implements PartitionService { } removed.forEach(queueKey -> { log.info("[{}] NO MORE PARTITIONS FOR CURRENT KEY", queueKey); - applicationEventPublisher.publishEvent(new PartitionChangeEvent(this, queueKey, Collections.emptySet())); + changedPartitionsMap.put(queueKey, Collections.emptySet()); }); myPartitions.forEach((queueKey, partitions) -> { @@ -295,9 +297,19 @@ public class HashPartitionService implements PartitionService { Set tpiList = partitions.stream() .map(partition -> buildTopicPartitionInfo(queueKey, partition)) .collect(Collectors.toSet()); - applicationEventPublisher.publishEvent(new PartitionChangeEvent(this, queueKey, tpiList)); + changedPartitionsMap.put(queueKey, tpiList); } }); + if (!changedPartitionsMap.isEmpty()) { + Map>> partitionsByServiceType = new HashMap<>(); + changedPartitionsMap.forEach((queueKey, partitions) -> { + partitionsByServiceType.computeIfAbsent(queueKey.getType(), serviceType -> new HashMap<>()) + .put(queueKey, partitions); + }); + partitionsByServiceType.forEach((serviceType, partitionsMap) -> { + applicationEventPublisher.publishEvent(new PartitionChangeEvent(this, serviceType, partitionsMap)); + }); + } if (currentOtherServices == null) { currentOtherServices = new ArrayList<>(otherServices); diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/discovery/event/PartitionChangeEvent.java b/common/queue/src/main/java/org/thingsboard/server/queue/discovery/event/PartitionChangeEvent.java index c7a00daa1c..0d74cdfaee 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/discovery/event/PartitionChangeEvent.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/discovery/event/PartitionChangeEvent.java @@ -21,6 +21,8 @@ import org.thingsboard.server.common.msg.queue.ServiceType; import org.thingsboard.server.common.msg.queue.TopicPartitionInfo; import org.thingsboard.server.queue.discovery.QueueKey; +import java.util.Collections; +import java.util.Map; import java.util.Set; @ToString(callSuper = true) @@ -29,17 +31,19 @@ public class PartitionChangeEvent extends TbApplicationEvent { private static final long serialVersionUID = -8731788167026510559L; @Getter - private final QueueKey queueKey; + private final ServiceType serviceType; @Getter - private final Set partitions; + private final Map> partitionsMap; - public PartitionChangeEvent(Object source, QueueKey queueKey, Set partitions) { + public PartitionChangeEvent(Object source, ServiceType serviceType, Map> partitionsMap) { super(source); - this.queueKey = queueKey; - this.partitions = partitions; + this.serviceType = serviceType; + this.partitionsMap = partitionsMap; } - public ServiceType getServiceType() { - return queueKey.getType(); + // only for service types that have single QueueKey + public Set getPartitions() { + return partitionsMap.values().stream().findAny().orElse(Collections.emptySet()); } + } From 4e526aa969bd446ee2b679b2cc7e555869f37ba9 Mon Sep 17 00:00:00 2001 From: ViacheslavKlimov Date: Thu, 14 Sep 2023 16:27:23 +0300 Subject: [PATCH 2/9] Queue removal: always publish PartitionChangeEvent; remove redundant recalculatePartitions; add debug log --- .../DefaultTbRuleEngineConsumerService.java | 2 -- .../queue/discovery/HashPartitionService.java | 24 ++++++++++++++++--- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/service/queue/DefaultTbRuleEngineConsumerService.java b/application/src/main/java/org/thingsboard/server/service/queue/DefaultTbRuleEngineConsumerService.java index f67d80cb1b..c715b7b03c 100644 --- a/application/src/main/java/org/thingsboard/server/service/queue/DefaultTbRuleEngineConsumerService.java +++ b/application/src/main/java/org/thingsboard/server/service/queue/DefaultTbRuleEngineConsumerService.java @@ -188,7 +188,6 @@ public class DefaultTbRuleEngineConsumerService extends AbstractConsumerService< log.info("[{}] Subscribing to partitions: {}", serviceQueue, partitions); Queue configuration = consumerConfigurations.get(queueKey); if (configuration == null) { - log.warn("Received invalid partition change event for {} that is not managed by this service", queueKey); return; } if (!configuration.isConsumerPerPartition()) { @@ -503,7 +502,6 @@ public class DefaultTbRuleEngineConsumerService extends AbstractConsumerService< } } } - partitionService.recalculatePartitions(serviceInfoProvider.getServiceInfo(), new ArrayList<>(partitionService.getOtherServices(ServiceType.TB_RULE_ENGINE))); } private void forwardToRuleEngineActor(String queueName, TenantId tenantId, ToRuleEngineMsg toRuleEngineMsg, TbMsgCallback callback) { diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/discovery/HashPartitionService.java b/common/queue/src/main/java/org/thingsboard/server/queue/discovery/HashPartitionService.java index 1974c82ec4..5be5caf6ff 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/discovery/HashPartitionService.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/discovery/HashPartitionService.java @@ -179,10 +179,15 @@ public class HashPartitionService implements PartitionService { public void removeQueue(TransportProtos.QueueDeleteMsg queueDeleteMsg) { TenantId tenantId = new TenantId(new UUID(queueDeleteMsg.getTenantIdMSB(), queueDeleteMsg.getTenantIdLSB())); QueueKey queueKey = new QueueKey(ServiceType.TB_RULE_ENGINE, queueDeleteMsg.getQueueName(), tenantId); + myPartitions.remove(queueKey); partitionTopicsMap.remove(queueKey); partitionSizesMap.remove(queueKey); //TODO: remove after merging tb entity services removeTenant(tenantId); + + if (serviceInfoProvider.isService(ServiceType.TB_RULE_ENGINE)) { + publishPartitionChangeEvent(ServiceType.TB_RULE_ENGINE, Map.of(queueKey, Collections.emptySet())); + } } @Override @@ -306,9 +311,7 @@ public class HashPartitionService implements PartitionService { partitionsByServiceType.computeIfAbsent(queueKey.getType(), serviceType -> new HashMap<>()) .put(queueKey, partitions); }); - partitionsByServiceType.forEach((serviceType, partitionsMap) -> { - applicationEventPublisher.publishEvent(new PartitionChangeEvent(this, serviceType, partitionsMap)); - }); + partitionsByServiceType.forEach(this::publishPartitionChangeEvent); } if (currentOtherServices == null) { @@ -340,6 +343,18 @@ public class HashPartitionService implements PartitionService { applicationEventPublisher.publishEvent(new ServiceListChangedEvent(otherServices, currentService)); } + private void publishPartitionChangeEvent(ServiceType serviceType, Map> partitionsMap) { + if (log.isDebugEnabled()) { + log.debug("Publishing partition change event for service type " + serviceType + ":" + System.lineSeparator() + + partitionsMap.entrySet().stream() + .map(entry -> entry.getKey() + " - " + entry.getValue().stream() + .map(TopicPartitionInfo::getFullTopicName).sorted() + .collect(Collectors.toList())) + .collect(Collectors.joining(System.lineSeparator()))); + } + applicationEventPublisher.publishEvent(new PartitionChangeEvent(this, serviceType, partitionsMap)); + } + @Override public Set getAllServiceIds(ServiceType serviceType) { return getAllServices(serviceType).stream().map(ServiceInfo::getServiceId).collect(Collectors.toSet()); @@ -505,6 +520,9 @@ public class HashPartitionService implements PartitionService { } responsibleServices.put(profileId, responsible); } + if (responsible.isEmpty()) { + return null; + } servers = responsible; } From 02390460464401734a6b564adfc28563bd918593 Mon Sep 17 00:00:00 2001 From: deaflynx Date: Fri, 15 Sep 2023 09:56:48 +0300 Subject: [PATCH 3/9] Edge instructions code wrapper style updated --- .../edge-instructions-dialog.component.scss | 31 ++++++++++++++++--- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/ui-ngx/src/app/modules/home/pages/edge/edge-instructions-dialog.component.scss b/ui-ngx/src/app/modules/home/pages/edge/edge-instructions-dialog.component.scss index a22671248a..092f3c6408 100644 --- a/ui-ngx/src/app/modules/home/pages/edge/edge-instructions-dialog.component.scss +++ b/ui-ngx/src/app/modules/home/pages/edge/edge-instructions-dialog.component.scss @@ -14,8 +14,11 @@ * limitations under the License. */ +@use '@angular/material' as mat; @import "../../../../../scss/constants"; +@import '../theme.scss'; +$tb-primary: mat.get-color-from-palette($tb-primary); :host { height: 100%; max-height: 100vh; @@ -63,7 +66,8 @@ .mat-mdc-dialog-content { max-height: 80vh; - padding: 16px; + padding: 0 16px 16px 16px; + border-top: 16px solid #fff; } } @@ -73,10 +77,10 @@ div.code-wrapper button.clipboard-btn { right: -2px !important; p { - color: #305680; + color: $tb-primary !important; } p, div { - background-color: #F3F6FA; + background-color: unset !important; } div { img { @@ -88,11 +92,17 @@ display: block; width: 18px; height: 18px; - background: #305680; + background: $tb-primary; mask-image: url(/assets/copy-code-icon.svg); mask-repeat: no-repeat; } } + a { + color: $tb-primary; + &:hover { + color: $tb-primary; + } + } &.multiline { right: -2px !important; } @@ -101,6 +111,12 @@ padding-right: unset !important; padding-left: unset !important; } + pre[class*="language-"] { + border: 1px solid $tb-primary !important; + } + div { + background-color: #F3F6FA; + } } .mdc-button__label > span { .mat-icon { @@ -109,6 +125,13 @@ } } + .mat-mdc-tab-header { + position: sticky; + top: 0; + z-index: 10; + background-color: #fff; + } + .tabs-icon { margin-right: 8px; } From fe8aaaa4d9fad48b3ba6081709a02a1a4269bdee Mon Sep 17 00:00:00 2001 From: ViacheslavKlimov Date: Fri, 15 Sep 2023 14:15:49 +0300 Subject: [PATCH 4/9] Fix HashPartitionServiceTest.testPartitionChangeEvents_isolatedProfile_oneCommonServer_oneDedicated --- .../server/queue/discovery/HashPartitionServiceTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/application/src/test/java/org/thingsboard/server/queue/discovery/HashPartitionServiceTest.java b/application/src/test/java/org/thingsboard/server/queue/discovery/HashPartitionServiceTest.java index 49008ab559..ef87794d96 100644 --- a/application/src/test/java/org/thingsboard/server/queue/discovery/HashPartitionServiceTest.java +++ b/application/src/test/java/org/thingsboard/server/queue/discovery/HashPartitionServiceTest.java @@ -338,7 +338,6 @@ public class HashPartitionServiceTest { .setQueueName(isolatedQueue.getName()) .build(); partitionService_dedicated.removeQueue(queueDeleteMsg); - partitionService_dedicated.recalculatePartitions(dedicatedRuleEngine, List.of(commonRuleEngine)); verifyPartitionChangeEvent(event -> { QueueKey queueKey = new QueueKey(ServiceType.TB_RULE_ENGINE, DataConstants.MAIN_QUEUE_NAME, tenantId); return event.getPartitionsMap().get(queueKey).isEmpty(); From 16e3a6e177b6ba766ee3b5bd3d0a0651cf5a704c Mon Sep 17 00:00:00 2001 From: Volodymyr Babak Date: Fri, 15 Sep 2023 16:39:58 +0300 Subject: [PATCH 5/9] edge tests stability: seq_id column - remove maxvalue. increased timeout for waiting on edge imitator respones --- .../java/org/thingsboard/server/edge/AssetEdgeTest.java | 6 +++--- .../java/org/thingsboard/server/edge/CustomerEdgeTest.java | 2 +- .../java/org/thingsboard/server/edge/DashboardEdgeTest.java | 2 +- .../java/org/thingsboard/server/edge/DeviceEdgeTest.java | 2 +- .../src/test/java/org/thingsboard/server/edge/EdgeTest.java | 2 +- .../org/thingsboard/server/edge/EntityViewEdgeTest.java | 2 +- .../java/org/thingsboard/server/edge/RuleChainEdgeTest.java | 2 +- .../java/org/thingsboard/server/edge/TelemetryEdgeTest.java | 4 ++++ .../test/java/org/thingsboard/server/edge/UserEdgeTest.java | 2 +- .../org/thingsboard/server/edge/imitator/EdgeImitator.java | 1 + application/src/test/resources/application-test.properties | 2 -- dao/src/test/resources/sql/system-test-psql.sql | 5 +---- 12 files changed, 16 insertions(+), 16 deletions(-) diff --git a/application/src/test/java/org/thingsboard/server/edge/AssetEdgeTest.java b/application/src/test/java/org/thingsboard/server/edge/AssetEdgeTest.java index faf0896b81..08ea322cb8 100644 --- a/application/src/test/java/org/thingsboard/server/edge/AssetEdgeTest.java +++ b/application/src/test/java/org/thingsboard/server/edge/AssetEdgeTest.java @@ -96,7 +96,7 @@ public class AssetEdgeTest extends AbstractEdgeTest { edgeImitator.expectMessageAmount(1); doDelete("/api/asset/" + savedAsset.getUuidId()) .andExpect(status().isOk()); - Assert.assertTrue(edgeImitator.waitForMessages(1)); + Assert.assertTrue(edgeImitator.waitForMessages(5)); // create asset #2 and assign to edge edgeImitator.expectMessageAmount(2); @@ -262,9 +262,9 @@ public class AssetEdgeTest extends AbstractEdgeTest { private Asset saveAssetOnCloudAndVerifyDeliveryToEdge() throws Exception { // create asset and assign to edge Asset savedAsset = saveAsset(StringUtils.randomAlphanumeric(15)); - edgeImitator.expectMessageAmount(1); // asset message + edgeImitator.expectMessageAmount(2); // asset and asset profile messages doPost("/api/edge/" + edge.getUuidId() - + "/asset/" + savedAsset.getUuidId(), Device.class); + + "/asset/" + savedAsset.getUuidId(), Asset.class); Assert.assertTrue(edgeImitator.waitForMessages()); Optional assetUpdateMsgOpt = edgeImitator.findMessageByType(AssetUpdateMsg.class); Assert.assertTrue(assetUpdateMsgOpt.isPresent()); diff --git a/application/src/test/java/org/thingsboard/server/edge/CustomerEdgeTest.java b/application/src/test/java/org/thingsboard/server/edge/CustomerEdgeTest.java index 251b4b4caf..6cc15837d9 100644 --- a/application/src/test/java/org/thingsboard/server/edge/CustomerEdgeTest.java +++ b/application/src/test/java/org/thingsboard/server/edge/CustomerEdgeTest.java @@ -42,7 +42,7 @@ public class CustomerEdgeTest extends AbstractEdgeTest { Customer customer = new Customer(); customer.setTitle("Edge Customer"); Customer savedCustomer = doPost("/api/customer", customer, Customer.class); - Assert.assertFalse(edgeImitator.waitForMessages(1)); + Assert.assertFalse(edgeImitator.waitForMessages(5)); // assign edge to customer edgeImitator.expectMessageAmount(2); diff --git a/application/src/test/java/org/thingsboard/server/edge/DashboardEdgeTest.java b/application/src/test/java/org/thingsboard/server/edge/DashboardEdgeTest.java index 2d21d30174..6180ced49c 100644 --- a/application/src/test/java/org/thingsboard/server/edge/DashboardEdgeTest.java +++ b/application/src/test/java/org/thingsboard/server/edge/DashboardEdgeTest.java @@ -99,7 +99,7 @@ public class DashboardEdgeTest extends AbstractEdgeTest { edgeImitator.expectMessageAmount(1); doDelete("/api/dashboard/" + savedDashboard.getUuidId()) .andExpect(status().isOk()); - Assert.assertTrue(edgeImitator.waitForMessages(1)); + Assert.assertTrue(edgeImitator.waitForMessages(5)); // create dashboard #2 and assign to edge edgeImitator.expectMessageAmount(1); diff --git a/application/src/test/java/org/thingsboard/server/edge/DeviceEdgeTest.java b/application/src/test/java/org/thingsboard/server/edge/DeviceEdgeTest.java index 15b15c0be0..aed99b4cba 100644 --- a/application/src/test/java/org/thingsboard/server/edge/DeviceEdgeTest.java +++ b/application/src/test/java/org/thingsboard/server/edge/DeviceEdgeTest.java @@ -106,7 +106,7 @@ public class DeviceEdgeTest extends AbstractEdgeTest { edgeImitator.expectMessageAmount(1); doDelete("/api/device/" + savedDevice.getUuidId()) .andExpect(status().isOk()); - Assert.assertTrue(edgeImitator.waitForMessages(1)); + Assert.assertTrue(edgeImitator.waitForMessages(5)); // create device #2 and assign to edge edgeImitator.expectMessageAmount(2); diff --git a/application/src/test/java/org/thingsboard/server/edge/EdgeTest.java b/application/src/test/java/org/thingsboard/server/edge/EdgeTest.java index 1f205af53a..fd34b0d973 100644 --- a/application/src/test/java/org/thingsboard/server/edge/EdgeTest.java +++ b/application/src/test/java/org/thingsboard/server/edge/EdgeTest.java @@ -39,7 +39,7 @@ public class EdgeTest extends AbstractEdgeTest { Customer customer = new Customer(); customer.setTitle("Edge Customer"); Customer savedCustomer = doPost("/api/customer", customer, Customer.class); - Assert.assertFalse(edgeImitator.waitForMessages(1)); + Assert.assertFalse(edgeImitator.waitForMessages(5)); // assign edge to customer edgeImitator.expectMessageAmount(2); diff --git a/application/src/test/java/org/thingsboard/server/edge/EntityViewEdgeTest.java b/application/src/test/java/org/thingsboard/server/edge/EntityViewEdgeTest.java index 470fd8e576..d56ded7014 100644 --- a/application/src/test/java/org/thingsboard/server/edge/EntityViewEdgeTest.java +++ b/application/src/test/java/org/thingsboard/server/edge/EntityViewEdgeTest.java @@ -105,7 +105,7 @@ public class EntityViewEdgeTest extends AbstractEdgeTest { edgeImitator.expectMessageAmount(1); doDelete("/api/entityView/" + savedEntityView.getUuidId()) .andExpect(status().isOk()); - Assert.assertTrue(edgeImitator.waitForMessages(1)); + Assert.assertTrue(edgeImitator.waitForMessages(5)); // create entity view #2 and assign to edge edgeImitator.expectMessageAmount(1); diff --git a/application/src/test/java/org/thingsboard/server/edge/RuleChainEdgeTest.java b/application/src/test/java/org/thingsboard/server/edge/RuleChainEdgeTest.java index 228a85fc91..848b115c72 100644 --- a/application/src/test/java/org/thingsboard/server/edge/RuleChainEdgeTest.java +++ b/application/src/test/java/org/thingsboard/server/edge/RuleChainEdgeTest.java @@ -229,6 +229,6 @@ public class RuleChainEdgeTest extends AbstractEdgeTest { edgeImitator.expectMessageAmount(1); doDelete("/api/ruleChain/" + savedRuleChain.getUuidId()) .andExpect(status().isOk()); - Assert.assertTrue(edgeImitator.waitForMessages(1)); + Assert.assertTrue(edgeImitator.waitForMessages(5)); } } diff --git a/application/src/test/java/org/thingsboard/server/edge/TelemetryEdgeTest.java b/application/src/test/java/org/thingsboard/server/edge/TelemetryEdgeTest.java index 2ee267b88c..922475f305 100644 --- a/application/src/test/java/org/thingsboard/server/edge/TelemetryEdgeTest.java +++ b/application/src/test/java/org/thingsboard/server/edge/TelemetryEdgeTest.java @@ -22,6 +22,7 @@ import com.google.protobuf.AbstractMessage; import org.awaitility.Awaitility; import org.junit.Assert; import org.junit.Test; +import org.springframework.test.context.TestPropertySource; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.Device; @@ -41,6 +42,9 @@ import java.util.List; import java.util.concurrent.TimeUnit; @DaoSqlTest +@TestPropertySource(properties = { + "edges.storage.sleep_between_batches=1000" +}) public class TelemetryEdgeTest extends AbstractEdgeTest { @Test diff --git a/application/src/test/java/org/thingsboard/server/edge/UserEdgeTest.java b/application/src/test/java/org/thingsboard/server/edge/UserEdgeTest.java index d1d555f691..3fd39328d5 100644 --- a/application/src/test/java/org/thingsboard/server/edge/UserEdgeTest.java +++ b/application/src/test/java/org/thingsboard/server/edge/UserEdgeTest.java @@ -120,7 +120,7 @@ public class UserEdgeTest extends AbstractEdgeTest { Customer customer = new Customer(); customer.setTitle("Edge Customer"); Customer savedCustomer = doPost("/api/customer", customer, Customer.class); - Assert.assertFalse(edgeImitator.waitForMessages(1)); + Assert.assertFalse(edgeImitator.waitForMessages(5)); // assign edge to customer edgeImitator.expectMessageAmount(2); diff --git a/application/src/test/java/org/thingsboard/server/edge/imitator/EdgeImitator.java b/application/src/test/java/org/thingsboard/server/edge/imitator/EdgeImitator.java index 9425001aac..f9efbb3ee1 100644 --- a/application/src/test/java/org/thingsboard/server/edge/imitator/EdgeImitator.java +++ b/application/src/test/java/org/thingsboard/server/edge/imitator/EdgeImitator.java @@ -173,6 +173,7 @@ public class EdgeImitator { } private ListenableFuture> processDownlinkMsg(DownlinkMsg downlinkMsg) { + log.trace("processDownlinkMsg: {}", downlinkMsg); List> result = new ArrayList<>(); if (downlinkMsg.getAdminSettingsUpdateMsgCount() > 0) { for (AdminSettingsUpdateMsg adminSettingsUpdateMsg : downlinkMsg.getAdminSettingsUpdateMsgList()) { diff --git a/application/src/test/resources/application-test.properties b/application/src/test/resources/application-test.properties index a964b0b700..d8943b47e9 100644 --- a/application/src/test/resources/application-test.properties +++ b/application/src/test/resources/application-test.properties @@ -11,8 +11,6 @@ transport.lwm2m.security.trust-credentials.keystore.store_file=lwm2m/credentials # Edge disabled to speed up the context init. Will be enabled by @TestPropertySource in respective tests edges.enabled=false -edges.storage.no_read_records_sleep=500 -edges.storage.sleep_between_batches=500 actors.rpc.submit_strategy=BURST queue.rule-engine.stats.enabled=true diff --git a/dao/src/test/resources/sql/system-test-psql.sql b/dao/src/test/resources/sql/system-test-psql.sql index 21af327f13..172731b9c5 100644 --- a/dao/src/test/resources/sql/system-test-psql.sql +++ b/dao/src/test/resources/sql/system-test-psql.sql @@ -1,5 +1,2 @@ --PostgreSQL specific truncate to fit constraints -TRUNCATE TABLE device_credentials, device, device_profile, asset, asset_profile, ota_package, rule_node_state, rule_node, rule_chain, alarm_comment, alarm, entity_alarm; - --- Decrease seq_id column to make sure to cover cases of new sequential cycle during the tests -ALTER SEQUENCE edge_event_seq_id_seq MAXVALUE 256; +TRUNCATE TABLE device_credentials, device, device_profile, asset, asset_profile, ota_package, rule_node_state, rule_node, rule_chain, alarm_comment, alarm, entity_alarm; \ No newline at end of file From 3c6d70b2c4a114b757eaad1f2033fd7244948aac Mon Sep 17 00:00:00 2001 From: Volodymyr Babak Date: Fri, 15 Sep 2023 16:49:36 +0300 Subject: [PATCH 6/9] edge test speed up --- .../java/org/thingsboard/server/edge/AbstractEdgeTest.java | 3 ++- .../java/org/thingsboard/server/edge/TelemetryEdgeTest.java | 4 ---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/application/src/test/java/org/thingsboard/server/edge/AbstractEdgeTest.java b/application/src/test/java/org/thingsboard/server/edge/AbstractEdgeTest.java index 410348762f..689847416c 100644 --- a/application/src/test/java/org/thingsboard/server/edge/AbstractEdgeTest.java +++ b/application/src/test/java/org/thingsboard/server/edge/AbstractEdgeTest.java @@ -102,7 +102,8 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. @TestPropertySource(properties = { "edges.enabled=true", - "queue.rule-engine.stats.enabled=false" + "queue.rule-engine.stats.enabled=false", + "edges.storage.sleep_between_batches=1000" }) abstract public class AbstractEdgeTest extends AbstractControllerTest { diff --git a/application/src/test/java/org/thingsboard/server/edge/TelemetryEdgeTest.java b/application/src/test/java/org/thingsboard/server/edge/TelemetryEdgeTest.java index 922475f305..2ee267b88c 100644 --- a/application/src/test/java/org/thingsboard/server/edge/TelemetryEdgeTest.java +++ b/application/src/test/java/org/thingsboard/server/edge/TelemetryEdgeTest.java @@ -22,7 +22,6 @@ import com.google.protobuf.AbstractMessage; import org.awaitility.Awaitility; import org.junit.Assert; import org.junit.Test; -import org.springframework.test.context.TestPropertySource; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.Device; @@ -42,9 +41,6 @@ import java.util.List; import java.util.concurrent.TimeUnit; @DaoSqlTest -@TestPropertySource(properties = { - "edges.storage.sleep_between_batches=1000" -}) public class TelemetryEdgeTest extends AbstractEdgeTest { @Test From 6f264dd698608fda821bfbb1dd5fa8b573c16c21 Mon Sep 17 00:00:00 2001 From: deaflynx Date: Fri, 15 Sep 2023 17:42:04 +0300 Subject: [PATCH 7/9] Edge instructions css optimization --- .../edge-instructions-dialog.component.scss | 61 ++++++++----------- 1 file changed, 26 insertions(+), 35 deletions(-) diff --git a/ui-ngx/src/app/modules/home/pages/edge/edge-instructions-dialog.component.scss b/ui-ngx/src/app/modules/home/pages/edge/edge-instructions-dialog.component.scss index 092f3c6408..54dc438011 100644 --- a/ui-ngx/src/app/modules/home/pages/edge/edge-instructions-dialog.component.scss +++ b/ui-ngx/src/app/modules/home/pages/edge/edge-instructions-dialog.component.scss @@ -14,11 +14,8 @@ * limitations under the License. */ -@use '@angular/material' as mat; @import "../../../../../scss/constants"; -@import '../theme.scss'; -$tb-primary: mat.get-color-from-palette($tb-primary); :host { height: 100%; max-height: 100vh; @@ -74,37 +71,34 @@ $tb-primary: mat.get-color-from-palette($tb-primary); :host ::ng-deep { .tb-markdown-view { padding: 16px 16px 32px 16px; - div.code-wrapper button.clipboard-btn { - right: -2px !important; - p { - color: $tb-primary !important; - } - p, div { - background-color: unset !important; - } - div { - img { - display: none; + div { + background-color: #F3F6FA; + &.code-wrapper button.clipboard-btn { + right: -2px !important; + p { + color: $tb-primary-color !important; } - &:after { - content: ""; - position: initial; - display: block; - width: 18px; - height: 18px; - background: $tb-primary; - mask-image: url(/assets/copy-code-icon.svg); - mask-repeat: no-repeat; + p, div { + background-color: unset !important; } - } - a { - color: $tb-primary; - &:hover { - color: $tb-primary; + div { + img { + display: none; + } + &:after { + content: ""; + position: initial; + display: block; + width: 18px; + height: 18px; + background: $tb-primary-color; + mask-image: url(/assets/copy-code-icon.svg); + mask-repeat: no-repeat; + } + } + &.multiline { + right: -2px !important; } - } - &.multiline { - right: -2px !important; } } & > *:not(ul) { @@ -112,10 +106,7 @@ $tb-primary: mat.get-color-from-palette($tb-primary); padding-left: unset !important; } pre[class*="language-"] { - border: 1px solid $tb-primary !important; - } - div { - background-color: #F3F6FA; + border: 1px solid $tb-primary-color !important; } } .mdc-button__label > span { From f08f3ea9219b0c70c543dff0bd2dfda1d15e4c07 Mon Sep 17 00:00:00 2001 From: Andrii Shvaika Date: Mon, 18 Sep 2023 12:51:01 +0300 Subject: [PATCH 8/9] Replace the image URL to CDN --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 581e71977d..d479296869 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ ThingsBoard documentation is hosted on [thingsboard.io](https://thingsboard.io/d [![Smart farming](https://user-images.githubusercontent.com/8308069/152984443-a98b7d3d-ff7a-4037-9011-e71e1e6f755f.gif "Smart farming")](https://thingsboard.io/smart-farming/) [**IoT Rule Engine**](https://thingsboard.io/docs/user-guide/rule-engine-2-0/re-getting-started/) -[![IoT Rule Engine](https://thingsboard.io/images/demo/send-email-rule-chain.gif "IoT Rule Engine")](https://thingsboard.io/docs/user-guide/rule-engine-2-0/re-getting-started/) +[![IoT Rule Engine](https://img.thingsboard.io/demo/send-email-rule-chain.gif "IoT Rule Engine")](https://thingsboard.io/docs/user-guide/rule-engine-2-0/re-getting-started/) [**Smart metering**](https://thingsboard.io/smart-metering/) [![Smart metering](https://user-images.githubusercontent.com/8308069/31455788-6888a948-aec1-11e7-9819-410e0ba785e0.gif "Smart metering")](https://thingsboard.io/smart-metering/) From e4acb717f3459d54ef5f5e243ccba2bce2a53627 Mon Sep 17 00:00:00 2001 From: Volodymyr Babak Date: Mon, 18 Sep 2023 14:52:50 +0300 Subject: [PATCH 9/9] Added SNMP_ENABLED=false for install edge instructions in case TB is already running on the same PC --- .../data/json/edge/install_instructions/centos/instructions.md | 1 + .../data/json/edge/install_instructions/ubuntu/instructions.md | 1 + 2 files changed, 2 insertions(+) diff --git a/application/src/main/data/json/edge/install_instructions/centos/instructions.md b/application/src/main/data/json/edge/install_instructions/centos/instructions.md index 0e9bf251c3..126c79b641 100644 --- a/application/src/main/data/json/edge/install_instructions/centos/instructions.md +++ b/application/src/main/data/json/edge/install_instructions/centos/instructions.md @@ -199,6 +199,7 @@ export HTTP_BIND_PORT=18080 export MQTT_BIND_PORT=11883 export COAP_BIND_PORT=15683 export LWM2M_ENABLED=false +export SNMP_ENABLED=false EOL' {:copy-code} ``` diff --git a/application/src/main/data/json/edge/install_instructions/ubuntu/instructions.md b/application/src/main/data/json/edge/install_instructions/ubuntu/instructions.md index 72b85e5190..425c08662b 100644 --- a/application/src/main/data/json/edge/install_instructions/ubuntu/instructions.md +++ b/application/src/main/data/json/edge/install_instructions/ubuntu/instructions.md @@ -131,6 +131,7 @@ export HTTP_BIND_PORT=18080 export MQTT_BIND_PORT=11883 export COAP_BIND_PORT=15683 export LWM2M_ENABLED=false +export SNMP_ENABLED=false EOL' {:copy-code} ```