From a9394b8fb6751f4850f2019740069b244e74edc1 Mon Sep 17 00:00:00 2001 From: Sergey Matvienko Date: Fri, 6 Mar 2026 00:19:58 +0100 Subject: [PATCH 1/6] Fix node_modules pollution between builds in parallel Maven execution MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When building with -T6, multiple JS modules run yarn install concurrently. The --mutex network flag serializes yarn processes, but if node_modules from a previous build (or a different branch/version) is left on disk, yarn may skip reinstalling packages — including devDependencies — treating the stale state as up-to-date. This causes tools like tsc to be missing at build time. Configure maven-clean-plugin to delete node_modules during mvn clean for all JS modules (ui-ngx, msa/js-executor, msa/web-ui). Yarn restores from its global cache (~/.cache/yarn), so the overhead is relinking only. Co-Authored-By: Claude Sonnet 4.6 --- msa/js-executor/pom.xml | 11 +++++++++++ msa/web-ui/pom.xml | 11 +++++++++++ ui-ngx/pom.xml | 11 +++++++++++ 3 files changed, 33 insertions(+) diff --git a/msa/js-executor/pom.xml b/msa/js-executor/pom.xml index 38cb484aee..b333349bd3 100644 --- a/msa/js-executor/pom.xml +++ b/msa/js-executor/pom.xml @@ -96,6 +96,17 @@ + + org.apache.maven.plugins + maven-clean-plugin + + + + ${basedir}/node_modules + + + + org.apache.maven.plugins maven-dependency-plugin diff --git a/msa/web-ui/pom.xml b/msa/web-ui/pom.xml index d1664b1311..93a56957dc 100644 --- a/msa/web-ui/pom.xml +++ b/msa/web-ui/pom.xml @@ -105,6 +105,17 @@ + + org.apache.maven.plugins + maven-clean-plugin + + + + ${basedir}/node_modules + + + + org.apache.maven.plugins maven-dependency-plugin diff --git a/ui-ngx/pom.xml b/ui-ngx/pom.xml index 389177c028..e971854fb4 100644 --- a/ui-ngx/pom.xml +++ b/ui-ngx/pom.xml @@ -71,6 +71,17 @@ + + org.apache.maven.plugins + maven-clean-plugin + + + + ${basedir}/node_modules + + + + From 5629302bdba7e8172de1b10cb49055c5154d33ae Mon Sep 17 00:00:00 2001 From: Sergey Matvienko Date: Fri, 6 Mar 2026 08:46:54 +0100 Subject: [PATCH 2/6] Align typescript version to ~5.9.3 across all JS modules --- msa/js-executor/package.json | 2 +- msa/web-ui/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/msa/js-executor/package.json b/msa/js-executor/package.json index bbfde94801..0efd464f30 100644 --- a/msa/js-executor/package.json +++ b/msa/js-executor/package.json @@ -39,7 +39,7 @@ "fs-extra": "^11.3.1", "nodemon": "^3.1.10", "ts-node": "^10.9.2", - "typescript": "5.9.2" + "typescript": "~5.9.3" }, "resolutions": { "@yao-pkg/pkg/tar": ">=7.5.8" diff --git a/msa/web-ui/package.json b/msa/web-ui/package.json index 98fd067e37..87f09128f6 100644 --- a/msa/web-ui/package.json +++ b/msa/web-ui/package.json @@ -42,7 +42,7 @@ "fs-extra": "^11.3.1", "nodemon": "^3.1.10", "ts-node": "^10.9.2", - "typescript": "5.9.2" + "typescript": "~5.9.3" }, "resolutions": { "@yao-pkg/pkg/tar": ">=7.5.8" From 1738ad3ef10468a776c982b43e744d3967c054b5 Mon Sep 17 00:00:00 2001 From: Sergey Matvienko Date: Fri, 6 Mar 2026 08:52:35 +0100 Subject: [PATCH 3/6] =?UTF-8?q?Update=20yarn.lock:=20typescript=205.9.2=20?= =?UTF-8?q?=E2=86=92=205.9.3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- msa/js-executor/yarn.lock | 8 ++++---- msa/web-ui/yarn.lock | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/msa/js-executor/yarn.lock b/msa/js-executor/yarn.lock index 4d80300b56..6457be1de7 100644 --- a/msa/js-executor/yarn.lock +++ b/msa/js-executor/yarn.lock @@ -1634,10 +1634,10 @@ type-is@^2.0.0, type-is@^2.0.1: media-typer "^1.1.0" mime-types "^3.0.0" -typescript@5.9.2: - version "5.9.2" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.9.2.tgz#d93450cddec5154a2d5cabe3b8102b83316fb2a6" - integrity sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A== +typescript@~5.9.3: + version "5.9.3" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.9.3.tgz#5b4f59e15310ab17a216f5d6cf53ee476ede670f" + integrity sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw== undefsafe@^2.0.5: version "2.0.5" diff --git a/msa/web-ui/yarn.lock b/msa/web-ui/yarn.lock index 456abcc488..11a708d8bf 100644 --- a/msa/web-ui/yarn.lock +++ b/msa/web-ui/yarn.lock @@ -1716,10 +1716,10 @@ type-is@^2.0.0, type-is@^2.0.1: media-typer "^1.1.0" mime-types "^3.0.0" -typescript@5.9.2: - version "5.9.2" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.9.2.tgz#d93450cddec5154a2d5cabe3b8102b83316fb2a6" - integrity sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A== +typescript@~5.9.3: + version "5.9.3" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.9.3.tgz#5b4f59e15310ab17a216f5d6cf53ee476ede670f" + integrity sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw== undefsafe@^2.0.5: version "2.0.5" From 680e906aa82638a1523607bbe63ec96aa7b0f50e Mon Sep 17 00:00:00 2001 From: Sergey Matvienko Date: Fri, 6 Mar 2026 11:38:37 +0100 Subject: [PATCH 4/6] Add --check-files to yarn install to enforce node_modules integrity --- msa/js-executor/pom.xml | 2 +- msa/web-ui/pom.xml | 2 +- ui-ngx/pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/msa/js-executor/pom.xml b/msa/js-executor/pom.xml index b333349bd3..c00257c0ac 100644 --- a/msa/js-executor/pom.xml +++ b/msa/js-executor/pom.xml @@ -81,7 +81,7 @@ yarn - install --non-interactive --network-concurrency 4 --network-timeout 100000 --mutex network + install --non-interactive --check-files --network-concurrency 4 --network-timeout 100000 --mutex network diff --git a/msa/web-ui/pom.xml b/msa/web-ui/pom.xml index 93a56957dc..59d22b47c8 100644 --- a/msa/web-ui/pom.xml +++ b/msa/web-ui/pom.xml @@ -90,7 +90,7 @@ yarn - install --non-interactive --network-concurrency 4 --network-timeout 100000 --mutex network + install --non-interactive --check-files --network-concurrency 4 --network-timeout 100000 --mutex network diff --git a/ui-ngx/pom.xml b/ui-ngx/pom.xml index e971854fb4..760addb451 100644 --- a/ui-ngx/pom.xml +++ b/ui-ngx/pom.xml @@ -66,7 +66,7 @@ yarn - install --non-interactive --network-concurrency 4 --network-timeout 100000 --mutex network + install --non-interactive --check-files --network-concurrency 4 --network-timeout 100000 --mutex network From 49341412a1ee509d4f908c463b936867f9c94b58 Mon Sep 17 00:00:00 2001 From: Vladyslav_Prykhodko Date: Fri, 6 Mar 2026 13:00:21 +0200 Subject: [PATCH 5/6] Fix old extensions loading: Force standalone false for pipe declared inside module. --- ui-ngx/src/app/core/services/resources.service.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/ui-ngx/src/app/core/services/resources.service.ts b/ui-ngx/src/app/core/services/resources.service.ts index 2929de8b6c..93b1b616b9 100644 --- a/ui-ngx/src/app/core/services/resources.service.ts +++ b/ui-ngx/src/app/core/services/resources.service.ts @@ -24,7 +24,9 @@ import { ɵCssSelectorList, ɵNG_COMP_DEF, ɵNG_MOD_DEF, + ɵNG_PIPE_DEF, ɵNgModuleDef, + ɵPipeDef, DOCUMENT } from '@angular/core'; @@ -302,6 +304,12 @@ export class ResourcesService { (component as any).standalone = false; } } + if (ɵNG_PIPE_DEF in decl) { + const pipe: ɵPipeDef = decl[ɵNG_PIPE_DEF]; + if (isUndefined(pipe.standalone) || pipe.standalone) { + (pipe as any).standalone = false; + } + } } } modulesWithComponents.modules.push(moduleInfo); From cc35e71e553c8ed7b6701ae524f89e810d250e35 Mon Sep 17 00:00:00 2001 From: Sergey Matvienko Date: Thu, 5 Mar 2026 17:16:20 +0100 Subject: [PATCH 6/6] fix: await RPC re-queuing after session close on delivery timeout MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After the MQTT transport closes the session on RPC delivery timeout, the server re-queues the RPC asynchronously. The test was asserting the RPC status immediately after the client disconnect latch fired, before the server-side re-queuing had completed — so the status was still SENT instead of the expected QUEUED. Replace the direct doGet assertion with an Awaitility poll that waits up to DEFAULT_WAIT_TIMEOUT_SECONDS for the status to become QUEUED. Fixes flaky: MqttV5CloseTransportSessionOnRpcDeliveryTimeoutIntegrationTest Co-Authored-By: Claude Sonnet 4.6 --- ...nsportSessionOnRpcDeliveryTimeoutIntegrationTest.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/rpc/MqttV5CloseTransportSessionOnRpcDeliveryTimeoutIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/rpc/MqttV5CloseTransportSessionOnRpcDeliveryTimeoutIntegrationTest.java index 23aa5133c5..1c9aa40a40 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/rpc/MqttV5CloseTransportSessionOnRpcDeliveryTimeoutIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv5/rpc/MqttV5CloseTransportSessionOnRpcDeliveryTimeoutIntegrationTest.java @@ -42,6 +42,7 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import static org.assertj.core.api.Assertions.assertThat; +import static org.awaitility.Awaitility.await; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import static org.thingsboard.server.common.data.device.profile.MqttTopics.DEVICE_RPC_REQUESTS_SUB_TOPIC; @@ -97,7 +98,13 @@ public class MqttV5CloseTransportSessionOnRpcDeliveryTimeoutIntegrationTest exte callback.getDisconnectLatch().await(DEFAULT_WAIT_TIMEOUT_SECONDS, TimeUnit.SECONDS); assertThat(callback.getReturnCode()).isEqualTo(MqttReturnCode.RETURN_CODE_ADMINISTRITIVE_ACTION); - Rpc persistedRpc = doGet("/api/rpc/persistent/" + response.get("rpcId").asText(), Rpc.class); + // The server re-queues the RPC asynchronously after closing the session. + // Poll until the status transitions from SENT to QUEUED. + String rpcId = response.get("rpcId").asText(); + Rpc persistedRpc = await("RPC re-queued after session close") + .atMost(DEFAULT_WAIT_TIMEOUT_SECONDS, TimeUnit.SECONDS) + .until(() -> doGet("/api/rpc/persistent/" + rpcId, Rpc.class), + rpc -> RpcStatus.QUEUED.equals(rpc.getStatus())); assertThat(persistedRpc).isNotNull(); assertThat(persistedRpc.getStatus()).isEqualTo(RpcStatus.QUEUED); assertThat(persistedRpc.getResponse()).isInstanceOf(NullNode.class);