From 1042ab8d16956ded6615691ec8aabd9a1a27a674 Mon Sep 17 00:00:00 2001 From: Ekaterina Chantsova Date: Wed, 11 Jun 2025 19:29:59 +0300 Subject: [PATCH 01/17] UI: fixed updating timewindow configuration --- ui-ngx/src/app/shared/models/time/time.models.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui-ngx/src/app/shared/models/time/time.models.ts b/ui-ngx/src/app/shared/models/time/time.models.ts index acb62d9d2a..c204cb6867 100644 --- a/ui-ngx/src/app/shared/models/time/time.models.ts +++ b/ui-ngx/src/app/shared/models/time/time.models.ts @@ -431,7 +431,7 @@ export const initModelFromDefaultTimewindow = (value: Timewindow, quickIntervalO if (isDefined(value.history.quickInterval)) { model.history.quickInterval = value.history.quickInterval; } - if (isDefined(value.history.fixedTimewindow)) { + if (isDefinedAndNotNull(value.history.fixedTimewindow)) { if (isDefined(value.history.fixedTimewindow.startTimeMs)) { model.history.fixedTimewindow.startTimeMs = value.history.fixedTimewindow.startTimeMs; } From a51600f30ea6bdb53c3ddbe004da7944d771534c Mon Sep 17 00:00:00 2001 From: Artem Dzhereleiko Date: Fri, 13 Jun 2025 11:21:42 +0300 Subject: [PATCH 02/17] UI: Fixed knob and digital gauge decimals setting --- .../gauge/digital-simple-gauge-basic-config.component.ts | 7 +++++-- .../home/components/widget/lib/rpc/knob.component.ts | 4 ++-- .../control/knob-control-widget-settings.component.ts | 2 +- .../gauge/digital-gauge-widget-settings.component.ts | 6 +++++- .../app/shared/models/widget/rpc/knob.component.models.ts | 4 ++-- 5 files changed, 15 insertions(+), 8 deletions(-) diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/gauge/digital-simple-gauge-basic-config.component.ts b/ui-ngx/src/app/modules/home/components/widget/config/basic/gauge/digital-simple-gauge-basic-config.component.ts index 67497b0b6e..9e2c46ec13 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/basic/gauge/digital-simple-gauge-basic-config.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/gauge/digital-simple-gauge-basic-config.component.ts @@ -30,7 +30,7 @@ import { getTimewindowConfig, setTimewindowConfig } from '@home/components/widget/config/timewindow-config-panel.component'; -import { formatValue, isUndefined } from '@core/utils'; +import { formatValue, isDefinedAndNotNull, isUndefined } from '@core/utils'; import { Component } from '@angular/core'; import { convertLevelColorsSettingsToColorProcessor, @@ -115,7 +115,7 @@ export class DigitalSimpleGaugeBasicConfigComponent extends BasicWidgetConfigCom minMaxColor: [settings.minMaxFont?.color, []], showValue: [settings.showValue, []], - decimals: [configData.config.decimals, []], + decimals: [configData.config.decimals || settings.decimals, []], units: [configData.config.units, []], valueFont: [settings.valueFont, []], valueColor: [settings.valueFont?.color, []], @@ -157,6 +157,9 @@ export class DigitalSimpleGaugeBasicConfigComponent extends BasicWidgetConfigCom this.widgetConfig.config.settings.showValue = config.showValue; this.widgetConfig.config.units = config.units; this.widgetConfig.config.decimals = config.decimals; + if (isDefinedAndNotNull(this.widgetConfig.config.settings.decimals)) { + this.widgetConfig.config.settings.decimals = null; + } this.widgetConfig.config.settings.valueFont = config.valueFont; this.widgetConfig.config.settings.valueFont.color = config.valueColor; diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/rpc/knob.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/rpc/knob.component.ts index 8c1fc3ab2a..1b93538b6c 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/rpc/knob.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/rpc/knob.component.ts @@ -145,7 +145,7 @@ export class KnobComponent extends BasicActionWidgetComponent implements OnInit, this.valueFormat = ValueFormatProcessor.fromSettings(this.ctx.$injector, { units: this.ctx.units, - decimals: this.ctx.decimals, + decimals: this.ctx.decimals || 0, showZeroDecimals: true }); @@ -299,7 +299,7 @@ export class KnobComponent extends BasicActionWidgetComponent implements OnInit, } private turn(ratio: number) { - this.newValue = Number((this.minValue + (this.maxValue - this.minValue) * ratio).toFixed(this.ctx.decimals)); + this.newValue = Number((this.minValue + (this.maxValue - this.minValue) * ratio).toFixed(this.ctx.decimals || 0)); if (this.canvasBar.value !== this.newValue) { this.canvasBar.value = this.newValue; } diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/knob-control-widget-settings.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/knob-control-widget-settings.component.ts index e5c57474c2..26a5d6cd4e 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/knob-control-widget-settings.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/knob-control-widget-settings.component.ts @@ -57,7 +57,7 @@ export class KnobControlWidgetSettingsComponent extends WidgetSettingsComponent protected prepareInputSettings(settings: WidgetSettings): WidgetSettings { const knobSettings = prepareKnobSettings(deepClone(settings) as any) as WidgetSettings; - knobSettings.valueDecimals = this.widgetConfig?.config?.decimals ?? 2; + knobSettings.valueDecimals = this.widgetConfig?.config?.decimals; knobSettings.valueUnits = deepClone(this.widgetConfig?.config?.units); return super.prepareInputSettings(knobSettings); } diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/gauge/digital-gauge-widget-settings.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/gauge/digital-gauge-widget-settings.component.ts index 7276c0e27d..9f095cdff0 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/gauge/digital-gauge-widget-settings.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/gauge/digital-gauge-widget-settings.component.ts @@ -37,7 +37,7 @@ import { digitalGaugeLayoutTranslations, DigitalGaugeType } from '@home/components/widget/lib/digital-gauge.models'; -import { formatValue } from '@core/utils'; +import { formatValue, isDefinedAndNotNull } from '@core/utils'; import { ColorSettings, ColorType, @@ -247,6 +247,10 @@ export class DigitalGaugeWidgetSettingsComponent extends WidgetSettingsComponent settings.titleFont.color = this.digitalGaugeWidgetSettingsForm.get('titleColor').value; settings.labelFont.color = this.digitalGaugeWidgetSettingsForm.get('labelColor').value; + if (isDefinedAndNotNull(settings.decimals)) { + settings.decimals = null; + } + return settings; } diff --git a/ui-ngx/src/app/shared/models/widget/rpc/knob.component.models.ts b/ui-ngx/src/app/shared/models/widget/rpc/knob.component.models.ts index 47b73f5a08..3ac15bf70c 100644 --- a/ui-ngx/src/app/shared/models/widget/rpc/knob.component.models.ts +++ b/ui-ngx/src/app/shared/models/widget/rpc/knob.component.models.ts @@ -45,7 +45,7 @@ export const knobWidgetDefaultSettings: KnobSettings = { defaultValue: 50, executeRpc: { method: 'getValue', - requestTimeout: 500, + requestTimeout: 5000, requestPersistent: false, persistentPollingInterval: 5000 }, @@ -70,7 +70,7 @@ export const knobWidgetDefaultSettings: KnobSettings = { action: SetValueAction.EXECUTE_RPC, executeRpc: { method: 'setValue', - requestTimeout: 500, + requestTimeout: 5000, requestPersistent: false, persistentPollingInterval: 5000 }, From f7bc348513aee3247941c93931d676d1bcd9481b Mon Sep 17 00:00:00 2001 From: Artem Dzhereleiko Date: Fri, 13 Jun 2025 11:53:33 +0300 Subject: [PATCH 03/17] UI: delete unused settings --- .../gauge/digital-simple-gauge-basic-config.component.ts | 6 +++--- .../home/components/widget/lib/rpc/knob.component.ts | 6 ++++-- .../gauge/digital-gauge-widget-settings.component.ts | 6 +++--- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/gauge/digital-simple-gauge-basic-config.component.ts b/ui-ngx/src/app/modules/home/components/widget/config/basic/gauge/digital-simple-gauge-basic-config.component.ts index 9e2c46ec13..aa93a56a4c 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/basic/gauge/digital-simple-gauge-basic-config.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/gauge/digital-simple-gauge-basic-config.component.ts @@ -30,7 +30,7 @@ import { getTimewindowConfig, setTimewindowConfig } from '@home/components/widget/config/timewindow-config-panel.component'; -import { formatValue, isDefinedAndNotNull, isUndefined } from '@core/utils'; +import { formatValue, isDefined, isUndefined } from '@core/utils'; import { Component } from '@angular/core'; import { convertLevelColorsSettingsToColorProcessor, @@ -157,8 +157,8 @@ export class DigitalSimpleGaugeBasicConfigComponent extends BasicWidgetConfigCom this.widgetConfig.config.settings.showValue = config.showValue; this.widgetConfig.config.units = config.units; this.widgetConfig.config.decimals = config.decimals; - if (isDefinedAndNotNull(this.widgetConfig.config.settings.decimals)) { - this.widgetConfig.config.settings.decimals = null; + if (isDefined(this.widgetConfig.config.settings.decimals)) { + delete this.widgetConfig.config.settings.decimals; } this.widgetConfig.config.settings.valueFont = config.valueFont; this.widgetConfig.config.settings.valueFont.color = config.valueColor; diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/rpc/knob.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/rpc/knob.component.ts index 1b93538b6c..f28b5e8f92 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/rpc/knob.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/rpc/knob.component.ts @@ -57,6 +57,7 @@ export class KnobComponent extends BasicActionWidgetComponent implements OnInit, maxValue: number; newValue = 0; + private decimals: number; private startDeg = -1; private currentDeg = 0; private rotation = 0; @@ -143,9 +144,10 @@ export class KnobComponent extends BasicActionWidgetComponent implements OnInit, actionLabel: this.ctx.translate.instant('widgets.slider.on-value-change')}; this.valueSetter = this.createValueSetter(valueChangeSettings); + this.decimals = isDefined(this.ctx.decimals) ? this.ctx.decimals : 0; this.valueFormat = ValueFormatProcessor.fromSettings(this.ctx.$injector, { units: this.ctx.units, - decimals: this.ctx.decimals || 0, + decimals: this.decimals, showZeroDecimals: true }); @@ -299,7 +301,7 @@ export class KnobComponent extends BasicActionWidgetComponent implements OnInit, } private turn(ratio: number) { - this.newValue = Number((this.minValue + (this.maxValue - this.minValue) * ratio).toFixed(this.ctx.decimals || 0)); + this.newValue = Number((this.minValue + (this.maxValue - this.minValue) * ratio).toFixed(this.decimals)); if (this.canvasBar.value !== this.newValue) { this.canvasBar.value = this.newValue; } diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/gauge/digital-gauge-widget-settings.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/gauge/digital-gauge-widget-settings.component.ts index 9f095cdff0..1f3ae36089 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/gauge/digital-gauge-widget-settings.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/gauge/digital-gauge-widget-settings.component.ts @@ -37,7 +37,7 @@ import { digitalGaugeLayoutTranslations, DigitalGaugeType } from '@home/components/widget/lib/digital-gauge.models'; -import { formatValue, isDefinedAndNotNull } from '@core/utils'; +import { formatValue, isDefined } from '@core/utils'; import { ColorSettings, ColorType, @@ -247,8 +247,8 @@ export class DigitalGaugeWidgetSettingsComponent extends WidgetSettingsComponent settings.titleFont.color = this.digitalGaugeWidgetSettingsForm.get('titleColor').value; settings.labelFont.color = this.digitalGaugeWidgetSettingsForm.get('labelColor').value; - if (isDefinedAndNotNull(settings.decimals)) { - settings.decimals = null; + if (isDefined(settings.decimals)) { + delete settings.decimals; } return settings; From 722aa6a77bf7b1fc8361806e639392a814410845 Mon Sep 17 00:00:00 2001 From: Artem Dzhereleiko Date: Fri, 13 Jun 2025 11:59:08 +0300 Subject: [PATCH 04/17] UI: Fixed set decimals value --- .../basic/gauge/digital-simple-gauge-basic-config.component.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/gauge/digital-simple-gauge-basic-config.component.ts b/ui-ngx/src/app/modules/home/components/widget/config/basic/gauge/digital-simple-gauge-basic-config.component.ts index aa93a56a4c..7d348662ae 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/basic/gauge/digital-simple-gauge-basic-config.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/gauge/digital-simple-gauge-basic-config.component.ts @@ -115,7 +115,7 @@ export class DigitalSimpleGaugeBasicConfigComponent extends BasicWidgetConfigCom minMaxColor: [settings.minMaxFont?.color, []], showValue: [settings.showValue, []], - decimals: [configData.config.decimals || settings.decimals, []], + decimals: [isDefined(configData.config.decimals) ? configData.config.decimals : settings.decimals, []], units: [configData.config.units, []], valueFont: [settings.valueFont, []], valueColor: [settings.valueFont?.color, []], From 7ba8e1366cbbe80981a70bb9d91f61471038335a Mon Sep 17 00:00:00 2001 From: IrynaMatveieva Date: Fri, 13 Jun 2025 12:06:22 +0300 Subject: [PATCH 05/17] fixed server failure when cf configuration is invalid --- .../service/cf/DefaultCalculatedFieldCache.java | 1 - .../configuration/CalculatedFieldConfiguration.java | 2 ++ .../cf/DefaultNativeCalculatedFieldRepository.java | 12 ++++++++---- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/service/cf/DefaultCalculatedFieldCache.java b/application/src/main/java/org/thingsboard/server/service/cf/DefaultCalculatedFieldCache.java index ed35d96cb7..3988cb38db 100644 --- a/application/src/main/java/org/thingsboard/server/service/cf/DefaultCalculatedFieldCache.java +++ b/application/src/main/java/org/thingsboard/server/service/cf/DefaultCalculatedFieldCache.java @@ -70,7 +70,6 @@ public class DefaultCalculatedFieldCache implements CalculatedFieldCache { @AfterStartUp(order = AfterStartUp.CF_READ_CF_SERVICE) public void init() { - //TODO: move to separate place to avoid circular references with the ActorSystemContext (@Lazy for tsSubService) PageDataIterable cfs = new PageDataIterable<>(calculatedFieldService::findAllCalculatedFields, initFetchPackSize); cfs.forEach(cf -> { calculatedFields.putIfAbsent(cf.getId(), cf); diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/cf/configuration/CalculatedFieldConfiguration.java b/common/data/src/main/java/org/thingsboard/server/common/data/cf/configuration/CalculatedFieldConfiguration.java index c53f1fe5f1..ad3d4373ad 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/cf/configuration/CalculatedFieldConfiguration.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/cf/configuration/CalculatedFieldConfiguration.java @@ -16,6 +16,7 @@ package org.thingsboard.server.common.data.cf.configuration; import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonSubTypes; import com.fasterxml.jackson.annotation.JsonTypeInfo; import org.thingsboard.server.common.data.cf.CalculatedFieldLink; @@ -36,6 +37,7 @@ import java.util.Map; @JsonSubTypes.Type(value = SimpleCalculatedFieldConfiguration.class, name = "SIMPLE"), @JsonSubTypes.Type(value = ScriptCalculatedFieldConfiguration.class, name = "SCRIPT") }) +@JsonIgnoreProperties(ignoreUnknown = true) public interface CalculatedFieldConfiguration { @JsonIgnore diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/cf/DefaultNativeCalculatedFieldRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/cf/DefaultNativeCalculatedFieldRepository.java index e59ff3f4e6..a01ad517b8 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/cf/DefaultNativeCalculatedFieldRepository.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/cf/DefaultNativeCalculatedFieldRepository.java @@ -38,6 +38,7 @@ import org.thingsboard.server.common.data.page.PageData; import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.UUID; import java.util.stream.Collectors; @@ -79,7 +80,6 @@ public class DefaultNativeCalculatedFieldRepository implements NativeCalculatedF JsonNode configuration = JacksonUtil.toJsonNode((String) row.get("configuration")); long version = row.get("version") != null ? (long) row.get("version") : 0; String debugSettings = (String) row.get("debug_settings"); - Object externalIdObj = row.get("external_id"); CalculatedField calculatedField = new CalculatedField(); calculatedField.setId(new CalculatedFieldId(id)); @@ -89,12 +89,17 @@ public class DefaultNativeCalculatedFieldRepository implements NativeCalculatedF calculatedField.setType(type); calculatedField.setName(name); calculatedField.setConfigurationVersion(configurationVersion); - calculatedField.setConfiguration(JacksonUtil.treeToValue(configuration, CalculatedFieldConfiguration.class)); + try { + calculatedField.setConfiguration(JacksonUtil.treeToValue(configuration, CalculatedFieldConfiguration.class)); + } catch (Exception e) { + log.error("Invalid configuration for CalculatedField [{}]. Skipping.", id, e); + return null; + } calculatedField.setVersion(version); calculatedField.setDebugSettings(JacksonUtil.fromString(debugSettings, DebugSettings.class)); return calculatedField; - }).collect(Collectors.toList()); + }).filter(Objects::nonNull).collect(Collectors.toList()); return new PageData<>(data, totalPages, totalElements, hasNext); }); } @@ -118,7 +123,6 @@ public class DefaultNativeCalculatedFieldRepository implements NativeCalculatedF EntityType entityType = EntityType.valueOf((String) row.get("entity_type")); UUID entityId = (UUID) row.get("entity_id"); UUID calculatedFieldId = (UUID) row.get("calculated_field_id"); - JsonNode configuration = JacksonUtil.toJsonNode((String) row.get("configuration")); CalculatedFieldLink calculatedFieldLink = new CalculatedFieldLink(); calculatedFieldLink.setId(new CalculatedFieldLinkId(id)); From 43429524364e1e7904157924e2cf8b3fa609f944 Mon Sep 17 00:00:00 2001 From: Vladyslav_Prykhodko Date: Fri, 13 Jun 2025 12:17:11 +0300 Subject: [PATCH 06/17] UI: Change mime type for csv export file --- ui-ngx/src/app/shared/import-export/import-export.models.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui-ngx/src/app/shared/import-export/import-export.models.ts b/ui-ngx/src/app/shared/import-export/import-export.models.ts index 2f20a421c3..60df84c737 100644 --- a/ui-ngx/src/app/shared/import-export/import-export.models.ts +++ b/ui-ngx/src/app/shared/import-export/import-export.models.ts @@ -160,7 +160,7 @@ export const ZIP_TYPE: FileType = { }; export const CSV_TYPE: FileType = { - mimeType: 'attachament/csv', + mimeType: 'text/csv', extension: 'csv' }; From edb3ab4ca020b6b03e93a9ab1d5fe0d56d34f3c3 Mon Sep 17 00:00:00 2001 From: IrynaMatveieva Date: Fri, 13 Jun 2025 12:25:16 +0300 Subject: [PATCH 07/17] removed links to the doc --- .../src/assets/help/en_US/rulenode/switch_node_script_fn.md | 6 ------ .../help/en_US/rulenode/tbel/switch_node_script_fn.md | 6 ------ 2 files changed, 12 deletions(-) diff --git a/ui-ngx/src/assets/help/en_US/rulenode/switch_node_script_fn.md b/ui-ngx/src/assets/help/en_US/rulenode/switch_node_script_fn.md index c4092455fa..49f0dd0a2b 100644 --- a/ui-ngx/src/assets/help/en_US/rulenode/switch_node_script_fn.md +++ b/ui-ngx/src/assets/help/en_US/rulenode/switch_node_script_fn.md @@ -91,11 +91,5 @@ return []; {:copy-code} ``` -
- -You can see real life example, how to use this node in this tutorial: - -- [Data function based on telemetry from 2 devices{:target="_blank"}](${siteBaseUrl}/docs${docPlatformPrefix}/user-guide/rule-engine-2-0/tutorials/function-based-on-telemetry-from-two-devices#delta-temperature-rule-chain) -

diff --git a/ui-ngx/src/assets/help/en_US/rulenode/tbel/switch_node_script_fn.md b/ui-ngx/src/assets/help/en_US/rulenode/tbel/switch_node_script_fn.md index 2461f4cace..77da936c73 100644 --- a/ui-ngx/src/assets/help/en_US/rulenode/tbel/switch_node_script_fn.md +++ b/ui-ngx/src/assets/help/en_US/rulenode/tbel/switch_node_script_fn.md @@ -91,11 +91,5 @@ return []; {:copy-code} ``` -
- -You can see real life example, how to use this node in this tutorial: - -- [Data function based on telemetry from 2 devices{:target="_blank"}](${siteBaseUrl}/docs${docPlatformPrefix}/user-guide/rule-engine-2-0/tutorials/function-based-on-telemetry-from-two-devices#delta-temperature-rule-chain) -

From 8ae39d4e9416d204453c91d66e04e2713711c1b3 Mon Sep 17 00:00:00 2001 From: IrynaMatveieva Date: Fri, 13 Jun 2025 12:59:25 +0300 Subject: [PATCH 08/17] moved check to higher level --- .../server/service/cf/DefaultCalculatedFieldCache.java | 6 ++++-- .../dao/sql/cf/DefaultNativeCalculatedFieldRepository.java | 3 +-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/service/cf/DefaultCalculatedFieldCache.java b/application/src/main/java/org/thingsboard/server/service/cf/DefaultCalculatedFieldCache.java index 3988cb38db..78042ffc0e 100644 --- a/application/src/main/java/org/thingsboard/server/service/cf/DefaultCalculatedFieldCache.java +++ b/application/src/main/java/org/thingsboard/server/service/cf/DefaultCalculatedFieldCache.java @@ -72,8 +72,10 @@ public class DefaultCalculatedFieldCache implements CalculatedFieldCache { public void init() { PageDataIterable cfs = new PageDataIterable<>(calculatedFieldService::findAllCalculatedFields, initFetchPackSize); cfs.forEach(cf -> { - calculatedFields.putIfAbsent(cf.getId(), cf); - actorSystemContext.tell(new CalculatedFieldInitMsg(cf.getTenantId(), cf)); + if (cf != null) { + calculatedFields.putIfAbsent(cf.getId(), cf); + actorSystemContext.tell(new CalculatedFieldInitMsg(cf.getTenantId(), cf)); + } }); calculatedFields.values().forEach(cf -> { entityIdCalculatedFields.computeIfAbsent(cf.getEntityId(), id -> new CopyOnWriteArrayList<>()).add(cf); diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/cf/DefaultNativeCalculatedFieldRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/cf/DefaultNativeCalculatedFieldRepository.java index a01ad517b8..bbce4e2721 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/cf/DefaultNativeCalculatedFieldRepository.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/cf/DefaultNativeCalculatedFieldRepository.java @@ -38,7 +38,6 @@ import org.thingsboard.server.common.data.page.PageData; import java.util.Collections; import java.util.List; import java.util.Map; -import java.util.Objects; import java.util.UUID; import java.util.stream.Collectors; @@ -99,7 +98,7 @@ public class DefaultNativeCalculatedFieldRepository implements NativeCalculatedF calculatedField.setDebugSettings(JacksonUtil.fromString(debugSettings, DebugSettings.class)); return calculatedField; - }).filter(Objects::nonNull).collect(Collectors.toList()); + }).collect(Collectors.toList()); return new PageData<>(data, totalPages, totalElements, hasNext); }); } From 513566bd7b666f9712c555d1ddf5c6f46c92f2c9 Mon Sep 17 00:00:00 2001 From: Andrii Shvaika Date: Fri, 23 May 2025 11:13:18 +0300 Subject: [PATCH 09/17] Docker file improvements to support installation without mounting the configuration folder (cherry picked from commit a6997cb4a1e61ebae64ab05a63d8dff4b6f0dded) --- msa/tb-node/docker/Dockerfile | 4 ++- msa/tb-node/docker/logback.xml | 38 +++++++++++++++++++++++++++++ msa/tb-node/docker/start-tb-node.sh | 18 ++++++++------ 3 files changed, 52 insertions(+), 8 deletions(-) create mode 100644 msa/tb-node/docker/logback.xml diff --git a/msa/tb-node/docker/Dockerfile b/msa/tb-node/docker/Dockerfile index dfca56acc7..013a37ef9c 100644 --- a/msa/tb-node/docker/Dockerfile +++ b/msa/tb-node/docker/Dockerfile @@ -16,12 +16,14 @@ FROM thingsboard/openjdk17:bookworm-slim -COPY start-tb-node.sh ${pkg.name}.deb /tmp/ +COPY logback.xml start-tb-node.sh ${pkg.name}.deb /tmp/ RUN chmod a+x /tmp/*.sh \ && mv /tmp/start-tb-node.sh /usr/bin && \ (yes | dpkg -i /tmp/${pkg.name}.deb) && \ rm /tmp/${pkg.name}.deb && \ + mv /tmp/logback.xml ${pkg.installFolder}/conf && \ + chown -R ${pkg.user}:${pkg.user} ${pkg.installFolder}/conf/logback.xml && \ (systemctl --no-reload disable --now ${pkg.name}.service > /dev/null 2>&1 || :) && \ chown -R ${pkg.user}:${pkg.user} /tmp && \ chmod 555 ${pkg.installFolder}/bin/${pkg.name}.jar diff --git a/msa/tb-node/docker/logback.xml b/msa/tb-node/docker/logback.xml new file mode 100644 index 0000000000..269cb89396 --- /dev/null +++ b/msa/tb-node/docker/logback.xml @@ -0,0 +1,38 @@ + + + + + + + + %d{ISO8601} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + + + + + + + diff --git a/msa/tb-node/docker/start-tb-node.sh b/msa/tb-node/docker/start-tb-node.sh index 7de30564c9..77221398be 100755 --- a/msa/tb-node/docker/start-tb-node.sh +++ b/msa/tb-node/docker/start-tb-node.sh @@ -15,14 +15,21 @@ # limitations under the License. # -CONF_FOLDER="/config" jarfile=${pkg.installFolder}/bin/${pkg.name}.jar configfile=${pkg.name}.conf run_user=${pkg.user} -source "${CONF_FOLDER}/${configfile}" +CONF_FOLDER="/config" +if [ -d "${CONF_FOLDER}" ]; then + LOGGING_CONFIG="${CONF_FOLDER}/logback.xml" + source "${CONF_FOLDER}/${configfile}" + export LOADER_PATH=${CONF_FOLDER},${LOADER_PATH} +else + CONF_FOLDER="/usr/share/${pkg.name}/conf" + LOGGING_CONFIG="/usr/share/${pkg.name}/conf/logback.xml" + source "${CONF_FOLDER}/${configfile}" +fi -export LOADER_PATH=/config,${LOADER_PATH} cd ${pkg.installFolder}/bin @@ -38,7 +45,6 @@ if [ "$INSTALL_TB" == "true" ]; then exec java -cp ${jarfile} $JAVA_OPTS -Dloader.main=org.thingsboard.server.ThingsboardInstallApplication \ -Dinstall.load_demo=${loadDemo} \ - -Dspring.jpa.hibernate.ddl-auto=none \ -Dinstall.upgrade=false \ -Dlogging.config=/usr/share/thingsboard/bin/install/logback.xml \ org.springframework.boot.loader.launch.PropertiesLauncher @@ -51,7 +57,6 @@ elif [ "$UPGRADE_TB" == "true" ]; then fromVersion="${FROM_VERSION// }" exec java -cp ${jarfile} $JAVA_OPTS -Dloader.main=org.thingsboard.server.ThingsboardInstallApplication \ - -Dspring.jpa.hibernate.ddl-auto=none \ -Dinstall.upgrade=true \ -Dinstall.upgrade.from_version=${fromVersion} \ -Dlogging.config=/usr/share/thingsboard/bin/install/logback.xml \ @@ -62,8 +67,7 @@ else echo "Starting '${project.name}' ..." exec java -cp ${jarfile} $JAVA_OPTS -Dloader.main=org.thingsboard.server.ThingsboardServerApplication \ - -Dspring.jpa.hibernate.ddl-auto=none \ - -Dlogging.config=/config/logback.xml \ + -Dlogging.config=${LOGGING_CONFIG} \ org.springframework.boot.loader.launch.PropertiesLauncher fi From 402cf9b5aafd75f11017afcfee263b037feaeeba Mon Sep 17 00:00:00 2001 From: Sergey Matvienko Date: Fri, 13 Jun 2025 14:13:01 +0200 Subject: [PATCH 10/17] CVE-2025-49146 postgresql.driver 4.7.5 -> 4.7.7 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 0260dc09be..5093c19435 100755 --- a/pom.xml +++ b/pom.xml @@ -103,7 +103,7 @@ 1.19.0 1.78.1 2.0.1 - 42.7.5 + 42.7.7 org/thingsboard/server/gen/**/*, org/thingsboard/server/extensions/core/plugin/telemetry/gen/**/* From 6e4ee1eb44a049cf401b51c66bf469bf61f721d0 Mon Sep 17 00:00:00 2001 From: Sergey Matvienko Date: Fri, 13 Jun 2025 14:46:10 +0200 Subject: [PATCH 11/17] CVE-2025-27817 kafka client 3.7.2 -> 3.9.1 (NetworkReceive.java has no code changes in the Kafka upstream) --- .../java/org/apache/kafka/common/network/NetworkReceive.java | 4 ++-- pom.xml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/application/src/main/java/org/apache/kafka/common/network/NetworkReceive.java b/application/src/main/java/org/apache/kafka/common/network/NetworkReceive.java index 80192520ca..88a03f5fc8 100644 --- a/application/src/main/java/org/apache/kafka/common/network/NetworkReceive.java +++ b/application/src/main/java/org/apache/kafka/common/network/NetworkReceive.java @@ -103,13 +103,13 @@ public class NetworkReceive implements Receive { if (maxSize != UNLIMITED && receiveSize > maxSize) { throw new ThingsboardKafkaClientError("Invalid receive (size = " + receiveSize + " larger than " + maxSize + ")"); } - requestedBufferSize = receiveSize; //may be 0 for some payloads (SASL) + requestedBufferSize = receiveSize; // may be 0 for some payloads (SASL) if (receiveSize == 0) { buffer = EMPTY_BUFFER; } } } - if (buffer == null && requestedBufferSize != -1) { //we know the size we want but havent been able to allocate it yet + if (buffer == null && requestedBufferSize != -1) { // we know the size we want but haven't been able to allocate it yet if (requestedBufferSize > TB_LOG_REQUESTED_BUFFER_SIZE) { String stackTrace = Arrays.stream(Thread.currentThread().getStackTrace()).map(StackTraceElement::toString).collect(Collectors.joining("|")); log.error("Allocating buffer of size {} for source {}", requestedBufferSize, source); diff --git a/pom.xml b/pom.xml index 5093c19435..66b153d63a 100755 --- a/pom.xml +++ b/pom.xml @@ -113,7 +113,7 @@ - 3.7.2 + 3.9.1 8.10.1 3.5.3 2.2 From 6a5fd0d45c171a06048c39bb5e2f58a038304627 Mon Sep 17 00:00:00 2001 From: Sergey Matvienko Date: Fri, 13 Jun 2025 15:32:44 +0200 Subject: [PATCH 12/17] CVE-2024-12798 logback 1.5.5 -> 1.5.18 --- pom.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index 66b153d63a..88efe6723f 100755 --- a/pom.xml +++ b/pom.xml @@ -52,9 +52,9 @@ 6.3.8 5.1.5 0.12.5 - 2.0.13 - 2.23.1 - 1.5.5 + 2.0.17 + 2.24.3 + 1.5.18 0.10 4.17.0 4.2.25 From 1d1a72d54dd0678fca776f555fa0ed6fda0a8aae Mon Sep 17 00:00:00 2001 From: Sergey Matvienko Date: Fri, 13 Jun 2025 15:35:06 +0200 Subject: [PATCH 13/17] CVE-2024-51504 org.apache.zookeeper:zookeeper@3.9.3 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 88efe6723f..011b1c967b 100755 --- a/pom.xml +++ b/pom.xml @@ -83,7 +83,7 @@ 2.3.32 2.0.1 5.6.0 - 3.9.2 + 3.9.3 3.25.5 1.63.0 1.2.6 From b69460ab01f86edbe81c5aef5f8220dcc1678942 Mon Sep 17 00:00:00 2001 From: Sergey Matvienko Date: Fri, 13 Jun 2025 15:42:13 +0200 Subject: [PATCH 14/17] CVE-2025-4949 org.eclipse.jgit:org.eclipse.jgit@6.10.1.202505221210-r --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 011b1c967b..fd21733bd3 100755 --- a/pom.xml +++ b/pom.xml @@ -158,7 +158,7 @@ 2.12.0 3.0.2 - 6.9.0.202403050737-r + 6.10.1.202505221210-r 0.4.8 1.0.0 From 14b3df350260142f856f0e62a1974e92dff981e7 Mon Sep 17 00:00:00 2001 From: Sergey Matvienko Date: Fri, 13 Jun 2025 15:44:51 +0200 Subject: [PATCH 15/17] CVE-2025-46701 org.apache.tomcat.embed:tomcat-embed-core@10.1.42 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index fd21733bd3..94cdff0e9f 100755 --- a/pom.xml +++ b/pom.xml @@ -42,7 +42,7 @@ 4.0.2 2.4.0-b180830.0359 4.0.5 - 10.1.40 + 10.1.42 2.5.2 3.2.12 3.2.12 From 56da48e2075743f212ec4613f07e90fa07eee6ef Mon Sep 17 00:00:00 2001 From: Sergey Matvienko Date: Fri, 13 Jun 2025 15:49:47 +0200 Subject: [PATCH 16/17] CVE-2025-41234 org.springframework:spring-web@6.1.15 -> org.springframework:spring-web@6.1.21 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 94cdff0e9f..f38ed581a1 100755 --- a/pom.xml +++ b/pom.xml @@ -47,7 +47,7 @@ 3.2.12 3.2.12 3.2.12 - 6.1.15 + 6.1.21 6.2.11 6.3.8 5.1.5 @@ -1173,7 +1173,7 @@ org.springframework.boot - spring-boot-starter + spring-boot-starter ${spring-boot.version} From a39547ddeedef581aad8cd57870c41b5dd224ee3 Mon Sep 17 00:00:00 2001 From: Sergey Matvienko Date: Fri, 13 Jun 2025 16:08:11 +0200 Subject: [PATCH 17/17] CVE-2025-22234 org.springframework.security:spring-security-crypto@6.3.9 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f38ed581a1..3e0a67ab0d 100755 --- a/pom.xml +++ b/pom.xml @@ -49,7 +49,7 @@ 3.2.12 6.1.21 6.2.11 - 6.3.8 + 6.3.9 5.1.5 0.12.5 2.0.17