The test verifies ctx.transformMsg(...), which exercises the response-
processing path. Without DirectListeningExecutor, the Reactor scheduler
is unavailable and the node calls ctx.tellFailure() instead.
Relax version check to allow maintenance digit increases within the same
LTS family (e.g. 4.3.0 -> 4.3.1), not just patch digit increases.
Add LTS SQL schema patch execution from upgrade/lts/schema_update.sql,
running before views and widget updates so schema changes are in place
for dependent objects.
Replace the blocking semaphore guard with a non-blocking bounded FIFO queue
+ semaphore pattern:
- No semaphore/queue when maxParallelRequestsCount=0 (default): direct doHttpCall,
identical to the old behavior.
- When a concurrency limit is set, incoming messages are enqueued via non-blocking
offer(); a full queue triggers onFailure immediately.
- tryProcess() acquires one semaphore slot and dispatches the next valid queued task.
Stale tasks (batch deadline expired) are dropped and the slot reused in the same pass.
- doFinally hook releases the semaphore and calls tryProcess() exactly once after any
terminal signal (success, error, cancel), preventing double-release and permit leaks.
- publishOn(externalCallExecutor) moves callbacks off reactor-netty I/O threads.
System-level safety caps are wired through thingsboard.yml → ActorSystemContext →
TbContext → TbHttpClient, scoped to rule-engine services only via @TbRuleEngineComponent:
actors.rule.external.http_client.max_parallel_requests (ACTORS_RULE_EXTERNAL_HTTP_CLIENT_MAX_PARALLEL_REQUESTS)
actors.rule.external.http_client.max_pending_requests (ACTORS_RULE_EXTERNAL_HTTP_CLIENT_MAX_PENDING_REQUESTS)
actors.rule.external.http_client.pool_max_connections (ACTORS_RULE_EXTERNAL_HTTP_CLIENT_POOL_MAX_CONNECTIONS)
Backward compat: TB_RE_HTTP_CLIENT_POOL_MAX_CONNECTIONS still honored via yaml fallback.
Observability: five AtomicLong counters (dispatched, success, failure, droppedQueueFull,
droppedStale) with periodic WARN anomaly logging including semaphorePermits for leak detection.
No configuration changes or upgrade scripts required — docker image update is sufficient.
Rename RestApiCallNodeSettings to TbHttpClientSettings
The settings are about HTTP client transport concerns (connection pool,
concurrency, queue depth), not REST API Call node business logic.
The new name matches the consumer (TbHttpClient) and the YAML path
(actors.rule.external.http_client.*).
Removed overflow:hidden from DynamicFormSelectItemsComponent that was hiding the Value/Label table headers and "No options configured" message. Added overflow-visible to nested dynamic-form-properties to prevent clipping in expansion panels.
Add optional roundDown parameter that uses Math.floor instead of
Math.round when abbreviating numbers. This prevents values like
3993979 from rounding up to 4M, showing 3.9M instead.
Also improve typing: replace any with ShortNumberArgs interface
and ensure transform always returns string.
The sanitize function escaped all @, {, } characters to prevent Angular
from interpreting markdown content as template syntax. With Angular 17+
control flow (@if, @for, @switch, @let, @defer), users need these
constructs to be preserved and compiled.
Extract sanitization logic into markdown-sanitize.helper.ts with a
config-driven pipeline:
- Protect <pre> code blocks from processing
- Extract and preserve control flow blocks (@if/@else, @for/@empty,
@switch/@case/@default, @defer/@placeholder/@loading/@error, @let)
- Decode HTML entities (', ", <, >, &) introduced
by markdown parser inside control flow expressions
- Escape @, {, } only in remaining non-Angular text
- Validate @let to avoid false matches in prose (e.g. headings)
- Handle chain keywords with proper whitespace skipping
- Handle optional parenthesized params (@loading (minimum 300ms))
Add OpenFreeMap as a new built-in map provider with Bright, Positron, and
Liberty styles. It becomes the default roadmap layer for new geo map widgets.
No API key required.
Extend the Custom provider with a "Vector tiles" toggle that allows using
MapLibre GL style URLs from providers like OpenFreeMap or MapTiler, alongside
the existing raster tile URL support. Add optional attribution field for
custom providers. Fully backward compatible with existing widget configurations.