From 28de53425b7d83b7b26d5397837524836c173987 Mon Sep 17 00:00:00 2001 From: Oleksii Kuripko Date: Tue, 21 Apr 2026 09:28:19 +0200 Subject: [PATCH 01/91] Incident feature for tb-monitoring Adds Slack-API-based incident grouping for the monitoring microservice: alerts that fire within resolution_timeout_s are threaded under a single "Incident" message whose header tracks affected services in real time, and the incident auto-resolves after a quiet period with a final summary. Highlights - Dual Slack modes: when bot_token + channel_id are set, alerts go through chat.postMessage / chat.update with threaded replies; otherwise the existing webhook path is used unchanged. - Incident header shows :red_circle: failing / :large_yellow_circle: high latency / :large_green_circle: recovered services with live failure counts and elapsed duration (updated every minute). - Notifications carry structured affected-service data (AffectedService { name, status, failureCount }) so the incident layer no longer parses formatted alert text with regex. - IncidentManager is decoupled from Slack via a small IncidentTransport interface; SlackIncidentTransport adapts SlackApiClient. - PE/other service-key types can plug in a friendly name via the ShortNameProvider interface; TransportInfo implements it. - Config lives under monitoring.notifications.incident.* (enabled, resolution_timeout_s, tag_channel). Slack bot config stays under monitoring.notifications.slack.{bot_token,channel_id}. YAML defaults are authoritative; Spring @Value no longer carries a conflicting fallback. - Concurrency: state and transport I/O run under the manager's monitor. Slack client has explicit 5s call timeouts (set on SlackConfig) so the hold time is bounded. Slack client is closed on PreDestroy. - HTTP failure text is sanitised: HTML response bodies are stripped so Nginx-style error pages don't flood alerts. - BaseMonitoringService splits login / WS connect / WS subscribe into distinct MonitoredServiceKey entries, uses catch(Exception) instead of catch(Throwable), and wraps WsClient in try-with-resources. - Unit tests cover incident lifecycle, status transitions, duration formatting, HTML body stripping, and the ShortNameProvider dispatch. --- monitoring/pom.xml | 9 + .../config/transport/TransportInfo.java | 10 +- .../monitoring/data/MonitoredServiceKey.java | 3 + .../data/notification/AffectedService.java | 34 +++ .../notification/HighLatencyNotification.java | 9 + .../data/notification/InfoNotification.java | 5 + .../data/notification/Notification.java | 10 + .../ServiceFailureNotification.java | 38 +++ .../ServiceRecoveryNotification.java | 7 + .../data/notification/ShortNameProvider.java | 22 ++ .../notification/NotificationService.java | 2 +- .../channels/NotificationChannel.java | 4 +- .../channels/impl/SlackApiClient.java | 125 ++++++++ .../channels/impl/SlackIncidentTransport.java | 45 +++ .../impl/SlackNotificationChannel.java | 69 ++++- .../incident/IncidentManager.java | 279 ++++++++++++++++++ .../incident/IncidentTransport.java | 26 ++ .../monitoring/service/BaseHealthChecker.java | 3 +- .../service/BaseMonitoringService.java | 37 ++- .../service/MonitoringReporter.java | 5 +- .../src/main/resources/tb-monitoring.yml | 13 + .../ServiceFailureNotificationTest.java | 70 +++++ .../incident/IncidentManagerTest.java | 162 ++++++++++ 23 files changed, 965 insertions(+), 22 deletions(-) create mode 100644 monitoring/src/main/java/org/thingsboard/monitoring/data/notification/AffectedService.java create mode 100644 monitoring/src/main/java/org/thingsboard/monitoring/data/notification/ShortNameProvider.java create mode 100644 monitoring/src/main/java/org/thingsboard/monitoring/notification/channels/impl/SlackApiClient.java create mode 100644 monitoring/src/main/java/org/thingsboard/monitoring/notification/channels/impl/SlackIncidentTransport.java create mode 100644 monitoring/src/main/java/org/thingsboard/monitoring/notification/incident/IncidentManager.java create mode 100644 monitoring/src/main/java/org/thingsboard/monitoring/notification/incident/IncidentTransport.java create mode 100644 monitoring/src/test/java/org/thingsboard/monitoring/data/notification/ServiceFailureNotificationTest.java create mode 100644 monitoring/src/test/java/org/thingsboard/monitoring/notification/incident/IncidentManagerTest.java diff --git a/monitoring/pom.xml b/monitoring/pom.xml index 5bc1fb5baa..571586b8c3 100644 --- a/monitoring/pom.xml +++ b/monitoring/pom.xml @@ -79,6 +79,10 @@ org.apache.httpcomponents httpclient + + com.slack.api + slack-api-client + org.eclipse.leshan leshan-client-cf @@ -118,6 +122,11 @@ ch.qos.logback logback-classic + + org.springframework.boot + spring-boot-starter-test + test + diff --git a/monitoring/src/main/java/org/thingsboard/monitoring/config/transport/TransportInfo.java b/monitoring/src/main/java/org/thingsboard/monitoring/config/transport/TransportInfo.java index 251b5e1d85..cc9801dcad 100644 --- a/monitoring/src/main/java/org/thingsboard/monitoring/config/transport/TransportInfo.java +++ b/monitoring/src/main/java/org/thingsboard/monitoring/config/transport/TransportInfo.java @@ -16,13 +16,21 @@ package org.thingsboard.monitoring.config.transport; import lombok.Data; +import org.thingsboard.monitoring.data.notification.ShortNameProvider; @Data -public class TransportInfo { +public class TransportInfo implements ShortNameProvider { private final TransportType type; private final TransportMonitoringTarget target; + public String getShortName() { + if (target.getQueue().equals("Main")) { + return type.getName(); + } + return type.getName() + " " + target.getQueue(); + } + @Override public String toString() { if (target.getQueue().equals("Main")) { diff --git a/monitoring/src/main/java/org/thingsboard/monitoring/data/MonitoredServiceKey.java b/monitoring/src/main/java/org/thingsboard/monitoring/data/MonitoredServiceKey.java index 28fa6a9e18..c566e8f896 100644 --- a/monitoring/src/main/java/org/thingsboard/monitoring/data/MonitoredServiceKey.java +++ b/monitoring/src/main/java/org/thingsboard/monitoring/data/MonitoredServiceKey.java @@ -18,6 +18,9 @@ package org.thingsboard.monitoring.data; public class MonitoredServiceKey { public static final String GENERAL = "Monitoring"; + public static final String LOGIN = "Login"; + public static final String WS_CONNECT = "WS Connect"; + public static final String WS_SUBSCRIBE = "WS Subscribe"; public static final String EDQS = "*EDQS*"; } diff --git a/monitoring/src/main/java/org/thingsboard/monitoring/data/notification/AffectedService.java b/monitoring/src/main/java/org/thingsboard/monitoring/data/notification/AffectedService.java new file mode 100644 index 0000000000..b30a398223 --- /dev/null +++ b/monitoring/src/main/java/org/thingsboard/monitoring/data/notification/AffectedService.java @@ -0,0 +1,34 @@ +/** + * Copyright © 2016-2026 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.monitoring.data.notification; + +public record AffectedService(String name, Status status, int failureCount) { + + public enum Status { FAILING, RECOVERED, HIGH_LATENCY } + + public static AffectedService failing(String name, int failureCount) { + return new AffectedService(name, Status.FAILING, failureCount); + } + + public static AffectedService recovered(String name) { + return new AffectedService(name, Status.RECOVERED, 0); + } + + public static AffectedService highLatency(String name) { + return new AffectedService(name, Status.HIGH_LATENCY, 0); + } + +} diff --git a/monitoring/src/main/java/org/thingsboard/monitoring/data/notification/HighLatencyNotification.java b/monitoring/src/main/java/org/thingsboard/monitoring/data/notification/HighLatencyNotification.java index 9a319eb6c9..3e739ec4dc 100644 --- a/monitoring/src/main/java/org/thingsboard/monitoring/data/notification/HighLatencyNotification.java +++ b/monitoring/src/main/java/org/thingsboard/monitoring/data/notification/HighLatencyNotification.java @@ -18,6 +18,8 @@ package org.thingsboard.monitoring.data.notification; import org.thingsboard.monitoring.data.Latency; import java.util.Collection; +import java.util.List; +import java.util.stream.Collectors; public class HighLatencyNotification implements Notification { @@ -39,4 +41,11 @@ public class HighLatencyNotification implements Notification { return text.toString(); } + @Override + public List getAffectedServices() { + return highLatencies.stream() + .map(latency -> AffectedService.highLatency(latency.getKey())) + .collect(Collectors.toList()); + } + } diff --git a/monitoring/src/main/java/org/thingsboard/monitoring/data/notification/InfoNotification.java b/monitoring/src/main/java/org/thingsboard/monitoring/data/notification/InfoNotification.java index b2b73414de..6906e8c732 100644 --- a/monitoring/src/main/java/org/thingsboard/monitoring/data/notification/InfoNotification.java +++ b/monitoring/src/main/java/org/thingsboard/monitoring/data/notification/InfoNotification.java @@ -24,4 +24,9 @@ public class InfoNotification implements Notification { public String getText() { return message; } + + @Override + public boolean isIncident() { + return false; + } } diff --git a/monitoring/src/main/java/org/thingsboard/monitoring/data/notification/Notification.java b/monitoring/src/main/java/org/thingsboard/monitoring/data/notification/Notification.java index 33ed7f8328..7734fc62ee 100644 --- a/monitoring/src/main/java/org/thingsboard/monitoring/data/notification/Notification.java +++ b/monitoring/src/main/java/org/thingsboard/monitoring/data/notification/Notification.java @@ -15,8 +15,18 @@ */ package org.thingsboard.monitoring.data.notification; +import java.util.List; + public interface Notification { String getText(); + default boolean isIncident() { + return true; + } + + default List getAffectedServices() { + return List.of(); + } + } diff --git a/monitoring/src/main/java/org/thingsboard/monitoring/data/notification/ServiceFailureNotification.java b/monitoring/src/main/java/org/thingsboard/monitoring/data/notification/ServiceFailureNotification.java index dd93f232a6..47daf043ab 100644 --- a/monitoring/src/main/java/org/thingsboard/monitoring/data/notification/ServiceFailureNotification.java +++ b/monitoring/src/main/java/org/thingsboard/monitoring/data/notification/ServiceFailureNotification.java @@ -18,6 +18,8 @@ package org.thingsboard.monitoring.data.notification; import lombok.Getter; import org.apache.commons.lang3.exception.ExceptionUtils; +import java.util.List; + @Getter public class ServiceFailureNotification implements Notification { @@ -43,7 +45,43 @@ public class ServiceFailureNotification implements Notification { if (errorMsg == null) { errorMsg = error.getClass().getSimpleName(); } + errorMsg = stripResponseBody(errorMsg); return String.format("%s - Failure: %s (number of subsequent failures: %s)", serviceKey, errorMsg, failuresCount); } + static String stripResponseBody(String msg) { + if (msg == null) { + return null; + } + int htmlIdx = -1; + for (String marker : new String[]{"= 0 && (htmlIdx < 0 || idx < htmlIdx)) { + htmlIdx = idx; + } + } + if (htmlIdx > 0) { + msg = msg.substring(0, htmlIdx).stripTrailing(); + if (msg.endsWith("\"")) { + msg = msg.substring(0, msg.length() - 1).stripTrailing(); + } + if (msg.endsWith(":")) { + msg = msg.substring(0, msg.length() - 1).stripTrailing(); + } + } + return msg; + } + + @Override + public List getAffectedServices() { + return List.of(AffectedService.failing(shortName(serviceKey), failuresCount)); + } + + static String shortName(Object serviceKey) { + if (serviceKey instanceof ShortNameProvider provider) { + return provider.getShortName(); + } + return serviceKey.toString(); + } + } diff --git a/monitoring/src/main/java/org/thingsboard/monitoring/data/notification/ServiceRecoveryNotification.java b/monitoring/src/main/java/org/thingsboard/monitoring/data/notification/ServiceRecoveryNotification.java index b6e0c7c695..31b32422a1 100644 --- a/monitoring/src/main/java/org/thingsboard/monitoring/data/notification/ServiceRecoveryNotification.java +++ b/monitoring/src/main/java/org/thingsboard/monitoring/data/notification/ServiceRecoveryNotification.java @@ -15,6 +15,8 @@ */ package org.thingsboard.monitoring.data.notification; +import java.util.List; + public class ServiceRecoveryNotification implements Notification { private final Object serviceKey; @@ -28,4 +30,9 @@ public class ServiceRecoveryNotification implements Notification { return String.format("%s is OK", serviceKey); } + @Override + public List getAffectedServices() { + return List.of(AffectedService.recovered(ServiceFailureNotification.shortName(serviceKey))); + } + } diff --git a/monitoring/src/main/java/org/thingsboard/monitoring/data/notification/ShortNameProvider.java b/monitoring/src/main/java/org/thingsboard/monitoring/data/notification/ShortNameProvider.java new file mode 100644 index 0000000000..96c63023af --- /dev/null +++ b/monitoring/src/main/java/org/thingsboard/monitoring/data/notification/ShortNameProvider.java @@ -0,0 +1,22 @@ +/** + * Copyright © 2016-2026 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.monitoring.data.notification; + +public interface ShortNameProvider { + + String getShortName(); + +} diff --git a/monitoring/src/main/java/org/thingsboard/monitoring/notification/NotificationService.java b/monitoring/src/main/java/org/thingsboard/monitoring/notification/NotificationService.java index e813b3205d..091a331438 100644 --- a/monitoring/src/main/java/org/thingsboard/monitoring/notification/NotificationService.java +++ b/monitoring/src/main/java/org/thingsboard/monitoring/notification/NotificationService.java @@ -51,7 +51,7 @@ public class NotificationService { return notificationChannels.stream().map(notificationChannel -> notificationExecutor.submit(() -> { try { - notificationChannel.sendNotification(message); + notificationChannel.sendNotification(message, notification); } catch (Exception e) { log.error("Failed to send notification to {}", notificationChannel.getClass().getSimpleName(), e); } diff --git a/monitoring/src/main/java/org/thingsboard/monitoring/notification/channels/NotificationChannel.java b/monitoring/src/main/java/org/thingsboard/monitoring/notification/channels/NotificationChannel.java index 126942cb3f..614fddda31 100644 --- a/monitoring/src/main/java/org/thingsboard/monitoring/notification/channels/NotificationChannel.java +++ b/monitoring/src/main/java/org/thingsboard/monitoring/notification/channels/NotificationChannel.java @@ -15,8 +15,10 @@ */ package org.thingsboard.monitoring.notification.channels; +import org.thingsboard.monitoring.data.notification.Notification; + public interface NotificationChannel { - void sendNotification(String message); + void sendNotification(String message, Notification notification); } diff --git a/monitoring/src/main/java/org/thingsboard/monitoring/notification/channels/impl/SlackApiClient.java b/monitoring/src/main/java/org/thingsboard/monitoring/notification/channels/impl/SlackApiClient.java new file mode 100644 index 0000000000..4ad74d7811 --- /dev/null +++ b/monitoring/src/main/java/org/thingsboard/monitoring/notification/channels/impl/SlackApiClient.java @@ -0,0 +1,125 @@ +/** + * Copyright © 2016-2026 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.monitoring.notification.channels.impl; + +import com.slack.api.Slack; +import com.slack.api.SlackConfig; +import com.slack.api.methods.MethodsClient; +import com.slack.api.methods.SlackApiTextResponse; +import com.slack.api.methods.request.chat.ChatPostMessageRequest; +import com.slack.api.methods.request.chat.ChatUpdateRequest; +import com.slack.api.methods.response.chat.ChatPostMessageResponse; +import com.slack.api.methods.response.chat.ChatUpdateResponse; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class SlackApiClient { + + private static final int DEFAULT_CALL_TIMEOUT_MS = 5000; + + private final Slack slack; + private final String botToken; + + public SlackApiClient(String botToken) { + this(botToken, DEFAULT_CALL_TIMEOUT_MS); + } + + public SlackApiClient(String botToken, int callTimeoutMs) { + this.botToken = botToken; + SlackConfig config = new SlackConfig(); + config.setHttpClientCallTimeoutMillis(callTimeoutMs); + config.setHttpClientReadTimeoutMillis(callTimeoutMs); + config.setHttpClientWriteTimeoutMillis(callTimeoutMs); + this.slack = Slack.getInstance(config); + } + + public String postMessage(String channelId, String text) { + ChatPostMessageRequest request = ChatPostMessageRequest.builder() + .channel(channelId) + .text(text) + .build(); + ChatPostMessageResponse response = sendRequest(request); + return response.getTs(); + } + + public String postThreadReply(String channelId, String threadTs, String text) { + ChatPostMessageRequest request = ChatPostMessageRequest.builder() + .channel(channelId) + .text(text) + .threadTs(threadTs) + .build(); + ChatPostMessageResponse response = sendRequest(request); + return response.getTs(); + } + + public void close() { + try { + slack.close(); + } catch (Exception e) { + log.warn("Failed to close Slack client", e); + } + } + + public void updateMessage(String channelId, String ts, String text) { + ChatUpdateRequest request = ChatUpdateRequest.builder() + .channel(channelId) + .ts(ts) + .text(text) + .build(); + MethodsClient client = slack.methods(botToken); + ChatUpdateResponse response; + try { + response = client.chatUpdate(request); + } catch (Exception e) { + throw new RuntimeException("Failed to update Slack message: " + e.getMessage(), e); + } + checkResponse(response); + } + + private ChatPostMessageResponse sendRequest(ChatPostMessageRequest request) { + MethodsClient client = slack.methods(botToken); + ChatPostMessageResponse response; + try { + response = client.chatPostMessage(request); + } catch (Exception e) { + throw new RuntimeException("Failed to send Slack message: " + e.getMessage(), e); + } + checkResponse(response); + return response; + } + + private void checkResponse(SlackApiTextResponse response) { + if (response.isOk()) { + return; + } + String error = response.getError(); + if (error != null) { + switch (error) { + case "missing_scope" -> { + String neededScope = response.getNeeded(); + error = "bot token scope '" + neededScope + "' is needed"; + } + case "not_in_channel" -> error = "app needs to be added to the channel"; + } + } else if (response.getWarning() != null) { + error = "warning: " + response.getWarning(); + } else { + error = "unknown error"; + } + throw new RuntimeException("Slack API error: " + error); + } + +} diff --git a/monitoring/src/main/java/org/thingsboard/monitoring/notification/channels/impl/SlackIncidentTransport.java b/monitoring/src/main/java/org/thingsboard/monitoring/notification/channels/impl/SlackIncidentTransport.java new file mode 100644 index 0000000000..8812714d62 --- /dev/null +++ b/monitoring/src/main/java/org/thingsboard/monitoring/notification/channels/impl/SlackIncidentTransport.java @@ -0,0 +1,45 @@ +/** + * Copyright © 2016-2026 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.monitoring.notification.channels.impl; + +import org.thingsboard.monitoring.notification.incident.IncidentTransport; + +public class SlackIncidentTransport implements IncidentTransport { + + private final SlackApiClient slackApiClient; + private final String channelId; + + public SlackIncidentTransport(SlackApiClient slackApiClient, String channelId) { + this.slackApiClient = slackApiClient; + this.channelId = channelId; + } + + @Override + public String postIncident(String text) { + return slackApiClient.postMessage(channelId, text); + } + + @Override + public void postThreadReply(String threadId, String text) { + slackApiClient.postThreadReply(channelId, threadId, text); + } + + @Override + public void updateIncident(String threadId, String text) { + slackApiClient.updateMessage(channelId, threadId, text); + } + +} diff --git a/monitoring/src/main/java/org/thingsboard/monitoring/notification/channels/impl/SlackNotificationChannel.java b/monitoring/src/main/java/org/thingsboard/monitoring/notification/channels/impl/SlackNotificationChannel.java index c1d25c43c0..06990c5a51 100644 --- a/monitoring/src/main/java/org/thingsboard/monitoring/notification/channels/impl/SlackNotificationChannel.java +++ b/monitoring/src/main/java/org/thingsboard/monitoring/notification/channels/impl/SlackNotificationChannel.java @@ -16,13 +16,16 @@ package org.thingsboard.monitoring.notification.channels.impl; import jakarta.annotation.PostConstruct; +import jakarta.annotation.PreDestroy; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.web.client.RestTemplateBuilder; import org.springframework.stereotype.Component; import org.springframework.web.client.RestTemplate; +import org.thingsboard.monitoring.data.notification.Notification; import org.thingsboard.monitoring.notification.channels.NotificationChannel; +import org.thingsboard.monitoring.notification.incident.IncidentManager; import java.time.Duration; import java.util.Map; @@ -35,19 +38,73 @@ public class SlackNotificationChannel implements NotificationChannel { @Value("${monitoring.notifications.slack.webhook_url}") private String webhookUrl; + @Value("${monitoring.notifications.slack.bot_token:}") + private String botToken; + + @Value("${monitoring.notifications.slack.channel_id:}") + private String channelId; + + @Value("${monitoring.notifications.incident.enabled:}") + private boolean incidentEnabled; + + @Value("${monitoring.notifications.incident.resolution_timeout_s:}") + private long resolutionTimeoutSeconds; + + @Value("${monitoring.notifications.incident.tag_channel:}") + private boolean tagChannel; + + @Value("${monitoring.notifications.message_prefix:}") + private String messagePrefix; + private RestTemplate restTemplate; + private SlackApiClient slackApiClient; + private IncidentManager incidentManager; @PostConstruct private void init() { - restTemplate = new RestTemplateBuilder() - .setConnectTimeout(Duration.ofSeconds(5)) - .setReadTimeout(Duration.ofSeconds(2)) - .build(); + boolean hasBotConfig = botToken != null && !botToken.isEmpty() && channelId != null && !channelId.isEmpty(); + if (hasBotConfig) { + slackApiClient = new SlackApiClient(botToken); + log.info("Slack API mode enabled (channel: {})", channelId); + if (incidentEnabled) { + incidentManager = new IncidentManager(new SlackIncidentTransport(slackApiClient, channelId), + resolutionTimeoutSeconds, messagePrefix, tagChannel); + log.info("Incident grouping enabled via Slack (resolution timeout: {}s)", resolutionTimeoutSeconds); + } + } else { + if (incidentEnabled) { + log.warn("Incident grouping is enabled but Slack bot_token/channel_id are not set; " + + "falling back to plain webhook mode without incident support"); + } + restTemplate = new RestTemplateBuilder() + .setConnectTimeout(Duration.ofSeconds(5)) + .setReadTimeout(Duration.ofSeconds(2)) + .build(); + log.info("Slack webhook mode enabled"); + } } @Override - public void sendNotification(String message) { - restTemplate.postForObject(webhookUrl, Map.of("text", message), String.class); + public void sendNotification(String message, Notification notification) { + if (incidentManager != null && notification.isIncident()) { + // Pass the raw notification text: IncidentManager already puts the prefix into the + // incident header, so pre-prefixing the thread reply would double it up. + incidentManager.sendAlert(notification.getText(), notification.getAffectedServices()); + } else if (slackApiClient != null) { + slackApiClient.postMessage(channelId, message); + } else { + restTemplate.postForObject(webhookUrl, Map.of("text", message), String.class); + } + } + + @PreDestroy + private void destroy() { + if (incidentManager != null) { + incidentManager.shutdown(); + } + if (slackApiClient != null) { + slackApiClient.close(); + } } } diff --git a/monitoring/src/main/java/org/thingsboard/monitoring/notification/incident/IncidentManager.java b/monitoring/src/main/java/org/thingsboard/monitoring/notification/incident/IncidentManager.java new file mode 100644 index 0000000000..133d665f4c --- /dev/null +++ b/monitoring/src/main/java/org/thingsboard/monitoring/notification/incident/IncidentManager.java @@ -0,0 +1,279 @@ +/** + * Copyright © 2016-2026 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.monitoring.notification.incident; + +import lombok.extern.slf4j.Slf4j; +import org.thingsboard.monitoring.data.notification.AffectedService; + +import java.time.Duration; +import java.time.Instant; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; + +/** + * Thread-safety: all public entry points and scheduled callbacks are {@code synchronized} on the + * manager instance. Transport I/O is performed while the monitor is held. This is safe under the + * assumptions that (a) the transport enforces a short per-call timeout, and (b) notification + * producers are single-threaded; see the Slack client (default 5s) for the Slack-based transport. + */ +@Slf4j +public class IncidentManager { + + private final IncidentTransport transport; + private final long resolutionTimeoutSeconds; + private final String messagePrefix; + private final boolean tagChannel; + private final ScheduledExecutorService scheduler; + + private String activeIncidentThreadId; + private ScheduledFuture resolutionTask; + private ScheduledFuture durationUpdateTask; + private Instant incidentStartTime; + private Instant lastAlertTime; + private final Map failingServices = new LinkedHashMap<>(); + private final Set recoveredServices = new LinkedHashSet<>(); + private final Set highLatencyServices = new LinkedHashSet<>(); + + public IncidentManager(IncidentTransport transport, long resolutionTimeoutSeconds, + String messagePrefix, boolean tagChannel) { + this.transport = transport; + this.resolutionTimeoutSeconds = resolutionTimeoutSeconds; + this.messagePrefix = messagePrefix; + this.tagChannel = tagChannel; + this.scheduler = Executors.newSingleThreadScheduledExecutor(r -> { + Thread t = new Thread(r, "incident-manager"); + t.setDaemon(true); + return t; + }); + } + + public synchronized void sendAlert(String message, List affectedServices) { + try { + if (activeIncidentThreadId == null) { + if (affectedServices.stream().allMatch(s -> s.status() == AffectedService.Status.RECOVERED)) { + return; + } + incidentStartTime = Instant.now(); + failingServices.clear(); + recoveredServices.clear(); + highLatencyServices.clear(); + applyAffectedServices(affectedServices); + activeIncidentThreadId = transport.postIncident(buildOngoingMessageText()); + startDurationUpdater(); + log.info("New incident created, thread id: {}", activeIncidentThreadId); + } else if (applyAffectedServices(affectedServices)) { + safeUpdateHeader(); + } + + try { + transport.postThreadReply(activeIncidentThreadId, message); + log.debug("Alert added to incident thread {}", activeIncidentThreadId); + } catch (Exception e) { + log.error("Failed to post alert to incident thread {}", activeIncidentThreadId, e); + } + } finally { + if (activeIncidentThreadId != null) { + lastAlertTime = Instant.now(); + resetResolutionTimer(); + } + } + } + + private boolean applyAffectedServices(List affectedServices) { + boolean changed = false; + Set latencySnapshot = null; + for (AffectedService service : affectedServices) { + String name = service.name(); + switch (service.status()) { + case FAILING -> { + Integer prev = failingServices.put(name, service.failureCount()); + if (prev == null || prev.intValue() != service.failureCount()) { + changed = true; + } + if (recoveredServices.remove(name)) { + changed = true; + } + } + case RECOVERED -> { + if (failingServices.remove(name) != null) { + recoveredServices.add(name); + changed = true; + } + } + case HIGH_LATENCY -> { + if (latencySnapshot == null) { + latencySnapshot = new LinkedHashSet<>(); + } + latencySnapshot.add(name); + } + } + } + // HighLatencyNotification carries the full current set of high latencies, so treat it as a + // snapshot: replace highLatencyServices entirely. Without this, a brief spike would stay + // yellow in the header until the incident resolves. + if (latencySnapshot != null && !latencySnapshot.equals(highLatencyServices)) { + highLatencyServices.clear(); + highLatencyServices.addAll(latencySnapshot); + changed = true; + } + return changed; + } + + private String buildOngoingMessageText() { + StringBuilder sb = new StringBuilder(); + if (tagChannel) { + sb.append(" "); + } + if (messagePrefix != null && !messagePrefix.isEmpty()) { + sb.append("*").append(messagePrefix).append("*"); + } + sb.append(" :rotating_light:"); + Duration elapsed = Duration.between(incidentStartTime, Instant.now()); + if (elapsed.toMinutes() >= 1) { + sb.append(" (").append(formatDuration(elapsed)).append(")"); + } + if (hasAffected()) { + sb.append(" | ").append(formatAffectedServices()); + } + return sb.toString(); + } + + private boolean hasAffected() { + return !failingServices.isEmpty() || !recoveredServices.isEmpty() || !highLatencyServices.isEmpty(); + } + + private void safeUpdateHeader() { + try { + transport.updateIncident(activeIncidentThreadId, buildOngoingMessageText()); + } catch (Exception e) { + log.error("Failed to update incident message", e); + } + } + + private void resetResolutionTimer() { + if (resolutionTask != null) { + resolutionTask.cancel(false); + } + resolutionTask = scheduler.schedule(this::resolveIncident, resolutionTimeoutSeconds, TimeUnit.SECONDS); + } + + private void startDurationUpdater() { + if (durationUpdateTask != null) { + durationUpdateTask.cancel(false); + } + durationUpdateTask = scheduler.scheduleAtFixedRate(this::updateDuration, 60, 60, TimeUnit.SECONDS); + } + + private synchronized void updateDuration() { + if (activeIncidentThreadId == null) { + return; + } + safeUpdateHeader(); + } + + private void stopDurationUpdater() { + if (durationUpdateTask != null) { + durationUpdateTask.cancel(false); + durationUpdateTask = null; + } + } + + static String formatDuration(Duration duration) { + long totalMinutes = duration.toMinutes(); + if (totalMinutes < 60) { + return totalMinutes + "m"; + } + long hours = totalMinutes / 60; + long minutes = totalMinutes % 60; + return minutes > 0 ? hours + "h" + minutes + "m" : hours + "h"; + } + + synchronized void resolveIncident() { + if (activeIncidentThreadId == null) { + return; + } + String threadId = activeIncidentThreadId; + stopDurationUpdater(); + String resolutionMessage = buildResolutionMessage(); + activeIncidentThreadId = null; + resolutionTask = null; + failingServices.clear(); + recoveredServices.clear(); + highLatencyServices.clear(); + try { + transport.updateIncident(threadId, resolutionMessage); + log.info("Incident resolved (thread was {})", threadId); + } catch (Exception e) { + log.error("Failed to send incident resolution message", e); + } + } + + private String buildResolutionMessage() { + Duration totalDuration = lastAlertTime != null + ? Duration.between(incidentStartTime, lastAlertTime) + : Duration.between(incidentStartTime, Instant.now()); + StringBuilder sb = new StringBuilder(); + if (messagePrefix != null && !messagePrefix.isEmpty()) { + sb.append("*").append(messagePrefix).append("*"); + } + sb.append(" :white_check_mark:"); + sb.append(" (").append(formatDuration(totalDuration)).append(")"); + if (hasAffected()) { + sb.append(" | ").append(formatAffectedServices()).append("\n"); + } + return sb.toString(); + } + + private String formatAffectedServices() { + StringBuilder sb = new StringBuilder(); + boolean first = true; + for (Map.Entry entry : failingServices.entrySet()) { + if (!first) sb.append(", "); + sb.append(":red_circle: ").append(entry.getKey()).append(" (").append(entry.getValue()).append(")"); + first = false; + } + for (String name : highLatencyServices) { + if (!first) sb.append(", "); + sb.append(":large_yellow_circle: ").append(name); + first = false; + } + for (String name : recoveredServices) { + if (!first) sb.append(", "); + sb.append(":large_green_circle: ").append(name); + first = false; + } + return sb.toString(); + } + + public void shutdown() { + scheduler.shutdownNow(); + try { + if (!scheduler.awaitTermination(5, TimeUnit.SECONDS)) { + log.warn("Incident scheduler did not terminate in time"); + } + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + } + +} diff --git a/monitoring/src/main/java/org/thingsboard/monitoring/notification/incident/IncidentTransport.java b/monitoring/src/main/java/org/thingsboard/monitoring/notification/incident/IncidentTransport.java new file mode 100644 index 0000000000..0d6b4cac2a --- /dev/null +++ b/monitoring/src/main/java/org/thingsboard/monitoring/notification/incident/IncidentTransport.java @@ -0,0 +1,26 @@ +/** + * Copyright © 2016-2026 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.monitoring.notification.incident; + +public interface IncidentTransport { + + String postIncident(String text); + + void postThreadReply(String threadId, String text); + + void updateIncident(String threadId, String text); + +} diff --git a/monitoring/src/main/java/org/thingsboard/monitoring/service/BaseHealthChecker.java b/monitoring/src/main/java/org/thingsboard/monitoring/service/BaseHealthChecker.java index b73194469f..c0e85da1ac 100644 --- a/monitoring/src/main/java/org/thingsboard/monitoring/service/BaseHealthChecker.java +++ b/monitoring/src/main/java/org/thingsboard/monitoring/service/BaseHealthChecker.java @@ -89,11 +89,10 @@ public abstract class BaseHealthChecker { diff --git a/monitoring/src/main/java/org/thingsboard/monitoring/service/BaseMonitoringService.java b/monitoring/src/main/java/org/thingsboard/monitoring/service/BaseMonitoringService.java index ea154e49c0..3f1c624200 100644 --- a/monitoring/src/main/java/org/thingsboard/monitoring/service/BaseMonitoringService.java +++ b/monitoring/src/main/java/org/thingsboard/monitoring/service/BaseMonitoringService.java @@ -117,17 +117,40 @@ public abstract class BaseMonitoringService, T ext } try { log.info("Starting {}", getName()); - stopWatch.start(); - String accessToken = tbClient.logIn(); - reporter.reportLatency(Latencies.LOG_IN, stopWatch.getTime()); - try (WsClient wsClient = wsClientFactory.createClient(accessToken)) { + String accessToken; + try { stopWatch.start(); - wsClient.subscribeForTelemetry(devices, getTestTelemetryKeys()).waitForReply(); - reporter.reportLatency(Latencies.WS_SUBSCRIBE, stopWatch.getTime()); + accessToken = tbClient.logIn(); + reporter.reportLatency(Latencies.LOG_IN, stopWatch.getTime()); + reporter.serviceIsOk(MonitoredServiceKey.LOGIN); + } catch (Exception e) { + reporter.serviceFailure(MonitoredServiceKey.LOGIN, e); + return; + } + + WsClient wsClient; + try { + wsClient = wsClientFactory.createClient(accessToken); + reporter.serviceIsOk(MonitoredServiceKey.WS_CONNECT); + } catch (Exception e) { + reporter.serviceFailure(MonitoredServiceKey.WS_CONNECT, e); + return; + } + + try (WsClient ws = wsClient) { + try { + stopWatch.start(); + ws.subscribeForTelemetry(devices, getTestTelemetryKeys()).waitForReply(); + reporter.reportLatency(Latencies.WS_SUBSCRIBE, stopWatch.getTime()); + reporter.serviceIsOk(MonitoredServiceKey.WS_SUBSCRIBE); + } catch (Exception e) { + reporter.serviceFailure(MonitoredServiceKey.WS_SUBSCRIBE, e); + return; + } for (BaseHealthChecker healthChecker : healthCheckers) { - check(healthChecker, wsClient); + check(healthChecker, ws); } } diff --git a/monitoring/src/main/java/org/thingsboard/monitoring/service/MonitoringReporter.java b/monitoring/src/main/java/org/thingsboard/monitoring/service/MonitoringReporter.java index b13394dbdc..75a8a819c0 100644 --- a/monitoring/src/main/java/org/thingsboard/monitoring/service/MonitoringReporter.java +++ b/monitoring/src/main/java/org/thingsboard/monitoring/service/MonitoringReporter.java @@ -25,7 +25,6 @@ import org.springframework.stereotype.Component; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.monitoring.client.TbClient; import org.thingsboard.monitoring.data.Latency; -import org.thingsboard.monitoring.data.MonitoredServiceKey; import org.thingsboard.monitoring.data.notification.HighLatencyNotification; import org.thingsboard.monitoring.data.notification.ServiceFailureNotification; import org.thingsboard.monitoring.data.notification.ServiceRecoveryNotification; @@ -119,9 +118,7 @@ public class MonitoringReporter { public void serviceIsOk(Object serviceKey) { ServiceRecoveryNotification notification = new ServiceRecoveryNotification(serviceKey); - if (!serviceKey.equals(MonitoredServiceKey.GENERAL)) { - log.info(notification.getText()); - } + log.info(notification.getText()); AtomicInteger failuresCounter = failuresCounters.get(serviceKey); if (failuresCounter != null) { if (failuresCounter.get() >= failuresThreshold) { diff --git a/monitoring/src/main/resources/tb-monitoring.yml b/monitoring/src/main/resources/tb-monitoring.yml index 053e42bb9d..768fd2e4c7 100644 --- a/monitoring/src/main/resources/tb-monitoring.yml +++ b/monitoring/src/main/resources/tb-monitoring.yml @@ -121,11 +121,24 @@ monitoring: notifications: message_prefix: '${NOTIFICATION_MESSAGE_PREFIX:}' + # Incident grouping (threads alerts into incidents, auto-resolves after timeout). + # Requires a channel that supports it — currently only Slack API (bot_token + channel_id). + incident: + # Enable incident grouping + enabled: '${INCIDENT_ENABLED:false}' + # Incident resolution timeout in seconds + resolution_timeout_s: '${INCIDENT_RESOLUTION_TIMEOUT_S:90}' + # Tag @channel in incident messages + tag_channel: '${INCIDENT_TAG_CHANNEL:false}' slack: # Enable notifying via Slack enabled: '${SLACK_NOTIFICATION_CHANNEL_ENABLED:false}' # Slack webhook url webhook_url: '${SLACK_WEBHOOK_URL:}' + # Slack Bot OAuth token (xoxb-...) for API-based messaging with incident support, requires chat:write:bot scope + bot_token: '${SLACK_BOT_TOKEN:}' + # Slack channel ID (e.g. C01234ABCDE) - required when incident feature is enabled + channel_id: '${SLACK_CHANNEL_ID:}' latency: # Enable latencies reporting diff --git a/monitoring/src/test/java/org/thingsboard/monitoring/data/notification/ServiceFailureNotificationTest.java b/monitoring/src/test/java/org/thingsboard/monitoring/data/notification/ServiceFailureNotificationTest.java new file mode 100644 index 0000000000..92c6996d1d --- /dev/null +++ b/monitoring/src/test/java/org/thingsboard/monitoring/data/notification/ServiceFailureNotificationTest.java @@ -0,0 +1,70 @@ +/** + * Copyright © 2016-2026 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.monitoring.data.notification; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +class ServiceFailureNotificationTest { + + @Test + void stripResponseBodyRemovesNginxErrorHtml() { + String msg = "503 Service Temporarily Unavailable on POST request for \"https://domain/api/auth/login\": \"" + + "503 Service Temporarily Unavailable" + + "

503 Service Temporarily Unavailable


nginx
\""; + + String sanitized = ServiceFailureNotification.stripResponseBody(msg); + + assertThat(sanitized) + .isEqualTo("503 Service Temporarily Unavailable on POST request for \"https://domain/api/auth/login\""); + } + + @Test + void stripResponseBodyRemovesDoctypeHtml() { + String msg = "500 Internal Server Error: \"...\""; + + String sanitized = ServiceFailureNotification.stripResponseBody(msg); + + assertThat(sanitized).isEqualTo("500 Internal Server Error"); + } + + @Test + void stripResponseBodyLeavesPlainMessagesUntouched() { + String msg = "Connection refused"; + assertThat(ServiceFailureNotification.stripResponseBody(msg)).isEqualTo(msg); + } + + @Test + void stripResponseBodyHandlesNull() { + assertThat(ServiceFailureNotification.stripResponseBody(null)).isNull(); + } + + @Test + void shortNameUsesShortNameProviderWhenAvailable() { + ShortNameProvider provider = () -> "MQTT"; + assertThat(ServiceFailureNotification.shortName(provider)).isEqualTo("MQTT"); + } + + @Test + void shortNameFallsBackToToStringForOtherKeys() { + Object key = new Object() { + @Override public String toString() { return "LOGIN"; } + }; + assertThat(ServiceFailureNotification.shortName(key)).isEqualTo("LOGIN"); + } + +} diff --git a/monitoring/src/test/java/org/thingsboard/monitoring/notification/incident/IncidentManagerTest.java b/monitoring/src/test/java/org/thingsboard/monitoring/notification/incident/IncidentManagerTest.java new file mode 100644 index 0000000000..81202efe25 --- /dev/null +++ b/monitoring/src/test/java/org/thingsboard/monitoring/notification/incident/IncidentManagerTest.java @@ -0,0 +1,162 @@ +/** + * Copyright © 2016-2026 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.monitoring.notification.incident; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.thingsboard.monitoring.data.notification.AffectedService; + +import java.time.Duration; +import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; + +import static org.assertj.core.api.Assertions.assertThat; + +class IncidentManagerTest { + + private RecordingTransport transport; + private IncidentManager manager; + + @BeforeEach + void setUp() { + transport = new RecordingTransport(); + manager = new IncidentManager(transport, 3600L, "tbqa", false); + } + + @AfterEach + void tearDown() { + manager.shutdown(); + } + + @Test + void formatDurationRendersMinutesAndHours() { + assertThat(IncidentManager.formatDuration(Duration.ofSeconds(30))).isEqualTo("0m"); + assertThat(IncidentManager.formatDuration(Duration.ofMinutes(5))).isEqualTo("5m"); + assertThat(IncidentManager.formatDuration(Duration.ofMinutes(59))).isEqualTo("59m"); + assertThat(IncidentManager.formatDuration(Duration.ofMinutes(60))).isEqualTo("1h"); + assertThat(IncidentManager.formatDuration(Duration.ofMinutes(75))).isEqualTo("1h15m"); + assertThat(IncidentManager.formatDuration(Duration.ofMinutes(120))).isEqualTo("2h"); + } + + @Test + void firstFailureOpensIncidentAndPostsHeaderAndReply() { + manager.sendAlert("CoAP failure message", + List.of(AffectedService.failing("CoAP", 1))); + + assertThat(transport.incidents).hasSize(1); + assertThat(transport.incidents.get(0)).contains(":rotating_light:").contains(":red_circle: CoAP (1)"); + assertThat(transport.replies).hasSize(1); + assertThat(transport.replies.get(0).text()).isEqualTo("CoAP failure message"); + } + + @Test + void isolatedRecoveryWithoutActiveIncidentIsIgnored() { + manager.sendAlert("Login is OK", + List.of(AffectedService.recovered("Login"))); + + assertThat(transport.incidents).isEmpty(); + assertThat(transport.replies).isEmpty(); + assertThat(transport.updates).isEmpty(); + } + + @Test + void subsequentFailureUpdatesHeaderAndPostsReply() { + manager.sendAlert("CoAP failure", List.of(AffectedService.failing("CoAP", 1))); + manager.sendAlert("CoAP repeat", List.of(AffectedService.failing("CoAP", 3))); + + assertThat(transport.incidents).hasSize(1); + assertThat(transport.replies).hasSize(2); + assertThat(transport.updates).hasSize(1); + assertThat(transport.updates.get(0).text()).contains(":red_circle: CoAP (3)"); + } + + @Test + void recoveryAfterFailureMovesServiceToGreenAndUpdatesHeader() { + manager.sendAlert("CoAP failure", List.of(AffectedService.failing("CoAP", 1))); + manager.sendAlert("CoAP is OK", List.of(AffectedService.recovered("CoAP"))); + + assertThat(transport.updates).hasSize(1); + String updated = transport.updates.get(0).text(); + assertThat(updated).contains(":large_green_circle: CoAP").doesNotContain(":red_circle:"); + } + + @Test + void highLatencyIsTrackedAsYellow() { + manager.sendAlert("high latency", + List.of(AffectedService.highLatency("logInLatency"))); + + assertThat(transport.incidents.get(0)).contains(":large_yellow_circle: logInLatency"); + } + + @Test + void repeatingSameFailureCountDoesNotTriggerRedundantUpdate() { + manager.sendAlert("CoAP failure", List.of(AffectedService.failing("CoAP", 3))); + manager.sendAlert("CoAP still failing", List.of(AffectedService.failing("CoAP", 3))); + + assertThat(transport.updates).isEmpty(); + assertThat(transport.replies).hasSize(2); + } + + @Test + void fullLifecycleStartFailRecoverResolve() { + manager.sendAlert("Login failure", List.of(AffectedService.failing("Login", 1))); + manager.sendAlert("WS failure", List.of(AffectedService.failing("WS Connect", 1))); + manager.sendAlert("Login is OK", List.of(AffectedService.recovered("Login"))); + + assertThat(transport.incidents).hasSize(1); + + manager.resolveIncident(); + + assertThat(transport.updates).last() + .extracting(RecordingTransport.Message::text) + .asString() + .contains(":white_check_mark:") + .contains(":red_circle: WS Connect") + .contains(":large_green_circle: Login"); + } + + @Test + void resolveWithoutActiveIncidentIsNoOp() { + manager.resolveIncident(); + assertThat(transport.updates).isEmpty(); + } + + private static class RecordingTransport implements IncidentTransport { + private final AtomicInteger threadCounter = new AtomicInteger(); + final java.util.List incidents = new java.util.ArrayList<>(); + final java.util.List replies = new java.util.ArrayList<>(); + final java.util.List updates = new java.util.ArrayList<>(); + + @Override + public String postIncident(String text) { + incidents.add(text); + return "thread-" + threadCounter.incrementAndGet(); + } + + @Override + public void postThreadReply(String threadId, String text) { + replies.add(new Message(threadId, text)); + } + + @Override + public void updateIncident(String threadId, String text) { + updates.add(new Message(threadId, text)); + } + + record Message(String threadId, String text) {} + } +} From 7033f60881deafb3d8cbe7ff1a5391a7e0f9dc41 Mon Sep 17 00:00:00 2001 From: Oleksii Kuripko Date: Tue, 21 Apr 2026 10:43:14 +0200 Subject: [PATCH 02/91] bump slack-api-client from 1.39.0 to 1.48.0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Changelog review (v1.40..v1.48): no breaking changes to the slack-api-client APIs used in this codebase. The only breaking changes in v1.45.0 were in slack-app-backend (servlet classes) and slack-api-bolt-aws-lambda-s3-storage (AWS SDK v1→v2), neither of which we depend on. Transitive deps (okhttp, gson, okio) are unchanged. Verified by compiling monitoring + application against 1.48.0 and running the monitoring unit tests plus the application Notification/Slack test suites (15 + 54 tests, all pass). --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index a4aa43688d..107e707bcf 100755 --- a/pom.xml +++ b/pom.xml @@ -164,7 +164,7 @@ 0.4.8 1.0.0 - 1.39.0 + 1.48.0 6.6.0 1.35.0 1.6.1 From c87b20e0c269d6f0c94b396ea371b045e17fa378 Mon Sep 17 00:00:00 2001 From: Oleksii Kuripko Date: Tue, 21 Apr 2026 18:41:46 +0200 Subject: [PATCH 03/91] linkify the URL in HTTP failure messages as a Slack hyperlink Transforms 'request for ""' into Slack mrkdwn , so the failure line renders the word 'request' as a clickable link instead of showing the raw URL in quotes. --- .../ServiceFailureNotification.java | 17 +++++++++++++++++ .../ServiceFailureNotificationTest.java | 19 +++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/monitoring/src/main/java/org/thingsboard/monitoring/data/notification/ServiceFailureNotification.java b/monitoring/src/main/java/org/thingsboard/monitoring/data/notification/ServiceFailureNotification.java index 47daf043ab..5fcc953cce 100644 --- a/monitoring/src/main/java/org/thingsboard/monitoring/data/notification/ServiceFailureNotification.java +++ b/monitoring/src/main/java/org/thingsboard/monitoring/data/notification/ServiceFailureNotification.java @@ -19,6 +19,8 @@ import lombok.Getter; import org.apache.commons.lang3.exception.ExceptionUtils; import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; @Getter public class ServiceFailureNotification implements Notification { @@ -46,9 +48,24 @@ public class ServiceFailureNotification implements Notification { errorMsg = error.getClass().getSimpleName(); } errorMsg = stripResponseBody(errorMsg); + errorMsg = linkifyRequestUrl(errorMsg); return String.format("%s - Failure: %s (number of subsequent failures: %s)", serviceKey, errorMsg, failuresCount); } + private static final Pattern REQUEST_URL_PATTERN = Pattern.compile("request for \"(https?://[^\"\\s]+)\""); + + static String linkifyRequestUrl(String msg) { + if (msg == null) { + return null; + } + Matcher m = REQUEST_URL_PATTERN.matcher(msg); + if (!m.find()) { + return msg; + } + // Slack mrkdwn link: + return m.replaceAll("<$1|request>"); + } + static String stripResponseBody(String msg) { if (msg == null) { return null; diff --git a/monitoring/src/test/java/org/thingsboard/monitoring/data/notification/ServiceFailureNotificationTest.java b/monitoring/src/test/java/org/thingsboard/monitoring/data/notification/ServiceFailureNotificationTest.java index 92c6996d1d..7f66a456fe 100644 --- a/monitoring/src/test/java/org/thingsboard/monitoring/data/notification/ServiceFailureNotificationTest.java +++ b/monitoring/src/test/java/org/thingsboard/monitoring/data/notification/ServiceFailureNotificationTest.java @@ -53,6 +53,25 @@ class ServiceFailureNotificationTest { assertThat(ServiceFailureNotification.stripResponseBody(null)).isNull(); } + @Test + void linkifyReplacesRequestForUrlWithSlackMrkdwnLink() { + String msg = "503 Service Temporarily Unavailable on POST request for \"https://qa-tb-pe-lts43.iot-private.cloud/api/auth/login\""; + + assertThat(ServiceFailureNotification.linkifyRequestUrl(msg)) + .isEqualTo("503 Service Temporarily Unavailable on POST "); + } + + @Test + void linkifyLeavesMessagesWithoutRequestUrlUntouched() { + String msg = "Connection refused"; + assertThat(ServiceFailureNotification.linkifyRequestUrl(msg)).isEqualTo(msg); + } + + @Test + void linkifyHandlesNull() { + assertThat(ServiceFailureNotification.linkifyRequestUrl(null)).isNull(); + } + @Test void shortNameUsesShortNameProviderWhenAvailable() { ShortNameProvider provider = () -> "MQTT"; From 43e87d458887b85c670ddb490900c823fd5015fc Mon Sep 17 00:00:00 2001 From: Oleksii Kuripko Date: Tue, 21 Apr 2026 18:45:44 +0200 Subject: [PATCH 04/91] preserve failure count on service recovery in incident header Recovered services are now shown as ':large_green_circle: ()' with the last failure count that was observed before the service recovered, matching the red-circle format. --- .../notification/incident/IncidentManager.java | 13 +++++++------ .../notification/incident/IncidentManagerTest.java | 8 ++++---- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/monitoring/src/main/java/org/thingsboard/monitoring/notification/incident/IncidentManager.java b/monitoring/src/main/java/org/thingsboard/monitoring/notification/incident/IncidentManager.java index 133d665f4c..1e52c37634 100644 --- a/monitoring/src/main/java/org/thingsboard/monitoring/notification/incident/IncidentManager.java +++ b/monitoring/src/main/java/org/thingsboard/monitoring/notification/incident/IncidentManager.java @@ -51,7 +51,7 @@ public class IncidentManager { private Instant incidentStartTime; private Instant lastAlertTime; private final Map failingServices = new LinkedHashMap<>(); - private final Set recoveredServices = new LinkedHashSet<>(); + private final Map recoveredServices = new LinkedHashMap<>(); private final Set highLatencyServices = new LinkedHashSet<>(); public IncidentManager(IncidentTransport transport, long resolutionTimeoutSeconds, @@ -110,13 +110,14 @@ public class IncidentManager { if (prev == null || prev.intValue() != service.failureCount()) { changed = true; } - if (recoveredServices.remove(name)) { + if (recoveredServices.remove(name) != null) { changed = true; } } case RECOVERED -> { - if (failingServices.remove(name) != null) { - recoveredServices.add(name); + Integer lastFailureCount = failingServices.remove(name); + if (lastFailureCount != null) { + recoveredServices.put(name, lastFailureCount); changed = true; } } @@ -257,9 +258,9 @@ public class IncidentManager { sb.append(":large_yellow_circle: ").append(name); first = false; } - for (String name : recoveredServices) { + for (Map.Entry entry : recoveredServices.entrySet()) { if (!first) sb.append(", "); - sb.append(":large_green_circle: ").append(name); + sb.append(":large_green_circle: ").append(entry.getKey()).append(" (").append(entry.getValue()).append(")"); first = false; } return sb.toString(); diff --git a/monitoring/src/test/java/org/thingsboard/monitoring/notification/incident/IncidentManagerTest.java b/monitoring/src/test/java/org/thingsboard/monitoring/notification/incident/IncidentManagerTest.java index 81202efe25..afcd20adf3 100644 --- a/monitoring/src/test/java/org/thingsboard/monitoring/notification/incident/IncidentManagerTest.java +++ b/monitoring/src/test/java/org/thingsboard/monitoring/notification/incident/IncidentManagerTest.java @@ -85,13 +85,13 @@ class IncidentManagerTest { } @Test - void recoveryAfterFailureMovesServiceToGreenAndUpdatesHeader() { - manager.sendAlert("CoAP failure", List.of(AffectedService.failing("CoAP", 1))); + void recoveryAfterFailureMovesServiceToGreenAndKeepsFailureCount() { + manager.sendAlert("CoAP failure", List.of(AffectedService.failing("CoAP", 4))); manager.sendAlert("CoAP is OK", List.of(AffectedService.recovered("CoAP"))); assertThat(transport.updates).hasSize(1); String updated = transport.updates.get(0).text(); - assertThat(updated).contains(":large_green_circle: CoAP").doesNotContain(":red_circle:"); + assertThat(updated).contains(":large_green_circle: CoAP (4)").doesNotContain(":red_circle:"); } @Test @@ -126,7 +126,7 @@ class IncidentManagerTest { .asString() .contains(":white_check_mark:") .contains(":red_circle: WS Connect") - .contains(":large_green_circle: Login"); + .contains(":large_green_circle: Login (1)"); } @Test From 27c2844fecb382a2d741572a100baf7d08cba043 Mon Sep 17 00:00:00 2001 From: Oleksii Kuripko Date: Tue, 21 Apr 2026 18:53:06 +0200 Subject: [PATCH 05/91] linkify URL for 'request: Connect to failed' error variant Spring wraps Apache HttpClient connect failures as 'I/O error on POST request: Connect to failed: '. Same treatment as the RestClient variant: the URL is embedded in the 'request' word and the 'Connect to ... failed' restatement is dropped from the visible text. --- .../ServiceFailureNotification.java | 19 +++++++++++++------ .../ServiceFailureNotificationTest.java | 12 ++++++++++-- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/monitoring/src/main/java/org/thingsboard/monitoring/data/notification/ServiceFailureNotification.java b/monitoring/src/main/java/org/thingsboard/monitoring/data/notification/ServiceFailureNotification.java index 5fcc953cce..69e336f334 100644 --- a/monitoring/src/main/java/org/thingsboard/monitoring/data/notification/ServiceFailureNotification.java +++ b/monitoring/src/main/java/org/thingsboard/monitoring/data/notification/ServiceFailureNotification.java @@ -52,18 +52,25 @@ public class ServiceFailureNotification implements Notification { return String.format("%s - Failure: %s (number of subsequent failures: %s)", serviceKey, errorMsg, failuresCount); } - private static final Pattern REQUEST_URL_PATTERN = Pattern.compile("request for \"(https?://[^\"\\s]+)\""); + // Spring RestClient: '... request for ""' + private static final Pattern REQUEST_FOR_URL_PATTERN = Pattern.compile("request for \"(https?://[^\"\\s]+)\""); + // Apache HttpClient wrapped by Spring: 'I/O error on POST request: Connect to failed: ' + private static final Pattern REQUEST_CONNECT_PATTERN = Pattern.compile("request: Connect to (https?://\\S+?) failed:"); static String linkifyRequestUrl(String msg) { if (msg == null) { return null; } - Matcher m = REQUEST_URL_PATTERN.matcher(msg); - if (!m.find()) { - return msg; - } // Slack mrkdwn link: - return m.replaceAll("<$1|request>"); + Matcher m = REQUEST_FOR_URL_PATTERN.matcher(msg); + if (m.find()) { + return m.replaceAll("<$1|request>"); + } + Matcher m2 = REQUEST_CONNECT_PATTERN.matcher(msg); + if (m2.find()) { + return m2.replaceAll("<$1|request>:"); + } + return msg; } static String stripResponseBody(String msg) { diff --git a/monitoring/src/test/java/org/thingsboard/monitoring/data/notification/ServiceFailureNotificationTest.java b/monitoring/src/test/java/org/thingsboard/monitoring/data/notification/ServiceFailureNotificationTest.java index 7f66a456fe..500a713f7b 100644 --- a/monitoring/src/test/java/org/thingsboard/monitoring/data/notification/ServiceFailureNotificationTest.java +++ b/monitoring/src/test/java/org/thingsboard/monitoring/data/notification/ServiceFailureNotificationTest.java @@ -55,10 +55,18 @@ class ServiceFailureNotificationTest { @Test void linkifyReplacesRequestForUrlWithSlackMrkdwnLink() { - String msg = "503 Service Temporarily Unavailable on POST request for \"https://qa-tb-pe-lts43.iot-private.cloud/api/auth/login\""; + String msg = "503 Service Temporarily Unavailable on POST request for \"https://example.com/api/auth/login\""; assertThat(ServiceFailureNotification.linkifyRequestUrl(msg)) - .isEqualTo("503 Service Temporarily Unavailable on POST "); + .isEqualTo("503 Service Temporarily Unavailable on POST "); + } + + @Test + void linkifyReplacesRequestConnectToUrlFailed() { + String msg = "I/O error on POST request: Connect to https://example.com:443 failed: Connect timed out"; + + assertThat(ServiceFailureNotification.linkifyRequestUrl(msg)) + .isEqualTo("I/O error on POST : Connect timed out"); } @Test From bec05fab535229e712ee92d13a2c7c6ddd8fe650 Mon Sep 17 00:00:00 2001 From: Oleksii Kuripko Date: Wed, 22 Apr 2026 09:51:35 +0200 Subject: [PATCH 06/91] hold incident resolution timer while services are still failing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The resolution countdown now only starts once every failing service has recovered. While any service is still firing the timer is cancelled, so the incident cannot auto-resolve and spawn a new incident for the same ongoing failure between alerts. High latency is a warning signal (no explicit recovery event) and therefore does not block resolution — only FAILING services do. --- .../incident/IncidentManager.java | 16 ++++++++++++-- .../incident/IncidentManagerTest.java | 21 +++++++++++++++++++ 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/monitoring/src/main/java/org/thingsboard/monitoring/notification/incident/IncidentManager.java b/monitoring/src/main/java/org/thingsboard/monitoring/notification/incident/IncidentManager.java index 1e52c37634..c25abfc081 100644 --- a/monitoring/src/main/java/org/thingsboard/monitoring/notification/incident/IncidentManager.java +++ b/monitoring/src/main/java/org/thingsboard/monitoring/notification/incident/IncidentManager.java @@ -94,7 +94,14 @@ public class IncidentManager { } finally { if (activeIncidentThreadId != null) { lastAlertTime = Instant.now(); - resetResolutionTimer(); + // High latency is a warning only — it has no explicit recovery signal + // (HighLatencyNotification fires only when something is above threshold), + // so resolution hinges on failing services alone. + if (failingServices.isEmpty()) { + resetResolutionTimer(); + } else { + cancelResolutionTimer(); + } } } } @@ -172,10 +179,15 @@ public class IncidentManager { } private void resetResolutionTimer() { + cancelResolutionTimer(); + resolutionTask = scheduler.schedule(this::resolveIncident, resolutionTimeoutSeconds, TimeUnit.SECONDS); + } + + private void cancelResolutionTimer() { if (resolutionTask != null) { resolutionTask.cancel(false); + resolutionTask = null; } - resolutionTask = scheduler.schedule(this::resolveIncident, resolutionTimeoutSeconds, TimeUnit.SECONDS); } private void startDurationUpdater() { diff --git a/monitoring/src/test/java/org/thingsboard/monitoring/notification/incident/IncidentManagerTest.java b/monitoring/src/test/java/org/thingsboard/monitoring/notification/incident/IncidentManagerTest.java index afcd20adf3..b7051db534 100644 --- a/monitoring/src/test/java/org/thingsboard/monitoring/notification/incident/IncidentManagerTest.java +++ b/monitoring/src/test/java/org/thingsboard/monitoring/notification/incident/IncidentManagerTest.java @@ -135,6 +135,27 @@ class IncidentManagerTest { assertThat(transport.updates).isEmpty(); } + @Test + void doesNotAutoResolveWhileServicesAreStillFailing() throws Exception { + manager.shutdown(); + transport = new RecordingTransport(); + manager = new IncidentManager(transport, 1L, "tbqa", false); + + manager.sendAlert("CoAP failure", List.of(AffectedService.failing("CoAP", 1))); + Thread.sleep(1500); + + assertThat(transport.updates) + .extracting(RecordingTransport.Message::text) + .noneMatch(t -> t.contains(":white_check_mark:")); + + manager.sendAlert("CoAP is OK", List.of(AffectedService.recovered("CoAP"))); + Thread.sleep(1500); + + assertThat(transport.updates) + .extracting(RecordingTransport.Message::text) + .anyMatch(t -> t.contains(":white_check_mark:")); + } + private static class RecordingTransport implements IncidentTransport { private final AtomicInteger threadCounter = new AtomicInteger(); final java.util.List incidents = new java.util.ArrayList<>(); From 30330057dbc64801b41e02e0a93e0cfa4fb420d1 Mon Sep 17 00:00:00 2001 From: Oleksandra Matviienko Date: Wed, 22 Apr 2026 11:01:51 +0200 Subject: [PATCH 07/91] Replaced deprecated @MockBean/@SpyBean with @MockitoBean in dao tests Spring Boot 3.4 deprecated @MockBean/@SpyBean in favor of @MockitoBean/@MockitoSpyBean. The 'answer' attribute was renamed to 'answers'. --- .../server/dao/AbstractDaoServiceTest.java | 4 ++-- .../server/dao/AbstractJpaDaoTest.java | 4 ++-- .../cache/RedisTbTransactionalCacheTest.java | 10 +++++----- .../server/dao/service/DeviceServiceTest.java | 4 ++-- .../server/dao/service/TenantServiceTest.java | 4 ++-- .../AdminSettingsDataValidatorTest.java | 8 ++++---- .../validator/AlarmDataValidatorTest.java | 8 ++++---- .../validator/AssetDataValidatorTest.java | 8 ++++---- .../AssetProfileDataValidatorTest.java | 18 ++++++++--------- .../CalculatedFieldDataValidatorTest.java | 10 +++++----- .../CalculatedFieldLinkDataValidatorTest.java | 8 ++++---- .../ComponentDescriptorDataValidatorTest.java | 4 ++-- .../validator/CustomerDataValidatorTest.java | 10 +++++----- .../validator/DashboardDataValidatorTest.java | 8 ++++---- .../validator/DeviceDataValidatorTest.java | 8 ++++---- .../DeviceProfileDataValidatorTest.java | 20 +++++++++---------- .../validator/EdgeDataValidatorTest.java | 12 +++++------ .../EntityViewDataValidatorTest.java | 12 +++++------ .../validator/ResourceDataValidatorTest.java | 14 ++++++------- .../validator/RuleChainDataValidatorTest.java | 10 +++++----- .../validator/TenantDataValidatorTest.java | 8 ++++---- .../TenantProfileDataValidatorTest.java | 10 +++++----- .../WidgetTypeDataValidatorTest.java | 12 +++++------ .../WidgetsBundleDataValidatorTest.java | 10 +++++----- .../DefaultEntityQueryRepositoryTest.java | 8 ++++---- .../query/DefaultQueryLogComponentTest.java | 4 ++-- ...esDaoPartitioningDaysAlwaysExistsTest.java | 8 ++++---- ...sDaoPartitioningHoursAlwaysExistsTest.java | 8 ++++---- ...artitioningIndefiniteAlwaysExistsTest.java | 8 ++++---- ...aoPartitioningMinutesAlwaysExistsTest.java | 8 ++++---- ...DaoPartitioningMonthsAlwaysExistsTest.java | 8 ++++---- ...sDaoPartitioningYearsAlwaysExistsTest.java | 8 ++++---- 32 files changed, 142 insertions(+), 142 deletions(-) diff --git a/dao/src/test/java/org/thingsboard/server/dao/AbstractDaoServiceTest.java b/dao/src/test/java/org/thingsboard/server/dao/AbstractDaoServiceTest.java index 267dd52882..4aa50de3cc 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/AbstractDaoServiceTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/AbstractDaoServiceTest.java @@ -17,7 +17,7 @@ package org.thingsboard.server.dao; import org.junit.runner.RunWith; import org.mockito.Answers; -import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.TestExecutionListeners; @@ -40,7 +40,7 @@ import org.thingsboard.server.dao.service.DaoSqlTest; DirtiesContextTestExecutionListener.class}) public abstract class AbstractDaoServiceTest { - @MockBean(answer = Answers.RETURNS_MOCKS) + @MockitoBean(answers = Answers.RETURNS_MOCKS) StatsFactory statsFactory; } diff --git a/dao/src/test/java/org/thingsboard/server/dao/AbstractJpaDaoTest.java b/dao/src/test/java/org/thingsboard/server/dao/AbstractJpaDaoTest.java index f68ab72786..dc5cc47cf7 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/AbstractJpaDaoTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/AbstractJpaDaoTest.java @@ -17,7 +17,7 @@ package org.thingsboard.server.dao; import org.junit.runner.RunWith; import org.mockito.Answers; -import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.TestExecutionListeners; import org.springframework.test.context.junit4.SpringRunner; @@ -42,7 +42,7 @@ import org.thingsboard.server.dao.service.DaoSqlTest; DirtiesContextTestExecutionListener.class}) public abstract class AbstractJpaDaoTest { - @MockBean(answer = Answers.RETURNS_MOCKS) + @MockitoBean(answers = Answers.RETURNS_MOCKS) StatsFactory statsFactory; } diff --git a/dao/src/test/java/org/thingsboard/server/dao/cache/RedisTbTransactionalCacheTest.java b/dao/src/test/java/org/thingsboard/server/dao/cache/RedisTbTransactionalCacheTest.java index 5de4378cf0..a9feec982b 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/cache/RedisTbTransactionalCacheTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/cache/RedisTbTransactionalCacheTest.java @@ -18,7 +18,7 @@ package org.thingsboard.server.dao.cache; import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; -import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.springframework.data.redis.connection.RedisConnection; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.test.context.ContextConfiguration; @@ -50,13 +50,13 @@ import static org.mockito.Mockito.when; @Slf4j public class RedisTbTransactionalCacheTest { - @MockBean + @MockitoBean private RelationRedisCache relationRedisCache; - @MockBean + @MockitoBean private RedisConnectionFactory connectionFactory; - @MockBean + @MockitoBean private RedisConnection redisConnection; - @MockBean + @MockitoBean private RedisSslCredentials redisSslCredentials; @Test diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/DeviceServiceTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/DeviceServiceTest.java index 94745c804e..90e3bf0603 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/DeviceServiceTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/DeviceServiceTest.java @@ -23,7 +23,7 @@ import org.junit.Test; import org.junit.jupiter.api.Assertions; import org.mockito.Mockito; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.TransactionStatus; import org.springframework.transaction.support.DefaultTransactionDefinition; @@ -103,7 +103,7 @@ public class DeviceServiceTest extends AbstractServiceTest { private CalculatedFieldService calculatedFieldService; @Autowired private PlatformTransactionManager platformTransactionManager; - @SpyBean + @MockitoSpyBean private DeviceCredentialsDataValidator validator; private IdComparator idComparator = new IdComparator<>(); diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/TenantServiceTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/TenantServiceTest.java index e9f5b4d16f..45b39c3ad7 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/TenantServiceTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/TenantServiceTest.java @@ -20,7 +20,7 @@ import org.junit.Test; import org.junit.jupiter.api.Assertions; import org.mockito.Mockito; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.cache.TbTransactionalCache; import org.thingsboard.server.common.data.Customer; @@ -87,7 +87,7 @@ import static org.mockito.Mockito.verify; @DaoSqlTest public class TenantServiceTest extends AbstractServiceTest { - @SpyBean + @MockitoSpyBean TenantDao tenantDao; @Autowired diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/validator/AdminSettingsDataValidatorTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/validator/AdminSettingsDataValidatorTest.java index c550772718..6241f2dea3 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/validator/AdminSettingsDataValidatorTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/validator/AdminSettingsDataValidatorTest.java @@ -17,8 +17,8 @@ package org.thingsboard.server.dao.service.validator; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.common.data.AdminSettings; import org.thingsboard.server.common.data.id.TenantId; @@ -31,9 +31,9 @@ import static org.mockito.Mockito.verify; @SpringBootTest(classes = AdminSettingsDataValidator.class) class AdminSettingsDataValidatorTest { - @MockBean + @MockitoBean AdminSettingsService adminSettingsService; - @SpyBean + @MockitoSpyBean AdminSettingsDataValidator validator; TenantId tenantId = TenantId.fromUUID(UUID.fromString("9ef79cdf-37a8-4119-b682-2e7ed4e018da")); diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/validator/AlarmDataValidatorTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/validator/AlarmDataValidatorTest.java index 89b0b0cec4..e36aa20773 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/validator/AlarmDataValidatorTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/validator/AlarmDataValidatorTest.java @@ -18,8 +18,8 @@ package org.thingsboard.server.dao.service.validator; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.thingsboard.server.common.data.alarm.Alarm; import org.thingsboard.server.common.data.alarm.AlarmSeverity; import org.thingsboard.server.common.data.id.TenantId; @@ -33,9 +33,9 @@ import static org.mockito.Mockito.verify; @SpringBootTest(classes = AlarmDataValidator.class) class AlarmDataValidatorTest { - @MockBean + @MockitoBean TenantService tenantService; - @SpyBean + @MockitoSpyBean AlarmDataValidator validator; TenantId tenantId = TenantId.fromUUID(UUID.fromString("9ef79cdf-37a8-4119-b682-2e7ed4e018da")); diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/validator/AssetDataValidatorTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/validator/AssetDataValidatorTest.java index 540d25578a..730daff5c5 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/validator/AssetDataValidatorTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/validator/AssetDataValidatorTest.java @@ -22,7 +22,7 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.thingsboard.server.common.data.asset.Asset; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.dao.asset.AssetDao; @@ -39,11 +39,11 @@ import static org.mockito.BDDMockito.willReturn; @Slf4j class AssetDataValidatorTest { - @MockBean + @MockitoBean AssetDao assetDao; - @MockBean + @MockitoBean TenantService tenantService; - @MockBean + @MockitoBean CustomerDao customerDao; @Autowired AssetDataValidator validator; diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/validator/AssetProfileDataValidatorTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/validator/AssetProfileDataValidatorTest.java index b5cfb4998c..a8060cd51f 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/validator/AssetProfileDataValidatorTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/validator/AssetProfileDataValidatorTest.java @@ -18,8 +18,8 @@ package org.thingsboard.server.dao.service.validator; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.thingsboard.server.common.data.asset.AssetProfile; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.dao.asset.AssetProfileDao; @@ -37,19 +37,19 @@ import static org.mockito.Mockito.verify; @SpringBootTest(classes = AssetProfileDataValidator.class) class AssetProfileDataValidatorTest { - @MockBean + @MockitoBean AssetProfileDao assetProfileDao; - @MockBean + @MockitoBean AssetProfileService assetProfileService; - @MockBean + @MockitoBean TenantService tenantService; - @MockBean + @MockitoBean QueueService queueService; - @MockBean + @MockitoBean RuleChainService ruleChainService; - @MockBean + @MockitoBean DashboardService dashboardService; - @SpyBean + @MockitoSpyBean AssetProfileDataValidator validator; TenantId tenantId = TenantId.fromUUID(UUID.fromString("9ef79cdf-37a8-4119-b682-2e7ed4e018da")); diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/validator/CalculatedFieldDataValidatorTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/validator/CalculatedFieldDataValidatorTest.java index 221782b23c..e781e60113 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/validator/CalculatedFieldDataValidatorTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/validator/CalculatedFieldDataValidatorTest.java @@ -17,8 +17,8 @@ package org.thingsboard.server.dao.service.validator; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.thingsboard.server.common.data.cf.CalculatedField; import org.thingsboard.server.common.data.cf.CalculatedFieldType; import org.thingsboard.server.common.data.id.CalculatedFieldId; @@ -38,11 +38,11 @@ public class CalculatedFieldDataValidatorTest { private final TenantId TENANT_ID = TenantId.fromUUID(UUID.fromString("7b5229e9-166e-41a9-a257-3b1dafad1b04")); private final CalculatedFieldId CALCULATED_FIELD_ID = new CalculatedFieldId(UUID.fromString("060fbe45-fbb2-4549-abf3-f72a6be3cb9f")); - @MockBean + @MockitoBean private CalculatedFieldDao calculatedFieldDao; - @MockBean + @MockitoBean private DefaultApiLimitService apiLimitService; - @SpyBean + @MockitoSpyBean private CalculatedFieldDataValidator validator; @Test diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/validator/CalculatedFieldLinkDataValidatorTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/validator/CalculatedFieldLinkDataValidatorTest.java index 41d16a0670..9ba5133071 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/validator/CalculatedFieldLinkDataValidatorTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/validator/CalculatedFieldLinkDataValidatorTest.java @@ -17,8 +17,8 @@ package org.thingsboard.server.dao.service.validator; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.thingsboard.server.common.data.cf.CalculatedFieldLink; import org.thingsboard.server.common.data.id.CalculatedFieldId; import org.thingsboard.server.common.data.id.CalculatedFieldLinkId; @@ -37,9 +37,9 @@ public class CalculatedFieldLinkDataValidatorTest { private final TenantId TENANT_ID = TenantId.fromUUID(UUID.fromString("2ba09d99-6143-43dc-b645-381fc0c43ebe")); private final CalculatedFieldLinkId CALCULATED_FIELD_LINK_ID = new CalculatedFieldLinkId(UUID.fromString("a5609ef4-cb42-43ce-9b23-e090a4878d1c")); - @MockBean + @MockitoBean private CalculatedFieldLinkDao calculatedFieldLinkDao; - @SpyBean + @MockitoSpyBean private CalculatedFieldLinkDataValidator validator; @Test diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/validator/ComponentDescriptorDataValidatorTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/validator/ComponentDescriptorDataValidatorTest.java index c810dd5c63..1dfc1d4e8d 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/validator/ComponentDescriptorDataValidatorTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/validator/ComponentDescriptorDataValidatorTest.java @@ -17,7 +17,7 @@ package org.thingsboard.server.dao.service.validator; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.plugin.ComponentDescriptor; import org.thingsboard.server.common.data.plugin.ComponentScope; @@ -27,7 +27,7 @@ import static org.mockito.Mockito.verify; @SpringBootTest(classes = ComponentDescriptorDataValidator.class) class ComponentDescriptorDataValidatorTest { - @SpyBean + @MockitoSpyBean ComponentDescriptorDataValidator validator; @Test diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/validator/CustomerDataValidatorTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/validator/CustomerDataValidatorTest.java index d434d8f231..aa66f4003f 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/validator/CustomerDataValidatorTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/validator/CustomerDataValidatorTest.java @@ -18,8 +18,8 @@ package org.thingsboard.server.dao.service.validator; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.thingsboard.server.common.data.Customer; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.dao.customer.CustomerDao; @@ -33,11 +33,11 @@ import static org.mockito.Mockito.verify; @SpringBootTest(classes = CustomerDataValidator.class) class CustomerDataValidatorTest { - @MockBean + @MockitoBean CustomerDao customerDao; - @MockBean + @MockitoBean TenantService tenantService; - @SpyBean + @MockitoSpyBean CustomerDataValidator validator; TenantId tenantId = TenantId.fromUUID(UUID.fromString("9ef79cdf-37a8-4119-b682-2e7ed4e018da")); diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/validator/DashboardDataValidatorTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/validator/DashboardDataValidatorTest.java index 3029027f37..cf5ad6e8fe 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/validator/DashboardDataValidatorTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/validator/DashboardDataValidatorTest.java @@ -18,8 +18,8 @@ package org.thingsboard.server.dao.service.validator; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.thingsboard.server.common.data.Dashboard; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.dao.tenant.TenantService; @@ -32,9 +32,9 @@ import static org.mockito.Mockito.verify; @SpringBootTest(classes = DashboardDataValidator.class) class DashboardDataValidatorTest { - @MockBean + @MockitoBean TenantService tenantService; - @SpyBean + @MockitoSpyBean DashboardDataValidator validator; TenantId tenantId = TenantId.fromUUID(UUID.fromString("9ef79cdf-37a8-4119-b682-2e7ed4e018da")); diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/validator/DeviceDataValidatorTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/validator/DeviceDataValidatorTest.java index 260114abd7..ae55b2caa5 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/validator/DeviceDataValidatorTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/validator/DeviceDataValidatorTest.java @@ -22,7 +22,7 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.dao.customer.CustomerDao; @@ -39,11 +39,11 @@ import static org.mockito.BDDMockito.willReturn; @Slf4j class DeviceDataValidatorTest { - @MockBean + @MockitoBean DeviceDao deviceDao; - @MockBean + @MockitoBean TenantService tenantService; - @MockBean + @MockitoBean CustomerDao customerDao; @Autowired DeviceDataValidator validator; diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/validator/DeviceProfileDataValidatorTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/validator/DeviceProfileDataValidatorTest.java index f3f172a5ce..b9a532f7d1 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/validator/DeviceProfileDataValidatorTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/validator/DeviceProfileDataValidatorTest.java @@ -18,8 +18,8 @@ package org.thingsboard.server.dao.service.validator; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.common.data.DeviceProfile; import org.thingsboard.server.common.data.DeviceProfileType; @@ -83,21 +83,21 @@ class DeviceProfileDataValidatorTest { private static final int port = 5685; private static final int portBs = 5687; - @MockBean + @MockitoBean DeviceProfileDao deviceProfileDao; - @MockBean + @MockitoBean DeviceProfileService deviceProfileService; - @MockBean + @MockitoBean DeviceDao deviceDao; - @MockBean + @MockitoBean TenantService tenantService; - @MockBean + @MockitoBean QueueService queueService; - @MockBean + @MockitoBean RuleChainService ruleChainService; - @MockBean + @MockitoBean DashboardService dashboardService; - @SpyBean + @MockitoSpyBean DeviceProfileDataValidator validator; TenantId tenantId = TenantId.fromUUID(UUID.fromString("9ef79cdf-37a8-4119-b682-2e7ed4e018da")); diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/validator/EdgeDataValidatorTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/validator/EdgeDataValidatorTest.java index 98699b0176..2f4ed4426f 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/validator/EdgeDataValidatorTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/validator/EdgeDataValidatorTest.java @@ -18,8 +18,8 @@ package org.thingsboard.server.dao.service.validator; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.thingsboard.server.common.data.edge.Edge; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.dao.customer.CustomerDao; @@ -34,13 +34,13 @@ import static org.mockito.Mockito.verify; @SpringBootTest(classes = EdgeDataValidator.class) class EdgeDataValidatorTest { - @MockBean + @MockitoBean EdgeDao edgeDao; - @MockBean + @MockitoBean TenantService tenantService; - @MockBean + @MockitoBean CustomerDao customerDao; - @SpyBean + @MockitoSpyBean EdgeDataValidator validator; TenantId tenantId = TenantId.fromUUID(UUID.fromString("9ef79cdf-37a8-4119-b682-2e7ed4e018da")); diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/validator/EntityViewDataValidatorTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/validator/EntityViewDataValidatorTest.java index 3db9d77469..ab821de252 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/validator/EntityViewDataValidatorTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/validator/EntityViewDataValidatorTest.java @@ -18,8 +18,8 @@ package org.thingsboard.server.dao.service.validator; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.thingsboard.server.common.data.EntityView; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.dao.customer.CustomerDao; @@ -34,13 +34,13 @@ import static org.mockito.Mockito.verify; @SpringBootTest(classes = EntityViewDataValidator.class) class EntityViewDataValidatorTest { - @MockBean + @MockitoBean EntityViewDao entityViewDao; - @MockBean + @MockitoBean TenantService tenantService; - @MockBean + @MockitoBean CustomerDao customerDao; - @SpyBean + @MockitoSpyBean EntityViewDataValidator validator; TenantId tenantId = TenantId.fromUUID(UUID.fromString("9ef79cdf-37a8-4119-b682-2e7ed4e018da")); diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/validator/ResourceDataValidatorTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/validator/ResourceDataValidatorTest.java index 9072bb5e62..059e966040 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/validator/ResourceDataValidatorTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/validator/ResourceDataValidatorTest.java @@ -18,8 +18,8 @@ package org.thingsboard.server.dao.service.validator; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.thingsboard.server.common.data.ResourceType; import org.thingsboard.server.common.data.TbResource; import org.thingsboard.server.common.data.id.TenantId; @@ -36,15 +36,15 @@ import static org.mockito.Mockito.verify; @SpringBootTest(classes = ResourceDataValidator.class) class ResourceDataValidatorTest { - @MockBean + @MockitoBean TbResourceDao resourceDao; - @MockBean + @MockitoBean WidgetTypeDao widgetTypeDao; - @MockBean + @MockitoBean TenantService tenantService; - @MockBean + @MockitoBean TbTenantProfileCache tenantProfileCache; - @SpyBean + @MockitoSpyBean ResourceDataValidator validator; TenantId tenantId = TenantId.fromUUID(UUID.fromString("9ef79cdf-37a8-4119-b682-2e7ed4e018da")); diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/validator/RuleChainDataValidatorTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/validator/RuleChainDataValidatorTest.java index 9107d1f8f2..eb884edbf3 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/validator/RuleChainDataValidatorTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/validator/RuleChainDataValidatorTest.java @@ -18,8 +18,8 @@ package org.thingsboard.server.dao.service.validator; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.rule.RuleChain; import org.thingsboard.server.common.data.rule.RuleChainType; @@ -34,11 +34,11 @@ import static org.mockito.Mockito.verify; @SpringBootTest(classes = RuleChainDataValidator.class) class RuleChainDataValidatorTest { - @MockBean + @MockitoBean RuleChainService ruleChainService; - @MockBean + @MockitoBean TenantService tenantService; - @SpyBean + @MockitoSpyBean RuleChainDataValidator validator; TenantId tenantId = TenantId.fromUUID(UUID.fromString("9ef79cdf-37a8-4119-b682-2e7ed4e018da")); diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/validator/TenantDataValidatorTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/validator/TenantDataValidatorTest.java index c7e4f73ce4..ca1871a1dc 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/validator/TenantDataValidatorTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/validator/TenantDataValidatorTest.java @@ -17,8 +17,8 @@ package org.thingsboard.server.dao.service.validator; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.thingsboard.server.common.data.Tenant; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.dao.tenant.TenantDao; @@ -30,9 +30,9 @@ import static org.mockito.Mockito.verify; @SpringBootTest(classes = TenantDataValidator.class) class TenantDataValidatorTest { - @MockBean + @MockitoBean TenantDao tenantDao; - @SpyBean + @MockitoSpyBean TenantDataValidator validator; TenantId tenantId = TenantId.fromUUID(UUID.fromString("9ef79cdf-37a8-4119-b682-2e7ed4e018da")); diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/validator/TenantProfileDataValidatorTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/validator/TenantProfileDataValidatorTest.java index 170b452fee..9d32fbd49e 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/validator/TenantProfileDataValidatorTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/validator/TenantProfileDataValidatorTest.java @@ -17,8 +17,8 @@ package org.thingsboard.server.dao.service.validator; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.thingsboard.server.common.data.TenantProfile; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.tenant.profile.DefaultTenantProfileConfiguration; @@ -33,11 +33,11 @@ import static org.mockito.Mockito.verify; @SpringBootTest(classes = TenantProfileDataValidator.class) class TenantProfileDataValidatorTest { - @MockBean + @MockitoBean TenantProfileDao tenantProfileDao; - @MockBean + @MockitoBean TenantProfileService tenantProfileService; - @SpyBean + @MockitoSpyBean TenantProfileDataValidator validator; TenantId tenantId = TenantId.fromUUID(UUID.fromString("9ef79cdf-37a8-4119-b682-2e7ed4e018da")); diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/validator/WidgetTypeDataValidatorTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/validator/WidgetTypeDataValidatorTest.java index 3849aa62bf..3904c7d509 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/validator/WidgetTypeDataValidatorTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/validator/WidgetTypeDataValidatorTest.java @@ -18,8 +18,8 @@ package org.thingsboard.server.dao.service.validator; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.widget.WidgetTypeDetails; @@ -34,13 +34,13 @@ import static org.mockito.Mockito.verify; @SpringBootTest(classes = WidgetTypeDataValidator.class) class WidgetTypeDataValidatorTest { - @MockBean + @MockitoBean WidgetTypeDao widgetTypeDao; - @MockBean + @MockitoBean WidgetsBundleDao widgetsBundleDao; - @MockBean + @MockitoBean TenantService tenantService; - @SpyBean + @MockitoSpyBean WidgetTypeDataValidator validator; TenantId tenantId = TenantId.fromUUID(UUID.fromString("9ef79cdf-37a8-4119-b682-2e7ed4e018da")); diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/validator/WidgetsBundleDataValidatorTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/validator/WidgetsBundleDataValidatorTest.java index 1affa60415..6ab7728471 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/validator/WidgetsBundleDataValidatorTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/validator/WidgetsBundleDataValidatorTest.java @@ -18,8 +18,8 @@ package org.thingsboard.server.dao.service.validator; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.widget.WidgetsBundle; import org.thingsboard.server.dao.tenant.TenantService; @@ -33,11 +33,11 @@ import static org.mockito.Mockito.verify; @SpringBootTest(classes = WidgetsBundleDataValidator.class) class WidgetsBundleDataValidatorTest { - @MockBean + @MockitoBean WidgetsBundleDao widgetsBundleDao; - @MockBean + @MockitoBean TenantService tenantService; - @SpyBean + @MockitoSpyBean WidgetsBundleDataValidator validator; TenantId tenantId = TenantId.fromUUID(UUID.fromString("9ef79cdf-37a8-4119-b682-2e7ed4e018da")); diff --git a/dao/src/test/java/org/thingsboard/server/dao/sql/query/DefaultEntityQueryRepositoryTest.java b/dao/src/test/java/org/thingsboard/server/dao/sql/query/DefaultEntityQueryRepositoryTest.java index b0d946ce3f..863d4ae2e8 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/sql/query/DefaultEntityQueryRepositoryTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/sql/query/DefaultEntityQueryRepositoryTest.java @@ -19,7 +19,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.transaction.support.TransactionTemplate; @@ -31,11 +31,11 @@ import static org.hamcrest.Matchers.equalTo; @SpringBootTest(classes = DefaultEntityQueryRepository.class) public class DefaultEntityQueryRepositoryTest { - @MockBean + @MockitoBean NamedParameterJdbcTemplate jdbcTemplate; - @MockBean + @MockitoBean TransactionTemplate transactionTemplate; - @MockBean + @MockitoBean DefaultQueryLogComponent queryLog; @Autowired diff --git a/dao/src/test/java/org/thingsboard/server/dao/sql/query/DefaultQueryLogComponentTest.java b/dao/src/test/java/org/thingsboard/server/dao/sql/query/DefaultQueryLogComponentTest.java index 83a06fe568..e47ed5bfbf 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/sql/query/DefaultQueryLogComponentTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/sql/query/DefaultQueryLogComponentTest.java @@ -22,7 +22,7 @@ import org.junit.runner.RunWith; import org.mockito.BDDMockito; import org.mockito.Mockito; import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.TestPropertySource; import org.springframework.test.context.junit.jupiter.SpringExtension; @@ -52,7 +52,7 @@ public class DefaultQueryLogComponentTest { private TenantId tenantId; private SqlQueryContext ctx; - @SpyBean + @MockitoSpyBean private DefaultQueryLogComponent queryLog; @Before diff --git a/dao/src/test/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDaoPartitioningDaysAlwaysExistsTest.java b/dao/src/test/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDaoPartitioningDaysAlwaysExistsTest.java index 43c8a064e1..05952e1203 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDaoPartitioningDaysAlwaysExistsTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDaoPartitioningDaysAlwaysExistsTest.java @@ -22,7 +22,7 @@ import org.mockito.Answers; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.springframework.test.context.TestPropertySource; import org.springframework.test.context.junit4.SpringRunner; import org.thingsboard.server.dao.cassandra.CassandraCluster; @@ -53,13 +53,13 @@ public class CassandraBaseTimeseriesDaoPartitioningDaysAlwaysExistsTest { @Autowired CassandraBaseTimeseriesDao tsDao; - @MockBean(answer = Answers.RETURNS_MOCKS) + @MockitoBean(answers = Answers.RETURNS_MOCKS) @Qualifier("CassandraCluster") CassandraCluster cassandraCluster; - @MockBean + @MockitoBean CassandraBufferedRateReadExecutor cassandraBufferedRateReadExecutor; - @MockBean + @MockitoBean CassandraBufferedRateWriteExecutor cassandraBufferedRateWriteExecutor; @Test diff --git a/dao/src/test/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDaoPartitioningHoursAlwaysExistsTest.java b/dao/src/test/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDaoPartitioningHoursAlwaysExistsTest.java index 5deccec298..83bb802c85 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDaoPartitioningHoursAlwaysExistsTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDaoPartitioningHoursAlwaysExistsTest.java @@ -22,7 +22,7 @@ import org.mockito.Answers; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.springframework.test.context.TestPropertySource; import org.springframework.test.context.junit4.SpringRunner; import org.thingsboard.server.dao.cassandra.CassandraCluster; @@ -53,13 +53,13 @@ public class CassandraBaseTimeseriesDaoPartitioningHoursAlwaysExistsTest { @Autowired CassandraBaseTimeseriesDao tsDao; - @MockBean(answer = Answers.RETURNS_MOCKS) + @MockitoBean(answers = Answers.RETURNS_MOCKS) @Qualifier("CassandraCluster") CassandraCluster cassandraCluster; - @MockBean + @MockitoBean CassandraBufferedRateReadExecutor cassandraBufferedRateReadExecutor; - @MockBean + @MockitoBean CassandraBufferedRateWriteExecutor cassandraBufferedRateWriteExecutor; @Test diff --git a/dao/src/test/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDaoPartitioningIndefiniteAlwaysExistsTest.java b/dao/src/test/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDaoPartitioningIndefiniteAlwaysExistsTest.java index a742e6cd2c..4f78f5b864 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDaoPartitioningIndefiniteAlwaysExistsTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDaoPartitioningIndefiniteAlwaysExistsTest.java @@ -22,7 +22,7 @@ import org.mockito.Answers; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.springframework.test.context.TestPropertySource; import org.springframework.test.context.junit4.SpringRunner; import org.thingsboard.server.dao.cassandra.CassandraCluster; @@ -52,13 +52,13 @@ public class CassandraBaseTimeseriesDaoPartitioningIndefiniteAlwaysExistsTest { @Autowired CassandraBaseTimeseriesDao tsDao; - @MockBean(answer = Answers.RETURNS_MOCKS) + @MockitoBean(answers = Answers.RETURNS_MOCKS) @Qualifier("CassandraCluster") CassandraCluster cassandraCluster; - @MockBean + @MockitoBean CassandraBufferedRateReadExecutor cassandraBufferedRateReadExecutor; - @MockBean + @MockitoBean CassandraBufferedRateWriteExecutor cassandraBufferedRateWriteExecutor; @Test diff --git a/dao/src/test/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDaoPartitioningMinutesAlwaysExistsTest.java b/dao/src/test/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDaoPartitioningMinutesAlwaysExistsTest.java index dd106cb439..455cf2cc00 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDaoPartitioningMinutesAlwaysExistsTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDaoPartitioningMinutesAlwaysExistsTest.java @@ -22,7 +22,7 @@ import org.mockito.Answers; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.springframework.test.context.TestPropertySource; import org.springframework.test.context.junit4.SpringRunner; import org.thingsboard.server.dao.cassandra.CassandraCluster; @@ -53,13 +53,13 @@ public class CassandraBaseTimeseriesDaoPartitioningMinutesAlwaysExistsTest { @Autowired CassandraBaseTimeseriesDao tsDao; - @MockBean(answer = Answers.RETURNS_MOCKS) + @MockitoBean(answers = Answers.RETURNS_MOCKS) @Qualifier("CassandraCluster") CassandraCluster cassandraCluster; - @MockBean + @MockitoBean CassandraBufferedRateReadExecutor cassandraBufferedRateReadExecutor; - @MockBean + @MockitoBean CassandraBufferedRateWriteExecutor cassandraBufferedRateWriteExecutor; @Test diff --git a/dao/src/test/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDaoPartitioningMonthsAlwaysExistsTest.java b/dao/src/test/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDaoPartitioningMonthsAlwaysExistsTest.java index 5699f5d5f7..ce8b66215b 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDaoPartitioningMonthsAlwaysExistsTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDaoPartitioningMonthsAlwaysExistsTest.java @@ -22,7 +22,7 @@ import org.junit.runner.RunWith; import org.mockito.Answers; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.springframework.test.context.TestPropertySource; import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.springframework.test.context.junit4.SpringRunner; @@ -63,13 +63,13 @@ public class CassandraBaseTimeseriesDaoPartitioningMonthsAlwaysExistsTest { @MockitoSpyBean CassandraBaseTimeseriesDao tsDao; - @MockBean(answer = Answers.RETURNS_MOCKS) + @MockitoBean(answers = Answers.RETURNS_MOCKS) @Qualifier("CassandraCluster") CassandraCluster cassandraCluster; - @MockBean + @MockitoBean CassandraBufferedRateReadExecutor cassandraBufferedRateReadExecutor; - @MockBean + @MockitoBean CassandraBufferedRateWriteExecutor cassandraBufferedRateWriteExecutor; @Test diff --git a/dao/src/test/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDaoPartitioningYearsAlwaysExistsTest.java b/dao/src/test/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDaoPartitioningYearsAlwaysExistsTest.java index a68daf664a..90575d5b14 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDaoPartitioningYearsAlwaysExistsTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDaoPartitioningYearsAlwaysExistsTest.java @@ -22,7 +22,7 @@ import org.mockito.Answers; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.springframework.test.context.TestPropertySource; import org.springframework.test.context.junit4.SpringRunner; import org.thingsboard.server.dao.cassandra.CassandraCluster; @@ -53,13 +53,13 @@ public class CassandraBaseTimeseriesDaoPartitioningYearsAlwaysExistsTest { @Autowired CassandraBaseTimeseriesDao tsDao; - @MockBean(answer = Answers.RETURNS_MOCKS) + @MockitoBean(answers = Answers.RETURNS_MOCKS) @Qualifier("CassandraCluster") CassandraCluster cassandraCluster; - @MockBean + @MockitoBean CassandraBufferedRateReadExecutor cassandraBufferedRateReadExecutor; - @MockBean + @MockitoBean CassandraBufferedRateWriteExecutor cassandraBufferedRateWriteExecutor; @Test From decd71f48fddb58632ac007319777b883a5f6d57 Mon Sep 17 00:00:00 2001 From: Oleksandra Matviienko Date: Wed, 22 Apr 2026 11:03:12 +0200 Subject: [PATCH 08/91] Replaced deprecated @MockBean/@SpyBean with @MockitoBean in edqs and coap-server tests Spring Boot 3.4 deprecated @MockBean/@SpyBean in favor of @MockitoBean/@MockitoSpyBean. --- .../server/coapserver/TbCoapDtlsSettingsTest.java | 8 ++++---- .../org/thingsboard/server/edqs/repo/AbstractEDQTest.java | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/common/coap-server/src/test/java/org/thingsboard/server/coapserver/TbCoapDtlsSettingsTest.java b/common/coap-server/src/test/java/org/thingsboard/server/coapserver/TbCoapDtlsSettingsTest.java index c75348d97e..f3af7b752f 100644 --- a/common/coap-server/src/test/java/org/thingsboard/server/coapserver/TbCoapDtlsSettingsTest.java +++ b/common/coap-server/src/test/java/org/thingsboard/server/coapserver/TbCoapDtlsSettingsTest.java @@ -18,7 +18,7 @@ package org.thingsboard.server.coapserver; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.springframework.test.context.TestPropertySource; import org.thingsboard.server.common.transport.TransportService; import org.thingsboard.server.common.transport.config.ssl.SslCredentialsConfig; @@ -41,11 +41,11 @@ class TbCoapDtlsSettingsTest { @Autowired TbCoapDtlsSettings coapDtlsSettings; - @MockBean + @MockitoBean SslCredentialsConfig sslCredentialsConfig; - @MockBean + @MockitoBean private TransportService transportService; - @MockBean + @MockitoBean private TbServiceInfoProvider serviceInfoProvider; @Test diff --git a/edqs/src/test/java/org/thingsboard/server/edqs/repo/AbstractEDQTest.java b/edqs/src/test/java/org/thingsboard/server/edqs/repo/AbstractEDQTest.java index adb42203e0..edf8832a33 100644 --- a/edqs/src/test/java/org/thingsboard/server/edqs/repo/AbstractEDQTest.java +++ b/edqs/src/test/java/org/thingsboard/server/edqs/repo/AbstractEDQTest.java @@ -20,7 +20,7 @@ import org.junit.Before; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.domain.EntityScan; -import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.test.context.TestExecutionListeners; @@ -81,7 +81,7 @@ public abstract class AbstractEDQTest { protected DefaultEdqsRepository repository; @Autowired protected EdqsMapper edqsMapper; - @MockBean + @MockitoBean private DummyEdqsStatsService edqsStatsService; protected final TenantId tenantId = TenantId.fromUUID(UUID.randomUUID()); From 3fad83d4e4c9c356d635d8f1b98148b67af1eb7a Mon Sep 17 00:00:00 2001 From: Oleksandra Matviienko Date: Wed, 22 Apr 2026 11:09:27 +0200 Subject: [PATCH 09/91] Replaced deprecated @MockBean/@SpyBean with @MockitoBean in application tests Spring Boot 3.4 deprecated @MockBean/@SpyBean in favor of @MockitoBean/@MockitoSpyBean. --- .../controller/AbstractNotifyEntityTest.java | 6 ++-- .../controller/AuditLogControllerTest.java | 6 ++-- ...trollerTest_DedicatedEventsDataSource.java | 4 +-- .../server/controller/AuthControllerTest.java | 4 +-- .../controller/BaseQueueControllerTest.java | 10 +++--- .../controller/DeviceControllerTest.java | 6 ++-- .../controller/EdgeEventControllerTest.java | 4 +-- .../EdqsEntityQueryControllerTest.java | 4 +-- .../server/controller/HomePageApiTest.java | 6 ++-- .../controller/RepositorySettingsTest.java | 4 +-- .../controller/RuleEngineControllerTest.java | 4 +-- .../controller/TenantControllerTest.java | 8 ++--- .../controller/TwoFactorAuthConfigTest.java | 10 +++--- .../server/controller/TwoFactorAuthTest.java | 8 ++--- .../server/controller/WebsocketApiTest.java | 4 +-- .../provision/DeviceProvisionServiceTest.java | 24 ++++++------- .../entitiy/EdqsEntityServiceTest.java | 4 +-- .../alarm/DefaultTbAlarmServiceTest.java | 32 ++++++++--------- .../DefaultTbAlarmCommentServiceTest.java | 34 +++++++++---------- .../service/install/InstallScriptsTest.java | 28 +++++++-------- .../update/DefaultDataUpdateServiceTest.java | 4 +-- .../server/service/job/JobManagerTest.java | 6 ++-- .../notification/NotificationApiTest.java | 4 +-- .../notification/NotificationRuleApiTest.java | 4 +-- .../queue/DefaultTbClusterServiceTest.java | 26 +++++++------- .../service/sms/DefaultSmsServiceTest.java | 4 +-- .../sync/ie/ExportImportServiceSqlTest.java | 6 ++-- .../DefaultTransportApiServiceTest.java | 34 +++++++++---------- .../service/ttl/AlarmsCleanUpServiceTest.java | 6 ++-- .../lwm2m/AbstractLwM2MIntegrationTest.java | 6 ++-- .../rpc/AbstractRpcLwM2MIntegrationTest.java | 4 +-- .../AbstractLwM2MIntegrationDiffPortTest.java | 4 +-- .../mqtt/MqttGatewayRateLimitsTest.java | 4 +-- ...AbstractMqttTimeseriesIntegrationTest.java | 4 +-- 34 files changed, 163 insertions(+), 163 deletions(-) diff --git a/application/src/test/java/org/thingsboard/server/controller/AbstractNotifyEntityTest.java b/application/src/test/java/org/thingsboard/server/controller/AbstractNotifyEntityTest.java index 58bf4b9798..2a03efc2ef 100644 --- a/application/src/test/java/org/thingsboard/server/controller/AbstractNotifyEntityTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/AbstractNotifyEntityTest.java @@ -18,7 +18,7 @@ package org.thingsboard.server.controller; import lombok.extern.slf4j.Slf4j; import org.mockito.ArgumentMatcher; import org.mockito.Mockito; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.thingsboard.server.cluster.TbClusterService; import org.thingsboard.server.common.data.EdgeUtils; import org.thingsboard.server.common.data.EntityType; @@ -53,10 +53,10 @@ import static org.mockito.Mockito.times; @Slf4j public abstract class AbstractNotifyEntityTest extends AbstractWebTest { - @SpyBean + @MockitoSpyBean protected TbClusterService tbClusterService; - @SpyBean + @MockitoSpyBean protected AuditLogService auditLogService; protected final String msgErrorPermission = "You don't have permission to perform this operation!"; diff --git a/application/src/test/java/org/thingsboard/server/controller/AuditLogControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/AuditLogControllerTest.java index a76da5f161..9c5b46ca70 100644 --- a/application/src/test/java/org/thingsboard/server/controller/AuditLogControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/AuditLogControllerTest.java @@ -25,7 +25,7 @@ import org.junit.Before; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.Tenant; import org.thingsboard.server.common.data.User; @@ -66,9 +66,9 @@ public class AuditLogControllerTest extends AbstractControllerTest { @Autowired private AuditLogDao auditLogDao; @Getter - @SpyBean + @MockitoSpyBean private SqlPartitioningRepository partitioningRepository; - @SpyBean + @MockitoSpyBean private AuditLogsCleanUpService auditLogsCleanUpService; @Value("#{${sql.audit_logs.partition_size} * 60 * 60 * 1000}") diff --git a/application/src/test/java/org/thingsboard/server/controller/AuditLogControllerTest_DedicatedEventsDataSource.java b/application/src/test/java/org/thingsboard/server/controller/AuditLogControllerTest_DedicatedEventsDataSource.java index c594beae98..0660dfe95e 100644 --- a/application/src/test/java/org/thingsboard/server/controller/AuditLogControllerTest_DedicatedEventsDataSource.java +++ b/application/src/test/java/org/thingsboard/server/controller/AuditLogControllerTest_DedicatedEventsDataSource.java @@ -16,7 +16,7 @@ package org.thingsboard.server.controller; import lombok.Getter; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.springframework.test.context.TestPropertySource; import org.thingsboard.server.dao.service.DaoSqlTest; import org.thingsboard.server.dao.sqlts.insert.sql.DedicatedEventsSqlPartitioningRepository; @@ -30,7 +30,7 @@ import org.thingsboard.server.dao.sqlts.insert.sql.DedicatedEventsSqlPartitionin public class AuditLogControllerTest_DedicatedEventsDataSource extends AuditLogControllerTest { @Getter - @SpyBean + @MockitoSpyBean private DedicatedEventsSqlPartitioningRepository partitioningRepository; } diff --git a/application/src/test/java/org/thingsboard/server/controller/AuthControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/AuthControllerTest.java index 9126c42f2f..419f442f87 100644 --- a/application/src/test/java/org/thingsboard/server/controller/AuthControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/AuthControllerTest.java @@ -20,7 +20,7 @@ import org.assertj.core.data.Offset; import org.junit.After; import org.junit.Test; import org.mockito.Mockito; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.springframework.http.HttpHeaders; import org.testcontainers.shaded.org.apache.commons.lang3.RandomStringUtils; import org.thingsboard.common.util.JacksonUtil; @@ -50,7 +50,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. @DaoSqlTest public class AuthControllerTest extends AbstractControllerTest { - @SpyBean + @MockitoSpyBean private UserCredentialsDao userCredentialsDao; @After diff --git a/application/src/test/java/org/thingsboard/server/controller/BaseQueueControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/BaseQueueControllerTest.java index 46a1dba3a7..b01f5f32f2 100644 --- a/application/src/test/java/org/thingsboard/server/controller/BaseQueueControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/BaseQueueControllerTest.java @@ -24,7 +24,7 @@ import org.junit.Test; import org.mockito.ArgumentCaptor; import org.mockito.Mockito; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.springframework.test.context.TestPropertySource; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.actors.ActorSystemContext; @@ -96,15 +96,15 @@ public class BaseQueueControllerTest extends AbstractControllerTest { private RuleEngineStatisticsService ruleEngineStatisticsService; @Autowired private StatsFactory statsFactory; - @SpyBean + @MockitoSpyBean private TimeseriesDao timeseriesDao; @Autowired private QueueStatsService queueStatsService; - @SpyBean + @MockitoSpyBean private PartitionService partitionService; - @SpyBean + @MockitoSpyBean private TimeseriesService timeseriesService; - @SpyBean + @MockitoSpyBean private ActorSystemContext actorSystemContext; @Test diff --git a/application/src/test/java/org/thingsboard/server/controller/DeviceControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/DeviceControllerTest.java index 0e404b2857..478b11dd3f 100644 --- a/application/src/test/java/org/thingsboard/server/controller/DeviceControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/DeviceControllerTest.java @@ -31,7 +31,7 @@ import org.mockito.AdditionalAnswers; import org.mockito.ArgumentCaptor; import org.mockito.Mockito; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Primary; import org.springframework.test.context.ContextConfiguration; @@ -109,10 +109,10 @@ public class DeviceControllerTest extends AbstractControllerTest { private Tenant savedTenant; private User tenantAdmin; - @SpyBean + @MockitoSpyBean private GatewayNotificationsService gatewayNotificationsService; - @SpyBean + @MockitoSpyBean private DeviceStateService deviceStateService; @Autowired diff --git a/application/src/test/java/org/thingsboard/server/controller/EdgeEventControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/EdgeEventControllerTest.java index ba389d3bd6..262d685d74 100644 --- a/application/src/test/java/org/thingsboard/server/controller/EdgeEventControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/EdgeEventControllerTest.java @@ -25,7 +25,7 @@ import org.junit.Before; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.springframework.test.context.TestPropertySource; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.common.data.AttributeScope; @@ -66,7 +66,7 @@ public class EdgeEventControllerTest extends AbstractControllerTest { @Autowired private EdgeEventDao edgeEventDao; - @SpyBean + @MockitoSpyBean private SqlPartitioningRepository partitioningRepository; @Autowired private EdgeEventsCleanUpService edgeEventsCleanUpService; diff --git a/application/src/test/java/org/thingsboard/server/controller/EdqsEntityQueryControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/EdqsEntityQueryControllerTest.java index 932980a3ca..8d3859b1bd 100644 --- a/application/src/test/java/org/thingsboard/server/controller/EdqsEntityQueryControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/EdqsEntityQueryControllerTest.java @@ -19,7 +19,7 @@ import org.assertj.core.api.ThrowingConsumer; import org.junit.Before; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.springframework.test.context.TestPropertySource; import org.thingsboard.server.common.data.edqs.EdqsState; import org.thingsboard.server.common.data.edqs.EdqsState.EdqsApiMode; @@ -59,7 +59,7 @@ public class EdqsEntityQueryControllerTest extends EntityQueryControllerTest { @Autowired private DiscoveryService discoveryService; - @MockBean // so that we don't do backup for tests + @MockitoBean // so that we don't do backup for tests private EdqsRocksDb edqsRocksDb; @Before diff --git a/application/src/test/java/org/thingsboard/server/controller/HomePageApiTest.java b/application/src/test/java/org/thingsboard/server/controller/HomePageApiTest.java index ee2aefc81a..efe553e8f2 100644 --- a/application/src/test/java/org/thingsboard/server/controller/HomePageApiTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/HomePageApiTest.java @@ -22,7 +22,7 @@ import org.junit.Assert; import org.junit.Test; import org.mockito.Mockito; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.rule.engine.api.MailService; import org.thingsboard.rule.engine.api.SmsService; @@ -85,10 +85,10 @@ public class HomePageApiTest extends AbstractControllerTest { @Autowired private OAuth2ClientService oAuth2ClientService; - @MockBean + @MockitoBean private MailService mailService; - @MockBean + @MockitoBean private SmsService smsService; private static final int DEFAULT_DASHBOARDS_COUNT = 0; diff --git a/application/src/test/java/org/thingsboard/server/controller/RepositorySettingsTest.java b/application/src/test/java/org/thingsboard/server/controller/RepositorySettingsTest.java index 072e83cc47..3d6c62d701 100644 --- a/application/src/test/java/org/thingsboard/server/controller/RepositorySettingsTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/RepositorySettingsTest.java @@ -18,7 +18,7 @@ package org.thingsboard.server.controller; import com.google.common.util.concurrent.SettableFuture; import lombok.extern.slf4j.Slf4j; import org.junit.Test; -import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.thingsboard.server.common.data.sync.vc.RepositoryAuthMethod; import org.thingsboard.server.common.data.sync.vc.RepositorySettings; import org.thingsboard.server.dao.service.DaoSqlTest; @@ -35,7 +35,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. @DaoSqlTest public class RepositorySettingsTest extends AbstractControllerTest { - @MockBean + @MockitoBean private GitVersionControlQueueService gitVersionControlQueueService; @Test diff --git a/application/src/test/java/org/thingsboard/server/controller/RuleEngineControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/RuleEngineControllerTest.java index 81c74de038..ff75d80d30 100644 --- a/application/src/test/java/org/thingsboard/server/controller/RuleEngineControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/RuleEngineControllerTest.java @@ -19,7 +19,7 @@ import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.JsonNode; import org.junit.Test; import org.mockito.ArgumentCaptor; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.Device; @@ -56,7 +56,7 @@ public class RuleEngineControllerTest extends AbstractControllerTest { private final String REQUEST_BODY = "{\"request\":\"download\"}"; private final String RESPONSE_BODY = "{\"response\":\"downloadOk\"}"; - @SpyBean + @MockitoSpyBean private RuleEngineCallService ruleEngineCallService; @Test diff --git a/application/src/test/java/org/thingsboard/server/controller/TenantControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/TenantControllerTest.java index cc217b05d5..cc0f64428e 100644 --- a/application/src/test/java/org/thingsboard/server/controller/TenantControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/TenantControllerTest.java @@ -27,7 +27,7 @@ import org.junit.Before; import org.junit.Test; import org.mockito.ArgumentMatcher; import org.mockito.Mockito; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.springframework.test.context.TestPropertySource; import org.springframework.test.web.servlet.ResultActions; import org.thingsboard.common.util.ThingsBoardExecutors; @@ -110,11 +110,11 @@ public class TenantControllerTest extends AbstractControllerTest { ListeningExecutorService executor; - @SpyBean + @MockitoSpyBean private PartitionService partitionService; - @SpyBean + @MockitoSpyBean private ActorSystemContext actorContext; - @SpyBean + @MockitoSpyBean private TbQueueAdmin queueAdmin; @Before diff --git a/application/src/test/java/org/thingsboard/server/controller/TwoFactorAuthConfigTest.java b/application/src/test/java/org/thingsboard/server/controller/TwoFactorAuthConfigTest.java index c3eb91db85..2a7422880c 100644 --- a/application/src/test/java/org/thingsboard/server/controller/TwoFactorAuthConfigTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/TwoFactorAuthConfigTest.java @@ -22,8 +22,8 @@ import org.junit.Before; import org.junit.Test; import org.mockito.ArgumentCaptor; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.springframework.cache.CacheManager; import org.springframework.web.util.UriComponents; import org.springframework.web.util.UriComponentsBuilder; @@ -62,15 +62,15 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. @DaoSqlTest public class TwoFactorAuthConfigTest extends AbstractControllerTest { - @SpyBean + @MockitoSpyBean private TotpTwoFaProvider totpTwoFactorAuthProvider; - @MockBean + @MockitoBean private SmsService smsService; @Autowired private CacheManager cacheManager; @Autowired private TwoFaConfigManager twoFaConfigManager; - @SpyBean + @MockitoSpyBean private TwoFactorAuthService twoFactorAuthService; @Before diff --git a/application/src/test/java/org/thingsboard/server/controller/TwoFactorAuthTest.java b/application/src/test/java/org/thingsboard/server/controller/TwoFactorAuthTest.java index b20dd570fb..2092c0b7e7 100644 --- a/application/src/test/java/org/thingsboard/server/controller/TwoFactorAuthTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/TwoFactorAuthTest.java @@ -23,8 +23,8 @@ import org.junit.Before; import org.junit.Test; import org.mockito.ArgumentCaptor; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.thingsboard.rule.engine.api.SmsService; import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.User; @@ -78,9 +78,9 @@ public class TwoFactorAuthTest extends AbstractControllerTest { @Autowired private TwoFaConfigManager twoFaConfigManager; - @SpyBean + @MockitoSpyBean private TwoFactorAuthService twoFactorAuthService; - @MockBean + @MockitoBean private SmsService smsService; @Autowired private AuditLogService auditLogService; diff --git a/application/src/test/java/org/thingsboard/server/controller/WebsocketApiTest.java b/application/src/test/java/org/thingsboard/server/controller/WebsocketApiTest.java index 6ec0f3ad64..e3b6a6efd8 100644 --- a/application/src/test/java/org/thingsboard/server/controller/WebsocketApiTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/WebsocketApiTest.java @@ -28,7 +28,7 @@ import org.junit.Before; import org.junit.Test; import org.mockito.Mockito; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.springframework.test.context.TestPropertySource; import org.testcontainers.shaded.org.apache.commons.lang3.RandomStringUtils; import org.thingsboard.common.util.JacksonUtil; @@ -100,7 +100,7 @@ public class WebsocketApiTest extends AbstractControllerTest { @Autowired private TelemetrySubscriptionService tsService; - @SpyBean + @MockitoSpyBean private TimeseriesService timeseriesService; Device device; diff --git a/application/src/test/java/org/thingsboard/server/service/device/provision/DeviceProvisionServiceTest.java b/application/src/test/java/org/thingsboard/server/service/device/provision/DeviceProvisionServiceTest.java index de86e46cd0..c5f10ea4b3 100644 --- a/application/src/test/java/org/thingsboard/server/service/device/provision/DeviceProvisionServiceTest.java +++ b/application/src/test/java/org/thingsboard/server/service/device/provision/DeviceProvisionServiceTest.java @@ -21,8 +21,8 @@ import org.assertj.core.api.Assertions; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringRunner; import org.thingsboard.server.cluster.TbClusterService; @@ -76,25 +76,25 @@ import static org.mockito.Mockito.when; @ContextConfiguration(classes = DeviceProvisionServiceImpl.class) public class DeviceProvisionServiceTest { - @MockBean + @MockitoBean protected TbQueueProducerProvider producerProvider; - @MockBean + @MockitoBean protected TbQueueProducer> ruleEngineMsgProducer; - @MockBean + @MockitoBean protected TbClusterService clusterService; - @MockBean + @MockitoBean protected DeviceProfileService deviceProfileService; - @MockBean + @MockitoBean protected DeviceService deviceService; - @MockBean + @MockitoBean protected DeviceCredentialsService deviceCredentialsService; - @MockBean + @MockitoBean protected AttributesService attributesService; - @MockBean + @MockitoBean protected AuditLogService auditLogService; - @MockBean + @MockitoBean protected PartitionService partitionService; - @SpyBean + @MockitoSpyBean DeviceProvisionServiceImpl service; private String[] chain; diff --git a/application/src/test/java/org/thingsboard/server/service/entitiy/EdqsEntityServiceTest.java b/application/src/test/java/org/thingsboard/server/service/entitiy/EdqsEntityServiceTest.java index a16cf99c1d..0b7be314a0 100644 --- a/application/src/test/java/org/thingsboard/server/service/entitiy/EdqsEntityServiceTest.java +++ b/application/src/test/java/org/thingsboard/server/service/entitiy/EdqsEntityServiceTest.java @@ -19,7 +19,7 @@ import com.google.common.collect.Lists; import org.junit.Before; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.springframework.test.context.TestPropertySource; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.asset.Asset; @@ -61,7 +61,7 @@ public class EdqsEntityServiceTest extends EntityServiceTest { @Autowired private EdqsService edqsService; - @MockBean + @MockitoBean private EdqsRocksDb edqsRocksDb; @Before diff --git a/application/src/test/java/org/thingsboard/server/service/entitiy/alarm/DefaultTbAlarmServiceTest.java b/application/src/test/java/org/thingsboard/server/service/entitiy/alarm/DefaultTbAlarmServiceTest.java index 4886310750..e5f8061fb8 100644 --- a/application/src/test/java/org/thingsboard/server/service/entitiy/alarm/DefaultTbAlarmServiceTest.java +++ b/application/src/test/java/org/thingsboard/server/service/entitiy/alarm/DefaultTbAlarmServiceTest.java @@ -19,7 +19,7 @@ import com.datastax.oss.driver.api.core.uuid.Uuids; import com.fasterxml.jackson.databind.node.ObjectNode; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.cluster.TbClusterService; @@ -66,35 +66,35 @@ import static org.mockito.Mockito.when; @SpringJUnitConfig(DefaultTbAlarmService.class) class DefaultTbAlarmServiceTest { - @MockBean + @MockitoBean TbLogEntityActionService logEntityActionService; - @MockBean + @MockitoBean EdgeService edgeService; - @MockBean + @MockitoBean AlarmService alarmService; - @MockBean + @MockitoBean TbAlarmCommentService alarmCommentService; - @MockBean + @MockitoBean AlarmSubscriptionService alarmSubscriptionService; - @MockBean + @MockitoBean CustomerService customerService; - @MockBean + @MockitoBean TbClusterService tbClusterService; - @MockBean + @MockitoBean EntitiesVersionControlService vcService; - @MockBean + @MockitoBean AccessControlService accessControlService; - @MockBean + @MockitoBean TenantService tenantService; - @MockBean + @MockitoBean AssetService assetService; - @MockBean + @MockitoBean DeviceService deviceService; - @MockBean + @MockitoBean AssetProfileService assetProfileService; - @MockBean + @MockitoBean DeviceProfileService deviceProfileService; - @MockBean + @MockitoBean EntityService entityService; @Autowired diff --git a/application/src/test/java/org/thingsboard/server/service/entitiy/alarmComment/DefaultTbAlarmCommentServiceTest.java b/application/src/test/java/org/thingsboard/server/service/entitiy/alarmComment/DefaultTbAlarmCommentServiceTest.java index 2c2d2bbdc3..122a939a9d 100644 --- a/application/src/test/java/org/thingsboard/server/service/entitiy/alarmComment/DefaultTbAlarmCommentServiceTest.java +++ b/application/src/test/java/org/thingsboard/server/service/entitiy/alarmComment/DefaultTbAlarmCommentServiceTest.java @@ -19,8 +19,8 @@ import lombok.extern.slf4j.Slf4j; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mockito; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.TestPropertySource; import org.springframework.test.context.junit4.SpringRunner; @@ -65,35 +65,35 @@ import static org.mockito.Mockito.when; }) public class DefaultTbAlarmCommentServiceTest { - @MockBean + @MockitoBean protected DbCallbackExecutorService dbExecutor; - @MockBean + @MockitoBean protected TbLogEntityActionService logEntityActionService; - @MockBean + @MockitoBean protected AlarmService alarmService; - @MockBean + @MockitoBean protected AlarmCommentService alarmCommentService; - @MockBean + @MockitoBean protected AlarmSubscriptionService alarmSubscriptionService; - @MockBean + @MockitoBean protected CustomerService customerService; - @MockBean + @MockitoBean protected TbClusterService tbClusterService; - @MockBean + @MockitoBean private AccessControlService accessControlService; - @MockBean + @MockitoBean private TenantService tenantService; - @MockBean + @MockitoBean private AssetService assetService; - @MockBean + @MockitoBean private DeviceService deviceService; - @MockBean + @MockitoBean private AssetProfileService assetProfileService; - @MockBean + @MockitoBean private DeviceProfileService deviceProfileService; - @MockBean + @MockitoBean private EntityService entityService; - @SpyBean + @MockitoSpyBean DefaultTbAlarmCommentService service; @Test diff --git a/application/src/test/java/org/thingsboard/server/service/install/InstallScriptsTest.java b/application/src/test/java/org/thingsboard/server/service/install/InstallScriptsTest.java index fa675fc3f8..5caf2ececd 100644 --- a/application/src/test/java/org/thingsboard/server/service/install/InstallScriptsTest.java +++ b/application/src/test/java/org/thingsboard/server/service/install/InstallScriptsTest.java @@ -20,8 +20,8 @@ import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.common.data.id.RuleChainId; import org.thingsboard.server.common.data.id.TenantId; @@ -52,30 +52,30 @@ import static org.mockito.BDDMockito.willReturn; @SpringBootTest(classes = {InstallScripts.class, RuleChainDataValidator.class}) class InstallScriptsTest { - @MockBean + @MockitoBean RuleChainService ruleChainService; - @MockBean + @MockitoBean DashboardService dashboardService; - @MockBean + @MockitoBean WidgetTypeService widgetTypeService; - @MockBean + @MockitoBean WidgetsBundleService widgetsBundleService; - @MockBean + @MockitoBean OAuth2ConfigTemplateService oAuth2TemplateService; - @MockBean + @MockitoBean ResourceService resourceService; - @MockBean + @MockitoBean ImageService imageService; - @MockBean + @MockitoBean ResourcesUpdater resourcesUpdater; - @SpyBean + @MockitoSpyBean InstallScripts installScripts; - @MockBean + @MockitoBean TenantService tenantService; - @MockBean + @MockitoBean ApiLimitService apiLimitService; - @SpyBean + @MockitoSpyBean RuleChainDataValidator ruleChainValidator; TenantId tenantId = TenantId.fromUUID(UUID.fromString("9ef79cdf-37a8-4119-b682-2e7ed4e018da")); diff --git a/application/src/test/java/org/thingsboard/server/service/install/update/DefaultDataUpdateServiceTest.java b/application/src/test/java/org/thingsboard/server/service/install/update/DefaultDataUpdateServiceTest.java index a82aad5b62..1690d854d9 100644 --- a/application/src/test/java/org/thingsboard/server/service/install/update/DefaultDataUpdateServiceTest.java +++ b/application/src/test/java/org/thingsboard/server/service/install/update/DefaultDataUpdateServiceTest.java @@ -20,7 +20,7 @@ import com.fasterxml.jackson.databind.JsonNode; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.springframework.test.context.ActiveProfiles; import org.thingsboard.common.util.JacksonUtil; @@ -34,7 +34,7 @@ import static org.mockito.BDDMockito.willCallRealMethod; @SpringBootTest(classes = DefaultDataUpdateService.class) class DefaultDataUpdateServiceTest { - @MockBean + @MockitoBean DefaultDataUpdateService service; @BeforeEach diff --git a/application/src/test/java/org/thingsboard/server/service/job/JobManagerTest.java b/application/src/test/java/org/thingsboard/server/service/job/JobManagerTest.java index c17a9f6bfb..b2aa361f27 100644 --- a/application/src/test/java/org/thingsboard/server/service/job/JobManagerTest.java +++ b/application/src/test/java/org/thingsboard/server/service/job/JobManagerTest.java @@ -21,7 +21,7 @@ import org.junit.Before; import org.junit.Test; import org.mockito.Mockito; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.springframework.test.context.TestPropertySource; import org.thingsboard.rule.engine.api.JobManager; import org.thingsboard.server.common.data.Device; @@ -64,10 +64,10 @@ public class JobManagerTest extends AbstractControllerTest { @Autowired private JobManager jobManager; - @SpyBean + @MockitoSpyBean private TestTaskProcessor taskProcessor; - @SpyBean + @MockitoSpyBean private JobStatsService jobStatsService; @Autowired diff --git a/application/src/test/java/org/thingsboard/server/service/notification/NotificationApiTest.java b/application/src/test/java/org/thingsboard/server/service/notification/NotificationApiTest.java index e9e239ec04..a24e303e29 100644 --- a/application/src/test/java/org/thingsboard/server/service/notification/NotificationApiTest.java +++ b/application/src/test/java/org/thingsboard/server/service/notification/NotificationApiTest.java @@ -24,7 +24,7 @@ import org.junit.Before; import org.junit.Test; import org.mockito.ArgumentCaptor; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.springframework.http.HttpEntity; import org.springframework.test.web.servlet.ResultActions; import org.springframework.web.client.RestTemplate; @@ -125,7 +125,7 @@ public class NotificationApiTest extends AbstractNotificationApiTest { private NotificationCenter notificationCenter; @Autowired private MicrosoftTeamsNotificationChannel microsoftTeamsNotificationChannel; - @MockBean + @MockitoBean private FirebaseService firebaseService; private static final String TEST_MOBILE_TOKEN = "tenantFcmToken"; diff --git a/application/src/test/java/org/thingsboard/server/service/notification/NotificationRuleApiTest.java b/application/src/test/java/org/thingsboard/server/service/notification/NotificationRuleApiTest.java index 7175f0981d..d13c5c737a 100644 --- a/application/src/test/java/org/thingsboard/server/service/notification/NotificationRuleApiTest.java +++ b/application/src/test/java/org/thingsboard/server/service/notification/NotificationRuleApiTest.java @@ -22,7 +22,7 @@ import org.junit.Before; import org.junit.Test; import org.junit.function.ThrowingRunnable; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.springframework.data.util.Pair; import org.springframework.test.context.TestPropertySource; import org.thingsboard.common.util.JacksonUtil; @@ -137,7 +137,7 @@ import static org.thingsboard.server.common.data.notification.rule.trigger.confi }) public class NotificationRuleApiTest extends AbstractNotificationApiTest { - @SpyBean + @MockitoSpyBean private AlarmSubscriptionService alarmSubscriptionService; @Autowired private DefaultSystemInfoService systemInfoService; diff --git a/application/src/test/java/org/thingsboard/server/service/queue/DefaultTbClusterServiceTest.java b/application/src/test/java/org/thingsboard/server/service/queue/DefaultTbClusterServiceTest.java index 8110f6c0e3..63b4c98142 100644 --- a/application/src/test/java/org/thingsboard/server/service/queue/DefaultTbClusterServiceTest.java +++ b/application/src/test/java/org/thingsboard/server/service/queue/DefaultTbClusterServiceTest.java @@ -20,8 +20,8 @@ import lombok.extern.slf4j.Slf4j; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringRunner; import org.thingsboard.common.util.JacksonUtil; @@ -87,28 +87,28 @@ public class DefaultTbClusterServiceTest { public static final String TRANSPORT = "transport"; - @MockBean + @MockitoBean protected TbDeviceProfileCache deviceProfileCache; - @MockBean + @MockitoBean protected TbAssetProfileCache assetProfileCache; - @MockBean + @MockitoBean protected GatewayNotificationsService gatewayNotificationsService; - @MockBean + @MockitoBean protected EdgeService edgeService; - @MockBean + @MockitoBean protected PartitionService partitionService; - @MockBean + @MockitoBean protected TbQueueProducerProvider producerProvider; - @MockBean + @MockitoBean protected TbRuleEngineProducerService ruleEngineProducerService; - @MockBean + @MockitoBean protected TbTransactionalCache edgeCache; - @MockBean + @MockitoBean protected CalculatedFieldService calculatedFieldService; - @SpyBean + @MockitoSpyBean protected TopicService topicService; - @SpyBean + @MockitoSpyBean protected TbClusterService clusterService; @Test diff --git a/application/src/test/java/org/thingsboard/server/service/sms/DefaultSmsServiceTest.java b/application/src/test/java/org/thingsboard/server/service/sms/DefaultSmsServiceTest.java index 445be6363a..8d23b32946 100644 --- a/application/src/test/java/org/thingsboard/server/service/sms/DefaultSmsServiceTest.java +++ b/application/src/test/java/org/thingsboard/server/service/sms/DefaultSmsServiceTest.java @@ -22,7 +22,7 @@ import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.springframework.test.context.TestPropertySource; import org.testcontainers.shaded.org.apache.commons.lang3.RandomStringUtils; import org.thingsboard.common.util.JacksonUtil; @@ -54,7 +54,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. "usage.stats.report.interval=1", }) public class DefaultSmsServiceTest extends AbstractControllerTest { - @SpyBean + @MockitoSpyBean private DefaultSmsService defaultSmsService; @Autowired private AdminSettingsService adminSettingsService; diff --git a/application/src/test/java/org/thingsboard/server/service/sync/ie/ExportImportServiceSqlTest.java b/application/src/test/java/org/thingsboard/server/service/sync/ie/ExportImportServiceSqlTest.java index e19efdf7e0..dde1c2ae27 100644 --- a/application/src/test/java/org/thingsboard/server/service/sync/ie/ExportImportServiceSqlTest.java +++ b/application/src/test/java/org/thingsboard/server/service/sync/ie/ExportImportServiceSqlTest.java @@ -22,7 +22,7 @@ import org.junit.Before; import org.junit.Test; import org.mockito.Mockito; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.rule.engine.debug.TbMsgGeneratorNode; import org.thingsboard.rule.engine.debug.TbMsgGeneratorNodeConfiguration; @@ -128,9 +128,9 @@ import static org.mockito.Mockito.verify; @DaoSqlTest public class ExportImportServiceSqlTest extends AbstractControllerTest { - @SpyBean + @MockitoSpyBean private EntityActionService entityActionService; - @SpyBean + @MockitoSpyBean private OtaPackageStateService otaPackageStateService; @Autowired diff --git a/application/src/test/java/org/thingsboard/server/service/transport/DefaultTransportApiServiceTest.java b/application/src/test/java/org/thingsboard/server/service/transport/DefaultTransportApiServiceTest.java index afb77945ab..952172a491 100644 --- a/application/src/test/java/org/thingsboard/server/service/transport/DefaultTransportApiServiceTest.java +++ b/application/src/test/java/org/thingsboard/server/service/transport/DefaultTransportApiServiceTest.java @@ -20,8 +20,8 @@ import lombok.extern.slf4j.Slf4j; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringRunner; import org.thingsboard.server.cache.ota.OtaPackageDataCache; @@ -72,35 +72,35 @@ import static org.mockito.Mockito.when; @ContextConfiguration(classes = DefaultTransportApiService.class) public class DefaultTransportApiServiceTest { - @MockBean + @MockitoBean protected TbDeviceProfileCache deviceProfileCache; - @MockBean + @MockitoBean protected TbTenantProfileCache tenantProfileCache; - @MockBean + @MockitoBean protected TbApiUsageStateService apiUsageStateService; - @MockBean + @MockitoBean protected DeviceService deviceService; - @MockBean + @MockitoBean protected DeviceProfileService deviceProfileService; - @MockBean + @MockitoBean protected RelationService relationService; - @MockBean + @MockitoBean protected DeviceCredentialsService deviceCredentialsService; - @MockBean + @MockitoBean protected DbCallbackExecutorService dbCallbackExecutorService; - @MockBean + @MockitoBean protected TbClusterService tbClusterService; - @MockBean + @MockitoBean protected DeviceProvisionService deviceProvisionService; - @MockBean + @MockitoBean protected ResourceService resourceService; - @MockBean + @MockitoBean protected OtaPackageService otaPackageService; - @MockBean + @MockitoBean protected OtaPackageDataCache otaPackageDataCache; - @MockBean + @MockitoBean protected QueueService queueService; - @SpyBean + @MockitoSpyBean DefaultTransportApiService service; private String certificateChain; diff --git a/application/src/test/java/org/thingsboard/server/service/ttl/AlarmsCleanUpServiceTest.java b/application/src/test/java/org/thingsboard/server/service/ttl/AlarmsCleanUpServiceTest.java index fcb948239f..a74db4593c 100644 --- a/application/src/test/java/org/thingsboard/server/service/ttl/AlarmsCleanUpServiceTest.java +++ b/application/src/test/java/org/thingsboard/server/service/ttl/AlarmsCleanUpServiceTest.java @@ -21,7 +21,7 @@ import org.mockito.Mockito; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.springframework.test.context.TestPropertySource; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.alarm.Alarm; @@ -50,9 +50,9 @@ import static org.mockito.Mockito.verify; }) public class AlarmsCleanUpServiceTest extends AbstractControllerTest { - @SpyBean + @MockitoSpyBean private AlarmsCleanUpService alarmsCleanUpService; - @SpyBean + @MockitoSpyBean private AlarmService alarmService; @Autowired private AlarmDao alarmDao; diff --git a/application/src/test/java/org/thingsboard/server/transport/lwm2m/AbstractLwM2MIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/lwm2m/AbstractLwM2MIntegrationTest.java index 8d0f0f2af0..9765a50f91 100644 --- a/application/src/test/java/org/thingsboard/server/transport/lwm2m/AbstractLwM2MIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/lwm2m/AbstractLwM2MIntegrationTest.java @@ -36,7 +36,7 @@ import org.junit.Assert; import org.junit.Before; import org.mockito.Mockito; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.springframework.http.HttpStatus; import org.springframework.test.context.DynamicPropertyRegistry; import org.springframework.test.context.DynamicPropertySource; @@ -132,10 +132,10 @@ import static org.thingsboard.server.transport.lwm2m.ota.AbstractOtaLwM2MIntegra @DaoSqlTest public abstract class AbstractLwM2MIntegrationTest extends AbstractTransportIntegrationTest { - @SpyBean + @MockitoSpyBean protected LwM2mUplinkMsgHandler defaultLwM2mUplinkMsgHandlerTest; - @SpyBean + @MockitoSpyBean protected DefaultLwM2mUplinkMsgHandler defaultUplinkMsgHandlerTest; @Autowired diff --git a/application/src/test/java/org/thingsboard/server/transport/lwm2m/rpc/AbstractRpcLwM2MIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/lwm2m/rpc/AbstractRpcLwM2MIntegrationTest.java index ad02b8f8fc..71c48f6d99 100644 --- a/application/src/test/java/org/thingsboard/server/transport/lwm2m/rpc/AbstractRpcLwM2MIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/lwm2m/rpc/AbstractRpcLwM2MIntegrationTest.java @@ -22,7 +22,7 @@ import org.eclipse.leshan.core.link.LinkParser; import org.eclipse.leshan.core.link.lwm2m.DefaultLwM2mLinkParser; import org.junit.Before; import org.mockito.Mockito; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.DeviceProfile; import org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MDeviceCredentials; @@ -104,7 +104,7 @@ public abstract class AbstractRpcLwM2MIntegrationTest extends AbstractLwM2MInteg protected String idVer_19_0_0; - @SpyBean + @MockitoSpyBean protected LwM2mTransportServerHelper lwM2mTransportServerHelperTest; @Before diff --git a/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/diffPort/AbstractLwM2MIntegrationDiffPortTest.java b/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/diffPort/AbstractLwM2MIntegrationDiffPortTest.java index afb179cc5f..f145d6a62a 100644 --- a/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/diffPort/AbstractLwM2MIntegrationDiffPortTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/diffPort/AbstractLwM2MIntegrationDiffPortTest.java @@ -24,7 +24,7 @@ import org.eclipse.leshan.server.registration.RegistrationStore; import org.eclipse.leshan.server.registration.RegistrationUpdate; import org.junit.Assert; import org.mockito.Mockito; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.DeviceProfile; import org.thingsboard.server.common.data.device.profile.Lwm2mDeviceProfileTransportConfiguration; @@ -49,7 +49,7 @@ import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MClient @Slf4j public abstract class AbstractLwM2MIntegrationDiffPortTest extends AbstractSecurityLwM2MIntegrationTest { - @SpyBean + @MockitoSpyBean private RegistrationStore registrationStoreTest; protected void basicTestConnectionDifferentPort(Lwm2mDeviceProfileTransportConfiguration transportConfiguration, diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/MqttGatewayRateLimitsTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/MqttGatewayRateLimitsTest.java index 541ca40072..d2c2b546f7 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/MqttGatewayRateLimitsTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/MqttGatewayRateLimitsTest.java @@ -22,7 +22,7 @@ import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.mockito.Mockito; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.springframework.test.context.DynamicPropertyRegistry; import org.springframework.test.context.DynamicPropertySource; import org.springframework.test.context.TestPropertySource; @@ -71,7 +71,7 @@ public class MqttGatewayRateLimitsTest extends AbstractControllerTest { private Device gateway; private String gatewayAccessToken; - @SpyBean + @MockitoSpyBean private NotificationRuleProcessor notificationRuleProcessor; @Before diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/telemetry/timeseries/AbstractMqttTimeseriesIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/telemetry/timeseries/AbstractMqttTimeseriesIntegrationTest.java index ea40a574a5..07837d9d8f 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/telemetry/timeseries/AbstractMqttTimeseriesIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/telemetry/timeseries/AbstractMqttTimeseriesIntegrationTest.java @@ -21,7 +21,7 @@ import lombok.extern.slf4j.Slf4j; import org.junit.Before; import org.junit.Test; import org.mockito.ArgumentCaptor; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.id.DeviceId; @@ -67,7 +67,7 @@ public abstract class AbstractMqttTimeseriesIntegrationTest extends AbstractMqtt protected static final String MALFORMED_JSON_PAYLOAD = "{\"key1\":, \"key2\":true, \"key3\": 3.0, \"key4\": 4," + " \"key5\": {\"someNumber\": 42, \"someArray\": [1,2,3], \"someNestedObject\": {\"key\": \"value\"}}}"; - @SpyBean + @MockitoSpyBean GatewayMetricsService gatewayMetricsService; @Before From 139b32f329c334b20d8601788000f997a32e94c6 Mon Sep 17 00:00:00 2001 From: Oleksandra Matviienko Date: Wed, 22 Apr 2026 15:44:10 +0200 Subject: [PATCH 10/91] cleanup(common): add @SafeVarargs, drop raw types and parameterize test collections --- .../server/common/data/util/CollectionsUtil.java | 3 ++- .../org/thingsboard/script/api/tbel/TbUtils.java | 2 +- .../org/thingsboard/script/api/tbel/TbUtilsTest.java | 12 ++++++------ .../org/thingsboard/common/util/ExceptionUtil.java | 1 + 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/util/CollectionsUtil.java b/common/data/src/main/java/org/thingsboard/server/common/data/util/CollectionsUtil.java index d0d8828649..125a370678 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/util/CollectionsUtil.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/util/CollectionsUtil.java @@ -83,6 +83,7 @@ public class CollectionsUtil { return result; } + @SafeVarargs public static boolean isOneOf(V value, V... others) { if (value == null) { return false; @@ -105,7 +106,7 @@ public class CollectionsUtil { Set newSet = new HashSet<>(existing.size() + 1); newSet.addAll(existing); newSet.add(value); - return (Set) Set.of(newSet.toArray()); + return Set.copyOf(newSet); } } diff --git a/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbUtils.java b/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbUtils.java index e206d2d78d..28e0357c3b 100644 --- a/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbUtils.java +++ b/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbUtils.java @@ -1349,7 +1349,7 @@ public class TbUtils { for (byte b : byteArray) { byteList.add(b); } - ExecutionArrayList list = new ExecutionArrayList(byteList, ctx); + ExecutionArrayList list = new ExecutionArrayList<>(byteList, ctx); return list; } diff --git a/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbUtilsTest.java b/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbUtilsTest.java index 622d298bbb..bc40ced5bb 100644 --- a/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbUtilsTest.java +++ b/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbUtilsTest.java @@ -1308,13 +1308,13 @@ public class TbUtilsTest { } @Test public void setTest() throws ExecutionException, InterruptedException { - Set actual = TbUtils.newSet(ctx); - Set expected = toSet(new byte[]{(byte) 0xDD, (byte) 0xCC, (byte) 0xCC}); + Set actual = TbUtils.newSet(ctx); + Set expected = toSet(new byte[]{(byte) 0xDD, (byte) 0xCC, (byte) 0xCC}); actual.add((byte) 0xDD); actual.add((byte) 0xCC); actual.add((byte) 0xCC); assertTrue(expected.containsAll(actual)); - List list = toList(new byte[]{(byte) 0xDD, (byte) 0xCC, (byte) 0xBB, (byte) 0xAA}); + List list = toList(new byte[]{(byte) 0xDD, (byte) 0xCC, (byte) 0xBB, (byte) 0xAA}); actual.addAll(list); assertEquals(4, actual.size()); assertTrue(actual.containsAll(expected)); @@ -1328,9 +1328,9 @@ public class TbUtilsTest { actual.clear(); assertTrue(actual.isEmpty()); actual = TbUtils.toSet(ctx, list); - Set actualClone = TbUtils.toSet(ctx, list); - Set actualClone_asc = TbUtils.toSet(ctx, list); - Set actualClone_desc = TbUtils.toSet(ctx, list); + Set actualClone = TbUtils.toSet(ctx, list); + Set actualClone_asc = TbUtils.toSet(ctx, list); + Set actualClone_desc = TbUtils.toSet(ctx, list); ((ExecutionLinkedHashSet)actualClone).sort(); ((ExecutionLinkedHashSet)actualClone_asc).sort(true); ((ExecutionLinkedHashSet)actualClone_desc).sort(false); diff --git a/common/util/src/main/java/org/thingsboard/common/util/ExceptionUtil.java b/common/util/src/main/java/org/thingsboard/common/util/ExceptionUtil.java index e5eed02675..7dc1ddde60 100644 --- a/common/util/src/main/java/org/thingsboard/common/util/ExceptionUtil.java +++ b/common/util/src/main/java/org/thingsboard/common/util/ExceptionUtil.java @@ -37,6 +37,7 @@ public class ExceptionUtil { } } + @SafeVarargs public static Exception lookupExceptionInCause(Throwable source, Class... clazzes) { while (source != null) { for (Class clazz : clazzes) { From 8d3f7bf416b5d6b652ef20da2c6e5959bd792229 Mon Sep 17 00:00:00 2001 From: Oleksandra Matviienko Date: Wed, 22 Apr 2026 17:03:48 +0200 Subject: [PATCH 11/91] cleanup(dao, transport/lwm2m): parameterize testcontainers and rpc callback types --- .../server/rpc/DefaultLwM2MRpcRequestHandler.java | 12 ++++++------ .../server/dao/AbstractRedisClusterContainer.java | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/rpc/DefaultLwM2MRpcRequestHandler.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/rpc/DefaultLwM2MRpcRequestHandler.java index 6980fb6341..c363cd3da5 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/rpc/DefaultLwM2MRpcRequestHandler.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/rpc/DefaultLwM2MRpcRequestHandler.java @@ -212,7 +212,7 @@ public class DefaultLwM2MRpcRequestHandler implements LwM2MRpcRequestHandler { String[] versionedIds = getIdsFromParameters(client, requestMsg); TbLwM2MReadCompositeRequest request = TbLwM2MReadCompositeRequest.builder().versionedIds(versionedIds).timeout(clientContext.getRequestTimeout(client)).build(); var mainCallback = new TbLwM2MReadCompositeCallback(uplinkHandler, logService, client, versionedIds); - var rpcCallback = new RpcReadResponseCompositeCallback(transportService, client, requestMsg, mainCallback); + var rpcCallback = new RpcReadResponseCompositeCallback<>(transportService, client, requestMsg, mainCallback); downlinkHandler.sendReadCompositeRequest(client, request, rpcCallback); } @@ -323,7 +323,7 @@ public class DefaultLwM2MRpcRequestHandler implements LwM2MRpcRequestHandler { } else if (path.isResource()) { validateResource(client, newNodes, nodes, key , value); } else if (path.isObjectInstance() && value instanceof Map) { - ((Map) value).forEach((k, v) -> { + ((Map) value).forEach((k, v) -> { validateResource(client, newNodes, nodes, validateResourceId (key, k.toString(), nodes), v); }); } else { @@ -337,7 +337,7 @@ public class DefaultLwM2MRpcRequestHandler implements LwM2MRpcRequestHandler { return newNodes; } - private void validateResource(LwM2mClient client, Map newNodes, Map nodes, String resourceId , Object value) { + private void validateResource(LwM2mClient client, Map newNodes, Map nodes, String resourceId , Object value) { if (value instanceof Map) { ((Map) value).forEach((k, v) -> { setValueToCompositeNodes(client, newNodes, nodes, validateResourceId (resourceId, k.toString(), nodes), v); @@ -347,7 +347,7 @@ public class DefaultLwM2MRpcRequestHandler implements LwM2MRpcRequestHandler { } } - private String validateResourceId (String key, String id, Map nodes) { + private String validateResourceId (String key, String id, Map nodes) { try { Integer.parseInt(id); return key + "/" + id; @@ -357,7 +357,7 @@ public class DefaultLwM2MRpcRequestHandler implements LwM2MRpcRequestHandler { } } - private void setValueToCompositeNodes (LwM2mClient client, Map newNodes, Map nodes, String versionedId , Object value) { + private void setValueToCompositeNodes (LwM2mClient client, Map newNodes, Map nodes, String versionedId , Object value) { // validate value. Must be only primitive, not JsonObject or JsonArray try { JsonElement element = JsonUtils.parse(value); @@ -388,7 +388,7 @@ public class DefaultLwM2MRpcRequestHandler implements LwM2MRpcRequestHandler { String[] versionedIds = getIdsFromParameters(client, requestMsg); TbLwM2MObserveCompositeRequest request = TbLwM2MObserveCompositeRequest.builder().versionedIds(versionedIds).timeout(clientContext.getRequestTimeout(client)).build(); var mainCallback = new TbLwM2MObserveCompositeCallback(uplinkHandler, logService, client, versionedIds); - var rpcCallback = new RpcObserveResponseCompositeCallback(transportService, client, requestMsg, mainCallback); + var rpcCallback = new RpcObserveResponseCompositeCallback<>(transportService, client, requestMsg, mainCallback); downlinkHandler.sendObserveCompositeRequest(client, request, rpcCallback); } diff --git a/dao/src/test/java/org/thingsboard/server/dao/AbstractRedisClusterContainer.java b/dao/src/test/java/org/thingsboard/server/dao/AbstractRedisClusterContainer.java index 827e50a5cc..1f057c802b 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/AbstractRedisClusterContainer.java +++ b/dao/src/test/java/org/thingsboard/server/dao/AbstractRedisClusterContainer.java @@ -40,17 +40,17 @@ public class AbstractRedisClusterContainer { ); @ClassRule(order = 1) - public static GenericContainer redis1 = new GenericContainer(IMAGE).withEnv(ENVS).withEnv("VALKEY_PORT_NUMBER", "6371").withNetworkMode("host").withLogConsumer(AbstractRedisClusterContainer::consumeLog); + public static GenericContainer redis1 = new GenericContainer<>(IMAGE).withEnv(ENVS).withEnv("VALKEY_PORT_NUMBER", "6371").withNetworkMode("host").withLogConsumer(AbstractRedisClusterContainer::consumeLog); @ClassRule(order = 2) - public static GenericContainer redis2 = new GenericContainer(IMAGE).withEnv(ENVS).withEnv("VALKEY_PORT_NUMBER", "6372").withNetworkMode("host").withLogConsumer(AbstractRedisClusterContainer::consumeLog); + public static GenericContainer redis2 = new GenericContainer<>(IMAGE).withEnv(ENVS).withEnv("VALKEY_PORT_NUMBER", "6372").withNetworkMode("host").withLogConsumer(AbstractRedisClusterContainer::consumeLog); @ClassRule(order = 3) - public static GenericContainer redis3 = new GenericContainer(IMAGE).withEnv(ENVS).withEnv("VALKEY_PORT_NUMBER", "6373").withNetworkMode("host").withLogConsumer(AbstractRedisClusterContainer::consumeLog); + public static GenericContainer redis3 = new GenericContainer<>(IMAGE).withEnv(ENVS).withEnv("VALKEY_PORT_NUMBER", "6373").withNetworkMode("host").withLogConsumer(AbstractRedisClusterContainer::consumeLog); @ClassRule(order = 4) - public static GenericContainer redis4 = new GenericContainer(IMAGE).withEnv(ENVS).withEnv("VALKEY_PORT_NUMBER", "6374").withNetworkMode("host").withLogConsumer(AbstractRedisClusterContainer::consumeLog); + public static GenericContainer redis4 = new GenericContainer<>(IMAGE).withEnv(ENVS).withEnv("VALKEY_PORT_NUMBER", "6374").withNetworkMode("host").withLogConsumer(AbstractRedisClusterContainer::consumeLog); @ClassRule(order = 5) - public static GenericContainer redis5 = new GenericContainer(IMAGE).withEnv(ENVS).withEnv("VALKEY_PORT_NUMBER", "6375").withNetworkMode("host").withLogConsumer(AbstractRedisClusterContainer::consumeLog); + public static GenericContainer redis5 = new GenericContainer<>(IMAGE).withEnv(ENVS).withEnv("VALKEY_PORT_NUMBER", "6375").withNetworkMode("host").withLogConsumer(AbstractRedisClusterContainer::consumeLog); @ClassRule(order = 6) - public static GenericContainer redis6 = new GenericContainer(IMAGE).withEnv(ENVS).withEnv("VALKEY_PORT_NUMBER", "6376").withNetworkMode("host").withLogConsumer(AbstractRedisClusterContainer::consumeLog); + public static GenericContainer redis6 = new GenericContainer<>(IMAGE).withEnv(ENVS).withEnv("VALKEY_PORT_NUMBER", "6376").withNetworkMode("host").withLogConsumer(AbstractRedisClusterContainer::consumeLog); @ClassRule(order = 100) From 6696879a54ec6f1dbc57aa1f7e7b4d6434eb2c13 Mon Sep 17 00:00:00 2001 From: Oleksandra Matviienko Date: Wed, 22 Apr 2026 22:07:16 +0200 Subject: [PATCH 12/91] cleanup(application): parameterize Set and Predicate fields in lwm2m rpc integration test base --- .../lwm2m/rpc/AbstractRpcLwM2MIntegrationTest.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/application/src/test/java/org/thingsboard/server/transport/lwm2m/rpc/AbstractRpcLwM2MIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/lwm2m/rpc/AbstractRpcLwM2MIntegrationTest.java index ad02b8f8fc..1e3b6fcbe7 100644 --- a/application/src/test/java/org/thingsboard/server/transport/lwm2m/rpc/AbstractRpcLwM2MIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/lwm2m/rpc/AbstractRpcLwM2MIntegrationTest.java @@ -78,16 +78,16 @@ public abstract class AbstractRpcLwM2MIntegrationTest extends AbstractLwM2MInteg protected final LinkParser linkParser = new DefaultLwM2mLinkParser(); protected String CONFIG_PROFILE_WITH_PARAMS_RPC; - public Set expectedObjects; - public Set expectedObjectIdVers; - public Set expectedInstances; - public Set expectedObjectIdVerInstances; + public Set expectedObjects; + public Set expectedObjectIdVers; + public Set expectedInstances; + public Set expectedObjectIdVerInstances; protected String objectInstanceIdVer_1; protected String objectIdVer_0; protected String objectIdVer_1; protected String objectIdVer_2; - private static final Predicate PREDICATE_3 = path -> (!((String) path).startsWith("/" + TEMPERATURE_SENSOR) && ((String) path).startsWith("/" + DEVICE)); + private static final Predicate PREDICATE_3 = path -> (!((String) path).startsWith("/" + TEMPERATURE_SENSOR) && ((String) path).startsWith("/" + DEVICE)); protected String objectIdVer_3; protected String objectInstanceIdVer_3; protected String objectInstanceIdVer_5; From de1f1a2d9dbdafc743f68b0252a632490d89a23f Mon Sep 17 00:00:00 2001 From: Oleksandra Matviienko Date: Wed, 22 Apr 2026 22:56:52 +0200 Subject: [PATCH 13/91] cleanup(tests, transport/lwm2m): use ArgumentCaptor.captor() and parameterize path list --- .../downlink/DefaultLwM2mDownlinkMsgHandler.java | 2 +- .../service/TransportActivityManagerTest.java | 4 ++-- .../rule/engine/flow/TbCheckpointNodeTest.java | 2 +- .../rule/engine/kafka/TbKafkaNodeTest.java | 2 +- .../rule/engine/metadata/TbGetTelemetryNodeTest.java | 12 ++++++------ .../telemetry/TbMsgDeleteAttributesNodeTest.java | 2 +- .../engine/transform/TbMsgDeduplicationNodeTest.java | 10 +++++----- .../engine/transform/TbSplitArrayMsgNodeTest.java | 2 +- 8 files changed, 18 insertions(+), 18 deletions(-) diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/DefaultLwM2mDownlinkMsgHandler.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/DefaultLwM2mDownlinkMsgHandler.java index 8f638cfa2a..6d6eea28ab 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/DefaultLwM2mDownlinkMsgHandler.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/DefaultLwM2mDownlinkMsgHandler.java @@ -815,7 +815,7 @@ public class DefaultLwM2mDownlinkMsgHandler extends LwM2MExecutorAwareService im LwM2mPath pathSingleOb = singleObs.getPath(); LwM2mPath pathObjectId = new LwM2mPath(objectId); if (!pathSingleOb.toString().equals(objectId)) { - List paths = Arrays.asList(pathSingleOb, pathObjectId); + List paths = Arrays.asList(pathSingleOb, pathObjectId); try { LwM2mPath.validateNotOverlapping(paths); } catch (IllegalArgumentException e){ diff --git a/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/service/TransportActivityManagerTest.java b/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/service/TransportActivityManagerTest.java index 3b3ce6e600..35ddba5d90 100644 --- a/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/service/TransportActivityManagerTest.java +++ b/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/service/TransportActivityManagerTest.java @@ -122,7 +122,7 @@ public class TransportActivityManagerTest { // THEN ArgumentCaptor sessionInfoCaptor = ArgumentCaptor.forClass(TransportProtos.SessionInfoProto.class); ArgumentCaptor subscriptionInfoCaptor = ArgumentCaptor.forClass(TransportProtos.SubscriptionInfoProto.class); - ArgumentCaptor> callbackCaptor = ArgumentCaptor.forClass(TransportServiceCallback.class); + ArgumentCaptor> callbackCaptor = ArgumentCaptor.captor(); verify(transportServiceMock).process(sessionInfoCaptor.capture(), subscriptionInfoCaptor.capture(), callbackCaptor.capture()); @@ -166,7 +166,7 @@ public class TransportActivityManagerTest { // THEN ArgumentCaptor sessionInfoCaptor = ArgumentCaptor.forClass(TransportProtos.SessionInfoProto.class); ArgumentCaptor subscriptionInfoCaptor = ArgumentCaptor.forClass(TransportProtos.SubscriptionInfoProto.class); - ArgumentCaptor> callbackCaptor = ArgumentCaptor.forClass(TransportServiceCallback.class); + ArgumentCaptor> callbackCaptor = ArgumentCaptor.captor(); verify(transportServiceMock).process(sessionInfoCaptor.capture(), subscriptionInfoCaptor.capture(), callbackCaptor.capture()); diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/flow/TbCheckpointNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/flow/TbCheckpointNodeTest.java index ab0f358684..7c47477fee 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/flow/TbCheckpointNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/flow/TbCheckpointNodeTest.java @@ -114,7 +114,7 @@ public class TbCheckpointNodeTest extends AbstractRuleNodeUpgradeTest { .build(); node.onMsg(ctxMock, msg); - ArgumentCaptor> onFailure = ArgumentCaptor.forClass(Consumer.class); + ArgumentCaptor> onFailure = ArgumentCaptor.captor(); then(ctxMock).should().enqueueForTellNext(eq(msg), eq(DataConstants.HP_QUEUE_NAME), eq(TbNodeConnectionType.SUCCESS), any(), onFailure.capture()); String errorMsg = "Something went wrong."; onFailure.getValue().accept(new RuntimeException(errorMsg)); diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/kafka/TbKafkaNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/kafka/TbKafkaNodeTest.java index 5df7e1be7b..392821b767 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/kafka/TbKafkaNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/kafka/TbKafkaNodeTest.java @@ -420,7 +420,7 @@ public class TbKafkaNodeTest extends AbstractRuleNodeUpgradeTest { } private void verifyProducerRecord(String expectedTopic, String expectedKey, String expectedValue, Headers expectedHeaders) { - ArgumentCaptor> actualRecordCaptor = ArgumentCaptor.forClass(ProducerRecord.class); + ArgumentCaptor> actualRecordCaptor = ArgumentCaptor.captor(); then(producerMock).should().send(actualRecordCaptor.capture(), any()); ProducerRecord actualRecord = actualRecordCaptor.getValue(); assertThat(actualRecord.topic()).isEqualTo(expectedTopic); diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetTelemetryNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetTelemetryNodeTest.java index ce3a1b5b22..5de65535e7 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetTelemetryNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetTelemetryNodeTest.java @@ -219,7 +219,7 @@ public class TbGetTelemetryNodeTest extends AbstractRuleNodeUpgradeTest { node.onMsg(ctxMock, msg); // THEN - ArgumentCaptor> actualReadTsKvQueryList = ArgumentCaptor.forClass(List.class); + ArgumentCaptor> actualReadTsKvQueryList = ArgumentCaptor.captor(); then(timeseriesServiceMock).should().findAll(eq(TENANT_ID), eq(DEVICE_ID), actualReadTsKvQueryList.capture()); ReadTsKvQuery actualReadTsKvQuery = actualReadTsKvQueryList.getValue().get(0); assertThat(actualReadTsKvQuery.getStartTs()).isEqualTo(startTs); @@ -246,7 +246,7 @@ public class TbGetTelemetryNodeTest extends AbstractRuleNodeUpgradeTest { node.onMsg(ctxMock, msg); // THEN - ArgumentCaptor> actualReadTsKvQueryList = ArgumentCaptor.forClass(List.class); + ArgumentCaptor> actualReadTsKvQueryList = ArgumentCaptor.captor(); then(timeseriesServiceMock).should().findAll(eq(TENANT_ID), eq(DEVICE_ID), actualReadTsKvQueryList.capture()); ReadTsKvQuery actualReadTsKvQuery = actualReadTsKvQueryList.getValue().get(0); assertThat(actualReadTsKvQuery.getStartTs()).isEqualTo(ts - TimeUnit.MINUTES.toMillis(config.getStartInterval())); @@ -275,7 +275,7 @@ public class TbGetTelemetryNodeTest extends AbstractRuleNodeUpgradeTest { node.onMsg(ctxMock, msg); // THEN - ArgumentCaptor> actualReadTsKvQueryList = ArgumentCaptor.forClass(List.class); + ArgumentCaptor> actualReadTsKvQueryList = ArgumentCaptor.captor(); then(timeseriesServiceMock).should().findAll(eq(TENANT_ID), eq(DEVICE_ID), actualReadTsKvQueryList.capture()); List actualKeys = actualReadTsKvQueryList.getValue().stream().map(TsKvQuery::getKey).toList(); assertThat(actualKeys).containsExactlyInAnyOrder("temperature", "humidity", "pressure"); @@ -305,7 +305,7 @@ public class TbGetTelemetryNodeTest extends AbstractRuleNodeUpgradeTest { node.onMsg(ctxMock, msg); // THEN - ArgumentCaptor> actualReadTsKvQueryList = ArgumentCaptor.forClass(List.class); + ArgumentCaptor> actualReadTsKvQueryList = ArgumentCaptor.captor(); then(timeseriesServiceMock).should().findAll(eq(TENANT_ID), eq(DEVICE_ID), actualReadTsKvQueryList.capture()); ReadTsKvQuery actualReadTsKvQuery = actualReadTsKvQueryList.getValue().get(0); aggregationStepVerifier.accept(actualReadTsKvQuery); @@ -340,7 +340,7 @@ public class TbGetTelemetryNodeTest extends AbstractRuleNodeUpgradeTest { node.onMsg(ctxMock, msg); // THEN - ArgumentCaptor> actualReadTsKvQueryList = ArgumentCaptor.forClass(List.class); + ArgumentCaptor> actualReadTsKvQueryList = ArgumentCaptor.captor(); then(timeseriesServiceMock).should().findAll(eq(TENANT_ID), eq(DEVICE_ID), actualReadTsKvQueryList.capture()); ReadTsKvQuery actualReadTsKvQuery = actualReadTsKvQueryList.getValue().get(0); limitInQueryVerifier.accept(actualReadTsKvQuery); @@ -385,7 +385,7 @@ public class TbGetTelemetryNodeTest extends AbstractRuleNodeUpgradeTest { node.onMsg(ctxMock, msg); // THEN - ArgumentCaptor> actualReadTsKvQueryList = ArgumentCaptor.forClass(List.class); + ArgumentCaptor> actualReadTsKvQueryList = ArgumentCaptor.captor(); then(timeseriesServiceMock).should().findAll(eq(TENANT_ID), eq(DEVICE_ID), actualReadTsKvQueryList.capture()); ReadTsKvQuery actualReadTsKvQuery = actualReadTsKvQueryList.getValue().get(0); orderInQueryVerifier.accept(actualReadTsKvQuery); diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/telemetry/TbMsgDeleteAttributesNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/telemetry/TbMsgDeleteAttributesNodeTest.java index b03794c39d..105962fd1e 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/telemetry/TbMsgDeleteAttributesNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/telemetry/TbMsgDeleteAttributesNodeTest.java @@ -147,7 +147,7 @@ public class TbMsgDeleteAttributesNodeTest { node.onMsg(ctx, msg); ArgumentCaptor successCaptor = ArgumentCaptor.forClass(Runnable.class); - ArgumentCaptor> failureCaptor = ArgumentCaptor.forClass(Consumer.class); + ArgumentCaptor> failureCaptor = ArgumentCaptor.captor(); ArgumentCaptor newMsgCaptor = ArgumentCaptor.forClass(TbMsg.class); if (sendAttributesDeletedNotification) { diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/transform/TbMsgDeduplicationNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/transform/TbMsgDeduplicationNodeTest.java index ec71819878..8fd2868f61 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/transform/TbMsgDeduplicationNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/transform/TbMsgDeduplicationNodeTest.java @@ -192,7 +192,7 @@ public class TbMsgDeduplicationNodeTest extends AbstractRuleNodeUpgradeTest { ArgumentCaptor newMsgCaptor = ArgumentCaptor.forClass(TbMsg.class); ArgumentCaptor successCaptor = ArgumentCaptor.forClass(Runnable.class); - ArgumentCaptor> failureCaptor = ArgumentCaptor.forClass(Consumer.class); + ArgumentCaptor> failureCaptor = ArgumentCaptor.captor(); verify(ctx, times(msgCount)).ack(any()); verify(ctx, times(1)).tellFailure(eq(msgToReject), any()); @@ -248,7 +248,7 @@ public class TbMsgDeduplicationNodeTest extends AbstractRuleNodeUpgradeTest { ArgumentCaptor newMsgCaptor = ArgumentCaptor.forClass(TbMsg.class); ArgumentCaptor successCaptor = ArgumentCaptor.forClass(Runnable.class); - ArgumentCaptor> failureCaptor = ArgumentCaptor.forClass(Consumer.class); + ArgumentCaptor> failureCaptor = ArgumentCaptor.captor(); verify(ctx, times(msgCount)).ack(any()); verify(ctx, times(1)).tellFailure(eq(msgToReject), any()); @@ -293,7 +293,7 @@ public class TbMsgDeduplicationNodeTest extends AbstractRuleNodeUpgradeTest { ArgumentCaptor newMsgCaptor = ArgumentCaptor.forClass(TbMsg.class); ArgumentCaptor successCaptor = ArgumentCaptor.forClass(Runnable.class); - ArgumentCaptor> failureCaptor = ArgumentCaptor.forClass(Consumer.class); + ArgumentCaptor> failureCaptor = ArgumentCaptor.captor(); verify(ctx, times(msgCount)).ack(any()); verify(node, times(msgCount + wantedNumberOfTellSelfInvocation)).onMsg(eq(ctx), any()); @@ -339,7 +339,7 @@ public class TbMsgDeduplicationNodeTest extends AbstractRuleNodeUpgradeTest { ArgumentCaptor newMsgCaptor = ArgumentCaptor.forClass(TbMsg.class); ArgumentCaptor successCaptor = ArgumentCaptor.forClass(Runnable.class); - ArgumentCaptor> failureCaptor = ArgumentCaptor.forClass(Consumer.class); + ArgumentCaptor> failureCaptor = ArgumentCaptor.captor(); verify(ctx, times(msgCount)).ack(any()); verify(node, times(msgCount + wantedNumberOfTellSelfInvocation)).onMsg(eq(ctx), any()); @@ -393,7 +393,7 @@ public class TbMsgDeduplicationNodeTest extends AbstractRuleNodeUpgradeTest { ArgumentCaptor newMsgCaptor = ArgumentCaptor.forClass(TbMsg.class); ArgumentCaptor successCaptor = ArgumentCaptor.forClass(Runnable.class); - ArgumentCaptor> failureCaptor = ArgumentCaptor.forClass(Consumer.class); + ArgumentCaptor> failureCaptor = ArgumentCaptor.captor(); verify(ctx, times(msgCount)).ack(any()); verify(node, times(msgCount + wantedNumberOfTellSelfInvocation)).onMsg(eq(ctx), any()); diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/transform/TbSplitArrayMsgNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/transform/TbSplitArrayMsgNodeTest.java index 5cd88c8ea9..b178def66e 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/transform/TbSplitArrayMsgNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/transform/TbSplitArrayMsgNodeTest.java @@ -114,7 +114,7 @@ public class TbSplitArrayMsgNodeTest { if (dataNode.size() > 1) { ArgumentCaptor successCaptor = ArgumentCaptor.forClass(Runnable.class); - ArgumentCaptor> failureCaptor = ArgumentCaptor.forClass(Consumer.class); + ArgumentCaptor> failureCaptor = ArgumentCaptor.captor(); verify(ctx, times(dataNode.size())).enqueueForTellNext(any(), anyString(), successCaptor.capture(), failureCaptor.capture()); for (Runnable valueCaptor : successCaptor.getAllValues()) { valueCaptor.run(); From df4dc250829e13b0442bc7b2ffd58a23e3573f47 Mon Sep 17 00:00:00 2001 From: Oleksii Kuripko Date: Thu, 23 Apr 2026 10:20:20 +0200 Subject: [PATCH 14/91] emit recovery signal for MonitoringServiceKey.GENERAL and route EDQS I/O errors correctly Two related fixes for a stuck-open 'Monitoring' entry in the incident header: 1. serviceIsOk(GENERAL) is now called when a monitoring cycle completes successfully. Previously GENERAL could only accumulate failures (via the outer Throwable catch), with no complementary recovery, so once the catch-all fired the service stayed red forever. 2. checkEdqs() is now wrapped in its own try/catch that reports any non-ServiceFailureException failures under EDQS rather than GENERAL. Connection/read timeouts hitting /api/entitiesQuery/find previously propagated unwrapped and were bucketed as GENERAL, which hid the fact that EDQS was the failing component. --- .../service/BaseMonitoringService.java | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/monitoring/src/main/java/org/thingsboard/monitoring/service/BaseMonitoringService.java b/monitoring/src/main/java/org/thingsboard/monitoring/service/BaseMonitoringService.java index 3f1c624200..9c8c8fc533 100644 --- a/monitoring/src/main/java/org/thingsboard/monitoring/service/BaseMonitoringService.java +++ b/monitoring/src/main/java/org/thingsboard/monitoring/service/BaseMonitoringService.java @@ -155,13 +155,22 @@ public abstract class BaseMonitoringService, T ext } if (checkEdqs) { - stopWatch.start(); - checkEdqs(); - reporter.reportLatency(Latencies.EDQS_QUERY, stopWatch.getTime()); - reporter.serviceIsOk(MonitoredServiceKey.EDQS); + try { + stopWatch.start(); + checkEdqs(); + reporter.reportLatency(Latencies.EDQS_QUERY, stopWatch.getTime()); + reporter.serviceIsOk(MonitoredServiceKey.EDQS); + } catch (ServiceFailureException e) { + reporter.serviceFailure(e.getServiceKey(), e); + return; + } catch (Exception e) { + reporter.serviceFailure(MonitoredServiceKey.EDQS, e); + return; + } } reporter.reportLatencies(); + reporter.serviceIsOk(MonitoredServiceKey.GENERAL); log.debug("Finished {}", getName()); } catch (ServiceFailureException e) { reporter.serviceFailure(e.getServiceKey(), e); From e31d04956ce27c61a0bbe1428b930777eba62c1f Mon Sep 17 00:00:00 2001 From: Oleksandra Matviienko Date: Thu, 23 Apr 2026 10:20:35 +0200 Subject: [PATCH 15/91] Fixed tests by adding context configuration, swapping @MockitoSpyBean for @MockitoBean and adding missing dependencies. Signed-off-by: Oleksandra Matviienko --- .../provision/DeviceProvisionServiceTest.java | 17 ++++++++++++- .../queue/DefaultTbClusterServiceTest.java | 19 ++++++++++++++- .../DefaultTransportApiServiceTest.java | 24 ++++++++++++++++++- 3 files changed, 57 insertions(+), 3 deletions(-) diff --git a/application/src/test/java/org/thingsboard/server/service/device/provision/DeviceProvisionServiceTest.java b/application/src/test/java/org/thingsboard/server/service/device/provision/DeviceProvisionServiceTest.java index c5f10ea4b3..4f2eaa5147 100644 --- a/application/src/test/java/org/thingsboard/server/service/device/provision/DeviceProvisionServiceTest.java +++ b/application/src/test/java/org/thingsboard/server/service/device/provision/DeviceProvisionServiceTest.java @@ -73,9 +73,24 @@ import static org.mockito.Mockito.when; @Slf4j @RunWith(SpringRunner.class) -@ContextConfiguration(classes = DeviceProvisionServiceImpl.class) +@ContextConfiguration(classes = DeviceProvisionServiceTest.ContextConfiguration.class) public class DeviceProvisionServiceTest { + @org.springframework.context.annotation.Configuration + static class ContextConfiguration { + @org.springframework.context.annotation.Bean + public DeviceProvisionServiceImpl deviceProvisionService(TbQueueProducerProvider producerProvider, + DeviceProfileService deviceProfileService, + DeviceService deviceService, + DeviceCredentialsService deviceCredentialsService, + AttributesService attributesService, + AuditLogService auditLogService, + PartitionService partitionService) { + return new DeviceProvisionServiceImpl(producerProvider, deviceProfileService, deviceService, + deviceCredentialsService, attributesService, auditLogService, partitionService); + } + } + @MockitoBean protected TbQueueProducerProvider producerProvider; @MockitoBean diff --git a/application/src/test/java/org/thingsboard/server/service/queue/DefaultTbClusterServiceTest.java b/application/src/test/java/org/thingsboard/server/service/queue/DefaultTbClusterServiceTest.java index 63b4c98142..79b31acf78 100644 --- a/application/src/test/java/org/thingsboard/server/service/queue/DefaultTbClusterServiceTest.java +++ b/application/src/test/java/org/thingsboard/server/service/queue/DefaultTbClusterServiceTest.java @@ -56,6 +56,7 @@ import org.thingsboard.server.queue.discovery.PartitionService; import org.thingsboard.server.queue.discovery.TopicService; import org.thingsboard.server.queue.provider.TbQueueProducerProvider; import org.thingsboard.server.service.gateway_device.GatewayNotificationsService; +import org.thingsboard.server.service.ota.OtaPackageStateService; import org.thingsboard.server.service.profile.TbAssetProfileCache; import org.thingsboard.server.service.profile.TbDeviceProfileCache; @@ -67,6 +68,7 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.isNull; import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.lenient; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; @@ -106,11 +108,26 @@ public class DefaultTbClusterServiceTest { @MockitoBean protected CalculatedFieldService calculatedFieldService; - @MockitoSpyBean + @MockitoBean protected TopicService topicService; + @MockitoBean + protected OtaPackageStateService otaPackageStateService; @MockitoSpyBean protected TbClusterService clusterService; + @org.junit.Before + public void setUp() { + lenient().when(topicService.getNotificationsTopic(any(), any())).thenAnswer(invocation -> { + ServiceType serviceType = invocation.getArgument(0); + String serviceId = invocation.getArgument(1); + return new TopicPartitionInfo(serviceType.name().toLowerCase() + ".notifications." + serviceId, null, null, false); + }); + lenient().when(topicService.getCalculatedFieldNotificationsTopic(any())).thenAnswer(invocation -> { + String serviceId = invocation.getArgument(0); + return new TopicPartitionInfo("calculated_field.notifications." + serviceId, null, null, false); + }); + } + @Test public void testOnQueueChangeSingleMonolith() { when(partitionService.getAllServiceIds(ServiceType.TB_RULE_ENGINE)).thenReturn(Sets.newHashSet(MONOLITH)); diff --git a/application/src/test/java/org/thingsboard/server/service/transport/DefaultTransportApiServiceTest.java b/application/src/test/java/org/thingsboard/server/service/transport/DefaultTransportApiServiceTest.java index 952172a491..6b667cc811 100644 --- a/application/src/test/java/org/thingsboard/server/service/transport/DefaultTransportApiServiceTest.java +++ b/application/src/test/java/org/thingsboard/server/service/transport/DefaultTransportApiServiceTest.java @@ -69,9 +69,31 @@ import static org.mockito.Mockito.when; @Slf4j @RunWith(SpringRunner.class) -@ContextConfiguration(classes = DefaultTransportApiService.class) +@ContextConfiguration(classes = DefaultTransportApiServiceTest.ContextConfiguration.class) public class DefaultTransportApiServiceTest { + @org.springframework.context.annotation.Configuration + static class ContextConfiguration { + @org.springframework.context.annotation.Bean + public DefaultTransportApiService defaultTransportApiService(TbDeviceProfileCache deviceProfileCache, + TbTenantProfileCache tenantProfileCache, + TbApiUsageStateService apiUsageStateService, + DeviceService deviceService, + DeviceProfileService deviceProfileService, + RelationService relationService, + DeviceCredentialsService deviceCredentialsService, + TbClusterService tbClusterService, + DeviceProvisionService deviceProvisionService, + ResourceService resourceService, + OtaPackageService otaPackageService, + OtaPackageDataCache otaPackageDataCache, + QueueService queueService) { + return new DefaultTransportApiService(deviceProfileCache, tenantProfileCache, apiUsageStateService, + deviceService, deviceProfileService, relationService, deviceCredentialsService, tbClusterService, + deviceProvisionService, resourceService, otaPackageService, otaPackageDataCache, queueService); + } + } + @MockitoBean protected TbDeviceProfileCache deviceProfileCache; @MockitoBean From e7751a0bf516246361cbe0e6896f974d6254caa5 Mon Sep 17 00:00:00 2001 From: Oleksandra Matviienko Date: Thu, 23 Apr 2026 15:11:11 +0200 Subject: [PATCH 16/91] Replaced deprecated X509Certificate.getSubjectDN()/getIssuerDN() with getSubjectX500Principal()/getIssuerX500Principal() in CertPemCredentials Uses X500Principal.getName(X500Principal.RFC1779) to keep DN output byte-identical to the old sun.security.x509.X500Name format; expected test strings unchanged. Removes 7 getSubjectDN() and 1 getIssuerDN() deprecation warnings in rule-engine-components. --- .../rule/engine/credentials/CertPemCredentials.java | 5 +++-- .../engine/credentials/CertPemCredentialsTest.java | 13 +++++++------ 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/credentials/CertPemCredentials.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/credentials/CertPemCredentials.java index 81def5a96b..46d844d2c4 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/credentials/CertPemCredentials.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/credentials/CertPemCredentials.java @@ -25,6 +25,7 @@ import org.thingsboard.server.common.data.StringUtils; import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.TrustManagerFactory; +import javax.security.auth.x500.X500Principal; import java.security.KeyStore; import java.security.PrivateKey; import java.security.cert.CertPath; @@ -77,7 +78,7 @@ public class CertPemCredentials implements ClientCredentials { KeyStore caKeyStore = KeyStore.getInstance(KeyStore.getDefaultType()); caKeyStore.load(null, null); for (X509Certificate caCert : caCerts) { - caKeyStore.setCertificateEntry(CA_CERT_CERT_ALIAS_PREFIX + caCert.getSubjectDN().getName(), caCert); + caKeyStore.setCertificateEntry(CA_CERT_CERT_ALIAS_PREFIX + caCert.getSubjectX500Principal().getName(X500Principal.RFC1779), caCert); } TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); @@ -99,7 +100,7 @@ public class CertPemCredentials implements ClientCredentials { keyStore.load(null); List unique = certificates.stream().distinct().collect(Collectors.toList()); for (X509Certificate cert : unique) { - keyStore.setCertificateEntry(CERT_ALIAS_PREFIX + cert.getSubjectDN().getName(), cert); + keyStore.setCertificateEntry(CERT_ALIAS_PREFIX + cert.getSubjectX500Principal().getName(X500Principal.RFC1779), cert); } if (privateKey != null) { diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/credentials/CertPemCredentialsTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/credentials/CertPemCredentialsTest.java index cd0d508fec..634b5d8754 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/credentials/CertPemCredentialsTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/credentials/CertPemCredentialsTest.java @@ -23,6 +23,7 @@ import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; import org.thingsboard.common.util.SslUtil; +import javax.security.auth.x500.X500Principal; import java.io.File; import java.io.IOException; import java.security.Key; @@ -49,13 +50,13 @@ public class CertPemCredentialsTest { Assertions.assertEquals(4, x509Certificates.size()); Assertions.assertEquals("CN=*.thingsboard.cloud, O=\"ThingsBoard, Inc.\", ST=New York, C=US", - x509Certificates.get(0).getSubjectDN().getName()); + x509Certificates.get(0).getSubjectX500Principal().getName(X500Principal.RFC1779)); Assertions.assertEquals("CN=Sectigo ECC Organization Validation Secure Server CA, O=Sectigo Limited, L=Salford, ST=Greater Manchester, C=GB", - x509Certificates.get(1).getSubjectDN().getName()); + x509Certificates.get(1).getSubjectX500Principal().getName(X500Principal.RFC1779)); Assertions.assertEquals("CN=USERTrust ECC Certification Authority, O=The USERTRUST Network, L=Jersey City, ST=New Jersey, C=US", - x509Certificates.get(2).getSubjectDN().getName()); + x509Certificates.get(2).getSubjectX500Principal().getName(X500Principal.RFC1779)); Assertions.assertEquals("CN=AAA Certificate Services, O=Comodo CA Limited, L=Salford, ST=Greater Manchester, C=GB", - x509Certificates.get(3).getSubjectDN().getName()); + x509Certificates.get(3).getSubjectX500Principal().getName(X500Principal.RFC1779)); } @Test @@ -66,7 +67,7 @@ public class CertPemCredentialsTest { Assertions.assertEquals(1, x509Certificates.size()); Assertions.assertEquals("CN=*.thingsboard.cloud, O=\"ThingsBoard, Inc.\", ST=New York, C=US", - x509Certificates.get(0).getSubjectDN().getName()); + x509Certificates.get(0).getSubjectX500Principal().getName(X500Principal.RFC1779)); } @Test @@ -103,7 +104,7 @@ public class CertPemCredentialsTest { List certs = SslUtil.readCertFile(certContent); for (X509Certificate cert : certs) { - String alias = CERT_ALIAS_PREFIX + cert.getIssuerDN().getName(); + String alias = CERT_ALIAS_PREFIX + cert.getIssuerX500Principal().getName(X500Principal.RFC1779); Certificate certificate = keyStore.getCertificate(alias); Assertions.assertNotNull(certificate); Assertions.assertEquals(new String(cert.getEncoded()), new String(certificate.getEncoded())); From 15cca51c42f83691a1c68995dab6906f3d88f336 Mon Sep 17 00:00:00 2001 From: Oleksandra Matviienko Date: Fri, 24 Apr 2026 08:54:24 +0200 Subject: [PATCH 17/91] chore(build): silence Lombok @Builder ignore-initializer warnings Added @Builder.Default to 5 fields with initializers in MobileLayoutConfig (pages) and DefaultTenantProfileConfiguration (maxCalculatedFieldsPerEntity, maxArgumentsPerCF, maxStateSizeInKBytes, maxSingleValueArgumentSizeInKBytes). Dropped the redundant `= 0` on Task.attempt (int default is already 0) to clear the same anomaly on @SuperBuilder. Eliminates 6 "@Builder/@SuperBuilder will ignore the initializing expression" warnings from #15481 Tier 2. `[WARNING]` total drops 843 -> 837, `[ERROR]` unchanged at 0. --- .../org/thingsboard/server/common/data/job/task/Task.java | 2 +- .../server/common/data/mobile/layout/MobileLayoutConfig.java | 1 + .../tenant/profile/DefaultTenantProfileConfiguration.java | 4 ++++ 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/job/task/Task.java b/common/data/src/main/java/org/thingsboard/server/common/data/job/task/Task.java index 8f3e0d814b..a881780012 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/job/task/Task.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/job/task/Task.java @@ -46,7 +46,7 @@ public abstract class Task { public Task() { } - private int attempt = 0; + private int attempt; public abstract R toFailed(Throwable error); diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/mobile/layout/MobileLayoutConfig.java b/common/data/src/main/java/org/thingsboard/server/common/data/mobile/layout/MobileLayoutConfig.java index a45fd90838..8cf0bfb618 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/mobile/layout/MobileLayoutConfig.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/mobile/layout/MobileLayoutConfig.java @@ -38,6 +38,7 @@ public class MobileLayoutConfig { @Schema(description = "List of pages") @JsonView(Views.Public.class) @Valid + @Builder.Default private List pages = new ArrayList<>(); } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/tenant/profile/DefaultTenantProfileConfiguration.java b/common/data/src/main/java/org/thingsboard/server/common/data/tenant/profile/DefaultTenantProfileConfiguration.java index e8dbfd1584..fd13317a38 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/tenant/profile/DefaultTenantProfileConfiguration.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/tenant/profile/DefaultTenantProfileConfiguration.java @@ -168,16 +168,20 @@ public class DefaultTenantProfileConfiguration implements TenantProfileConfigura private double warnThreshold; + @Builder.Default @Schema(example = "5") private long maxCalculatedFieldsPerEntity = 5; + @Builder.Default @Schema(example = "10") private long maxArgumentsPerCF = 10; @Builder.Default @Min(value = 1, message = "must be at least 1") @Schema(example = "1000") private long maxDataPointsPerRollingArg = 1000; + @Builder.Default @Schema(example = "32") private long maxStateSizeInKBytes = 32; + @Builder.Default @Schema(example = "2") private long maxSingleValueArgumentSizeInKBytes = 2; From d7dc035ebc3f0cda4bec345a89e9b521baea27a0 Mon Sep 17 00:00:00 2001 From: Oleksandra Matviienko Date: Fri, 24 Apr 2026 10:09:17 +0200 Subject: [PATCH 18/91] chore(build): silence Lombok @EqualsAndHashCode callSuper warnings --- .../server/service/cf/ctx/state/ScriptCalculatedFieldState.java | 2 ++ .../server/service/cf/ctx/state/SimpleCalculatedFieldState.java | 2 ++ .../main/java/org/thingsboard/server/common/data/EventInfo.java | 2 ++ .../java/org/thingsboard/server/common/data/HomeDashboard.java | 2 ++ .../java/org/thingsboard/server/common/data/TenantInfo.java | 2 ++ .../org/thingsboard/server/common/data/alarm/AlarmComment.java | 1 + .../data/device/data/CoapDeviceTransportConfiguration.java | 2 ++ .../data/device/data/Lwm2mDeviceTransportConfiguration.java | 2 ++ .../lwm2m/bootstrap/LwM2MServerSecurityConfigDefault.java | 2 ++ .../java/org/thingsboard/server/common/data/edge/EdgeInfo.java | 2 ++ .../thingsboard/server/common/data/edqs/fields/AssetFields.java | 2 ++ .../server/common/data/edqs/fields/AssetProfileFields.java | 2 ++ .../server/common/data/edqs/fields/CustomerFields.java | 2 ++ .../server/common/data/edqs/fields/DashboardFields.java | 2 ++ .../server/common/data/edqs/fields/DeviceFields.java | 2 ++ .../server/common/data/edqs/fields/DeviceProfileFields.java | 2 ++ .../thingsboard/server/common/data/edqs/fields/EdgeFields.java | 2 ++ .../server/common/data/edqs/fields/EntityViewFields.java | 2 ++ .../server/common/data/edqs/fields/QueueStatsFields.java | 2 ++ .../server/common/data/edqs/fields/RuleChainFields.java | 2 ++ .../server/common/data/edqs/fields/TenantFields.java | 2 ++ .../server/common/data/edqs/fields/TenantProfileFields.java | 2 ++ .../thingsboard/server/common/data/edqs/fields/UserFields.java | 2 ++ .../thingsboard/server/common/data/kv/BaseDeleteTsKvQuery.java | 2 ++ .../thingsboard/server/common/data/query/AlarmCountQuery.java | 2 ++ .../java/org/thingsboard/server/common/data/queue/Queue.java | 2 ++ .../org/thingsboard/server/common/data/rule/RuleNodeState.java | 2 ++ .../thingsboard/server/common/data/widget/WidgetTypeInfo.java | 2 ++ .../server/transport/mqtt/limits/GatewaySessionLimits.java | 2 ++ .../server/dao/model/sqlts/latest/TsKvLatestEntity.java | 2 ++ .../rule/engine/action/TbClearAlarmNodeConfiguration.java | 2 ++ .../rule/engine/action/TbCreateAlarmNodeConfiguration.java | 2 ++ .../rule/engine/geo/TbGpsGeofencingActionNodeConfiguration.java | 2 ++ .../rule/engine/mqtt/azure/AzureIotHubSasCredentials.java | 2 ++ .../rule/engine/mqtt/azure/TbAzureIotHubNodeConfiguration.java | 2 ++ 35 files changed, 69 insertions(+) diff --git a/application/src/main/java/org/thingsboard/server/service/cf/ctx/state/ScriptCalculatedFieldState.java b/application/src/main/java/org/thingsboard/server/service/cf/ctx/state/ScriptCalculatedFieldState.java index 24f3acd4a7..be95922dbb 100644 --- a/application/src/main/java/org/thingsboard/server/service/cf/ctx/state/ScriptCalculatedFieldState.java +++ b/application/src/main/java/org/thingsboard/server/service/cf/ctx/state/ScriptCalculatedFieldState.java @@ -20,6 +20,7 @@ import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.MoreExecutors; import lombok.Data; +import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.thingsboard.script.api.tbel.TbelCfArg; @@ -35,6 +36,7 @@ import java.util.List; import java.util.Map; @Data +@EqualsAndHashCode(callSuper = false) @Slf4j @NoArgsConstructor public class ScriptCalculatedFieldState extends BaseCalculatedFieldState { diff --git a/application/src/main/java/org/thingsboard/server/service/cf/ctx/state/SimpleCalculatedFieldState.java b/application/src/main/java/org/thingsboard/server/service/cf/ctx/state/SimpleCalculatedFieldState.java index 0d018f5def..62c3f840f4 100644 --- a/application/src/main/java/org/thingsboard/server/service/cf/ctx/state/SimpleCalculatedFieldState.java +++ b/application/src/main/java/org/thingsboard/server/service/cf/ctx/state/SimpleCalculatedFieldState.java @@ -20,6 +20,7 @@ import com.fasterxml.jackson.databind.node.ObjectNode; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import lombok.Data; +import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.script.api.tbel.TbUtils; @@ -33,6 +34,7 @@ import java.util.List; import java.util.Map; @Data +@EqualsAndHashCode(callSuper = false) @NoArgsConstructor public class SimpleCalculatedFieldState extends BaseCalculatedFieldState { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/EventInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/EventInfo.java index 9ca3957050..e0bdde1dd8 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/EventInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/EventInfo.java @@ -18,6 +18,7 @@ package org.thingsboard.server.common.data; import com.fasterxml.jackson.databind.JsonNode; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; +import lombok.EqualsAndHashCode; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.EventId; import org.thingsboard.server.common.data.id.TenantId; @@ -26,6 +27,7 @@ import org.thingsboard.server.common.data.id.TenantId; * @author Andrew Shvayka */ @Data +@EqualsAndHashCode(callSuper = false) @Schema public class EventInfo extends BaseData { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/HomeDashboard.java b/common/data/src/main/java/org/thingsboard/server/common/data/HomeDashboard.java index ce9c8fce78..df2cdf2bf5 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/HomeDashboard.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/HomeDashboard.java @@ -17,9 +17,11 @@ package org.thingsboard.server.common.data; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; +import lombok.EqualsAndHashCode; @Schema @Data +@EqualsAndHashCode(callSuper = false) public class HomeDashboard extends Dashboard { public static final String HIDE_DASHBOARD_TOOLBAR_DESCRIPTION = "Hide dashboard toolbar flag. Useful for rendering dashboards on mobile."; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/TenantInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/TenantInfo.java index 4126b1acdd..8f38ecd750 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/TenantInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/TenantInfo.java @@ -17,10 +17,12 @@ package org.thingsboard.server.common.data; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; +import lombok.EqualsAndHashCode; import org.thingsboard.server.common.data.id.TenantId; @Schema @Data +@EqualsAndHashCode(callSuper = false) public class TenantInfo extends Tenant { @Schema(description = "Tenant Profile name", example = "Default") private String tenantProfileName; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/alarm/AlarmComment.java b/common/data/src/main/java/org/thingsboard/server/common/data/alarm/AlarmComment.java index 0a011c287f..29269e5bd8 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/alarm/AlarmComment.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/alarm/AlarmComment.java @@ -34,6 +34,7 @@ import java.io.Serial; @Schema @Data +@EqualsAndHashCode(callSuper = false) @Builder @AllArgsConstructor public class AlarmComment extends BaseData implements HasName { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/device/data/CoapDeviceTransportConfiguration.java b/common/data/src/main/java/org/thingsboard/server/common/data/device/data/CoapDeviceTransportConfiguration.java index 3f23e4fe14..662887c08c 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/device/data/CoapDeviceTransportConfiguration.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/device/data/CoapDeviceTransportConfiguration.java @@ -19,12 +19,14 @@ import com.fasterxml.jackson.annotation.JsonAnyGetter; import com.fasterxml.jackson.annotation.JsonAnySetter; import com.fasterxml.jackson.annotation.JsonIgnore; import lombok.Data; +import lombok.EqualsAndHashCode; import org.thingsboard.server.common.data.DeviceTransportType; import java.util.HashMap; import java.util.Map; @Data +@EqualsAndHashCode(callSuper = false) public class CoapDeviceTransportConfiguration extends PowerSavingConfiguration implements DeviceTransportConfiguration { private static final long serialVersionUID = 6061442236008925609L; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/device/data/Lwm2mDeviceTransportConfiguration.java b/common/data/src/main/java/org/thingsboard/server/common/data/device/data/Lwm2mDeviceTransportConfiguration.java index 079ceffada..1c53412ef9 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/device/data/Lwm2mDeviceTransportConfiguration.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/device/data/Lwm2mDeviceTransportConfiguration.java @@ -19,12 +19,14 @@ import com.fasterxml.jackson.annotation.JsonAnyGetter; import com.fasterxml.jackson.annotation.JsonAnySetter; import com.fasterxml.jackson.annotation.JsonIgnore; import lombok.Data; +import lombok.EqualsAndHashCode; import org.thingsboard.server.common.data.DeviceTransportType; import java.util.HashMap; import java.util.Map; @Data +@EqualsAndHashCode(callSuper = false) public class Lwm2mDeviceTransportConfiguration extends PowerSavingConfiguration implements DeviceTransportConfiguration { @JsonIgnore diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/lwm2m/bootstrap/LwM2MServerSecurityConfigDefault.java b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/lwm2m/bootstrap/LwM2MServerSecurityConfigDefault.java index 85c1e97e24..14ef402718 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/lwm2m/bootstrap/LwM2MServerSecurityConfigDefault.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/lwm2m/bootstrap/LwM2MServerSecurityConfigDefault.java @@ -17,9 +17,11 @@ package org.thingsboard.server.common.data.device.profile.lwm2m.bootstrap; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; +import lombok.EqualsAndHashCode; @Schema @Data +@EqualsAndHashCode(callSuper = false) public class LwM2MServerSecurityConfigDefault extends LwM2MServerSecurityConfig { @Schema(description = "Host for 'Security' mode (DTLS)", example = "0.0.0.0", accessMode = Schema.AccessMode.READ_ONLY) protected String securityHost; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/edge/EdgeInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/edge/EdgeInfo.java index dd751b8b9d..5dbd0212b3 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/edge/EdgeInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/edge/EdgeInfo.java @@ -16,9 +16,11 @@ package org.thingsboard.server.common.data.edge; import lombok.Data; +import lombok.EqualsAndHashCode; import org.thingsboard.server.common.data.id.EdgeId; @Data +@EqualsAndHashCode(callSuper = false) public class EdgeInfo extends Edge { private String customerTitle; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/AssetFields.java b/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/AssetFields.java index 40ad22ed19..d05147b4d7 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/AssetFields.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/AssetFields.java @@ -18,6 +18,7 @@ package org.thingsboard.server.common.data.edqs.fields; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.databind.JsonNode; import lombok.Data; +import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import lombok.experimental.SuperBuilder; @@ -26,6 +27,7 @@ import java.util.UUID; import static org.thingsboard.server.common.data.edqs.fields.FieldsUtil.getText; @Data +@EqualsAndHashCode(callSuper = false) @NoArgsConstructor @SuperBuilder public class AssetFields extends AbstractEntityFields implements ProfileAwareFields { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/AssetProfileFields.java b/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/AssetProfileFields.java index ce91aac9d0..c519daa800 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/AssetProfileFields.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/AssetProfileFields.java @@ -16,12 +16,14 @@ package org.thingsboard.server.common.data.edqs.fields; import lombok.Data; +import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import lombok.experimental.SuperBuilder; import java.util.UUID; @Data +@EqualsAndHashCode(callSuper = false) @NoArgsConstructor @SuperBuilder public class AssetProfileFields extends AbstractEntityFields { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/CustomerFields.java b/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/CustomerFields.java index e2cdf8f295..c324f0f1ab 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/CustomerFields.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/CustomerFields.java @@ -17,6 +17,7 @@ package org.thingsboard.server.common.data.edqs.fields; import com.fasterxml.jackson.databind.JsonNode; import lombok.Data; +import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import lombok.experimental.SuperBuilder; @@ -25,6 +26,7 @@ import java.util.UUID; import static org.thingsboard.server.common.data.edqs.fields.FieldsUtil.getText; @Data +@EqualsAndHashCode(callSuper = false) @NoArgsConstructor @SuperBuilder public class CustomerFields extends AbstractEntityFields { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/DashboardFields.java b/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/DashboardFields.java index 4131d58e98..608a64436e 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/DashboardFields.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/DashboardFields.java @@ -19,6 +19,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import lombok.Data; +import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import lombok.experimental.SuperBuilder; @@ -28,6 +29,7 @@ import java.util.UUID; @Data +@EqualsAndHashCode(callSuper = false) @NoArgsConstructor @SuperBuilder public class DashboardFields extends AbstractEntityFields { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/DeviceFields.java b/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/DeviceFields.java index 90400ae70d..ef8aee952b 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/DeviceFields.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/DeviceFields.java @@ -18,6 +18,7 @@ package org.thingsboard.server.common.data.edqs.fields; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.databind.JsonNode; import lombok.Data; +import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import lombok.experimental.SuperBuilder; @@ -26,6 +27,7 @@ import java.util.UUID; import static org.thingsboard.server.common.data.edqs.fields.FieldsUtil.getText; @Data +@EqualsAndHashCode(callSuper = false) @NoArgsConstructor @SuperBuilder public class DeviceFields extends AbstractEntityFields implements ProfileAwareFields { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/DeviceProfileFields.java b/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/DeviceProfileFields.java index 067c961b9e..2331829054 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/DeviceProfileFields.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/DeviceProfileFields.java @@ -16,6 +16,7 @@ package org.thingsboard.server.common.data.edqs.fields; import lombok.Data; +import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import lombok.experimental.SuperBuilder; import org.thingsboard.server.common.data.DeviceProfileType; @@ -23,6 +24,7 @@ import org.thingsboard.server.common.data.DeviceProfileType; import java.util.UUID; @Data +@EqualsAndHashCode(callSuper = false) @NoArgsConstructor @SuperBuilder public class DeviceProfileFields extends AbstractEntityFields { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/EdgeFields.java b/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/EdgeFields.java index 1d257b06e1..e048eb22a8 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/EdgeFields.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/EdgeFields.java @@ -17,6 +17,7 @@ package org.thingsboard.server.common.data.edqs.fields; import com.fasterxml.jackson.databind.JsonNode; import lombok.Data; +import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import lombok.experimental.SuperBuilder; @@ -25,6 +26,7 @@ import java.util.UUID; import static org.thingsboard.server.common.data.edqs.fields.FieldsUtil.getText; @Data +@EqualsAndHashCode(callSuper = false) @NoArgsConstructor @SuperBuilder public class EdgeFields extends AbstractEntityFields { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/EntityViewFields.java b/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/EntityViewFields.java index 4e326cf779..c5027dfc8f 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/EntityViewFields.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/EntityViewFields.java @@ -17,6 +17,7 @@ package org.thingsboard.server.common.data.edqs.fields; import com.fasterxml.jackson.databind.JsonNode; import lombok.Data; +import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import lombok.experimental.SuperBuilder; @@ -25,6 +26,7 @@ import java.util.UUID; import static org.thingsboard.server.common.data.edqs.fields.FieldsUtil.getText; @Data +@EqualsAndHashCode(callSuper = false) @NoArgsConstructor @SuperBuilder public class EntityViewFields extends AbstractEntityFields { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/QueueStatsFields.java b/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/QueueStatsFields.java index 13e05daad4..5c5a139364 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/QueueStatsFields.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/QueueStatsFields.java @@ -16,12 +16,14 @@ package org.thingsboard.server.common.data.edqs.fields; import lombok.Data; +import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import lombok.experimental.SuperBuilder; import java.util.UUID; @Data +@EqualsAndHashCode(callSuper = false) @NoArgsConstructor @SuperBuilder public class QueueStatsFields extends AbstractEntityFields { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/RuleChainFields.java b/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/RuleChainFields.java index 25b7db6aaa..d580f6b913 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/RuleChainFields.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/RuleChainFields.java @@ -17,6 +17,7 @@ package org.thingsboard.server.common.data.edqs.fields; import com.fasterxml.jackson.databind.JsonNode; import lombok.Data; +import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import lombok.experimental.SuperBuilder; @@ -25,6 +26,7 @@ import java.util.UUID; import static org.thingsboard.server.common.data.edqs.fields.FieldsUtil.getText; @Data +@EqualsAndHashCode(callSuper = false) @NoArgsConstructor @SuperBuilder public class RuleChainFields extends AbstractEntityFields { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/TenantFields.java b/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/TenantFields.java index 9b538511b2..ba350fec54 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/TenantFields.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/TenantFields.java @@ -17,6 +17,7 @@ package org.thingsboard.server.common.data.edqs.fields; import com.fasterxml.jackson.databind.JsonNode; import lombok.Data; +import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import lombok.experimental.SuperBuilder; @@ -25,6 +26,7 @@ import java.util.UUID; import static org.thingsboard.server.common.data.edqs.fields.FieldsUtil.getText; @Data +@EqualsAndHashCode(callSuper = false) @NoArgsConstructor @SuperBuilder public class TenantFields extends AbstractEntityFields { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/TenantProfileFields.java b/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/TenantProfileFields.java index f6a2889f67..5d1ff0e0e2 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/TenantProfileFields.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/TenantProfileFields.java @@ -16,6 +16,7 @@ package org.thingsboard.server.common.data.edqs.fields; import lombok.Data; +import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import lombok.experimental.SuperBuilder; import org.thingsboard.server.common.data.id.TenantId; @@ -23,6 +24,7 @@ import org.thingsboard.server.common.data.id.TenantId; import java.util.UUID; @Data +@EqualsAndHashCode(callSuper = false) @NoArgsConstructor @SuperBuilder public class TenantProfileFields extends AbstractEntityFields { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/UserFields.java b/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/UserFields.java index 225b85680f..70fde8bf9c 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/UserFields.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/UserFields.java @@ -17,6 +17,7 @@ package org.thingsboard.server.common.data.edqs.fields; import com.fasterxml.jackson.databind.JsonNode; import lombok.Data; +import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import lombok.experimental.SuperBuilder; @@ -25,6 +26,7 @@ import java.util.UUID; import static org.thingsboard.server.common.data.edqs.fields.FieldsUtil.getText; @Data +@EqualsAndHashCode(callSuper = false) @NoArgsConstructor @SuperBuilder public class UserFields extends AbstractEntityFields { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/kv/BaseDeleteTsKvQuery.java b/common/data/src/main/java/org/thingsboard/server/common/data/kv/BaseDeleteTsKvQuery.java index 233c53849c..f46339c15a 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/kv/BaseDeleteTsKvQuery.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/kv/BaseDeleteTsKvQuery.java @@ -16,8 +16,10 @@ package org.thingsboard.server.common.data.kv; import lombok.Data; +import lombok.EqualsAndHashCode; @Data +@EqualsAndHashCode(callSuper = false) public class BaseDeleteTsKvQuery extends BaseTsKvQuery implements DeleteTsKvQuery { private final Boolean rewriteLatestIfDeleted; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/query/AlarmCountQuery.java b/common/data/src/main/java/org/thingsboard/server/common/data/query/AlarmCountQuery.java index f9d2e8d3d8..1599413c1c 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/query/AlarmCountQuery.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/query/AlarmCountQuery.java @@ -18,6 +18,7 @@ package org.thingsboard.server.common.data.query; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; +import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import lombok.ToString; import org.thingsboard.server.common.data.alarm.AlarmSearchStatus; @@ -30,6 +31,7 @@ import java.util.List; @NoArgsConstructor @AllArgsConstructor @Data +@EqualsAndHashCode(callSuper = false) @ToString public class AlarmCountQuery extends EntityCountQuery { private long startTs; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/queue/Queue.java b/common/data/src/main/java/org/thingsboard/server/common/data/queue/Queue.java index 57e0e6af66..d6a4f2b12f 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/queue/Queue.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/queue/Queue.java @@ -18,6 +18,7 @@ package org.thingsboard.server.common.data.queue; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.databind.JsonNode; import lombok.Data; +import lombok.EqualsAndHashCode; import org.thingsboard.server.common.data.BaseDataWithAdditionalInfo; import org.thingsboard.server.common.data.HasName; import org.thingsboard.server.common.data.HasTenantId; @@ -30,6 +31,7 @@ import org.thingsboard.server.common.data.validation.NoXss; import java.util.Optional; @Data +@EqualsAndHashCode(callSuper = false) public class Queue extends BaseDataWithAdditionalInfo implements HasName, HasTenantId, QueueConfig { private TenantId tenantId; @NoXss diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleNodeState.java b/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleNodeState.java index cb861a6726..0624350d7e 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleNodeState.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleNodeState.java @@ -16,12 +16,14 @@ package org.thingsboard.server.common.data.rule; import lombok.Data; +import lombok.EqualsAndHashCode; import org.thingsboard.server.common.data.BaseData; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.RuleNodeId; import org.thingsboard.server.common.data.id.RuleNodeStateId; @Data +@EqualsAndHashCode(callSuper = false) public class RuleNodeState extends BaseData { private RuleNodeId ruleNodeId; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/widget/WidgetTypeInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/widget/WidgetTypeInfo.java index 9fe846796b..9acce93aa3 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/widget/WidgetTypeInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/widget/WidgetTypeInfo.java @@ -18,6 +18,7 @@ package org.thingsboard.server.common.data.widget; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.Valid; import lombok.Data; +import lombok.EqualsAndHashCode; import org.thingsboard.server.common.data.id.WidgetTypeId; import org.thingsboard.server.common.data.validation.NoXss; @@ -26,6 +27,7 @@ import java.util.Collections; import java.util.List; @Data +@EqualsAndHashCode(callSuper = false) public class WidgetTypeInfo extends BaseWidgetType { @Serial diff --git a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/limits/GatewaySessionLimits.java b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/limits/GatewaySessionLimits.java index 45d9e21e39..8356a17748 100644 --- a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/limits/GatewaySessionLimits.java +++ b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/limits/GatewaySessionLimits.java @@ -16,8 +16,10 @@ package org.thingsboard.server.transport.mqtt.limits; import lombok.Data; +import lombok.EqualsAndHashCode; @Data +@EqualsAndHashCode(callSuper = false) public class GatewaySessionLimits extends SessionLimits { private SessionRateLimits gatewayRateLimits; diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sqlts/latest/TsKvLatestEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sqlts/latest/TsKvLatestEntity.java index 44a38bf445..421a22a9d2 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sqlts/latest/TsKvLatestEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sqlts/latest/TsKvLatestEntity.java @@ -26,6 +26,7 @@ import jakarta.persistence.SqlResultSetMapping; import jakarta.persistence.SqlResultSetMappings; import jakarta.persistence.Table; import lombok.Data; +import lombok.EqualsAndHashCode; import org.thingsboard.server.common.data.kv.TsKvEntry; import org.thingsboard.server.dao.model.sql.AbstractTsKvEntity; import org.thingsboard.server.dao.sqlts.latest.SearchTsKvLatestRepository; @@ -35,6 +36,7 @@ import java.util.UUID; import static org.thingsboard.server.dao.model.ModelConstants.VERSION_COLUMN; @Data +@EqualsAndHashCode(callSuper = false) @Entity @Table(name = "ts_kv_latest") @IdClass(TsKvLatestCompositeKey.class) diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbClearAlarmNodeConfiguration.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbClearAlarmNodeConfiguration.java index a69a157241..ab305919fd 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbClearAlarmNodeConfiguration.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbClearAlarmNodeConfiguration.java @@ -16,10 +16,12 @@ package org.thingsboard.rule.engine.action; import lombok.Data; +import lombok.EqualsAndHashCode; import org.thingsboard.rule.engine.api.NodeConfiguration; import org.thingsboard.server.common.data.script.ScriptLanguage; @Data +@EqualsAndHashCode(callSuper = false) public class TbClearAlarmNodeConfiguration extends TbAbstractAlarmNodeConfiguration implements NodeConfiguration { @Override diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbCreateAlarmNodeConfiguration.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbCreateAlarmNodeConfiguration.java index 8c791e7634..bf305a55d1 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbCreateAlarmNodeConfiguration.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbCreateAlarmNodeConfiguration.java @@ -16,6 +16,7 @@ package org.thingsboard.rule.engine.action; import lombok.Data; +import lombok.EqualsAndHashCode; import org.thingsboard.rule.engine.api.NodeConfiguration; import org.thingsboard.server.common.data.alarm.AlarmSeverity; import org.thingsboard.server.common.data.script.ScriptLanguage; @@ -25,6 +26,7 @@ import java.util.Collections; import java.util.List; @Data +@EqualsAndHashCode(callSuper = false) public class TbCreateAlarmNodeConfiguration extends TbAbstractAlarmNodeConfiguration implements NodeConfiguration { @NoXss diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/geo/TbGpsGeofencingActionNodeConfiguration.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/geo/TbGpsGeofencingActionNodeConfiguration.java index 3b59d814f1..6551352823 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/geo/TbGpsGeofencingActionNodeConfiguration.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/geo/TbGpsGeofencingActionNodeConfiguration.java @@ -16,6 +16,7 @@ package org.thingsboard.rule.engine.geo; import lombok.Data; +import lombok.EqualsAndHashCode; import org.thingsboard.common.util.geo.PerimeterType; import java.util.concurrent.TimeUnit; @@ -24,6 +25,7 @@ import java.util.concurrent.TimeUnit; * Created by ashvayka on 19.01.18. */ @Data +@EqualsAndHashCode(callSuper = false) public class TbGpsGeofencingActionNodeConfiguration extends TbGpsGeofencingFilterNodeConfiguration { private int minInsideDuration; diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/mqtt/azure/AzureIotHubSasCredentials.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/mqtt/azure/AzureIotHubSasCredentials.java index fe17c659e1..93d1ef7ef8 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/mqtt/azure/AzureIotHubSasCredentials.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/mqtt/azure/AzureIotHubSasCredentials.java @@ -20,6 +20,7 @@ import io.netty.handler.ssl.ClientAuth; import io.netty.handler.ssl.SslContext; import io.netty.handler.ssl.SslContextBuilder; import lombok.Data; +import lombok.EqualsAndHashCode; import lombok.extern.slf4j.Slf4j; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.thingsboard.common.util.AzureIotHubUtil; @@ -29,6 +30,7 @@ import org.thingsboard.rule.engine.credentials.CredentialsType; import java.security.Security; @Data +@EqualsAndHashCode(callSuper = false) @Slf4j @JsonIgnoreProperties(ignoreUnknown = true) public class AzureIotHubSasCredentials extends CertPemCredentials { diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/mqtt/azure/TbAzureIotHubNodeConfiguration.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/mqtt/azure/TbAzureIotHubNodeConfiguration.java index c786478575..f11173f3f9 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/mqtt/azure/TbAzureIotHubNodeConfiguration.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/mqtt/azure/TbAzureIotHubNodeConfiguration.java @@ -17,9 +17,11 @@ package org.thingsboard.rule.engine.mqtt.azure; import io.netty.handler.codec.mqtt.MqttVersion; import lombok.Data; +import lombok.EqualsAndHashCode; import org.thingsboard.rule.engine.mqtt.TbMqttNodeConfiguration; @Data +@EqualsAndHashCode(callSuper = false) public class TbAzureIotHubNodeConfiguration extends TbMqttNodeConfiguration { @Override From 3615de5d75a00afb3c23b7da977617e243c7d3c5 Mon Sep 17 00:00:00 2001 From: Oleksandra Matviienko Date: Fri, 24 Apr 2026 11:31:54 +0200 Subject: [PATCH 19/91] chore(build): migrate deprecated DefaultedRedisConnection byte[] calls to typed command APIs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Routes get/set/del/scan/getSet/hGet/hSet/hDel/lRange/zRem/getRange calls through stringCommands()/keyCommands()/hashCommands()/listCommands()/ zSetCommands() instead of the deprecated shortcut methods on DefaultedRedisConnection. Behavior-preserving — Spring Data Redis delegates the deprecated overloads to these same typed commands. Eliminates 70 deprecation warnings across RedisOtaPackageDataCache, five Leshan-forked lwm2m stores (TbLwM2mRedisRegistrationStore, TbLwM2mRedisSecurityStore, TbRedisLwM2MClientStore, TbRedisLwM2MModelConfigStore, TbLwM2mRedisClientOtaInfoStore, TbLwM2MDtlsSessionRedisStore) and the TbRedisLwM2MClientStoreTest unit test, which now uses Answers.RETURNS_DEEP_STUBS to mock the typed command chain. Part of #15481 Tier 3 cleanup. --- .../cache/ota/RedisOtaPackageDataCache.java | 8 +-- .../store/TbLwM2MDtlsSessionRedisStore.java | 6 +- .../store/TbLwM2mRedisClientOtaInfoStore.java | 4 +- .../store/TbLwM2mRedisRegistrationStore.java | 66 +++++++++---------- .../store/TbLwM2mRedisSecurityStore.java | 24 +++---- .../server/store/TbRedisLwM2MClientStore.java | 10 +-- .../store/TbRedisLwM2MModelConfigStore.java | 8 +-- .../store/TbRedisLwM2MClientStoreTest.java | 21 +++--- 8 files changed, 74 insertions(+), 73 deletions(-) diff --git a/common/cache/src/main/java/org/thingsboard/server/cache/ota/RedisOtaPackageDataCache.java b/common/cache/src/main/java/org/thingsboard/server/cache/ota/RedisOtaPackageDataCache.java index c3a9ff0385..1e13b1cfe9 100644 --- a/common/cache/src/main/java/org/thingsboard/server/cache/ota/RedisOtaPackageDataCache.java +++ b/common/cache/src/main/java/org/thingsboard/server/cache/ota/RedisOtaPackageDataCache.java @@ -39,26 +39,26 @@ public class RedisOtaPackageDataCache implements OtaPackageDataCache { public byte[] get(String key, int chunkSize, int chunk) { try (RedisConnection connection = redisConnectionFactory.getConnection()) { if (chunkSize == 0) { - return connection.get(toOtaPackageCacheKey(key)); + return connection.stringCommands().get(toOtaPackageCacheKey(key)); } int startIndex = chunkSize * chunk; int endIndex = startIndex + chunkSize - 1; - return connection.getRange(toOtaPackageCacheKey(key), startIndex, endIndex); + return connection.stringCommands().getRange(toOtaPackageCacheKey(key), startIndex, endIndex); } } @Override public void put(String key, byte[] value) { try (RedisConnection connection = redisConnectionFactory.getConnection()) { - connection.set(toOtaPackageCacheKey(key), value); + connection.stringCommands().set(toOtaPackageCacheKey(key), value); } } @Override public void evict(String key) { try (RedisConnection connection = redisConnectionFactory.getConnection()) { - connection.del(toOtaPackageCacheKey(key)); + connection.keyCommands().del(toOtaPackageCacheKey(key)); } } diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbLwM2MDtlsSessionRedisStore.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbLwM2MDtlsSessionRedisStore.java index ead9269108..fa78bbb7bb 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbLwM2MDtlsSessionRedisStore.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbLwM2MDtlsSessionRedisStore.java @@ -33,7 +33,7 @@ public class TbLwM2MDtlsSessionRedisStore implements TbLwM2MDtlsSessionStore { try (var c = connectionFactory.getConnection()) { var serializedMsg = JavaSerDesUtil.encode(msg); if (serializedMsg != null) { - c.set(getKey(endpoint), serializedMsg); + c.stringCommands().set(getKey(endpoint), serializedMsg); } else { throw new RuntimeException("Problem with serialization of message: " + msg); } @@ -43,7 +43,7 @@ public class TbLwM2MDtlsSessionRedisStore implements TbLwM2MDtlsSessionStore { @Override public TbX509DtlsSessionInfo get(String endpoint) { try (var c = connectionFactory.getConnection()) { - var data = c.get(getKey(endpoint)); + var data = c.stringCommands().get(getKey(endpoint)); if (data != null) { return JavaSerDesUtil.decode(data); } else { @@ -55,7 +55,7 @@ public class TbLwM2MDtlsSessionRedisStore implements TbLwM2MDtlsSessionStore { @Override public void remove(String endpoint) { try (var c = connectionFactory.getConnection()) { - c.del(getKey(endpoint)); + c.keyCommands().del(getKey(endpoint)); } } diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbLwM2mRedisClientOtaInfoStore.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbLwM2mRedisClientOtaInfoStore.java index 8301d4a448..c75a5ff8a0 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbLwM2mRedisClientOtaInfoStore.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbLwM2mRedisClientOtaInfoStore.java @@ -33,7 +33,7 @@ public class TbLwM2mRedisClientOtaInfoStore implements TbLwM2MClientOtaInfoStore private void put(OtaPackageType type, LwM2MClientOtaInfo info) { try (var connection = connectionFactory.getConnection()) { - connection.set((OTA_EP + type + info.getEndpoint()).getBytes(), JacksonUtil.toString(info).getBytes()); + connection.stringCommands().set((OTA_EP + type + info.getEndpoint()).getBytes(), JacksonUtil.toString(info).getBytes()); } } @@ -59,7 +59,7 @@ public class TbLwM2mRedisClientOtaInfoStore implements TbLwM2MClientOtaInfoStore private > T getLwM2MClientOtaInfo(OtaPackageType type, String endpoint, Class clazz) { try (var connection = connectionFactory.getConnection()) { - byte[] data = connection.get((OTA_EP + type + endpoint).getBytes()); + byte[] data = connection.stringCommands().get((OTA_EP + type + endpoint).getBytes()); return JacksonUtil.fromBytes(data, clazz); } } diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbLwM2mRedisRegistrationStore.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbLwM2mRedisRegistrationStore.java index 8158e82a81..5937383156 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbLwM2mRedisRegistrationStore.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbLwM2mRedisRegistrationStore.java @@ -163,15 +163,15 @@ public class TbLwM2mRedisRegistrationStore implements RegistrationStore, Startab lock.lock(); // add registration byte[] k = toEndpointKey(registration.getEndpoint()); - byte[] old = connection.getSet(k, serializeReg(registration)); + byte[] old = connection.stringCommands().getSet(k, serializeReg(registration)); // add registration: secondary indexes byte[] regid_idx = toRegIdKey(registration.getId()); - connection.set(regid_idx, registration.getEndpoint().getBytes(UTF_8)); + connection.stringCommands().set(regid_idx, registration.getEndpoint().getBytes(UTF_8)); byte[] addr_idx = toRegAddrKey(registration.getSocketAddress()); - connection.set(addr_idx, registration.getEndpoint().getBytes(UTF_8)); + connection.stringCommands().set(addr_idx, registration.getEndpoint().getBytes(UTF_8)); byte[] identity_idx = toRegIdentityKey(registration.getClientTransportData().getIdentity()); - connection.set(identity_idx, registration.getEndpoint().getBytes(UTF_8)); + connection.stringCommands().set(identity_idx, registration.getEndpoint().getBytes(UTF_8)); // Add or update expiration addOrUpdateExpiration(connection, registration); @@ -180,7 +180,7 @@ public class TbLwM2mRedisRegistrationStore implements RegistrationStore, Startab Registration oldRegistration = deserializeReg(old); // remove old secondary index if (!registration.getId().equals(oldRegistration.getId())) - connection.del(toRegIdKey(oldRegistration.getId())); + connection.keyCommands().del(toRegIdKey(oldRegistration.getId())); if (!oldRegistration.getSocketAddress().equals(registration.getSocketAddress())) { removeAddrIndex(connection, oldRegistration); } @@ -209,7 +209,7 @@ public class TbLwM2mRedisRegistrationStore implements RegistrationStore, Startab try (var connection = connectionFactory.getConnection()) { // Fetch the registration ep by registration ID index - byte[] ep = connection.get(toRegIdKey(update.getRegistrationId())); + byte[] ep = connection.stringCommands().get(toRegIdKey(update.getRegistrationId())); if (ep == null) { return null; } @@ -220,7 +220,7 @@ public class TbLwM2mRedisRegistrationStore implements RegistrationStore, Startab lock.lock(); // Fetch the registration - byte[] data = connection.get(toEndpointKey(ep)); + byte[] data = connection.stringCommands().get(toEndpointKey(ep)); if (data == null) { return null; } @@ -230,7 +230,7 @@ public class TbLwM2mRedisRegistrationStore implements RegistrationStore, Startab Registration updatedRegistration = update.update(r); // Store the new registration - connection.set(toEndpointKey(updatedRegistration.getEndpoint()), serializeReg(updatedRegistration)); + connection.stringCommands().set(toEndpointKey(updatedRegistration.getEndpoint()), serializeReg(updatedRegistration)); // Add or update expiration addOrUpdateExpiration(connection, updatedRegistration); @@ -239,7 +239,7 @@ public class TbLwM2mRedisRegistrationStore implements RegistrationStore, Startab * If registration is already associated to this address we don't care as we only want to keep the most * recent binding. */ byte[] addr_idx = toRegAddrKey(updatedRegistration.getSocketAddress()); - connection.set(addr_idx, updatedRegistration.getEndpoint().getBytes(UTF_8)); + connection.stringCommands().set(addr_idx, updatedRegistration.getEndpoint().getBytes(UTF_8)); if (!r.getSocketAddress().equals(updatedRegistration.getSocketAddress())) { removeAddrIndex(connection, r); } @@ -265,11 +265,11 @@ public class TbLwM2mRedisRegistrationStore implements RegistrationStore, Startab } private Registration getRegistration(RedisConnection connection, String registrationId) { - byte[] ep = connection.get(toRegIdKey(registrationId)); + byte[] ep = connection.stringCommands().get(toRegIdKey(registrationId)); if (ep == null) { return null; } - byte[] data = connection.get(toEndpointKey(ep)); + byte[] data = connection.stringCommands().get(toEndpointKey(ep)); if (data == null) { return null; } @@ -281,7 +281,7 @@ public class TbLwM2mRedisRegistrationStore implements RegistrationStore, Startab public Registration getRegistrationByEndpoint(String endpoint) { Validate.notNull(endpoint); try (var connection = connectionFactory.getConnection()) { - byte[] data = connection.get(toEndpointKey(endpoint)); + byte[] data = connection.stringCommands().get(toEndpointKey(endpoint)); if (data == null) { return null; } @@ -293,11 +293,11 @@ public class TbLwM2mRedisRegistrationStore implements RegistrationStore, Startab public Registration getRegistrationByAdress(InetSocketAddress address) { Validate.notNull(address); try (var connection = connectionFactory.getConnection()) { - byte[] ep = connection.get(toRegAddrKey(address)); + byte[] ep = connection.stringCommands().get(toRegAddrKey(address)); if (ep == null) { return null; } - byte[] data = connection.get(toEndpointKey(ep)); + byte[] data = connection.stringCommands().get(toEndpointKey(ep)); if (data == null) { return null; } @@ -309,11 +309,11 @@ public class TbLwM2mRedisRegistrationStore implements RegistrationStore, Startab public Registration getRegistrationByIdentity(LwM2mIdentity identity) { Validate.notNull(identity); try (var connection = connectionFactory.getConnection()) { - byte[] ep = connection.get(toRegIdentityKey(identity)); + byte[] ep = connection.stringCommands().get(toRegIdentityKey(identity)); if (ep == null) { return null; } - byte[] data = connection.get(toEndpointKey(ep)); + byte[] data = connection.stringCommands().get(toEndpointKey(ep)); if (data == null) { return null; } @@ -332,12 +332,12 @@ public class TbLwM2mRedisRegistrationStore implements RegistrationStore, Startab clusterConnection.clusterGetNodes().forEach(node -> scans.add(clusterConnection.scan(node, scanOptions))); } else { - scans.add(scanConnection.scan(scanOptions)); + scans.add(scanConnection.keyCommands().scan(scanOptions)); } scans.forEach(scan -> { scan.forEachRemaining(key -> { - byte[] element = getConnection.get(key); + byte[] element = getConnection.stringCommands().get(key); if (element != null) { list.add(deserializeReg(element)); } @@ -357,7 +357,7 @@ public class TbLwM2mRedisRegistrationStore implements RegistrationStore, Startab private Deregistration removeRegistration(RedisConnection connection, String registrationId, boolean removeOnlyIfNotAlive) { // fetch the client ep by registration ID index - byte[] ep = connection.get(toRegIdKey(registrationId)); + byte[] ep = connection.stringCommands().get(toRegIdKey(registrationId)); if (ep == null) { return null; } @@ -369,16 +369,16 @@ public class TbLwM2mRedisRegistrationStore implements RegistrationStore, Startab lock.lock(); // fetch the client - byte[] data = connection.get(toEndpointKey(ep)); + byte[] data = connection.stringCommands().get(toEndpointKey(ep)); if (data == null) { return null; } Registration r = deserializeReg(data); if (!removeOnlyIfNotAlive || !r.isAlive(gracePeriod)) { - long nbRemoved = connection.del(toRegIdKey(r.getId())); + long nbRemoved = connection.keyCommands().del(toRegIdKey(r.getId())); if (nbRemoved > 0) { - connection.del(toEndpointKey(r.getEndpoint())); + connection.keyCommands().del(toEndpointKey(r.getEndpoint())); Collection obsRemoved = unsafeRemoveAllObservations(connection, r.getId()); removeAddrIndex(connection, r); removeIdentityIndex(connection, r); @@ -407,12 +407,12 @@ public class TbLwM2mRedisRegistrationStore implements RegistrationStore, Startab // Watch the key to remove. // connection.watch(indexKey); - byte[] epFromAddr = connection.get(indexKey); + byte[] epFromAddr = connection.stringCommands().get(indexKey); // Delete the key if needed. if (Arrays.equals(epFromAddr, endpointName.getBytes(UTF_8))) { // Try to delete the key // connection.multi(); - connection.del(indexKey); + connection.keyCommands().del(indexKey); // connection.exec(); // if transaction failed this is not an issue as the index is probably reused and we don't need to // delete it anymore. @@ -427,7 +427,7 @@ public class TbLwM2mRedisRegistrationStore implements RegistrationStore, Startab } private void removeExpiration(RedisConnection connection, Registration registration) { - connection.zRem(EXP_EP, registration.getEndpoint().getBytes(UTF_8)); + connection.zSetCommands().zRem(EXP_EP, registration.getEndpoint().getBytes(UTF_8)); } private byte[] toRegIdKey(String registrationId) { @@ -556,7 +556,7 @@ public class TbLwM2mRedisRegistrationStore implements RegistrationStore, Startab @Override public Observation getObservation(ObservationIdentifier observationId) { try (var connection = connectionFactory.getConnection()) { - byte[] observationValue = connection.get(toKey(OBS_TKN, observationId.getBytes())); + byte[] observationValue = connection.stringCommands().get(toKey(OBS_TKN, observationId.getBytes())); return deserializeObs(observationValue); } } @@ -570,7 +570,7 @@ public class TbLwM2mRedisRegistrationStore implements RegistrationStore, Startab try (var connection = connectionFactory.getConnection()) { // fetch the client ep by registration ID index - byte[] ep = connection.get(toRegIdKey(registrationId)); + byte[] ep = connection.stringCommands().get(toRegIdKey(registrationId)); if (ep == null) { return null; } @@ -635,7 +635,7 @@ public class TbLwM2mRedisRegistrationStore implements RegistrationStore, Startab public Observation get(Token token) { try (var connection = connectionFactory.getConnection()) { - byte[] obs = connection.get(toKey(OBS_TKN, token.getBytes())); + byte[] obs = connection.stringCommands().get(toKey(OBS_TKN, token.getBytes())); if (obs == null) { return null; } else { @@ -664,14 +664,14 @@ public class TbLwM2mRedisRegistrationStore implements RegistrationStore, Startab byte[] regIdKey = toKey(OBS_TKNS_REGID_IDX, registrationId); // fetch all observations by token - for (byte[] token : connection.lRange(regIdKey, 0, -1)) { - byte[] obs = connection.get(toKey(OBS_TKN, token)); + for (byte[] token : connection.listCommands().lRange(regIdKey, 0, -1)) { + byte[] obs = connection.stringCommands().get(toKey(OBS_TKN, token)); if (obs != null) { removed.add(deserializeObs(obs)); } - connection.del(toKey(OBS_TKN, token)); + connection.keyCommands().del(toKey(OBS_TKN, token)); } - connection.del(regIdKey); + connection.keyCommands().del(regIdKey); return removed; } @@ -752,7 +752,7 @@ public class TbLwM2mRedisRegistrationStore implements RegistrationStore, Startab System.currentTimeMillis(), 0, cleanLimit); for (byte[] endpoint : endpointsExpired) { - byte[] data = connection.get(toEndpointKey(endpoint)); + byte[] data = connection.stringCommands().get(toEndpointKey(endpoint)); if (data != null && data.length > 0) { Registration r = deserializeReg(data); if (!r.isAlive(gracePeriod)) { diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbLwM2mRedisSecurityStore.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbLwM2mRedisSecurityStore.java index b07156d0ef..1e5d480c81 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbLwM2mRedisSecurityStore.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbLwM2mRedisSecurityStore.java @@ -52,7 +52,7 @@ public class TbLwM2mRedisSecurityStore implements TbEditableSecurityStore { try (var connection = connectionFactory.getConnection()) { lock = redisLock.obtain(toLockKey(endpoint)); lock.lock(); - byte[] data = connection.get((SEC_EP + endpoint).getBytes()); + byte[] data = connection.stringCommands().get((SEC_EP + endpoint).getBytes()); if (data == null || data.length == 0) { return null; } else { @@ -96,11 +96,11 @@ public class TbLwM2mRedisSecurityStore implements TbEditableSecurityStore { try (var connection = connectionFactory.getConnection()) { lock = redisLock.obtain(toLockKey(identity)); lock.lock(); - byte[] ep = connection.hGet(PSKID_SEC.getBytes(), identity.getBytes()); + byte[] ep = connection.hashCommands().hGet(PSKID_SEC.getBytes(), identity.getBytes()); if (ep == null) { return null; } else { - byte[] data = connection.get((SEC_EP + new String(ep)).getBytes()); + byte[] data = connection.stringCommands().get((SEC_EP + new String(ep)).getBytes()); if (data == null || data.length == 0) { return null; } else { @@ -128,17 +128,17 @@ public class TbLwM2mRedisSecurityStore implements TbEditableSecurityStore { lock = redisLock.obtain(tbSecurityInfo.getEndpoint()); lock.lock(); if (info != null && info.getPskIdentity() != null) { - byte[] oldEndpointBytes = connection.hGet(PSKID_SEC.getBytes(), info.getPskIdentity().getBytes()); + byte[] oldEndpointBytes = connection.hashCommands().hGet(PSKID_SEC.getBytes(), info.getPskIdentity().getBytes()); if (oldEndpointBytes != null) { String oldEndpoint = new String(oldEndpointBytes); if (!oldEndpoint.equals(info.getEndpoint())) { throw new NonUniqueSecurityInfoException("PSK Identity " + info.getPskIdentity() + " is already used"); } - connection.hSet(PSKID_SEC.getBytes(), info.getPskIdentity().getBytes(), info.getEndpoint().getBytes()); + connection.hashCommands().hSet(PSKID_SEC.getBytes(), info.getPskIdentity().getBytes(), info.getEndpoint().getBytes()); } } - byte[] previousData = connection.getSet((SEC_EP + tbSecurityInfo.getEndpoint()).getBytes(), tbSecurityInfoSerialized); + byte[] previousData = connection.stringCommands().getSet((SEC_EP + tbSecurityInfo.getEndpoint()).getBytes(), tbSecurityInfoSerialized); // for tests: redis connect NoSec (securityInfo == null) log.info("lwm2m redis connect. Endpoint: [{}], secMode: [{}] key: [{}], tbSecurityInfoSerialized [{}]", @@ -147,7 +147,7 @@ public class TbLwM2mRedisSecurityStore implements TbEditableSecurityStore { if (previousData != null && info != null) { String previousIdentity = ((TbLwM2MSecurityInfo) JavaSerDesUtil.decode(previousData)).getSecurityInfo().getPskIdentity(); if (previousIdentity != null && !previousIdentity.equals(info.getPskIdentity())) { - connection.hDel(PSKID_SEC.getBytes(), previousIdentity.getBytes()); + connection.hashCommands().hDel(PSKID_SEC.getBytes(), previousIdentity.getBytes()); } } } finally { @@ -163,7 +163,7 @@ public class TbLwM2mRedisSecurityStore implements TbEditableSecurityStore { try (var connection = connectionFactory.getConnection()) { lock = redisLock.obtain(endpoint); lock.lock(); - byte[] data = connection.get((SEC_EP + endpoint).getBytes()); + byte[] data = connection.stringCommands().get((SEC_EP + endpoint).getBytes()); if (data != null && data.length > 0) { return JavaSerDesUtil.decode(data); } else { @@ -182,13 +182,13 @@ public class TbLwM2mRedisSecurityStore implements TbEditableSecurityStore { try (var connection = connectionFactory.getConnection()) { lock = redisLock.obtain(endpoint); lock.lock(); - byte[] data = connection.get((SEC_EP + endpoint).getBytes()); + byte[] data = connection.stringCommands().get((SEC_EP + endpoint).getBytes()); if (data != null && data.length > 0) { SecurityInfo info = ((TbLwM2MSecurityInfo) JavaSerDesUtil.decode(data)).getSecurityInfo(); if (info != null && info.getPskIdentity() != null) { - connection.hDel(PSKID_SEC.getBytes(), info.getPskIdentity().getBytes()); + connection.hashCommands().hDel(PSKID_SEC.getBytes(), info.getPskIdentity().getBytes()); } - connection.del((SEC_EP + endpoint).getBytes()); + connection.keyCommands().del((SEC_EP + endpoint).getBytes()); } } finally { if (lock != null) { @@ -203,7 +203,7 @@ public class TbLwM2mRedisSecurityStore implements TbEditableSecurityStore { private SecurityMode getSecurityModeByRegistration (RedisConnection connection, String endpoint) { try { - byte[] data = connection.get((REG_EP + endpoint).getBytes()); + byte[] data = connection.stringCommands().get((REG_EP + endpoint).getBytes()); JsonNode registrationNode = JacksonUtil.fromString(new String(data != null ? data : new byte[0]), JsonNode.class); String typeModeStr = registrationNode.get("transportdata").get("identity").get("type").asText(); return "unsecure".equals(typeModeStr) ? SecurityMode.NO_SEC : null; diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbRedisLwM2MClientStore.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbRedisLwM2MClientStore.java index 4beefb4896..73d4bd95da 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbRedisLwM2MClientStore.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbRedisLwM2MClientStore.java @@ -45,7 +45,7 @@ public class TbRedisLwM2MClientStore implements TbLwM2MClientStore { @Override public LwM2mClient get(String endpoint) { try (var connection = connectionFactory.getConnection()) { - byte[] data = connection.get(getKey(endpoint)); + byte[] data = connection.stringCommands().get(getKey(endpoint)); if (data == null) { return null; } else { @@ -70,12 +70,12 @@ public class TbRedisLwM2MClientStore implements TbLwM2MClientStore { clusterConnection.clusterGetNodes().forEach(node -> scans.add(clusterConnection.scan(node, scanOptions))); } else { - scans.add(scanConnection.scan(scanOptions)); + scans.add(scanConnection.keyCommands().scan(scanOptions)); } scans.forEach(scan -> { scan.forEachRemaining(key -> { - byte[] element = getConnection.get(key); + byte[] element = getConnection.stringCommands().get(key); if (element != null) { try { clients.add(deserialize(element)); @@ -97,7 +97,7 @@ public class TbRedisLwM2MClientStore implements TbLwM2MClientStore { try { byte[] clientSerialized = serialize(client); try (var connection = connectionFactory.getConnection()) { - connection.getSet(getKey(client.getEndpoint()), clientSerialized); + connection.stringCommands().getSet(getKey(client.getEndpoint()), clientSerialized); } } catch (Exception e) { log.warn("Failed to serialize client: {}", client, e); @@ -108,7 +108,7 @@ public class TbRedisLwM2MClientStore implements TbLwM2MClientStore { @Override public void remove(String endpoint) { try (var connection = connectionFactory.getConnection()) { - connection.del(getKey(endpoint)); + connection.keyCommands().del(getKey(endpoint)); } } diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbRedisLwM2MModelConfigStore.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbRedisLwM2MModelConfigStore.java index 31a78234d0..65ed90d15d 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbRedisLwM2MModelConfigStore.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbRedisLwM2MModelConfigStore.java @@ -44,12 +44,12 @@ public class TbRedisLwM2MModelConfigStore implements TbLwM2MModelConfigStore { clusterConnection.clusterGetNodes().forEach(node -> scans.add(clusterConnection.scan(node, scanOptions))); } else { - scans.add(scanConnection.scan(scanOptions)); + scans.add(scanConnection.keyCommands().scan(scanOptions)); } scans.forEach(scan -> { scan.forEachRemaining(key -> { - byte[] element = getConnection.get(key); + byte[] element = getConnection.stringCommands().get(key); if (element != null) { configs.add(JacksonUtil.fromBytes(element, LwM2MModelConfig.class)); } @@ -63,14 +63,14 @@ public class TbRedisLwM2MModelConfigStore implements TbLwM2MModelConfigStore { public void put(LwM2MModelConfig modelConfig) { byte[] clientSerialized = JacksonUtil.writeValueAsBytes(modelConfig); try (var connection = connectionFactory.getConnection()) { - connection.getSet(getKey(modelConfig.getEndpoint()), clientSerialized); + connection.stringCommands().getSet(getKey(modelConfig.getEndpoint()), clientSerialized); } } @Override public void remove(String endpoint) { try (var connection = connectionFactory.getConnection()) { - connection.del(getKey(endpoint)); + connection.keyCommands().del(getKey(endpoint)); } } diff --git a/common/transport/lwm2m/src/test/java/org/thingsboard/server/transport/lwm2m/server/store/TbRedisLwM2MClientStoreTest.java b/common/transport/lwm2m/src/test/java/org/thingsboard/server/transport/lwm2m/server/store/TbRedisLwM2MClientStoreTest.java index 9fe29c1188..fe8d66365f 100644 --- a/common/transport/lwm2m/src/test/java/org/thingsboard/server/transport/lwm2m/server/store/TbRedisLwM2MClientStoreTest.java +++ b/common/transport/lwm2m/src/test/java/org/thingsboard/server/transport/lwm2m/server/store/TbRedisLwM2MClientStoreTest.java @@ -18,6 +18,7 @@ package org.thingsboard.server.transport.lwm2m.server.store; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Answers; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.data.redis.connection.RedisConnection; @@ -51,10 +52,10 @@ class TbRedisLwM2MClientStoreTest { @Mock RedisConnectionFactory connectionFactory; - @Mock + @Mock(answer = Answers.RETURNS_DEEP_STUBS) RedisConnection scanConnection; - @Mock + @Mock(answer = Answers.RETURNS_DEEP_STUBS) RedisConnection getConnection; TbRedisLwM2MClientStore store; @@ -77,8 +78,8 @@ class TbRedisLwM2MClientStoreTest { // Cursor created before thenReturn to avoid Mockito unfinished-stubbing error Cursor cursor = cursorOf(key); - when(scanConnection.scan(any(ScanOptions.class))).thenReturn(cursor); - when(getConnection.get(key)).thenReturn(value); + when(scanConnection.keyCommands().scan(any(ScanOptions.class))).thenReturn(cursor); + when(getConnection.stringCommands().get(key)).thenReturn(value); Set result = store.getAll(); @@ -89,29 +90,29 @@ class TbRedisLwM2MClientStoreTest { @Test void getAll_getIsNeverCalledOnScanConnection() { Cursor cursor = cursorOf(); - when(scanConnection.scan(any(ScanOptions.class))).thenReturn(cursor); + when(scanConnection.keyCommands().scan(any(ScanOptions.class))).thenReturn(cursor); store.getAll(); - verify(scanConnection, never()).get(any(byte[].class)); + verify(scanConnection.stringCommands(), never()).get(any(byte[].class)); } @Test void getAll_scanIsNeverCalledOnGetConnection() { Cursor cursor = cursorOf(); - when(scanConnection.scan(any(ScanOptions.class))).thenReturn(cursor); + when(scanConnection.keyCommands().scan(any(ScanOptions.class))).thenReturn(cursor); store.getAll(); - verify(getConnection, never()).scan(any(ScanOptions.class)); + verify(getConnection.keyCommands(), never()).scan(any(ScanOptions.class)); } @Test void getAll_skipsKeyWhenValueIsNull() { byte[] key = "CLIENT#EP#gone".getBytes(); Cursor cursor = cursorOf(key); - when(scanConnection.scan(any(ScanOptions.class))).thenReturn(cursor); - // getConnection.get(key) returns null by default — no stubbing needed + when(scanConnection.keyCommands().scan(any(ScanOptions.class))).thenReturn(cursor); + // getConnection.stringCommands().get(key) returns null by default — no stubbing needed Set result = store.getAll(); From 0340612e091efeea50b63a20528014f516296174 Mon Sep 17 00:00:00 2001 From: Oleksandra Matviienko Date: Fri, 24 Apr 2026 15:00:26 +0200 Subject: [PATCH 20/91] chore(hygiene): replaced 24 deprecated commons-lang3 API calls on lts-4.2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - RandomStringUtils.randomAlphanumeric/Alphabetic/Numeric/random → secure().nextX (10) - RandomUtils.nextInt/nextBytes → secure().randomX (3) - NumberUtils.isNumber → isCreatable (2) - StringUtils.equals → Objects.equals where both args are String (3) - StringUtils.removeStart → common.data.StringUtils.removeStart wrapper (6) --- .../install/DefaultSystemDataLoaderService.java | 2 +- .../auth/mfa/provider/impl/TotpTwoFaProvider.java | 2 +- .../server/service/ws/WebSocketSessionType.java | 4 ++-- .../server/controller/AbstractWebTest.java | 2 +- .../notification/AbstractNotificationApiTest.java | 2 +- .../notification/NotificationApiWsClient.java | 2 +- .../thingsboard/server/common/data/EntityType.java | 4 +++- .../thingsboard/server/common/data/StringUtils.java | 13 +++++++------ .../server/common/data/util/TemplateUtils.java | 2 +- .../server/common/data/util/TypeCastUtil.java | 2 +- .../server/service/sync/vc/GitRepository.java | 5 +++-- .../server/dao/resource/BaseImageService.java | 2 +- .../server/dao/resource/BaseResourceService.java | 8 +++++--- .../org/thingsboard/monitoring/client/WsClient.java | 2 +- .../monitoring/service/MonitoringEntityService.java | 2 +- .../client/tools/migrator/PgCaMigrator.java | 2 +- 16 files changed, 31 insertions(+), 25 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/service/install/DefaultSystemDataLoaderService.java b/application/src/main/java/org/thingsboard/server/service/install/DefaultSystemDataLoaderService.java index 4864f53e17..9b921699f9 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/DefaultSystemDataLoaderService.java +++ b/application/src/main/java/org/thingsboard/server/service/install/DefaultSystemDataLoaderService.java @@ -330,7 +330,7 @@ public class DefaultSystemDataLoaderService implements SystemDataLoaderService { private String generateRandomKey() { return Base64.getEncoder().encodeToString( - RandomStringUtils.randomAlphanumeric(64).getBytes(StandardCharsets.UTF_8)); + RandomStringUtils.secure().nextAlphanumeric(64).getBytes(StandardCharsets.UTF_8)); } @Override diff --git a/application/src/main/java/org/thingsboard/server/service/security/auth/mfa/provider/impl/TotpTwoFaProvider.java b/application/src/main/java/org/thingsboard/server/service/security/auth/mfa/provider/impl/TotpTwoFaProvider.java index 23eda67a77..a7fbdb84e4 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/auth/mfa/provider/impl/TotpTwoFaProvider.java +++ b/application/src/main/java/org/thingsboard/server/service/security/auth/mfa/provider/impl/TotpTwoFaProvider.java @@ -62,7 +62,7 @@ public class TotpTwoFaProvider implements TwoFaProvider forName(String name) { return Arrays.stream(values()) - .filter(sessionType -> StringUtils.equals(sessionType.name, name)) + .filter(sessionType -> Objects.equals(sessionType.name, name)) .findFirst(); } diff --git a/application/src/test/java/org/thingsboard/server/controller/AbstractWebTest.java b/application/src/test/java/org/thingsboard/server/controller/AbstractWebTest.java index bbf3a3467e..4f8ed55731 100644 --- a/application/src/test/java/org/thingsboard/server/controller/AbstractWebTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/AbstractWebTest.java @@ -1223,7 +1223,7 @@ public abstract class AbstractWebTest extends AbstractInMemoryStorageTest { protected NotificationTarget createNotificationTarget(UsersFilter usersFilter) { NotificationTarget notificationTarget = new NotificationTarget(); - notificationTarget.setName(usersFilter.toString() + RandomStringUtils.randomNumeric(5)); + notificationTarget.setName(usersFilter.toString() + RandomStringUtils.secure().nextNumeric(5)); PlatformUsersNotificationTargetConfig targetConfig = new PlatformUsersNotificationTargetConfig(); targetConfig.setUsersFilter(usersFilter); notificationTarget.setConfiguration(targetConfig); diff --git a/application/src/test/java/org/thingsboard/server/service/notification/AbstractNotificationApiTest.java b/application/src/test/java/org/thingsboard/server/service/notification/AbstractNotificationApiTest.java index f5607415fa..65a7e2b4fa 100644 --- a/application/src/test/java/org/thingsboard/server/service/notification/AbstractNotificationApiTest.java +++ b/application/src/test/java/org/thingsboard/server/service/notification/AbstractNotificationApiTest.java @@ -155,7 +155,7 @@ public abstract class AbstractNotificationApiTest extends AbstractControllerTest User user = new User(); user.setTenantId(tenantId); user.setAuthority(authority); - user.setEmail(RandomStringUtils.randomAlphabetic(20) + "@thingsboard.com"); + user.setEmail(RandomStringUtils.secure().nextAlphabetic(20) + "@thingsboard.com"); user = createUserAndLogin(user, "12345678"); NotificationApiWsClient wsClient = buildAndConnectWebSocketClient(); return Pair.of(user, wsClient); diff --git a/application/src/test/java/org/thingsboard/server/service/notification/NotificationApiWsClient.java b/application/src/test/java/org/thingsboard/server/service/notification/NotificationApiWsClient.java index b538972dd7..f6d94f5170 100644 --- a/application/src/test/java/org/thingsboard/server/service/notification/NotificationApiWsClient.java +++ b/application/src/test/java/org/thingsboard/server/service/notification/NotificationApiWsClient.java @@ -131,7 +131,7 @@ public class NotificationApiWsClient extends TbTestWebSocketClient { } private int newCmdId() { - return RandomUtils.nextInt(1, 1000); + return RandomUtils.secure().randomInt(1, 1000); } } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/EntityType.java b/common/data/src/main/java/org/thingsboard/server/common/data/EntityType.java index a95208e457..7eef085340 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/EntityType.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/EntityType.java @@ -22,6 +22,8 @@ import java.util.Arrays; import java.util.EnumSet; import java.util.List; +import static org.thingsboard.server.common.data.StringUtils.removeStart; + public enum EntityType { TENANT(1), CUSTOMER(2), @@ -76,7 +78,7 @@ public enum EntityType { @Getter private final String tableName; @Getter - private final String normalName = StringUtils.capitalize(StringUtils.removeStart(name(), "TB_") + private final String normalName = StringUtils.capitalize(removeStart(name(), "TB_") .toLowerCase().replaceAll("_", " ")); public static final List NORMAL_NAMES = EnumSet.allOf(EntityType.class).stream() diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/StringUtils.java b/common/data/src/main/java/org/thingsboard/server/common/data/StringUtils.java index 37242dfa1d..59977264b6 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/StringUtils.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/StringUtils.java @@ -23,6 +23,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Base64; import java.util.List; +import java.util.Objects; import java.util.function.Function; import static org.apache.commons.lang3.StringUtils.repeat; @@ -155,7 +156,7 @@ public class StringUtils { } public static boolean equals(String str1, String str2) { - return org.apache.commons.lang3.StringUtils.equals(str1, str2); + return Objects.equals(str1, str2); } public static boolean equalsAny(String string, String... otherStrings) { @@ -210,23 +211,23 @@ public class StringUtils { } public static String randomNumeric(int length) { - return RandomStringUtils.randomNumeric(length); + return RandomStringUtils.secure().nextNumeric(length); } public static String random(int length) { - return RandomStringUtils.random(length); + return RandomStringUtils.secure().next(length); } public static String random(int length, String chars) { - return RandomStringUtils.random(length, chars); + return RandomStringUtils.secure().next(length, chars); } public static String randomAlphanumeric(int count) { - return RandomStringUtils.randomAlphanumeric(count); + return RandomStringUtils.secure().nextAlphanumeric(count); } public static String randomAlphabetic(int count) { - return RandomStringUtils.randomAlphabetic(count); + return RandomStringUtils.secure().nextAlphabetic(count); } public static String generateSafeToken(int length) { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/util/TemplateUtils.java b/common/data/src/main/java/org/thingsboard/server/common/data/util/TemplateUtils.java index beaec13748..d740a065ce 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/util/TemplateUtils.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/util/TemplateUtils.java @@ -23,7 +23,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import static com.google.common.base.Strings.nullToEmpty; -import static org.apache.commons.lang3.StringUtils.removeStart; +import static org.thingsboard.server.common.data.StringUtils.removeStart; public class TemplateUtils { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/util/TypeCastUtil.java b/common/data/src/main/java/org/thingsboard/server/common/data/util/TypeCastUtil.java index 78ff4b0eba..887cedefa4 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/util/TypeCastUtil.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/util/TypeCastUtil.java @@ -63,7 +63,7 @@ public class TypeCastUtil { } private static boolean isNumber(String value) { - return NumberUtils.isNumber(value.replace(',', '.')); + return NumberUtils.isCreatable(value.replace(',', '.')); } private static boolean isSimpleDouble(String valueAsString) { diff --git a/common/version-control/src/main/java/org/thingsboard/server/service/sync/vc/GitRepository.java b/common/version-control/src/main/java/org/thingsboard/server/service/sync/vc/GitRepository.java index 3602dd55ca..15dd615111 100644 --- a/common/version-control/src/main/java/org/thingsboard/server/service/sync/vc/GitRepository.java +++ b/common/version-control/src/main/java/org/thingsboard/server/service/sync/vc/GitRepository.java @@ -99,6 +99,7 @@ import static org.eclipse.jgit.transport.RemoteRefUpdate.Status.REJECTED_NODELET import static org.eclipse.jgit.transport.RemoteRefUpdate.Status.REJECTED_NONFASTFORWARD; import static org.eclipse.jgit.transport.RemoteRefUpdate.Status.REJECTED_OTHER_REASON; import static org.eclipse.jgit.transport.RemoteRefUpdate.Status.REJECTED_REMOTE_CHANGED; +import static org.thingsboard.server.common.data.StringUtils.removeStart; @Slf4j public class GitRepository { @@ -448,7 +449,7 @@ public class GitRepository { private BranchInfo toBranchInfo(Ref ref) { String name = org.eclipse.jgit.lib.Repository.shortenRefName(ref.getName()); - String branchName = StringUtils.removeStart(name, "origin/"); + String branchName = removeStart(name, "origin/"); boolean isDefault = this.headId != null && this.headId.equals(ref.getObjectId()); return new BranchInfo(branchName, isDefault); } @@ -465,7 +466,7 @@ public class GitRepository { private ObjectId resolve(String rev) throws IOException { if (settings.isLocalOnly()) { - rev = StringUtils.removeStart(rev, "origin/"); + rev = removeStart(rev, "origin/"); } ObjectId result = git.getRepository().resolve(rev); if (result == null) { diff --git a/dao/src/main/java/org/thingsboard/server/dao/resource/BaseImageService.java b/dao/src/main/java/org/thingsboard/server/dao/resource/BaseImageService.java index 11bbe797cf..18023f653c 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/resource/BaseImageService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/resource/BaseImageService.java @@ -173,7 +173,7 @@ public class BaseImageService extends BaseResourceService implements ImageServic } private String generatePublicResourceKey() { - return RandomStringUtils.randomAlphanumeric(32); + return RandomStringUtils.secure().nextAlphanumeric(32); } @Override diff --git a/dao/src/main/java/org/thingsboard/server/dao/resource/BaseResourceService.java b/dao/src/main/java/org/thingsboard/server/dao/resource/BaseResourceService.java index 40b5a9778b..9af324e7ec 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/resource/BaseResourceService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/resource/BaseResourceService.java @@ -74,6 +74,7 @@ import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Optional; import java.util.Set; import java.util.UUID; @@ -82,6 +83,7 @@ import java.util.function.UnaryOperator; import static com.google.common.util.concurrent.MoreExecutors.directExecutor; import static org.thingsboard.server.common.data.StringUtils.isNotEmpty; +import static org.thingsboard.server.common.data.StringUtils.removeStart; import static org.thingsboard.server.dao.device.DeviceServiceImpl.INCORRECT_TENANT_ID; import static org.thingsboard.server.dao.service.Validator.validateId; @@ -588,7 +590,7 @@ public class BaseResourceService extends AbstractCachedEntityService devices, List keys) { EntityDataCmd cmd = new EntityDataCmd(); - cmd.setCmdId(RandomUtils.nextInt(0, 1000)); + cmd.setCmdId(RandomUtils.secure().randomInt(0, 1000)); EntityListFilter devicesFilter = new EntityListFilter(); devicesFilter.setEntityType(EntityType.DEVICE); diff --git a/monitoring/src/main/java/org/thingsboard/monitoring/service/MonitoringEntityService.java b/monitoring/src/main/java/org/thingsboard/monitoring/service/MonitoringEntityService.java index 57fd7d280d..d85c0d3cc0 100644 --- a/monitoring/src/main/java/org/thingsboard/monitoring/service/MonitoringEntityService.java +++ b/monitoring/src/main/java/org/thingsboard/monitoring/service/MonitoringEntityService.java @@ -162,7 +162,7 @@ public class MonitoringEntityService { device.setName(deviceName); DeviceCredentials credentials = new DeviceCredentials(); - credentials.setCredentialsId(RandomStringUtils.randomAlphabetic(20)); + credentials.setCredentialsId(RandomStringUtils.secure().nextAlphabetic(20)); DeviceData deviceData = new DeviceData(); deviceData.setConfiguration(new DefaultDeviceConfiguration()); diff --git a/tools/src/main/java/org/thingsboard/client/tools/migrator/PgCaMigrator.java b/tools/src/main/java/org/thingsboard/client/tools/migrator/PgCaMigrator.java index b88012c00e..2ef202dc9f 100644 --- a/tools/src/main/java/org/thingsboard/client/tools/migrator/PgCaMigrator.java +++ b/tools/src/main/java/org/thingsboard/client/tools/migrator/PgCaMigrator.java @@ -249,7 +249,7 @@ public class PgCaMigrator { private List castToNumericIfPossible(List values) { try { - if (values.get(6) != null && NumberUtils.isNumber(values.get(6).toString())) { + if (values.get(6) != null && NumberUtils.isCreatable(values.get(6).toString())) { Double casted = NumberUtils.createDouble(values.get(6).toString()); List numeric = Lists.newArrayList(); numeric.addAll(values); From 6d125f57e92f86a9fd6285617b924873e004d92d Mon Sep 17 00:00:00 2001 From: Oleksandra Matviienko Date: Fri, 24 Apr 2026 23:18:47 +0200 Subject: [PATCH 21/91] Replaced 23 deprecated TenantId(UUID) constructor calls with TenantId.fromUUID on lts-4.2 --- .../transport/mqtt/session/GatewaySessionHandlerTest.java | 2 +- .../dao/sql/cf/DefaultNativeCalculatedFieldRepository.java | 2 +- .../thingsboard/server/dao/sql/event/JpaBaseEventDaoTest.java | 2 +- .../rule/engine/action/TbAssignToCustomerNodeTest.java | 2 +- .../rule/engine/action/TbCreateRelationNodeTest.java | 2 +- .../rule/engine/action/TbDeleteRelationNodeTest.java | 2 +- .../rule/engine/action/TbUnassignFromCustomerNodeTest.java | 2 +- .../rule/engine/filter/TbAssetTypeSwitchNodeTest.java | 2 +- .../rule/engine/filter/TbCheckAlarmStatusNodeTest.java | 2 +- .../rule/engine/filter/TbCheckRelationNodeTest.java | 2 +- .../rule/engine/filter/TbDeviceTypeSwitchNodeTest.java | 2 +- .../rule/engine/flow/TbRuleChainInputNodeTest.java | 2 +- .../rule/engine/metadata/TbGetCustomerDetailsNodeTest.java | 2 +- .../rule/engine/metadata/TbGetDeviceAttrNodeTest.java | 2 +- .../rule/engine/metadata/TbGetOriginatorFieldsNodeTest.java | 2 +- .../rule/engine/metadata/TbGetRelatedAttributeNodeTest.java | 4 ++-- .../rule/engine/metadata/TbGetTenantAttributeNodeTest.java | 2 +- .../rule/engine/metadata/TbGetTenantDetailsNodeTest.java | 2 +- .../rule/engine/util/EntitiesFieldsAsyncLoaderTest.java | 4 ++-- .../engine/util/EntitiesRelatedDeviceIdAsyncLoaderTest.java | 2 +- .../engine/util/EntitiesRelatedEntityIdAsyncLoaderTest.java | 2 +- 21 files changed, 23 insertions(+), 23 deletions(-) diff --git a/common/transport/mqtt/src/test/java/org/thingsboard/server/transport/mqtt/session/GatewaySessionHandlerTest.java b/common/transport/mqtt/src/test/java/org/thingsboard/server/transport/mqtt/session/GatewaySessionHandlerTest.java index 6b4e5e9925..30dc825a9b 100644 --- a/common/transport/mqtt/src/test/java/org/thingsboard/server/transport/mqtt/session/GatewaySessionHandlerTest.java +++ b/common/transport/mqtt/src/test/java/org/thingsboard/server/transport/mqtt/session/GatewaySessionHandlerTest.java @@ -75,7 +75,7 @@ public class GatewaySessionHandlerTest { ConcurrentHashMap devices = new ConcurrentHashMap<>(); TransportDeviceInfo deviceInfo = new TransportDeviceInfo(); deviceInfo.setDeviceId(new DeviceId(UUID.randomUUID())); - deviceInfo.setTenantId(new TenantId(UUID.randomUUID())); + deviceInfo.setTenantId(TenantId.fromUUID(UUID.randomUUID())); deviceInfo.setCustomerId(new CustomerId(UUID.randomUUID())); deviceInfo.setDeviceName("device1"); deviceInfo.setDeviceType("default"); 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 9734af7d7a..4cce4c5041 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 @@ -126,7 +126,7 @@ public class DefaultNativeCalculatedFieldRepository implements NativeCalculatedF CalculatedFieldLink calculatedFieldLink = new CalculatedFieldLink(); calculatedFieldLink.setId(new CalculatedFieldLinkId(id)); calculatedFieldLink.setCreatedTime(createdTime); - calculatedFieldLink.setTenantId(new TenantId(tenantId)); + calculatedFieldLink.setTenantId(TenantId.fromUUID(tenantId)); calculatedFieldLink.setEntityId(EntityIdFactory.getByTypeAndUuid(entityType, entityId)); calculatedFieldLink.setCalculatedFieldId(new CalculatedFieldId(calculatedFieldId)); diff --git a/dao/src/test/java/org/thingsboard/server/dao/sql/event/JpaBaseEventDaoTest.java b/dao/src/test/java/org/thingsboard/server/dao/sql/event/JpaBaseEventDaoTest.java index 3ddf318e2f..e03b161692 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/sql/event/JpaBaseEventDaoTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/sql/event/JpaBaseEventDaoTest.java @@ -132,7 +132,7 @@ public class JpaBaseEventDaoTest extends AbstractJpaDaoTest { StatisticsEvent.StatisticsEventBuilder event = StatisticsEvent.builder(); event.id(eventId); event.ts(System.currentTimeMillis()); - event.tenantId(new TenantId(tenantId)); + event.tenantId(TenantId.fromUUID(tenantId)); event.entityId(entityId); event.serviceId("server A"); event.messagesProcessed(1); diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/action/TbAssignToCustomerNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/action/TbAssignToCustomerNodeTest.java index 0db2d77c01..7f329b1411 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/action/TbAssignToCustomerNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/action/TbAssignToCustomerNodeTest.java @@ -97,7 +97,7 @@ class TbAssignToCustomerNodeTest extends AbstractRuleNodeUpgradeTest { private final Edge EDGE = new Edge(); private final Dashboard DASHBOARD = new Dashboard(); - private final TenantId TENANT_ID = new TenantId(UUID.fromString("c818385f-e661-407f-8c52-daf2dddf406d")); + private final TenantId TENANT_ID = TenantId.fromUUID(UUID.fromString("c818385f-e661-407f-8c52-daf2dddf406d")); private final RuleNodeId RULE_NODE_ID = new RuleNodeId(UUID.fromString("c3570bd0-c0bc-4609-97a4-6f57d7c8b809")); private static Stream givenUnsupportedOriginatorType_whenOnMsg_thenVerifyExceptionThrown() { diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/action/TbCreateRelationNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/action/TbCreateRelationNodeTest.java index 60924002da..50c54b91de 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/action/TbCreateRelationNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/action/TbCreateRelationNodeTest.java @@ -111,7 +111,7 @@ public class TbCreateRelationNodeTest extends AbstractRuleNodeUpgradeTest { return supportedEntityTypes.stream().filter(entityType -> !entityType.equals(EntityType.TENANT)).map(Arguments::of); } - private static final TenantId tenantId = new TenantId(UUID.fromString("6fc86fc9-b25c-4893-b340-51cf4e101ab2")); + private static final TenantId tenantId = TenantId.fromUUID(UUID.fromString("6fc86fc9-b25c-4893-b340-51cf4e101ab2")); private static final DeviceId deviceId = new DeviceId(UUID.fromString("191ab124-1d8d-4749-97c6-fc84c113c1f5")); private static final AssetId assetId = new AssetId(UUID.fromString("a47a5867-deab-4333-b845-88cb1695990c")); private static final CustomerId customerId = new CustomerId(UUID.fromString("4af69229-273d-40de-9fba-f49f87373d23")); diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/action/TbDeleteRelationNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/action/TbDeleteRelationNodeTest.java index a8087cc40b..f6ef490aba 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/action/TbDeleteRelationNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/action/TbDeleteRelationNodeTest.java @@ -108,7 +108,7 @@ public class TbDeleteRelationNodeTest extends AbstractRuleNodeUpgradeTest { return supportedEntityTypes.stream().filter(entityType -> !entityType.equals(EntityType.TENANT)).map(Arguments::of); } - private static final TenantId tenantId = new TenantId(UUID.fromString("6fdb457d-0910-401c-8880-abc251e6a1e2")); + private static final TenantId tenantId = TenantId.fromUUID(UUID.fromString("6fdb457d-0910-401c-8880-abc251e6a1e2")); private static final DeviceId deviceId = new DeviceId(UUID.fromString("4eef91a7-8865-4c3c-837d-ed6f6577508b")); private static final AssetId assetId = new AssetId(UUID.fromString("f4fd3b10-3f36-4d46-a162-5e62050774cc")); private static final CustomerId customerId = new CustomerId(UUID.fromString("ab890af2-3622-41e0-ac94-14d50af84348")); diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/action/TbUnassignFromCustomerNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/action/TbUnassignFromCustomerNodeTest.java index de891c13d4..dd1307b10a 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/action/TbUnassignFromCustomerNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/action/TbUnassignFromCustomerNodeTest.java @@ -98,7 +98,7 @@ class TbUnassignFromCustomerNodeTest extends AbstractRuleNodeUpgradeTest { private final Edge EDGE = new Edge(); private final Dashboard DASHBOARD = new Dashboard(); - private final TenantId TENANT_ID = new TenantId(UUID.fromString("06fcc15f-2677-436d-a1cb-7754bd0bcccf")); + private final TenantId TENANT_ID = TenantId.fromUUID(UUID.fromString("06fcc15f-2677-436d-a1cb-7754bd0bcccf")); private final ListeningExecutor DB_EXECUTOR = DirectListeningExecutor.INSTANCE; diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/filter/TbAssetTypeSwitchNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/filter/TbAssetTypeSwitchNodeTest.java index 557fb5b71d..b0788a1817 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/filter/TbAssetTypeSwitchNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/filter/TbAssetTypeSwitchNodeTest.java @@ -58,7 +58,7 @@ class TbAssetTypeSwitchNodeTest { @BeforeEach void setUp() throws TbNodeException { - TenantId tenantId = new TenantId(UUID.randomUUID()); + TenantId tenantId = TenantId.fromUUID(UUID.randomUUID()); assetId = new AssetId(UUID.randomUUID()); assetIdDeleted = new AssetId(UUID.randomUUID()); diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/filter/TbCheckAlarmStatusNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/filter/TbCheckAlarmStatusNodeTest.java index d8a302ae92..9155221a26 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/filter/TbCheckAlarmStatusNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/filter/TbCheckAlarmStatusNodeTest.java @@ -50,7 +50,7 @@ import static org.mockito.Mockito.when; class TbCheckAlarmStatusNodeTest { - private static final TenantId TENANT_ID = new TenantId(UUID.randomUUID()); + private static final TenantId TENANT_ID = TenantId.fromUUID(UUID.randomUUID()); private static final DeviceId DEVICE_ID = new DeviceId(UUID.randomUUID()); private static final AlarmId ALARM_ID = new AlarmId(UUID.randomUUID()); private static final DirectListeningExecutor DB_EXECUTOR = DirectListeningExecutor.INSTANCE; diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/filter/TbCheckRelationNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/filter/TbCheckRelationNodeTest.java index e6011c74d8..fb8ad655c0 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/filter/TbCheckRelationNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/filter/TbCheckRelationNodeTest.java @@ -63,7 +63,7 @@ import static org.mockito.Mockito.when; class TbCheckRelationNodeTest extends AbstractRuleNodeUpgradeTest { - private final TenantId TENANT_ID = new TenantId(UUID.randomUUID()); + private final TenantId TENANT_ID = TenantId.fromUUID(UUID.randomUUID()); private final DeviceId ORIGINATOR_ID = new DeviceId(UUID.randomUUID()); private final DirectListeningExecutor DB_EXECUTOR = DirectListeningExecutor.INSTANCE; private final TbMsg EMPTY_POST_ATTRIBUTES_MSG = TbMsg.newMsg() diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/filter/TbDeviceTypeSwitchNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/filter/TbDeviceTypeSwitchNodeTest.java index 55e9c33b7e..ebbdbe14c7 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/filter/TbDeviceTypeSwitchNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/filter/TbDeviceTypeSwitchNodeTest.java @@ -58,7 +58,7 @@ class TbDeviceTypeSwitchNodeTest { @BeforeEach void setUp() throws TbNodeException { - TenantId tenantId = new TenantId(UUID.randomUUID()); + TenantId tenantId = TenantId.fromUUID(UUID.randomUUID()); deviceId = new DeviceId(UUID.randomUUID()); deviceIdDeleted = new DeviceId(UUID.randomUUID()); diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/flow/TbRuleChainInputNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/flow/TbRuleChainInputNodeTest.java index 3ae26e6560..963e25f6b6 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/flow/TbRuleChainInputNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/flow/TbRuleChainInputNodeTest.java @@ -64,7 +64,7 @@ import static org.mockito.Mockito.when; @ExtendWith(MockitoExtension.class) public class TbRuleChainInputNodeTest extends AbstractRuleNodeUpgradeTest { - private final TenantId TENANT_ID = new TenantId(UUID.fromString("4ba69ea5-6b27-42df-ab66-e7a727a67027")); + private final TenantId TENANT_ID = TenantId.fromUUID(UUID.fromString("4ba69ea5-6b27-42df-ab66-e7a727a67027")); private final DeviceId DEVICE_ID = new DeviceId(UUID.fromString("97731954-2147-4176-8f1a-d14f1b73e4e6")); private final AssetId ASSET_ID = new AssetId(UUID.fromString("841a47bd-4e8e-4ea5-88e6-420da0d70e51")); // A stable "current" rule chain ID: this node lives here. Must differ from any target used in tests. diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetCustomerDetailsNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetCustomerDetailsNodeTest.java index 5e9726ec97..3940ab56c4 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetCustomerDetailsNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetCustomerDetailsNodeTest.java @@ -76,7 +76,7 @@ import static org.mockito.Mockito.when; public class TbGetCustomerDetailsNodeTest { private static final DeviceId DUMMY_DEVICE_ORIGINATOR = new DeviceId(UUID.randomUUID()); - private static final TenantId TENANT_ID = new TenantId(UUID.randomUUID()); + private static final TenantId TENANT_ID = TenantId.fromUUID(UUID.randomUUID()); private static final ListeningExecutor DB_EXECUTOR = DirectListeningExecutor.INSTANCE; @Mock private TbContext ctxMock; diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetDeviceAttrNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetDeviceAttrNodeTest.java index 4f267c0dfb..f9a230a437 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetDeviceAttrNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetDeviceAttrNodeTest.java @@ -60,7 +60,7 @@ import static org.mockito.BDDMockito.then; @ExtendWith(MockitoExtension.class) public class TbGetDeviceAttrNodeTest extends AbstractRuleNodeUpgradeTest { - private final TenantId TENANT_ID = new TenantId(UUID.fromString("5aea576c-66c4-4732-86b8-dc6bfcde7443")); + private final TenantId TENANT_ID = TenantId.fromUUID(UUID.fromString("5aea576c-66c4-4732-86b8-dc6bfcde7443")); private final DeviceId DEVICE_ID = new DeviceId(UUID.fromString("40b6b393-6ddf-47f9-973a-18550ca70384")); private final ListeningExecutor executor = DirectListeningExecutor.INSTANCE; diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetOriginatorFieldsNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetOriginatorFieldsNodeTest.java index fff7437fdf..a0d0a5a957 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetOriginatorFieldsNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetOriginatorFieldsNodeTest.java @@ -59,7 +59,7 @@ import static org.mockito.Mockito.when; public class TbGetOriginatorFieldsNodeTest { private static final DeviceId DUMMY_DEVICE_ORIGINATOR = new DeviceId(UUID.randomUUID()); - private static final TenantId DUMMY_TENANT_ID = new TenantId(UUID.randomUUID()); + private static final TenantId DUMMY_TENANT_ID = TenantId.fromUUID(UUID.randomUUID()); private static final ListeningExecutor DB_EXECUTOR = DirectListeningExecutor.INSTANCE; @Mock private TbContext ctxMock; diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttributeNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttributeNodeTest.java index a31d23db55..88195973e6 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttributeNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttributeNodeTest.java @@ -91,7 +91,7 @@ import static org.mockito.Mockito.when; public class TbGetRelatedAttributeNodeTest { private static final EntityId DUMMY_DEVICE_ORIGINATOR = new DeviceId(UUID.randomUUID()); - private static final TenantId TENANT_ID = new TenantId(UUID.randomUUID()); + private static final TenantId TENANT_ID = TenantId.fromUUID(UUID.randomUUID()); private static final ListeningExecutor DB_EXECUTOR = DirectListeningExecutor.INSTANCE; @Mock private TbContext ctxMock; @@ -427,7 +427,7 @@ public class TbGetRelatedAttributeNodeTest { @Test public void givenFetchTelemetryToMetaData_whenOnMsg_thenShouldFetchTelemetryToMetaData() { // GIVEN - var tenant = new Tenant(new TenantId(UUID.randomUUID())); + var tenant = new Tenant(TenantId.fromUUID(UUID.randomUUID())); var device = new Device(new DeviceId(UUID.randomUUID())); prepareMsgAndConfig(TbMsgSource.METADATA, DataToFetch.LATEST_TELEMETRY, tenant.getId()); diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetTenantAttributeNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetTenantAttributeNodeTest.java index 88db3dc0cd..fa528a724c 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetTenantAttributeNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetTenantAttributeNodeTest.java @@ -70,7 +70,7 @@ import static org.mockito.Mockito.when; public class TbGetTenantAttributeNodeTest { private static final DeviceId DUMMY_DEVICE_ORIGINATOR = new DeviceId(UUID.randomUUID()); - private static final TenantId TENANT_ID = new TenantId(UUID.randomUUID()); + private static final TenantId TENANT_ID = TenantId.fromUUID(UUID.randomUUID()); private static final DirectListeningExecutor DB_EXECUTOR = DirectListeningExecutor.INSTANCE; @Mock private TbContext ctxMock; diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetTenantDetailsNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetTenantDetailsNodeTest.java index b77bd263f8..7f476ea775 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetTenantDetailsNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetTenantDetailsNodeTest.java @@ -73,7 +73,7 @@ public class TbGetTenantDetailsNodeTest { config = new TbGetTenantDetailsNodeConfiguration().defaultConfiguration(); nodeConfiguration = new TbNodeConfiguration(JacksonUtil.valueToTree(config)); tenant = new Tenant(); - tenant.setId(new TenantId(UUID.randomUUID())); + tenant.setId(TenantId.fromUUID(UUID.randomUUID())); tenant.setTitle("Tenant title"); tenant.setCountry("Tenant country"); tenant.setCity("Tenant city"); diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/util/EntitiesFieldsAsyncLoaderTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/util/EntitiesFieldsAsyncLoaderTest.java index d1bcc4559e..75dc8d227a 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/util/EntitiesFieldsAsyncLoaderTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/util/EntitiesFieldsAsyncLoaderTest.java @@ -104,7 +104,7 @@ public class EntitiesFieldsAsyncLoaderTest { @BeforeAll public static void setup() { RANDOM_UUID = UUID.randomUUID(); - TENANT_ID = new TenantId(UUID.randomUUID()); + TENANT_ID = TenantId.fromUUID(UUID.randomUUID()); SUPPORTED_ENTITY_TYPES = EnumSet.of( EntityType.TENANT, EntityType.CUSTOMER, @@ -172,7 +172,7 @@ public class EntitiesFieldsAsyncLoaderTest { private void initMocks(EntityType entityType, boolean entityDoesNotExist) { switch (entityType) { case TENANT: - var tenant = Futures.immediateFuture(entityDoesNotExist ? null : new Tenant(new TenantId(RANDOM_UUID))); + var tenant = Futures.immediateFuture(entityDoesNotExist ? null : new Tenant(TenantId.fromUUID(RANDOM_UUID))); when(ctxMock.getDbCallbackExecutor()).thenReturn(DB_EXECUTOR); when(ctxMock.getTenantService()).thenReturn(tenantServiceMock); diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/util/EntitiesRelatedDeviceIdAsyncLoaderTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/util/EntitiesRelatedDeviceIdAsyncLoaderTest.java index 23e98dfc58..6a840a1ae3 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/util/EntitiesRelatedDeviceIdAsyncLoaderTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/util/EntitiesRelatedDeviceIdAsyncLoaderTest.java @@ -48,7 +48,7 @@ import static org.mockito.Mockito.when; public class EntitiesRelatedDeviceIdAsyncLoaderTest { private static final EntityId DUMMY_ORIGINATOR = new DeviceId(UUID.randomUUID()); - private static final TenantId TENANT_ID = new TenantId(UUID.randomUUID()); + private static final TenantId TENANT_ID = TenantId.fromUUID(UUID.randomUUID()); private static final ListeningExecutor DB_EXECUTOR = DirectListeningExecutor.INSTANCE; @Mock private TbContext ctxMock; diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/util/EntitiesRelatedEntityIdAsyncLoaderTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/util/EntitiesRelatedEntityIdAsyncLoaderTest.java index 1131586a07..edeb72ba59 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/util/EntitiesRelatedEntityIdAsyncLoaderTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/util/EntitiesRelatedEntityIdAsyncLoaderTest.java @@ -55,7 +55,7 @@ import static org.thingsboard.common.util.DonAsynchron.withCallback; public class EntitiesRelatedEntityIdAsyncLoaderTest { private static final EntityId ASSET_ORIGINATOR_ID = new AssetId(UUID.randomUUID()); - private static final TenantId TENANT_ID = new TenantId(UUID.randomUUID()); + private static final TenantId TENANT_ID = TenantId.fromUUID(UUID.randomUUID()); private static final ListeningExecutor DB_EXECUTOR = DirectListeningExecutor.INSTANCE; private TbContext ctxMock; From 8314e1403c1b0b09d844d8243484324f63d9ac1f Mon Sep 17 00:00:00 2001 From: Oleksandra Matviienko Date: Sat, 25 Apr 2026 00:09:18 +0200 Subject: [PATCH 22/91] Migrated 17 deprecated Validator.validateId(UUIDBased, String) calls to the Function-based signature on lts-4.2 Wrapped each literal error message in an id-ignoring lambda so the IncorrectParameterException message stays byte-identical. --- .../server/controller/BaseController.java | 4 +-- .../BaseComponentDescriptorService.java | 2 +- .../server/dao/rule/BaseRuleChainService.java | 28 +++++++++---------- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/controller/BaseController.java b/application/src/main/java/org/thingsboard/server/controller/BaseController.java index de69c239e9..13135aa72f 100644 --- a/application/src/main/java/org/thingsboard/server/controller/BaseController.java +++ b/application/src/main/java/org/thingsboard/server/controller/BaseController.java @@ -657,7 +657,7 @@ public abstract class BaseController { protected & HasTenantId, I extends EntityId> E checkEntityId(I entityId, ThrowingBiFunction findingFunction, Operation operation) throws ThingsboardException { try { - validateId((UUIDBased) entityId, "Invalid entity id"); + validateId((UUIDBased) entityId, id -> "Invalid entity id"); SecurityUser user = getCurrentUser(); E entity = findingFunction.apply(user.getTenantId(), entityId); checkNotNull(entity, entityId.getEntityType().getNormalName() + " with id [" + entityId + "] is not found"); @@ -939,7 +939,7 @@ public abstract class BaseController { } private CalculatedField checkCalculatedFieldId(CalculatedFieldId calculatedFieldId, Operation operation) throws ThingsboardException { - validateId(calculatedFieldId, "Invalid entity id"); + validateId(calculatedFieldId, id -> "Invalid entity id"); SecurityUser user = getCurrentUser(); CalculatedField cf = calculatedFieldService.findById(user.getTenantId(), calculatedFieldId); checkNotNull(cf, calculatedFieldId.getEntityType().getNormalName() + " with id [" + calculatedFieldId + "] is not found"); diff --git a/dao/src/main/java/org/thingsboard/server/dao/component/BaseComponentDescriptorService.java b/dao/src/main/java/org/thingsboard/server/dao/component/BaseComponentDescriptorService.java index ccf145be21..ac9e43270f 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/component/BaseComponentDescriptorService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/component/BaseComponentDescriptorService.java @@ -60,7 +60,7 @@ public class BaseComponentDescriptorService implements ComponentDescriptorServic @Override public ComponentDescriptor findById(TenantId tenantId, ComponentDescriptorId componentId) { - Validator.validateId(componentId, "Incorrect component id for search request."); + Validator.validateId(componentId, id -> "Incorrect component id for search request."); return componentDescriptorDao.findById(tenantId, componentId); } diff --git a/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java b/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java index c96ba0542f..4061c75097 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java @@ -182,7 +182,7 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC @Transactional @Override public RuleChainUpdateResult saveRuleChainMetaData(TenantId tenantId, RuleChainMetaData ruleChainMetaData, Function ruleNodeUpdater, boolean publishSaveEvent) { - Validator.validateId(ruleChainMetaData.getRuleChainId(), "Incorrect rule chain id."); + Validator.validateId(ruleChainMetaData.getRuleChainId(), id -> "Incorrect rule chain id."); RuleChain ruleChain = findRuleChainById(tenantId, ruleChainMetaData.getRuleChainId()); if (ruleChain == null) { return RuleChainUpdateResult.failed(); @@ -335,7 +335,7 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC @Override public RuleChainMetaData loadRuleChainMetaData(TenantId tenantId, RuleChainId ruleChainId) { - Validator.validateId(ruleChainId, "Incorrect rule chain id."); + Validator.validateId(ruleChainId, id -> "Incorrect rule chain id."); RuleChain ruleChain = findRuleChainById(tenantId, ruleChainId); if (ruleChain == null) { return null; @@ -376,37 +376,37 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC @Override public RuleChain findRuleChainById(TenantId tenantId, RuleChainId ruleChainId) { - Validator.validateId(ruleChainId, "Incorrect rule chain id for search request."); + Validator.validateId(ruleChainId, id -> "Incorrect rule chain id for search request."); return ruleChainDao.findById(tenantId, ruleChainId.getId()); } @Override public RuleNode findRuleNodeById(TenantId tenantId, RuleNodeId ruleNodeId) { - Validator.validateId(ruleNodeId, "Incorrect rule node id for search request."); + Validator.validateId(ruleNodeId, id -> "Incorrect rule node id for search request."); return ruleNodeDao.findById(tenantId, ruleNodeId.getId()); } @Override public ListenableFuture findRuleChainByIdAsync(TenantId tenantId, RuleChainId ruleChainId) { - Validator.validateId(ruleChainId, "Incorrect rule chain id for search request."); + Validator.validateId(ruleChainId, id -> "Incorrect rule chain id for search request."); return ruleChainDao.findByIdAsync(tenantId, ruleChainId.getId()); } @Override public ListenableFuture findRuleNodeByIdAsync(TenantId tenantId, RuleNodeId ruleNodeId) { - Validator.validateId(ruleNodeId, "Incorrect rule node id for search request."); + Validator.validateId(ruleNodeId, id -> "Incorrect rule node id for search request."); return ruleNodeDao.findByIdAsync(tenantId, ruleNodeId.getId()); } @Override public RuleChain getRootTenantRuleChain(TenantId tenantId) { - Validator.validateId(tenantId, "Incorrect tenant id for search request."); + Validator.validateId(tenantId, id -> "Incorrect tenant id for search request."); return ruleChainDao.findRootRuleChainByTenantIdAndType(tenantId.getId(), RuleChainType.CORE); } @Override public List getRuleChainNodes(TenantId tenantId, RuleChainId ruleChainId) { - Validator.validateId(ruleChainId, "Incorrect rule chain id for search request."); + Validator.validateId(ruleChainId, id -> "Incorrect rule chain id for search request."); List relations = getRuleChainToNodeRelations(tenantId, ruleChainId); List ruleNodes = new ArrayList<>(); for (EntityRelation relation : relations) { @@ -422,7 +422,7 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC @Override public List getReferencingRuleChainNodes(TenantId tenantId, RuleChainId ruleChainId) { - Validator.validateId(ruleChainId, "Incorrect rule chain id for search request."); + Validator.validateId(ruleChainId, id -> "Incorrect rule chain id for search request."); List relations = getNodeToRuleChainRelations(tenantId, ruleChainId); List ruleNodes = new ArrayList<>(); for (EntityRelation relation : relations) { @@ -436,7 +436,7 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC @Override public List getRuleNodeRelations(TenantId tenantId, RuleNodeId ruleNodeId) { - Validator.validateId(ruleNodeId, "Incorrect rule node id for search request."); + Validator.validateId(ruleNodeId, id -> "Incorrect rule node id for search request."); List relations = relationService.findByFrom(tenantId, ruleNodeId, RelationTypeGroup.RULE_NODE); List validRelations = new ArrayList<>(); for (EntityRelation relation : relations) { @@ -463,7 +463,7 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC @Override public PageData findTenantRuleChainsByType(TenantId tenantId, RuleChainType type, PageLink pageLink) { - Validator.validateId(tenantId, "Incorrect tenant id for search rule chain request."); + Validator.validateId(tenantId, id -> "Incorrect tenant id for search rule chain request."); Validator.validatePageLink(pageLink); return ruleChainDao.findRuleChainsByTenantIdAndType(tenantId.getId(), type, pageLink); } @@ -476,7 +476,7 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC @Override @Transactional public void deleteRuleChainById(TenantId tenantId, RuleChainId ruleChainId) { - Validator.validateId(ruleChainId, "Incorrect rule chain id for delete request."); + Validator.validateId(ruleChainId, id -> "Incorrect rule chain id for delete request."); RuleChain ruleChain = ruleChainDao.findById(tenantId, ruleChainId.getId()); if (ruleChain == null) { return; @@ -515,7 +515,7 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC @Transactional @Override public void deleteRuleChainsByTenantId(TenantId tenantId) { - Validator.validateId(tenantId, "Incorrect tenant id for delete rule chains request."); + Validator.validateId(tenantId, id -> "Incorrect tenant id for delete rule chains request."); tenantRuleChainsRemover.removeEntities(tenantId, tenantId); } @@ -527,7 +527,7 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC @Override public RuleChainData exportTenantRuleChains(TenantId tenantId, PageLink pageLink) { - Validator.validateId(tenantId, "Incorrect tenant id for search rule chain request."); + Validator.validateId(tenantId, id -> "Incorrect tenant id for search rule chain request."); Validator.validatePageLink(pageLink); PageData ruleChainData = ruleChainDao.findRuleChainsByTenantId(tenantId.getId(), pageLink); List ruleChains = ruleChainData.getData(); From 8e8dcd493339e29ac393006f5d05d5333e51decd Mon Sep 17 00:00:00 2001 From: Oleksandra Matviienko Date: Mon, 27 Apr 2026 08:55:19 +0200 Subject: [PATCH 23/91] Replace deprecated PathChildrenCache with CuratorCache in ZK discovery Switches the ZooKeeper-based service discovery from the deprecated org.apache.curator.framework.recipes.cache.PathChildrenCache to the modern CuratorCache replacement (Curator 5.x). - ZkDiscoveryService: field type, construction, listener registration and child-event handler migrated to the new API. parentPathFilter and zkNodesDir guard preserve the original direct-children semantics against the recursive-by-default behaviour of CuratorCache. - ZkDiscoveryServiceTest: mock type and event construction adapted to the new listener signature; existing assertions unchanged. Eliminates 11 [WARNING] lines for PathChildrenCache deprecation on lts-4.2 (targeted Tier 3 slice of #15481): repo-wide [WARNING] count 843 -> 832, [ERROR] count 0 -> 0. --- .../queue/discovery/ZkDiscoveryService.java | 47 ++++++++++--------- .../discovery/ZkDiscoveryServiceTest.java | 31 ++++++------ 2 files changed, 40 insertions(+), 38 deletions(-) diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/discovery/ZkDiscoveryService.java b/common/queue/src/main/java/org/thingsboard/server/queue/discovery/ZkDiscoveryService.java index ccc242a1a3..a1cbe6332e 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/discovery/ZkDiscoveryService.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/discovery/ZkDiscoveryService.java @@ -26,9 +26,8 @@ import org.apache.curator.framework.CuratorFramework; import org.apache.curator.framework.CuratorFrameworkFactory; import org.apache.curator.framework.imps.CuratorFrameworkState; import org.apache.curator.framework.recipes.cache.ChildData; -import org.apache.curator.framework.recipes.cache.PathChildrenCache; -import org.apache.curator.framework.recipes.cache.PathChildrenCacheEvent; -import org.apache.curator.framework.recipes.cache.PathChildrenCacheListener; +import org.apache.curator.framework.recipes.cache.CuratorCache; +import org.apache.curator.framework.recipes.cache.CuratorCacheListener; import org.apache.curator.framework.state.ConnectionState; import org.apache.curator.framework.state.ConnectionStateListener; import org.apache.curator.retry.RetryForever; @@ -54,12 +53,12 @@ import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; -import static org.apache.curator.framework.recipes.cache.PathChildrenCacheEvent.Type.CHILD_REMOVED; +import static org.apache.curator.framework.recipes.cache.CuratorCacheAccessor.parentPathFilter; @Service @ConditionalOnProperty(prefix = "zk", value = "enabled", havingValue = "true", matchIfMissing = false) @Slf4j -public class ZkDiscoveryService implements DiscoveryService, PathChildrenCacheListener { +public class ZkDiscoveryService implements DiscoveryService { @Value("${zk.url}") private String zkUrl; @@ -84,7 +83,7 @@ public class ZkDiscoveryService implements DiscoveryService, PathChildrenCacheLi private ScheduledExecutorService zkExecutorService; @Getter private CuratorFramework client; - private PathChildrenCache cache; + private CuratorCache cache; private String nodePath; private String zkNodesDir; @@ -117,7 +116,8 @@ public class ZkDiscoveryService implements DiscoveryService, PathChildrenCacheLi @Override public List getOtherServers() { - return cache.getCurrentData().stream() + return cache.stream() + .filter(parentPathFilter(zkNodesDir)) .filter(cd -> !cd.getPath().equals(nodePath)) .map(cd -> { try { @@ -241,7 +241,7 @@ public class ZkDiscoveryService implements DiscoveryService, PathChildrenCacheLi client = CuratorFrameworkFactory.newClient(zkUrl, zkSessionTimeout, zkConnectionTimeout, new RetryForever(zkRetryInterval)); client.start(); client.blockUntilConnected(); - cache = new PathChildrenCache(client, zkNodesDir, true); + cache = CuratorCache.builder(client, zkNodesDir).build(); cache.start(); stopped = false; log.info("ZK client connected"); @@ -254,7 +254,7 @@ public class ZkDiscoveryService implements DiscoveryService, PathChildrenCacheLi } private void subscribeToEvents() { - cache.getListenable().addListener(this); + cache.listenable().addListener(this::onCacheEvent); } private void unpublishCurrentServer() { @@ -286,29 +286,32 @@ public class ZkDiscoveryService implements DiscoveryService, PathChildrenCacheLi return "The " + propertyName + " property need to be set!"; } - @Override - public void childEvent(CuratorFramework curatorFramework, PathChildrenCacheEvent pathChildrenCacheEvent) throws Exception { + @SneakyThrows + void onCacheEvent(CuratorCacheListener.Type type, ChildData oldData, ChildData newData) { if (stopped) { - log.debug("Ignoring {}. Service is stopped.", pathChildrenCacheEvent); + log.debug("Ignoring {}. Service is stopped.", type); return; } if (client.getState() != CuratorFrameworkState.STARTED) { - log.debug("Ignoring {}, ZK client is not started, ZK client state [{}]", pathChildrenCacheEvent, client.getState()); + log.debug("Ignoring {}, ZK client is not started, ZK client state [{}]", type, client.getState()); return; } - ChildData data = pathChildrenCacheEvent.getData(); + ChildData data = type == CuratorCacheListener.Type.NODE_DELETED ? oldData : newData; if (data == null) { - log.debug("Ignoring {} due to empty child data", pathChildrenCacheEvent); + log.debug("Ignoring {} due to empty child data", type); return; } else if (data.getData() == null) { - log.debug("Ignoring {} due to empty child's data", pathChildrenCacheEvent); + log.debug("Ignoring {} due to empty child's data", type); + return; + } else if (zkNodesDir.equals(data.getPath())) { + log.debug("Ignoring event about parent node {}", data.getPath()); return; } else if (nodePath != null && nodePath.equals(data.getPath())) { - if (pathChildrenCacheEvent.getType() == CHILD_REMOVED) { + if (type == CuratorCacheListener.Type.NODE_DELETED) { log.info("ZK node for current instance is somehow deleted."); publishCurrentServer(); } - log.debug("Ignoring event about current server {}", pathChildrenCacheEvent); + log.debug("Ignoring event about current server {}", data.getPath()); return; } TransportProtos.ServiceInfo instance; @@ -322,9 +325,9 @@ public class ZkDiscoveryService implements DiscoveryService, PathChildrenCacheLi String serviceId = instance.getServiceId(); ProtocolStringList serviceTypesList = instance.getServiceTypesList(); - log.trace("Processing [{}] event for [{}]", pathChildrenCacheEvent.getType(), serviceId); - switch (pathChildrenCacheEvent.getType()) { - case CHILD_ADDED: + log.trace("Processing [{}] event for [{}]", type, serviceId); + switch (type) { + case NODE_CREATED: ScheduledFuture task = delayedTasks.remove(serviceId); if (task != null) { if (task.cancel(false)) { @@ -341,7 +344,7 @@ public class ZkDiscoveryService implements DiscoveryService, PathChildrenCacheLi recalculatePartitions(); } break; - case CHILD_REMOVED: + case NODE_DELETED: zkExecutorService.submit(() -> applicationEventPublisher.publishEvent(new OtherServiceShutdownEvent(this, serviceId, serviceTypesList))); ScheduledFuture future = zkExecutorService.schedule(() -> { log.debug("[{}] Going to recalculate partitions due to removed node [{}]", diff --git a/common/queue/src/test/java/org/thingsboard/server/queue/discovery/ZkDiscoveryServiceTest.java b/common/queue/src/test/java/org/thingsboard/server/queue/discovery/ZkDiscoveryServiceTest.java index 74bf30dca6..a7be216f66 100644 --- a/common/queue/src/test/java/org/thingsboard/server/queue/discovery/ZkDiscoveryServiceTest.java +++ b/common/queue/src/test/java/org/thingsboard/server/queue/discovery/ZkDiscoveryServiceTest.java @@ -18,8 +18,8 @@ package org.thingsboard.server.queue.discovery; import org.apache.curator.framework.CuratorFramework; import org.apache.curator.framework.imps.CuratorFrameworkState; import org.apache.curator.framework.recipes.cache.ChildData; -import org.apache.curator.framework.recipes.cache.PathChildrenCache; -import org.apache.curator.framework.recipes.cache.PathChildrenCacheEvent; +import org.apache.curator.framework.recipes.cache.CuratorCache; +import org.apache.curator.framework.recipes.cache.CuratorCacheListener; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -36,8 +36,8 @@ import java.util.Collections; import java.util.List; import java.util.concurrent.ScheduledExecutorService; -import static org.apache.curator.framework.recipes.cache.PathChildrenCacheEvent.Type.CHILD_ADDED; -import static org.apache.curator.framework.recipes.cache.PathChildrenCacheEvent.Type.CHILD_REMOVED; +import static org.apache.curator.framework.recipes.cache.CuratorCacheListener.Type.NODE_CREATED; +import static org.apache.curator.framework.recipes.cache.CuratorCacheListener.Type.NODE_DELETED; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.ArgumentMatchers.any; @@ -63,12 +63,10 @@ public class ZkDiscoveryServiceTest { private CuratorFramework client; @Mock - private PathChildrenCache cache; - - @Mock - private CuratorFramework curatorFramework; + private CuratorCache cache; private ZkDiscoveryService zkDiscoveryService; + private List dataList; private static final long RECALCULATE_DELAY = 100L; @@ -89,12 +87,13 @@ public class ZkDiscoveryServiceTest { ReflectionTestUtils.setField(zkDiscoveryService, "zkExecutorService", zkExecutorService); ReflectionTestUtils.setField(zkDiscoveryService, "recalculateDelay", RECALCULATE_DELAY); ReflectionTestUtils.setField(zkDiscoveryService, "zkDir", "/thingsboard"); + ReflectionTestUtils.setField(zkDiscoveryService, "zkNodesDir", "/thingsboard/nodes"); when(serviceInfoProvider.getServiceInfo()).thenReturn(currentInfo); - List dataList = new ArrayList<>(); + dataList = new ArrayList<>(); dataList.add(currentData); - when(cache.getCurrentData()).thenReturn(dataList); + when(cache.stream()).thenAnswer(inv -> dataList.stream()); } @Test @@ -178,14 +177,14 @@ public class ZkDiscoveryServiceTest { verify(partitionService, times(1)).recalculatePartitions(eq(currentInfo), eq(List.of(anotherInfo, childInfo))); } - private void startNode(ChildData data) throws Exception { - cache.getCurrentData().add(data); - zkDiscoveryService.childEvent(curatorFramework, new PathChildrenCacheEvent(CHILD_ADDED, data)); + private void startNode(ChildData data) { + dataList.add(data); + zkDiscoveryService.onCacheEvent(NODE_CREATED, null, data); } - private void stopNode(ChildData data) throws Exception { - cache.getCurrentData().remove(data); - zkDiscoveryService.childEvent(curatorFramework, new PathChildrenCacheEvent(CHILD_REMOVED, data)); + private void stopNode(ChildData data) { + dataList.remove(data); + zkDiscoveryService.onCacheEvent(NODE_DELETED, data, null); } } From eaa00ab83b9c137067f0a4fdc477b93a55a27318 Mon Sep 17 00:00:00 2001 From: Oleksandra Matviienko Date: Mon, 27 Apr 2026 09:45:21 +0200 Subject: [PATCH 24/91] Replace deprecated RestTemplateBuilder setConnectTimeout/setReadTimeout with non-deprecated variants Spring Boot 3.5 deprecated RestTemplateBuilder.setConnectTimeout(Duration) and setReadTimeout(Duration) for removal; their non-deprecated replacements connectTimeout(Duration) and readTimeout(Duration) are direct, behavior-equivalent delegations. --- .../channels/MicrosoftTeamsNotificationChannel.java | 4 ++-- .../main/java/org/thingsboard/monitoring/client/TbClient.java | 4 ++-- .../notification/channels/impl/SlackNotificationChannel.java | 4 ++-- .../service/transport/impl/HttpTransportHealthChecker.java | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/service/notification/channels/MicrosoftTeamsNotificationChannel.java b/application/src/main/java/org/thingsboard/server/service/notification/channels/MicrosoftTeamsNotificationChannel.java index d023ed9b53..459c857d02 100644 --- a/application/src/main/java/org/thingsboard/server/service/notification/channels/MicrosoftTeamsNotificationChannel.java +++ b/application/src/main/java/org/thingsboard/server/service/notification/channels/MicrosoftTeamsNotificationChannel.java @@ -54,8 +54,8 @@ public class MicrosoftTeamsNotificationChannel implements NotificationChannel Date: Mon, 27 Apr 2026 11:37:35 +0200 Subject: [PATCH 25/91] Create ZK nodes container before starting CuratorCache PathChildrenCache invoked EnsureContainers internally during start(), so the parent znode existed when publishCurrentServer ran. CuratorCache does not, so on a fresh ZK creatingParentsIfNeeded reaches ZKPaths.mkdirs with the trailing-slash forPath argument and fails with "Path must not end with / character", aborting Spring startup. --- .../thingsboard/server/queue/discovery/ZkDiscoveryService.java | 1 + 1 file changed, 1 insertion(+) diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/discovery/ZkDiscoveryService.java b/common/queue/src/main/java/org/thingsboard/server/queue/discovery/ZkDiscoveryService.java index a1cbe6332e..47c2761020 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/discovery/ZkDiscoveryService.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/discovery/ZkDiscoveryService.java @@ -241,6 +241,7 @@ public class ZkDiscoveryService implements DiscoveryService { client = CuratorFrameworkFactory.newClient(zkUrl, zkSessionTimeout, zkConnectionTimeout, new RetryForever(zkRetryInterval)); client.start(); client.blockUntilConnected(); + client.createContainers(zkNodesDir); cache = CuratorCache.builder(client, zkNodesDir).build(); cache.start(); stopped = false; From c33546be5e45240466d3508b2f3b314e32f70181 Mon Sep 17 00:00:00 2001 From: Oleksandra Matviienko Date: Mon, 27 Apr 2026 15:08:24 +0200 Subject: [PATCH 26/91] Replace deprecated JsonNode.fields, HttpMessageNotReadableException(String), Assert.assertThat(Matcher), io.jsonwebtoken.SignatureException, StopWatch.getLastTaskTimeNanos calls with non-deprecated variants --- .../service/security/model/token/JwtTokenFactory.java | 2 +- .../security/model/token/OAuth2AppTokenFactory.java | 2 +- .../transport/lwm2m/AbstractLwM2MIntegrationTest.java | 2 +- .../server/transport/http/DeviceApiControllerTest.java | 7 ++++--- .../java/org/thingsboard/common/util/JacksonUtil.java | 7 ++----- .../java/org/thingsboard/common/util/TbStopWatch.java | 6 +++--- .../rule/engine/ai/Langchain4jJsonSchemaAdapter.java | 2 +- .../rule/engine/transform/TbCopyKeysNode.java | 5 +---- .../thingsboard/client/tools/i18n/TranslationPruner.java | 9 ++------- 9 files changed, 16 insertions(+), 26 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/service/security/model/token/JwtTokenFactory.java b/application/src/main/java/org/thingsboard/server/service/security/model/token/JwtTokenFactory.java index 5b4f4dc94a..2eced691a5 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/model/token/JwtTokenFactory.java +++ b/application/src/main/java/org/thingsboard/server/service/security/model/token/JwtTokenFactory.java @@ -23,9 +23,9 @@ import io.jsonwebtoken.JwtBuilder; import io.jsonwebtoken.JwtParser; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.MalformedJwtException; -import io.jsonwebtoken.SignatureException; import io.jsonwebtoken.UnsupportedJwtException; import io.jsonwebtoken.security.Keys; +import io.jsonwebtoken.security.SignatureException; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.context.annotation.Lazy; diff --git a/application/src/main/java/org/thingsboard/server/service/security/model/token/OAuth2AppTokenFactory.java b/application/src/main/java/org/thingsboard/server/service/security/model/token/OAuth2AppTokenFactory.java index 98f9215ebf..a353aac86b 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/model/token/OAuth2AppTokenFactory.java +++ b/application/src/main/java/org/thingsboard/server/service/security/model/token/OAuth2AppTokenFactory.java @@ -20,9 +20,9 @@ import io.jsonwebtoken.ExpiredJwtException; import io.jsonwebtoken.Jws; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.MalformedJwtException; -import io.jsonwebtoken.SignatureException; import io.jsonwebtoken.UnsupportedJwtException; import io.jsonwebtoken.security.Keys; +import io.jsonwebtoken.security.SignatureException; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import org.thingsboard.server.common.data.StringUtils; diff --git a/application/src/test/java/org/thingsboard/server/transport/lwm2m/AbstractLwM2MIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/lwm2m/AbstractLwM2MIntegrationTest.java index 8d0f0f2af0..90f9679343 100644 --- a/application/src/test/java/org/thingsboard/server/transport/lwm2m/AbstractLwM2MIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/lwm2m/AbstractLwM2MIntegrationTest.java @@ -101,10 +101,10 @@ import java.util.concurrent.atomic.AtomicLong; import static org.awaitility.Awaitility.await; import static org.eclipse.leshan.client.object.Security.noSec; +import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.core.IsInstanceOf.instanceOf; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.timeout; diff --git a/common/transport/http/src/test/java/org/thingsboard/server/transport/http/DeviceApiControllerTest.java b/common/transport/http/src/test/java/org/thingsboard/server/transport/http/DeviceApiControllerTest.java index 397ea791c6..fcdb2b04ea 100644 --- a/common/transport/http/src/test/java/org/thingsboard/server/transport/http/DeviceApiControllerTest.java +++ b/common/transport/http/src/test/java/org/thingsboard/server/transport/http/DeviceApiControllerTest.java @@ -18,6 +18,7 @@ package org.thingsboard.server.transport.http; import com.google.gson.JsonParseException; import org.junit.jupiter.api.Test; import org.mockito.Mockito; +import org.springframework.http.HttpInputMessage; import org.springframework.http.ResponseEntity; import org.springframework.http.converter.HttpMessageNotReadableException; import org.springframework.web.context.request.async.DeferredResult; @@ -37,7 +38,7 @@ class DeviceApiControllerTest { }; var callback = new DeviceApiController.DeviceAuthCallback(transportContext, responseWriter, onSuccess); - callback.onError(new HttpMessageNotReadableException("JSON incorrect syntax")); + callback.onError(new HttpMessageNotReadableException("JSON incorrect syntax", (HttpInputMessage) null)); callback.onError(new JsonParseException("Json ; expected")); @@ -51,7 +52,7 @@ class DeviceApiControllerTest { DeferredResult responseWriter = Mockito.mock(DeferredResult.class); var callback = new DeviceApiController.DeviceProvisionCallback(responseWriter); - callback.onError(new HttpMessageNotReadableException("JSON incorrect syntax")); + callback.onError(new HttpMessageNotReadableException("JSON incorrect syntax", (HttpInputMessage) null)); callback.onError(new JsonParseException("Json ; expected")); @@ -71,7 +72,7 @@ class DeviceApiControllerTest { var callback = new DeviceApiController.GetOtaPackageCallback(transportContext, responseWriter, title, version, chunkSize, chunk); - callback.onError(new HttpMessageNotReadableException("JSON incorrect syntax")); + callback.onError(new HttpMessageNotReadableException("JSON incorrect syntax", (HttpInputMessage) null)); callback.onError(new JsonParseException("Json ; expected")); diff --git a/common/util/src/main/java/org/thingsboard/common/util/JacksonUtil.java b/common/util/src/main/java/org/thingsboard/common/util/JacksonUtil.java index 9913210c1a..d6785934a2 100644 --- a/common/util/src/main/java/org/thingsboard/common/util/JacksonUtil.java +++ b/common/util/src/main/java/org/thingsboard/common/util/JacksonUtil.java @@ -434,10 +434,8 @@ public class JacksonUtil { private static void toFlatMap(JsonNode node, String currentPath, Map map) { if (node.isObject()) { - Iterator> fields = node.fields(); currentPath = currentPath.isEmpty() ? "" : currentPath + "."; - while (fields.hasNext()) { - Map.Entry entry = fields.next(); + for (Map.Entry entry : node.properties()) { toFlatMap(entry.getValue(), currentPath + entry.getKey(), map); } } else if (node.isValueNode()) { @@ -541,8 +539,7 @@ public class JacksonUtil { } } else if (node.isObject()) { ObjectNode on = (ObjectNode) node; - for (Iterator> it = on.fields(); it.hasNext(); ) { - var kv = it.next(); + for (Map.Entry kv : on.properties()) { if (variableName != null) { tasks.add(task.next(kv.getValue(), variableName, kv.getKey())); } else { diff --git a/common/util/src/main/java/org/thingsboard/common/util/TbStopWatch.java b/common/util/src/main/java/org/thingsboard/common/util/TbStopWatch.java index 3a8b94c56e..fab0a72d3d 100644 --- a/common/util/src/main/java/org/thingsboard/common/util/TbStopWatch.java +++ b/common/util/src/main/java/org/thingsboard/common/util/TbStopWatch.java @@ -52,17 +52,17 @@ public class TbStopWatch extends StopWatch { public long stopAndGetTotalTimeNanos(){ stop(); - return getLastTaskTimeNanos(); + return lastTaskInfo().getTimeNanos(); } public long stopAndGetLastTaskTimeMillis(){ stop(); - return getLastTaskTimeMillis(); + return lastTaskInfo().getTimeMillis(); } public long stopAndGetLastTaskTimeNanos(){ stop(); - return getLastTaskTimeNanos(); + return lastTaskInfo().getTimeNanos(); } } diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/ai/Langchain4jJsonSchemaAdapter.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/ai/Langchain4jJsonSchemaAdapter.java index afe4372101..a6d1c60730 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/ai/Langchain4jJsonSchemaAdapter.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/ai/Langchain4jJsonSchemaAdapter.java @@ -94,7 +94,7 @@ final class Langchain4jJsonSchemaAdapter { JsonNode propertiesNode = objectSchema.get("properties"); if (propertiesNode != null) { - propertiesNode.fields().forEachRemaining(entry -> { + propertiesNode.properties().forEach(entry -> { String key = entry.getKey(); JsonNode value = entry.getValue(); builder.addProperty(key, parse(value)); diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transform/TbCopyKeysNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transform/TbCopyKeysNode.java index 08919f37fe..f9e732a53d 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transform/TbCopyKeysNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transform/TbCopyKeysNode.java @@ -29,7 +29,6 @@ import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.msg.TbMsg; import java.util.Arrays; -import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.concurrent.ExecutionException; @@ -87,9 +86,7 @@ public class TbCopyKeysNode extends TbAbstractTransformNodeWithTbMsgSource { msgData = JacksonUtil.toString(msgDataNode); break; case DATA: - Iterator> iteratorNode = dataNode.fields(); - while (iteratorNode.hasNext()) { - Map.Entry entry = iteratorNode.next(); + for (Map.Entry entry : dataNode.properties()) { String msgKey = entry.getKey(); JsonNode msgValue = entry.getValue(); if (matches(msgKey)) { diff --git a/tools/src/main/java/org/thingsboard/client/tools/i18n/TranslationPruner.java b/tools/src/main/java/org/thingsboard/client/tools/i18n/TranslationPruner.java index 4181180521..6467c72114 100644 --- a/tools/src/main/java/org/thingsboard/client/tools/i18n/TranslationPruner.java +++ b/tools/src/main/java/org/thingsboard/client/tools/i18n/TranslationPruner.java @@ -25,7 +25,6 @@ import com.fasterxml.jackson.databind.node.ObjectNode; import java.io.File; import java.io.IOException; import java.util.HashSet; -import java.util.Iterator; import java.util.Map; import java.util.Set; @@ -37,9 +36,7 @@ public class TranslationPruner { */ private static void collectKeys(JsonNode node, String prefix, Set keys) { if (!node.isObject()) return; - Iterator> fields = node.fields(); - while (fields.hasNext()) { - Map.Entry entry = fields.next(); + for (Map.Entry entry : node.properties()) { String key = entry.getKey(); String fullKey = prefix.isEmpty() ? key : prefix + "." + key; keys.add(fullKey); @@ -52,9 +49,7 @@ public class TranslationPruner { */ private static ObjectNode pruneNode(ObjectNode node, Set keys, String prefix, ObjectMapper mapper) { ObjectNode pruned = mapper.createObjectNode(); - Iterator> fields = node.fields(); - while (fields.hasNext()) { - Map.Entry entry = fields.next(); + for (Map.Entry entry : node.properties()) { String key = entry.getKey(); JsonNode value = entry.getValue(); String fullKey = prefix.isEmpty() ? key : prefix + "." + key; From 459c47310a9c14fb21af722b117eda77d6be8475 Mon Sep 17 00:00:00 2001 From: Oleksandra Matviienko Date: Tue, 19 May 2026 14:51:52 +0200 Subject: [PATCH 27/91] Technical cleanup of annotations in test code --- .../controller/AbstractNotifyEntityTest.java | 10 ++-- .../controller/AuditLogControllerTest.java | 6 +- ...trollerTest_DedicatedEventsDataSource.java | 4 +- .../server/controller/AuthControllerTest.java | 4 +- .../controller/DeviceControllerTest.java | 6 +- .../controller/EdgeEventControllerTest.java | 4 +- .../server/controller/HomePageApiTest.java | 6 +- .../controller/RepositorySettingsTest.java | 4 +- .../controller/RuleEngineControllerTest.java | 4 +- .../controller/TwoFactorAuthConfigTest.java | 10 ++-- .../server/controller/TwoFactorAuthTest.java | 8 +-- .../server/controller/WebsocketApiTest.java | 4 +- .../provision/DeviceProvisionServiceTest.java | 41 ++++++++----- .../alarm/DefaultTbAlarmServiceTest.java | 32 +++++----- .../DefaultTbAlarmCommentServiceTest.java | 34 +++++------ .../service/install/InstallScriptsTest.java | 28 ++++----- .../server/service/job/JobManagerTest.java | 6 +- .../queue/DefaultTbClusterServiceTest.java | 43 +++++++++----- .../service/sms/DefaultSmsServiceTest.java | 4 +- .../sync/ie/ExportImportServiceSqlTest.java | 6 +- .../DefaultTransportApiServiceTest.java | 58 +++++++++++++------ .../service/ttl/AlarmsCleanUpServiceTest.java | 6 +- .../lwm2m/AbstractLwM2MIntegrationTest.java | 6 +- .../rpc/AbstractRpcLwM2MIntegrationTest.java | 4 +- .../AbstractLwM2MIntegrationDiffPortTest.java | 4 +- .../mqtt/MqttGatewayRateLimitsTest.java | 4 +- ...AbstractMqttTimeseriesIntegrationTest.java | 4 +- .../server/dao/AbstractDaoServiceTest.java | 4 +- .../server/dao/AbstractJpaDaoTest.java | 4 +- .../cache/RedisTbTransactionalCacheTest.java | 10 ++-- .../server/dao/service/DeviceServiceTest.java | 4 +- .../server/dao/service/TenantServiceTest.java | 4 +- .../AdminSettingsDataValidatorTest.java | 8 +-- .../validator/AlarmDataValidatorTest.java | 8 +-- .../validator/AssetDataValidatorTest.java | 8 +-- .../AssetProfileDataValidatorTest.java | 18 +++--- .../ComponentDescriptorDataValidatorTest.java | 4 +- .../validator/CustomerDataValidatorTest.java | 10 ++-- .../validator/DashboardDataValidatorTest.java | 8 +-- .../validator/DeviceDataValidatorTest.java | 8 +-- .../DeviceProfileDataValidatorTest.java | 20 +++---- .../validator/EdgeDataValidatorTest.java | 12 ++-- .../EntityViewDataValidatorTest.java | 12 ++-- .../validator/ResourceDataValidatorTest.java | 14 ++--- .../validator/RuleChainDataValidatorTest.java | 10 ++-- .../validator/TenantDataValidatorTest.java | 8 +-- .../WidgetTypeDataValidatorTest.java | 12 ++-- .../WidgetsBundleDataValidatorTest.java | 10 ++-- .../DefaultEntityQueryRepositoryTest.java | 8 +-- .../query/DefaultQueryLogComponentTest.java | 4 +- ...esDaoPartitioningDaysAlwaysExistsTest.java | 8 +-- ...sDaoPartitioningHoursAlwaysExistsTest.java | 8 +-- ...artitioningIndefiniteAlwaysExistsTest.java | 8 +-- ...aoPartitioningMinutesAlwaysExistsTest.java | 8 +-- ...DaoPartitioningMonthsAlwaysExistsTest.java | 8 +-- ...sDaoPartitioningYearsAlwaysExistsTest.java | 8 +-- .../server/edqs/repo/AbstractEDQTest.java | 4 +- 57 files changed, 332 insertions(+), 278 deletions(-) diff --git a/application/src/test/java/org/thingsboard/server/controller/AbstractNotifyEntityTest.java b/application/src/test/java/org/thingsboard/server/controller/AbstractNotifyEntityTest.java index 62a266f26a..d62fac47a6 100644 --- a/application/src/test/java/org/thingsboard/server/controller/AbstractNotifyEntityTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/AbstractNotifyEntityTest.java @@ -19,8 +19,8 @@ import lombok.extern.slf4j.Slf4j; import org.mockito.ArgumentMatcher; import org.mockito.Mockito; import org.springframework.boot.info.BuildProperties; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.thingsboard.server.cluster.TbClusterService; import org.thingsboard.server.common.data.EdgeUtils; import org.thingsboard.server.common.data.EntityType; @@ -55,13 +55,13 @@ import static org.mockito.Mockito.times; @Slf4j public abstract class AbstractNotifyEntityTest extends AbstractWebTest { - @SpyBean + @MockitoSpyBean protected TbClusterService tbClusterService; - @SpyBean + @MockitoSpyBean protected AuditLogService auditLogService; - @MockBean + @MockitoBean BuildProperties buildProperties; protected final String msgErrorPermission = "You don't have permission to perform this operation!"; diff --git a/application/src/test/java/org/thingsboard/server/controller/AuditLogControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/AuditLogControllerTest.java index 95582cf261..af3702cb7d 100644 --- a/application/src/test/java/org/thingsboard/server/controller/AuditLogControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/AuditLogControllerTest.java @@ -26,7 +26,7 @@ import org.junit.Before; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.Tenant; import org.thingsboard.server.common.data.TenantProfile; @@ -71,9 +71,9 @@ public class AuditLogControllerTest extends AbstractControllerTest { @Autowired private AuditLogDao auditLogDao; @Getter - @SpyBean + @MockitoSpyBean private SqlPartitioningRepository partitioningRepository; - @SpyBean + @MockitoSpyBean private AuditLogsCleanUpService auditLogsCleanUpService; @Value("#{${sql.audit_logs.partition_size} * 60 * 60 * 1000}") diff --git a/application/src/test/java/org/thingsboard/server/controller/AuditLogControllerTest_DedicatedEventsDataSource.java b/application/src/test/java/org/thingsboard/server/controller/AuditLogControllerTest_DedicatedEventsDataSource.java index c594beae98..0660dfe95e 100644 --- a/application/src/test/java/org/thingsboard/server/controller/AuditLogControllerTest_DedicatedEventsDataSource.java +++ b/application/src/test/java/org/thingsboard/server/controller/AuditLogControllerTest_DedicatedEventsDataSource.java @@ -16,7 +16,7 @@ package org.thingsboard.server.controller; import lombok.Getter; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.springframework.test.context.TestPropertySource; import org.thingsboard.server.dao.service.DaoSqlTest; import org.thingsboard.server.dao.sqlts.insert.sql.DedicatedEventsSqlPartitioningRepository; @@ -30,7 +30,7 @@ import org.thingsboard.server.dao.sqlts.insert.sql.DedicatedEventsSqlPartitionin public class AuditLogControllerTest_DedicatedEventsDataSource extends AuditLogControllerTest { @Getter - @SpyBean + @MockitoSpyBean private DedicatedEventsSqlPartitioningRepository partitioningRepository; } diff --git a/application/src/test/java/org/thingsboard/server/controller/AuthControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/AuthControllerTest.java index 9126c42f2f..419f442f87 100644 --- a/application/src/test/java/org/thingsboard/server/controller/AuthControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/AuthControllerTest.java @@ -20,7 +20,7 @@ import org.assertj.core.data.Offset; import org.junit.After; import org.junit.Test; import org.mockito.Mockito; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.springframework.http.HttpHeaders; import org.testcontainers.shaded.org.apache.commons.lang3.RandomStringUtils; import org.thingsboard.common.util.JacksonUtil; @@ -50,7 +50,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. @DaoSqlTest public class AuthControllerTest extends AbstractControllerTest { - @SpyBean + @MockitoSpyBean private UserCredentialsDao userCredentialsDao; @After diff --git a/application/src/test/java/org/thingsboard/server/controller/DeviceControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/DeviceControllerTest.java index 07b68210bb..43d25566df 100644 --- a/application/src/test/java/org/thingsboard/server/controller/DeviceControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/DeviceControllerTest.java @@ -31,7 +31,7 @@ import org.mockito.AdditionalAnswers; import org.mockito.ArgumentCaptor; import org.mockito.Mockito; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Primary; import org.springframework.test.context.ContextConfiguration; @@ -115,10 +115,10 @@ public class DeviceControllerTest extends AbstractControllerTest { private Tenant savedTenant; private User tenantAdmin; - @SpyBean + @MockitoSpyBean private GatewayNotificationsService gatewayNotificationsService; - @SpyBean + @MockitoSpyBean private DeviceStateService deviceStateService; @Autowired diff --git a/application/src/test/java/org/thingsboard/server/controller/EdgeEventControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/EdgeEventControllerTest.java index ba389d3bd6..262d685d74 100644 --- a/application/src/test/java/org/thingsboard/server/controller/EdgeEventControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/EdgeEventControllerTest.java @@ -25,7 +25,7 @@ import org.junit.Before; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.springframework.test.context.TestPropertySource; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.common.data.AttributeScope; @@ -66,7 +66,7 @@ public class EdgeEventControllerTest extends AbstractControllerTest { @Autowired private EdgeEventDao edgeEventDao; - @SpyBean + @MockitoSpyBean private SqlPartitioningRepository partitioningRepository; @Autowired private EdgeEventsCleanUpService edgeEventsCleanUpService; diff --git a/application/src/test/java/org/thingsboard/server/controller/HomePageApiTest.java b/application/src/test/java/org/thingsboard/server/controller/HomePageApiTest.java index ee2aefc81a..efe553e8f2 100644 --- a/application/src/test/java/org/thingsboard/server/controller/HomePageApiTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/HomePageApiTest.java @@ -22,7 +22,7 @@ import org.junit.Assert; import org.junit.Test; import org.mockito.Mockito; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.rule.engine.api.MailService; import org.thingsboard.rule.engine.api.SmsService; @@ -85,10 +85,10 @@ public class HomePageApiTest extends AbstractControllerTest { @Autowired private OAuth2ClientService oAuth2ClientService; - @MockBean + @MockitoBean private MailService mailService; - @MockBean + @MockitoBean private SmsService smsService; private static final int DEFAULT_DASHBOARDS_COUNT = 0; diff --git a/application/src/test/java/org/thingsboard/server/controller/RepositorySettingsTest.java b/application/src/test/java/org/thingsboard/server/controller/RepositorySettingsTest.java index 072e83cc47..3d6c62d701 100644 --- a/application/src/test/java/org/thingsboard/server/controller/RepositorySettingsTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/RepositorySettingsTest.java @@ -18,7 +18,7 @@ package org.thingsboard.server.controller; import com.google.common.util.concurrent.SettableFuture; import lombok.extern.slf4j.Slf4j; import org.junit.Test; -import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.thingsboard.server.common.data.sync.vc.RepositoryAuthMethod; import org.thingsboard.server.common.data.sync.vc.RepositorySettings; import org.thingsboard.server.dao.service.DaoSqlTest; @@ -35,7 +35,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. @DaoSqlTest public class RepositorySettingsTest extends AbstractControllerTest { - @MockBean + @MockitoBean private GitVersionControlQueueService gitVersionControlQueueService; @Test diff --git a/application/src/test/java/org/thingsboard/server/controller/RuleEngineControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/RuleEngineControllerTest.java index 81c74de038..ff75d80d30 100644 --- a/application/src/test/java/org/thingsboard/server/controller/RuleEngineControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/RuleEngineControllerTest.java @@ -19,7 +19,7 @@ import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.JsonNode; import org.junit.Test; import org.mockito.ArgumentCaptor; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.Device; @@ -56,7 +56,7 @@ public class RuleEngineControllerTest extends AbstractControllerTest { private final String REQUEST_BODY = "{\"request\":\"download\"}"; private final String RESPONSE_BODY = "{\"response\":\"downloadOk\"}"; - @SpyBean + @MockitoSpyBean private RuleEngineCallService ruleEngineCallService; @Test diff --git a/application/src/test/java/org/thingsboard/server/controller/TwoFactorAuthConfigTest.java b/application/src/test/java/org/thingsboard/server/controller/TwoFactorAuthConfigTest.java index c8b5bf06c9..558ceb2d10 100644 --- a/application/src/test/java/org/thingsboard/server/controller/TwoFactorAuthConfigTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/TwoFactorAuthConfigTest.java @@ -22,8 +22,8 @@ import org.junit.Before; import org.junit.Test; import org.mockito.ArgumentCaptor; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.springframework.cache.CacheManager; import org.springframework.web.util.UriComponents; import org.springframework.web.util.UriComponentsBuilder; @@ -65,15 +65,15 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. @DaoSqlTest public class TwoFactorAuthConfigTest extends AbstractControllerTest { - @SpyBean + @MockitoSpyBean private TotpTwoFaProvider totpTwoFactorAuthProvider; - @MockBean + @MockitoBean private SmsService smsService; @Autowired private CacheManager cacheManager; @Autowired private TwoFaConfigManager twoFaConfigManager; - @SpyBean + @MockitoSpyBean private TwoFactorAuthService twoFactorAuthService; @Before diff --git a/application/src/test/java/org/thingsboard/server/controller/TwoFactorAuthTest.java b/application/src/test/java/org/thingsboard/server/controller/TwoFactorAuthTest.java index ca81b97a48..6acae7d1eb 100644 --- a/application/src/test/java/org/thingsboard/server/controller/TwoFactorAuthTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/TwoFactorAuthTest.java @@ -23,8 +23,8 @@ import org.junit.Before; import org.junit.Test; import org.mockito.ArgumentCaptor; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.springframework.web.util.UriComponentsBuilder; import org.thingsboard.rule.engine.api.SmsService; import org.thingsboard.server.common.data.StringUtils; @@ -82,9 +82,9 @@ public class TwoFactorAuthTest extends AbstractControllerTest { @Autowired private TwoFaConfigManager twoFaConfigManager; - @SpyBean + @MockitoSpyBean private TwoFactorAuthService twoFactorAuthService; - @MockBean + @MockitoBean private SmsService smsService; @Autowired private AuditLogService auditLogService; diff --git a/application/src/test/java/org/thingsboard/server/controller/WebsocketApiTest.java b/application/src/test/java/org/thingsboard/server/controller/WebsocketApiTest.java index 6ec0f3ad64..e3b6a6efd8 100644 --- a/application/src/test/java/org/thingsboard/server/controller/WebsocketApiTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/WebsocketApiTest.java @@ -28,7 +28,7 @@ import org.junit.Before; import org.junit.Test; import org.mockito.Mockito; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.springframework.test.context.TestPropertySource; import org.testcontainers.shaded.org.apache.commons.lang3.RandomStringUtils; import org.thingsboard.common.util.JacksonUtil; @@ -100,7 +100,7 @@ public class WebsocketApiTest extends AbstractControllerTest { @Autowired private TelemetrySubscriptionService tsService; - @SpyBean + @MockitoSpyBean private TimeseriesService timeseriesService; Device device; diff --git a/application/src/test/java/org/thingsboard/server/service/device/provision/DeviceProvisionServiceTest.java b/application/src/test/java/org/thingsboard/server/service/device/provision/DeviceProvisionServiceTest.java index de86e46cd0..4f2eaa5147 100644 --- a/application/src/test/java/org/thingsboard/server/service/device/provision/DeviceProvisionServiceTest.java +++ b/application/src/test/java/org/thingsboard/server/service/device/provision/DeviceProvisionServiceTest.java @@ -21,8 +21,8 @@ import org.assertj.core.api.Assertions; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringRunner; import org.thingsboard.server.cluster.TbClusterService; @@ -73,28 +73,43 @@ import static org.mockito.Mockito.when; @Slf4j @RunWith(SpringRunner.class) -@ContextConfiguration(classes = DeviceProvisionServiceImpl.class) +@ContextConfiguration(classes = DeviceProvisionServiceTest.ContextConfiguration.class) public class DeviceProvisionServiceTest { - @MockBean + @org.springframework.context.annotation.Configuration + static class ContextConfiguration { + @org.springframework.context.annotation.Bean + public DeviceProvisionServiceImpl deviceProvisionService(TbQueueProducerProvider producerProvider, + DeviceProfileService deviceProfileService, + DeviceService deviceService, + DeviceCredentialsService deviceCredentialsService, + AttributesService attributesService, + AuditLogService auditLogService, + PartitionService partitionService) { + return new DeviceProvisionServiceImpl(producerProvider, deviceProfileService, deviceService, + deviceCredentialsService, attributesService, auditLogService, partitionService); + } + } + + @MockitoBean protected TbQueueProducerProvider producerProvider; - @MockBean + @MockitoBean protected TbQueueProducer> ruleEngineMsgProducer; - @MockBean + @MockitoBean protected TbClusterService clusterService; - @MockBean + @MockitoBean protected DeviceProfileService deviceProfileService; - @MockBean + @MockitoBean protected DeviceService deviceService; - @MockBean + @MockitoBean protected DeviceCredentialsService deviceCredentialsService; - @MockBean + @MockitoBean protected AttributesService attributesService; - @MockBean + @MockitoBean protected AuditLogService auditLogService; - @MockBean + @MockitoBean protected PartitionService partitionService; - @SpyBean + @MockitoSpyBean DeviceProvisionServiceImpl service; private String[] chain; diff --git a/application/src/test/java/org/thingsboard/server/service/entitiy/alarm/DefaultTbAlarmServiceTest.java b/application/src/test/java/org/thingsboard/server/service/entitiy/alarm/DefaultTbAlarmServiceTest.java index 96e4444ffd..67535b6266 100644 --- a/application/src/test/java/org/thingsboard/server/service/entitiy/alarm/DefaultTbAlarmServiceTest.java +++ b/application/src/test/java/org/thingsboard/server/service/entitiy/alarm/DefaultTbAlarmServiceTest.java @@ -19,7 +19,7 @@ import com.datastax.oss.driver.api.core.uuid.Uuids; import com.fasterxml.jackson.databind.node.ObjectNode; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.cluster.TbClusterService; @@ -69,35 +69,35 @@ import static org.thingsboard.server.common.data.alarm.AlarmCommentSubType.UNASS @SpringJUnitConfig(DefaultTbAlarmService.class) class DefaultTbAlarmServiceTest { - @MockBean + @MockitoBean TbLogEntityActionService logEntityActionService; - @MockBean + @MockitoBean EdgeService edgeService; - @MockBean + @MockitoBean AlarmService alarmService; - @MockBean + @MockitoBean TbAlarmCommentService alarmCommentService; - @MockBean + @MockitoBean AlarmSubscriptionService alarmSubscriptionService; - @MockBean + @MockitoBean CustomerService customerService; - @MockBean + @MockitoBean TbClusterService tbClusterService; - @MockBean + @MockitoBean EntitiesVersionControlService vcService; - @MockBean + @MockitoBean AccessControlService accessControlService; - @MockBean + @MockitoBean TenantService tenantService; - @MockBean + @MockitoBean AssetService assetService; - @MockBean + @MockitoBean DeviceService deviceService; - @MockBean + @MockitoBean AssetProfileService assetProfileService; - @MockBean + @MockitoBean DeviceProfileService deviceProfileService; - @MockBean + @MockitoBean EntityService entityService; @Autowired diff --git a/application/src/test/java/org/thingsboard/server/service/entitiy/alarmComment/DefaultTbAlarmCommentServiceTest.java b/application/src/test/java/org/thingsboard/server/service/entitiy/alarmComment/DefaultTbAlarmCommentServiceTest.java index 2c2d2bbdc3..122a939a9d 100644 --- a/application/src/test/java/org/thingsboard/server/service/entitiy/alarmComment/DefaultTbAlarmCommentServiceTest.java +++ b/application/src/test/java/org/thingsboard/server/service/entitiy/alarmComment/DefaultTbAlarmCommentServiceTest.java @@ -19,8 +19,8 @@ import lombok.extern.slf4j.Slf4j; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mockito; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.TestPropertySource; import org.springframework.test.context.junit4.SpringRunner; @@ -65,35 +65,35 @@ import static org.mockito.Mockito.when; }) public class DefaultTbAlarmCommentServiceTest { - @MockBean + @MockitoBean protected DbCallbackExecutorService dbExecutor; - @MockBean + @MockitoBean protected TbLogEntityActionService logEntityActionService; - @MockBean + @MockitoBean protected AlarmService alarmService; - @MockBean + @MockitoBean protected AlarmCommentService alarmCommentService; - @MockBean + @MockitoBean protected AlarmSubscriptionService alarmSubscriptionService; - @MockBean + @MockitoBean protected CustomerService customerService; - @MockBean + @MockitoBean protected TbClusterService tbClusterService; - @MockBean + @MockitoBean private AccessControlService accessControlService; - @MockBean + @MockitoBean private TenantService tenantService; - @MockBean + @MockitoBean private AssetService assetService; - @MockBean + @MockitoBean private DeviceService deviceService; - @MockBean + @MockitoBean private AssetProfileService assetProfileService; - @MockBean + @MockitoBean private DeviceProfileService deviceProfileService; - @MockBean + @MockitoBean private EntityService entityService; - @SpyBean + @MockitoSpyBean DefaultTbAlarmCommentService service; @Test diff --git a/application/src/test/java/org/thingsboard/server/service/install/InstallScriptsTest.java b/application/src/test/java/org/thingsboard/server/service/install/InstallScriptsTest.java index fa675fc3f8..5caf2ececd 100644 --- a/application/src/test/java/org/thingsboard/server/service/install/InstallScriptsTest.java +++ b/application/src/test/java/org/thingsboard/server/service/install/InstallScriptsTest.java @@ -20,8 +20,8 @@ import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.common.data.id.RuleChainId; import org.thingsboard.server.common.data.id.TenantId; @@ -52,30 +52,30 @@ import static org.mockito.BDDMockito.willReturn; @SpringBootTest(classes = {InstallScripts.class, RuleChainDataValidator.class}) class InstallScriptsTest { - @MockBean + @MockitoBean RuleChainService ruleChainService; - @MockBean + @MockitoBean DashboardService dashboardService; - @MockBean + @MockitoBean WidgetTypeService widgetTypeService; - @MockBean + @MockitoBean WidgetsBundleService widgetsBundleService; - @MockBean + @MockitoBean OAuth2ConfigTemplateService oAuth2TemplateService; - @MockBean + @MockitoBean ResourceService resourceService; - @MockBean + @MockitoBean ImageService imageService; - @MockBean + @MockitoBean ResourcesUpdater resourcesUpdater; - @SpyBean + @MockitoSpyBean InstallScripts installScripts; - @MockBean + @MockitoBean TenantService tenantService; - @MockBean + @MockitoBean ApiLimitService apiLimitService; - @SpyBean + @MockitoSpyBean RuleChainDataValidator ruleChainValidator; TenantId tenantId = TenantId.fromUUID(UUID.fromString("9ef79cdf-37a8-4119-b682-2e7ed4e018da")); diff --git a/application/src/test/java/org/thingsboard/server/service/job/JobManagerTest.java b/application/src/test/java/org/thingsboard/server/service/job/JobManagerTest.java index 63fa4a7da4..4e74a3e06e 100644 --- a/application/src/test/java/org/thingsboard/server/service/job/JobManagerTest.java +++ b/application/src/test/java/org/thingsboard/server/service/job/JobManagerTest.java @@ -22,7 +22,7 @@ import org.junit.Before; import org.junit.Test; import org.mockito.Mockito; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.springframework.test.context.TestPropertySource; import org.thingsboard.rule.engine.api.JobManager; import org.thingsboard.server.common.data.Device; @@ -68,10 +68,10 @@ public class JobManagerTest extends AbstractControllerTest { @Autowired private JobManager jobManager; - @SpyBean + @MockitoSpyBean private TestTaskProcessor taskProcessor; - @SpyBean + @MockitoSpyBean private JobStatsService jobStatsService; @Autowired diff --git a/application/src/test/java/org/thingsboard/server/service/queue/DefaultTbClusterServiceTest.java b/application/src/test/java/org/thingsboard/server/service/queue/DefaultTbClusterServiceTest.java index 8110f6c0e3..79b31acf78 100644 --- a/application/src/test/java/org/thingsboard/server/service/queue/DefaultTbClusterServiceTest.java +++ b/application/src/test/java/org/thingsboard/server/service/queue/DefaultTbClusterServiceTest.java @@ -20,8 +20,8 @@ import lombok.extern.slf4j.Slf4j; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringRunner; import org.thingsboard.common.util.JacksonUtil; @@ -56,6 +56,7 @@ import org.thingsboard.server.queue.discovery.PartitionService; import org.thingsboard.server.queue.discovery.TopicService; import org.thingsboard.server.queue.provider.TbQueueProducerProvider; import org.thingsboard.server.service.gateway_device.GatewayNotificationsService; +import org.thingsboard.server.service.ota.OtaPackageStateService; import org.thingsboard.server.service.profile.TbAssetProfileCache; import org.thingsboard.server.service.profile.TbDeviceProfileCache; @@ -67,6 +68,7 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.isNull; import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.lenient; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; @@ -87,30 +89,45 @@ public class DefaultTbClusterServiceTest { public static final String TRANSPORT = "transport"; - @MockBean + @MockitoBean protected TbDeviceProfileCache deviceProfileCache; - @MockBean + @MockitoBean protected TbAssetProfileCache assetProfileCache; - @MockBean + @MockitoBean protected GatewayNotificationsService gatewayNotificationsService; - @MockBean + @MockitoBean protected EdgeService edgeService; - @MockBean + @MockitoBean protected PartitionService partitionService; - @MockBean + @MockitoBean protected TbQueueProducerProvider producerProvider; - @MockBean + @MockitoBean protected TbRuleEngineProducerService ruleEngineProducerService; - @MockBean + @MockitoBean protected TbTransactionalCache edgeCache; - @MockBean + @MockitoBean protected CalculatedFieldService calculatedFieldService; - @SpyBean + @MockitoBean protected TopicService topicService; - @SpyBean + @MockitoBean + protected OtaPackageStateService otaPackageStateService; + @MockitoSpyBean protected TbClusterService clusterService; + @org.junit.Before + public void setUp() { + lenient().when(topicService.getNotificationsTopic(any(), any())).thenAnswer(invocation -> { + ServiceType serviceType = invocation.getArgument(0); + String serviceId = invocation.getArgument(1); + return new TopicPartitionInfo(serviceType.name().toLowerCase() + ".notifications." + serviceId, null, null, false); + }); + lenient().when(topicService.getCalculatedFieldNotificationsTopic(any())).thenAnswer(invocation -> { + String serviceId = invocation.getArgument(0); + return new TopicPartitionInfo("calculated_field.notifications." + serviceId, null, null, false); + }); + } + @Test public void testOnQueueChangeSingleMonolith() { when(partitionService.getAllServiceIds(ServiceType.TB_RULE_ENGINE)).thenReturn(Sets.newHashSet(MONOLITH)); diff --git a/application/src/test/java/org/thingsboard/server/service/sms/DefaultSmsServiceTest.java b/application/src/test/java/org/thingsboard/server/service/sms/DefaultSmsServiceTest.java index 28ce4ea46a..8d27b07550 100644 --- a/application/src/test/java/org/thingsboard/server/service/sms/DefaultSmsServiceTest.java +++ b/application/src/test/java/org/thingsboard/server/service/sms/DefaultSmsServiceTest.java @@ -22,7 +22,7 @@ import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.springframework.test.context.TestPropertySource; import org.testcontainers.shaded.org.apache.commons.lang3.RandomStringUtils; import org.thingsboard.common.util.JacksonUtil; @@ -55,7 +55,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. "usage.stats.report.urgent_interval=1" }) public class DefaultSmsServiceTest extends AbstractControllerTest { - @SpyBean + @MockitoSpyBean private DefaultSmsService defaultSmsService; @Autowired private AdminSettingsService adminSettingsService; diff --git a/application/src/test/java/org/thingsboard/server/service/sync/ie/ExportImportServiceSqlTest.java b/application/src/test/java/org/thingsboard/server/service/sync/ie/ExportImportServiceSqlTest.java index 9630dacdd4..75dce3b2b3 100644 --- a/application/src/test/java/org/thingsboard/server/service/sync/ie/ExportImportServiceSqlTest.java +++ b/application/src/test/java/org/thingsboard/server/service/sync/ie/ExportImportServiceSqlTest.java @@ -22,7 +22,7 @@ import org.junit.Before; import org.junit.Test; import org.mockito.Mockito; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.rule.engine.debug.TbMsgGeneratorNode; import org.thingsboard.rule.engine.debug.TbMsgGeneratorNodeConfiguration; @@ -127,9 +127,9 @@ import static org.mockito.Mockito.verify; @DaoSqlTest public class ExportImportServiceSqlTest extends AbstractControllerTest { - @SpyBean + @MockitoSpyBean private EntityActionService entityActionService; - @SpyBean + @MockitoSpyBean private OtaPackageStateService otaPackageStateService; @Autowired diff --git a/application/src/test/java/org/thingsboard/server/service/transport/DefaultTransportApiServiceTest.java b/application/src/test/java/org/thingsboard/server/service/transport/DefaultTransportApiServiceTest.java index afb77945ab..6b667cc811 100644 --- a/application/src/test/java/org/thingsboard/server/service/transport/DefaultTransportApiServiceTest.java +++ b/application/src/test/java/org/thingsboard/server/service/transport/DefaultTransportApiServiceTest.java @@ -20,8 +20,8 @@ import lombok.extern.slf4j.Slf4j; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringRunner; import org.thingsboard.server.cache.ota.OtaPackageDataCache; @@ -69,38 +69,60 @@ import static org.mockito.Mockito.when; @Slf4j @RunWith(SpringRunner.class) -@ContextConfiguration(classes = DefaultTransportApiService.class) +@ContextConfiguration(classes = DefaultTransportApiServiceTest.ContextConfiguration.class) public class DefaultTransportApiServiceTest { - @MockBean + @org.springframework.context.annotation.Configuration + static class ContextConfiguration { + @org.springframework.context.annotation.Bean + public DefaultTransportApiService defaultTransportApiService(TbDeviceProfileCache deviceProfileCache, + TbTenantProfileCache tenantProfileCache, + TbApiUsageStateService apiUsageStateService, + DeviceService deviceService, + DeviceProfileService deviceProfileService, + RelationService relationService, + DeviceCredentialsService deviceCredentialsService, + TbClusterService tbClusterService, + DeviceProvisionService deviceProvisionService, + ResourceService resourceService, + OtaPackageService otaPackageService, + OtaPackageDataCache otaPackageDataCache, + QueueService queueService) { + return new DefaultTransportApiService(deviceProfileCache, tenantProfileCache, apiUsageStateService, + deviceService, deviceProfileService, relationService, deviceCredentialsService, tbClusterService, + deviceProvisionService, resourceService, otaPackageService, otaPackageDataCache, queueService); + } + } + + @MockitoBean protected TbDeviceProfileCache deviceProfileCache; - @MockBean + @MockitoBean protected TbTenantProfileCache tenantProfileCache; - @MockBean + @MockitoBean protected TbApiUsageStateService apiUsageStateService; - @MockBean + @MockitoBean protected DeviceService deviceService; - @MockBean + @MockitoBean protected DeviceProfileService deviceProfileService; - @MockBean + @MockitoBean protected RelationService relationService; - @MockBean + @MockitoBean protected DeviceCredentialsService deviceCredentialsService; - @MockBean + @MockitoBean protected DbCallbackExecutorService dbCallbackExecutorService; - @MockBean + @MockitoBean protected TbClusterService tbClusterService; - @MockBean + @MockitoBean protected DeviceProvisionService deviceProvisionService; - @MockBean + @MockitoBean protected ResourceService resourceService; - @MockBean + @MockitoBean protected OtaPackageService otaPackageService; - @MockBean + @MockitoBean protected OtaPackageDataCache otaPackageDataCache; - @MockBean + @MockitoBean protected QueueService queueService; - @SpyBean + @MockitoSpyBean DefaultTransportApiService service; private String certificateChain; diff --git a/application/src/test/java/org/thingsboard/server/service/ttl/AlarmsCleanUpServiceTest.java b/application/src/test/java/org/thingsboard/server/service/ttl/AlarmsCleanUpServiceTest.java index fcb948239f..a74db4593c 100644 --- a/application/src/test/java/org/thingsboard/server/service/ttl/AlarmsCleanUpServiceTest.java +++ b/application/src/test/java/org/thingsboard/server/service/ttl/AlarmsCleanUpServiceTest.java @@ -21,7 +21,7 @@ import org.mockito.Mockito; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.springframework.test.context.TestPropertySource; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.alarm.Alarm; @@ -50,9 +50,9 @@ import static org.mockito.Mockito.verify; }) public class AlarmsCleanUpServiceTest extends AbstractControllerTest { - @SpyBean + @MockitoSpyBean private AlarmsCleanUpService alarmsCleanUpService; - @SpyBean + @MockitoSpyBean private AlarmService alarmService; @Autowired private AlarmDao alarmDao; diff --git a/application/src/test/java/org/thingsboard/server/transport/lwm2m/AbstractLwM2MIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/lwm2m/AbstractLwM2MIntegrationTest.java index f3a3212e67..4d5114425f 100644 --- a/application/src/test/java/org/thingsboard/server/transport/lwm2m/AbstractLwM2MIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/lwm2m/AbstractLwM2MIntegrationTest.java @@ -37,7 +37,7 @@ import org.junit.Assert; import org.junit.Before; import org.mockito.Mockito; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.springframework.http.HttpStatus; import org.springframework.test.context.DynamicPropertyRegistry; import org.springframework.test.context.DynamicPropertySource; @@ -133,10 +133,10 @@ import static org.thingsboard.server.transport.lwm2m.ota.AbstractOtaLwM2MIntegra }) public abstract class AbstractLwM2MIntegrationTest extends AbstractTransportIntegrationTest { - @SpyBean + @MockitoSpyBean protected LwM2mUplinkMsgHandler defaultLwM2mUplinkMsgHandlerTest; - @SpyBean + @MockitoSpyBean protected DefaultLwM2mUplinkMsgHandler defaultUplinkMsgHandlerTest; @Autowired diff --git a/application/src/test/java/org/thingsboard/server/transport/lwm2m/rpc/AbstractRpcLwM2MIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/lwm2m/rpc/AbstractRpcLwM2MIntegrationTest.java index 3c4bdcd3e7..b511d8b1e2 100644 --- a/application/src/test/java/org/thingsboard/server/transport/lwm2m/rpc/AbstractRpcLwM2MIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/lwm2m/rpc/AbstractRpcLwM2MIntegrationTest.java @@ -22,7 +22,7 @@ import org.eclipse.leshan.core.link.LinkParser; import org.eclipse.leshan.core.link.lwm2m.DefaultLwM2mLinkParser; import org.junit.Before; import org.mockito.Mockito; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.DeviceProfile; import org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MDeviceCredentials; @@ -103,7 +103,7 @@ public abstract class AbstractRpcLwM2MIntegrationTest extends AbstractLwM2MInteg protected String idVer_19_0_0; - @SpyBean + @MockitoSpyBean protected LwM2mTransportServerHelper lwM2mTransportServerHelperTest; @Before diff --git a/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/diffPort/AbstractLwM2MIntegrationDiffPortTest.java b/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/diffPort/AbstractLwM2MIntegrationDiffPortTest.java index afb179cc5f..f145d6a62a 100644 --- a/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/diffPort/AbstractLwM2MIntegrationDiffPortTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/diffPort/AbstractLwM2MIntegrationDiffPortTest.java @@ -24,7 +24,7 @@ import org.eclipse.leshan.server.registration.RegistrationStore; import org.eclipse.leshan.server.registration.RegistrationUpdate; import org.junit.Assert; import org.mockito.Mockito; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.DeviceProfile; import org.thingsboard.server.common.data.device.profile.Lwm2mDeviceProfileTransportConfiguration; @@ -49,7 +49,7 @@ import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MClient @Slf4j public abstract class AbstractLwM2MIntegrationDiffPortTest extends AbstractSecurityLwM2MIntegrationTest { - @SpyBean + @MockitoSpyBean private RegistrationStore registrationStoreTest; protected void basicTestConnectionDifferentPort(Lwm2mDeviceProfileTransportConfiguration transportConfiguration, diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/MqttGatewayRateLimitsTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/MqttGatewayRateLimitsTest.java index 541ca40072..d2c2b546f7 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/MqttGatewayRateLimitsTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/MqttGatewayRateLimitsTest.java @@ -22,7 +22,7 @@ import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.mockito.Mockito; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.springframework.test.context.DynamicPropertyRegistry; import org.springframework.test.context.DynamicPropertySource; import org.springframework.test.context.TestPropertySource; @@ -71,7 +71,7 @@ public class MqttGatewayRateLimitsTest extends AbstractControllerTest { private Device gateway; private String gatewayAccessToken; - @SpyBean + @MockitoSpyBean private NotificationRuleProcessor notificationRuleProcessor; @Before diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/telemetry/timeseries/AbstractMqttTimeseriesIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/telemetry/timeseries/AbstractMqttTimeseriesIntegrationTest.java index ea40a574a5..07837d9d8f 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/telemetry/timeseries/AbstractMqttTimeseriesIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/telemetry/timeseries/AbstractMqttTimeseriesIntegrationTest.java @@ -21,7 +21,7 @@ import lombok.extern.slf4j.Slf4j; import org.junit.Before; import org.junit.Test; import org.mockito.ArgumentCaptor; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.id.DeviceId; @@ -67,7 +67,7 @@ public abstract class AbstractMqttTimeseriesIntegrationTest extends AbstractMqtt protected static final String MALFORMED_JSON_PAYLOAD = "{\"key1\":, \"key2\":true, \"key3\": 3.0, \"key4\": 4," + " \"key5\": {\"someNumber\": 42, \"someArray\": [1,2,3], \"someNestedObject\": {\"key\": \"value\"}}}"; - @SpyBean + @MockitoSpyBean GatewayMetricsService gatewayMetricsService; @Before diff --git a/dao/src/test/java/org/thingsboard/server/dao/AbstractDaoServiceTest.java b/dao/src/test/java/org/thingsboard/server/dao/AbstractDaoServiceTest.java index 267dd52882..4aa50de3cc 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/AbstractDaoServiceTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/AbstractDaoServiceTest.java @@ -17,7 +17,7 @@ package org.thingsboard.server.dao; import org.junit.runner.RunWith; import org.mockito.Answers; -import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.TestExecutionListeners; @@ -40,7 +40,7 @@ import org.thingsboard.server.dao.service.DaoSqlTest; DirtiesContextTestExecutionListener.class}) public abstract class AbstractDaoServiceTest { - @MockBean(answer = Answers.RETURNS_MOCKS) + @MockitoBean(answers = Answers.RETURNS_MOCKS) StatsFactory statsFactory; } diff --git a/dao/src/test/java/org/thingsboard/server/dao/AbstractJpaDaoTest.java b/dao/src/test/java/org/thingsboard/server/dao/AbstractJpaDaoTest.java index f68ab72786..dc5cc47cf7 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/AbstractJpaDaoTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/AbstractJpaDaoTest.java @@ -17,7 +17,7 @@ package org.thingsboard.server.dao; import org.junit.runner.RunWith; import org.mockito.Answers; -import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.TestExecutionListeners; import org.springframework.test.context.junit4.SpringRunner; @@ -42,7 +42,7 @@ import org.thingsboard.server.dao.service.DaoSqlTest; DirtiesContextTestExecutionListener.class}) public abstract class AbstractJpaDaoTest { - @MockBean(answer = Answers.RETURNS_MOCKS) + @MockitoBean(answers = Answers.RETURNS_MOCKS) StatsFactory statsFactory; } diff --git a/dao/src/test/java/org/thingsboard/server/dao/cache/RedisTbTransactionalCacheTest.java b/dao/src/test/java/org/thingsboard/server/dao/cache/RedisTbTransactionalCacheTest.java index 5de4378cf0..a9feec982b 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/cache/RedisTbTransactionalCacheTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/cache/RedisTbTransactionalCacheTest.java @@ -18,7 +18,7 @@ package org.thingsboard.server.dao.cache; import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; -import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.springframework.data.redis.connection.RedisConnection; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.test.context.ContextConfiguration; @@ -50,13 +50,13 @@ import static org.mockito.Mockito.when; @Slf4j public class RedisTbTransactionalCacheTest { - @MockBean + @MockitoBean private RelationRedisCache relationRedisCache; - @MockBean + @MockitoBean private RedisConnectionFactory connectionFactory; - @MockBean + @MockitoBean private RedisConnection redisConnection; - @MockBean + @MockitoBean private RedisSslCredentials redisSslCredentials; @Test diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/DeviceServiceTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/DeviceServiceTest.java index b9fd609521..9765923967 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/DeviceServiceTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/DeviceServiceTest.java @@ -27,7 +27,7 @@ import org.junit.Test; import org.junit.jupiter.api.Assertions; import org.mockito.Mockito; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.TransactionStatus; import org.springframework.transaction.support.DefaultTransactionDefinition; @@ -111,7 +111,7 @@ public class DeviceServiceTest extends AbstractServiceTest { private CalculatedFieldService calculatedFieldService; @Autowired private PlatformTransactionManager platformTransactionManager; - @SpyBean + @MockitoSpyBean private DeviceCredentialsDataValidator validator; private IdComparator idComparator = new IdComparator<>(); diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/TenantServiceTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/TenantServiceTest.java index 1873fa9ea9..53630a9167 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/TenantServiceTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/TenantServiceTest.java @@ -20,7 +20,7 @@ import org.junit.Test; import org.junit.jupiter.api.Assertions; import org.mockito.Mockito; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.cache.TbTransactionalCache; import org.thingsboard.server.common.data.Customer; @@ -87,7 +87,7 @@ import static org.mockito.Mockito.verify; @DaoSqlTest public class TenantServiceTest extends AbstractServiceTest { - @SpyBean + @MockitoSpyBean TenantDao tenantDao; @Autowired diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/validator/AdminSettingsDataValidatorTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/validator/AdminSettingsDataValidatorTest.java index c550772718..6241f2dea3 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/validator/AdminSettingsDataValidatorTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/validator/AdminSettingsDataValidatorTest.java @@ -17,8 +17,8 @@ package org.thingsboard.server.dao.service.validator; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.common.data.AdminSettings; import org.thingsboard.server.common.data.id.TenantId; @@ -31,9 +31,9 @@ import static org.mockito.Mockito.verify; @SpringBootTest(classes = AdminSettingsDataValidator.class) class AdminSettingsDataValidatorTest { - @MockBean + @MockitoBean AdminSettingsService adminSettingsService; - @SpyBean + @MockitoSpyBean AdminSettingsDataValidator validator; TenantId tenantId = TenantId.fromUUID(UUID.fromString("9ef79cdf-37a8-4119-b682-2e7ed4e018da")); diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/validator/AlarmDataValidatorTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/validator/AlarmDataValidatorTest.java index 89b0b0cec4..e36aa20773 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/validator/AlarmDataValidatorTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/validator/AlarmDataValidatorTest.java @@ -18,8 +18,8 @@ package org.thingsboard.server.dao.service.validator; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.thingsboard.server.common.data.alarm.Alarm; import org.thingsboard.server.common.data.alarm.AlarmSeverity; import org.thingsboard.server.common.data.id.TenantId; @@ -33,9 +33,9 @@ import static org.mockito.Mockito.verify; @SpringBootTest(classes = AlarmDataValidator.class) class AlarmDataValidatorTest { - @MockBean + @MockitoBean TenantService tenantService; - @SpyBean + @MockitoSpyBean AlarmDataValidator validator; TenantId tenantId = TenantId.fromUUID(UUID.fromString("9ef79cdf-37a8-4119-b682-2e7ed4e018da")); diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/validator/AssetDataValidatorTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/validator/AssetDataValidatorTest.java index eb46a87018..e5c51ac064 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/validator/AssetDataValidatorTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/validator/AssetDataValidatorTest.java @@ -22,7 +22,7 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.thingsboard.server.common.data.asset.Asset; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.dao.asset.AssetDao; @@ -39,11 +39,11 @@ import static org.mockito.BDDMockito.willReturn; @Slf4j class AssetDataValidatorTest { - @MockBean + @MockitoBean AssetDao assetDao; - @MockBean + @MockitoBean TenantService tenantService; - @MockBean + @MockitoBean CustomerDao customerDao; @Autowired AssetDataValidator validator; diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/validator/AssetProfileDataValidatorTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/validator/AssetProfileDataValidatorTest.java index b5cfb4998c..a8060cd51f 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/validator/AssetProfileDataValidatorTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/validator/AssetProfileDataValidatorTest.java @@ -18,8 +18,8 @@ package org.thingsboard.server.dao.service.validator; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.thingsboard.server.common.data.asset.AssetProfile; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.dao.asset.AssetProfileDao; @@ -37,19 +37,19 @@ import static org.mockito.Mockito.verify; @SpringBootTest(classes = AssetProfileDataValidator.class) class AssetProfileDataValidatorTest { - @MockBean + @MockitoBean AssetProfileDao assetProfileDao; - @MockBean + @MockitoBean AssetProfileService assetProfileService; - @MockBean + @MockitoBean TenantService tenantService; - @MockBean + @MockitoBean QueueService queueService; - @MockBean + @MockitoBean RuleChainService ruleChainService; - @MockBean + @MockitoBean DashboardService dashboardService; - @SpyBean + @MockitoSpyBean AssetProfileDataValidator validator; TenantId tenantId = TenantId.fromUUID(UUID.fromString("9ef79cdf-37a8-4119-b682-2e7ed4e018da")); diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/validator/ComponentDescriptorDataValidatorTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/validator/ComponentDescriptorDataValidatorTest.java index c810dd5c63..1dfc1d4e8d 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/validator/ComponentDescriptorDataValidatorTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/validator/ComponentDescriptorDataValidatorTest.java @@ -17,7 +17,7 @@ package org.thingsboard.server.dao.service.validator; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.plugin.ComponentDescriptor; import org.thingsboard.server.common.data.plugin.ComponentScope; @@ -27,7 +27,7 @@ import static org.mockito.Mockito.verify; @SpringBootTest(classes = ComponentDescriptorDataValidator.class) class ComponentDescriptorDataValidatorTest { - @SpyBean + @MockitoSpyBean ComponentDescriptorDataValidator validator; @Test diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/validator/CustomerDataValidatorTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/validator/CustomerDataValidatorTest.java index d434d8f231..aa66f4003f 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/validator/CustomerDataValidatorTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/validator/CustomerDataValidatorTest.java @@ -18,8 +18,8 @@ package org.thingsboard.server.dao.service.validator; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.thingsboard.server.common.data.Customer; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.dao.customer.CustomerDao; @@ -33,11 +33,11 @@ import static org.mockito.Mockito.verify; @SpringBootTest(classes = CustomerDataValidator.class) class CustomerDataValidatorTest { - @MockBean + @MockitoBean CustomerDao customerDao; - @MockBean + @MockitoBean TenantService tenantService; - @SpyBean + @MockitoSpyBean CustomerDataValidator validator; TenantId tenantId = TenantId.fromUUID(UUID.fromString("9ef79cdf-37a8-4119-b682-2e7ed4e018da")); diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/validator/DashboardDataValidatorTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/validator/DashboardDataValidatorTest.java index 3029027f37..cf5ad6e8fe 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/validator/DashboardDataValidatorTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/validator/DashboardDataValidatorTest.java @@ -18,8 +18,8 @@ package org.thingsboard.server.dao.service.validator; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.thingsboard.server.common.data.Dashboard; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.dao.tenant.TenantService; @@ -32,9 +32,9 @@ import static org.mockito.Mockito.verify; @SpringBootTest(classes = DashboardDataValidator.class) class DashboardDataValidatorTest { - @MockBean + @MockitoBean TenantService tenantService; - @SpyBean + @MockitoSpyBean DashboardDataValidator validator; TenantId tenantId = TenantId.fromUUID(UUID.fromString("9ef79cdf-37a8-4119-b682-2e7ed4e018da")); diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/validator/DeviceDataValidatorTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/validator/DeviceDataValidatorTest.java index f0aacc91bd..a77c3e5fb7 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/validator/DeviceDataValidatorTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/validator/DeviceDataValidatorTest.java @@ -22,7 +22,7 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.dao.customer.CustomerDao; @@ -39,11 +39,11 @@ import static org.mockito.BDDMockito.willReturn; @Slf4j class DeviceDataValidatorTest { - @MockBean + @MockitoBean DeviceDao deviceDao; - @MockBean + @MockitoBean TenantService tenantService; - @MockBean + @MockitoBean CustomerDao customerDao; @Autowired DeviceDataValidator validator; diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/validator/DeviceProfileDataValidatorTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/validator/DeviceProfileDataValidatorTest.java index 34523c1829..8b2fa3c030 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/validator/DeviceProfileDataValidatorTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/validator/DeviceProfileDataValidatorTest.java @@ -18,8 +18,8 @@ package org.thingsboard.server.dao.service.validator; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.common.data.DeviceProfile; import org.thingsboard.server.common.data.DeviceProfileType; @@ -86,21 +86,21 @@ class DeviceProfileDataValidatorTest { private static final int port = 5685; private static final int portBs = 5687; - @MockBean + @MockitoBean DeviceProfileDao deviceProfileDao; - @MockBean + @MockitoBean DeviceProfileService deviceProfileService; - @MockBean + @MockitoBean DeviceDao deviceDao; - @MockBean + @MockitoBean TenantService tenantService; - @MockBean + @MockitoBean QueueService queueService; - @MockBean + @MockitoBean RuleChainService ruleChainService; - @MockBean + @MockitoBean DashboardService dashboardService; - @SpyBean + @MockitoSpyBean DeviceProfileDataValidator validator; TenantId tenantId = TenantId.fromUUID(UUID.fromString("9ef79cdf-37a8-4119-b682-2e7ed4e018da")); diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/validator/EdgeDataValidatorTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/validator/EdgeDataValidatorTest.java index 98699b0176..2f4ed4426f 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/validator/EdgeDataValidatorTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/validator/EdgeDataValidatorTest.java @@ -18,8 +18,8 @@ package org.thingsboard.server.dao.service.validator; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.thingsboard.server.common.data.edge.Edge; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.dao.customer.CustomerDao; @@ -34,13 +34,13 @@ import static org.mockito.Mockito.verify; @SpringBootTest(classes = EdgeDataValidator.class) class EdgeDataValidatorTest { - @MockBean + @MockitoBean EdgeDao edgeDao; - @MockBean + @MockitoBean TenantService tenantService; - @MockBean + @MockitoBean CustomerDao customerDao; - @SpyBean + @MockitoSpyBean EdgeDataValidator validator; TenantId tenantId = TenantId.fromUUID(UUID.fromString("9ef79cdf-37a8-4119-b682-2e7ed4e018da")); diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/validator/EntityViewDataValidatorTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/validator/EntityViewDataValidatorTest.java index 3db9d77469..ab821de252 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/validator/EntityViewDataValidatorTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/validator/EntityViewDataValidatorTest.java @@ -18,8 +18,8 @@ package org.thingsboard.server.dao.service.validator; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.thingsboard.server.common.data.EntityView; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.dao.customer.CustomerDao; @@ -34,13 +34,13 @@ import static org.mockito.Mockito.verify; @SpringBootTest(classes = EntityViewDataValidator.class) class EntityViewDataValidatorTest { - @MockBean + @MockitoBean EntityViewDao entityViewDao; - @MockBean + @MockitoBean TenantService tenantService; - @MockBean + @MockitoBean CustomerDao customerDao; - @SpyBean + @MockitoSpyBean EntityViewDataValidator validator; TenantId tenantId = TenantId.fromUUID(UUID.fromString("9ef79cdf-37a8-4119-b682-2e7ed4e018da")); diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/validator/ResourceDataValidatorTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/validator/ResourceDataValidatorTest.java index 9072bb5e62..059e966040 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/validator/ResourceDataValidatorTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/validator/ResourceDataValidatorTest.java @@ -18,8 +18,8 @@ package org.thingsboard.server.dao.service.validator; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.thingsboard.server.common.data.ResourceType; import org.thingsboard.server.common.data.TbResource; import org.thingsboard.server.common.data.id.TenantId; @@ -36,15 +36,15 @@ import static org.mockito.Mockito.verify; @SpringBootTest(classes = ResourceDataValidator.class) class ResourceDataValidatorTest { - @MockBean + @MockitoBean TbResourceDao resourceDao; - @MockBean + @MockitoBean WidgetTypeDao widgetTypeDao; - @MockBean + @MockitoBean TenantService tenantService; - @MockBean + @MockitoBean TbTenantProfileCache tenantProfileCache; - @SpyBean + @MockitoSpyBean ResourceDataValidator validator; TenantId tenantId = TenantId.fromUUID(UUID.fromString("9ef79cdf-37a8-4119-b682-2e7ed4e018da")); diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/validator/RuleChainDataValidatorTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/validator/RuleChainDataValidatorTest.java index 9107d1f8f2..eb884edbf3 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/validator/RuleChainDataValidatorTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/validator/RuleChainDataValidatorTest.java @@ -18,8 +18,8 @@ package org.thingsboard.server.dao.service.validator; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.rule.RuleChain; import org.thingsboard.server.common.data.rule.RuleChainType; @@ -34,11 +34,11 @@ import static org.mockito.Mockito.verify; @SpringBootTest(classes = RuleChainDataValidator.class) class RuleChainDataValidatorTest { - @MockBean + @MockitoBean RuleChainService ruleChainService; - @MockBean + @MockitoBean TenantService tenantService; - @SpyBean + @MockitoSpyBean RuleChainDataValidator validator; TenantId tenantId = TenantId.fromUUID(UUID.fromString("9ef79cdf-37a8-4119-b682-2e7ed4e018da")); diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/validator/TenantDataValidatorTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/validator/TenantDataValidatorTest.java index c7e4f73ce4..ca1871a1dc 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/validator/TenantDataValidatorTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/validator/TenantDataValidatorTest.java @@ -17,8 +17,8 @@ package org.thingsboard.server.dao.service.validator; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.thingsboard.server.common.data.Tenant; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.dao.tenant.TenantDao; @@ -30,9 +30,9 @@ import static org.mockito.Mockito.verify; @SpringBootTest(classes = TenantDataValidator.class) class TenantDataValidatorTest { - @MockBean + @MockitoBean TenantDao tenantDao; - @SpyBean + @MockitoSpyBean TenantDataValidator validator; TenantId tenantId = TenantId.fromUUID(UUID.fromString("9ef79cdf-37a8-4119-b682-2e7ed4e018da")); diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/validator/WidgetTypeDataValidatorTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/validator/WidgetTypeDataValidatorTest.java index 3849aa62bf..3904c7d509 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/validator/WidgetTypeDataValidatorTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/validator/WidgetTypeDataValidatorTest.java @@ -18,8 +18,8 @@ package org.thingsboard.server.dao.service.validator; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.widget.WidgetTypeDetails; @@ -34,13 +34,13 @@ import static org.mockito.Mockito.verify; @SpringBootTest(classes = WidgetTypeDataValidator.class) class WidgetTypeDataValidatorTest { - @MockBean + @MockitoBean WidgetTypeDao widgetTypeDao; - @MockBean + @MockitoBean WidgetsBundleDao widgetsBundleDao; - @MockBean + @MockitoBean TenantService tenantService; - @SpyBean + @MockitoSpyBean WidgetTypeDataValidator validator; TenantId tenantId = TenantId.fromUUID(UUID.fromString("9ef79cdf-37a8-4119-b682-2e7ed4e018da")); diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/validator/WidgetsBundleDataValidatorTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/validator/WidgetsBundleDataValidatorTest.java index 1affa60415..6ab7728471 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/validator/WidgetsBundleDataValidatorTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/validator/WidgetsBundleDataValidatorTest.java @@ -18,8 +18,8 @@ package org.thingsboard.server.dao.service.validator; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.widget.WidgetsBundle; import org.thingsboard.server.dao.tenant.TenantService; @@ -33,11 +33,11 @@ import static org.mockito.Mockito.verify; @SpringBootTest(classes = WidgetsBundleDataValidator.class) class WidgetsBundleDataValidatorTest { - @MockBean + @MockitoBean WidgetsBundleDao widgetsBundleDao; - @MockBean + @MockitoBean TenantService tenantService; - @SpyBean + @MockitoSpyBean WidgetsBundleDataValidator validator; TenantId tenantId = TenantId.fromUUID(UUID.fromString("9ef79cdf-37a8-4119-b682-2e7ed4e018da")); diff --git a/dao/src/test/java/org/thingsboard/server/dao/sql/query/DefaultEntityQueryRepositoryTest.java b/dao/src/test/java/org/thingsboard/server/dao/sql/query/DefaultEntityQueryRepositoryTest.java index b0d946ce3f..863d4ae2e8 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/sql/query/DefaultEntityQueryRepositoryTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/sql/query/DefaultEntityQueryRepositoryTest.java @@ -19,7 +19,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.transaction.support.TransactionTemplate; @@ -31,11 +31,11 @@ import static org.hamcrest.Matchers.equalTo; @SpringBootTest(classes = DefaultEntityQueryRepository.class) public class DefaultEntityQueryRepositoryTest { - @MockBean + @MockitoBean NamedParameterJdbcTemplate jdbcTemplate; - @MockBean + @MockitoBean TransactionTemplate transactionTemplate; - @MockBean + @MockitoBean DefaultQueryLogComponent queryLog; @Autowired diff --git a/dao/src/test/java/org/thingsboard/server/dao/sql/query/DefaultQueryLogComponentTest.java b/dao/src/test/java/org/thingsboard/server/dao/sql/query/DefaultQueryLogComponentTest.java index 83a06fe568..e47ed5bfbf 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/sql/query/DefaultQueryLogComponentTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/sql/query/DefaultQueryLogComponentTest.java @@ -22,7 +22,7 @@ import org.junit.runner.RunWith; import org.mockito.BDDMockito; import org.mockito.Mockito; import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.TestPropertySource; import org.springframework.test.context.junit.jupiter.SpringExtension; @@ -52,7 +52,7 @@ public class DefaultQueryLogComponentTest { private TenantId tenantId; private SqlQueryContext ctx; - @SpyBean + @MockitoSpyBean private DefaultQueryLogComponent queryLog; @Before diff --git a/dao/src/test/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDaoPartitioningDaysAlwaysExistsTest.java b/dao/src/test/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDaoPartitioningDaysAlwaysExistsTest.java index 43c8a064e1..05952e1203 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDaoPartitioningDaysAlwaysExistsTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDaoPartitioningDaysAlwaysExistsTest.java @@ -22,7 +22,7 @@ import org.mockito.Answers; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.springframework.test.context.TestPropertySource; import org.springframework.test.context.junit4.SpringRunner; import org.thingsboard.server.dao.cassandra.CassandraCluster; @@ -53,13 +53,13 @@ public class CassandraBaseTimeseriesDaoPartitioningDaysAlwaysExistsTest { @Autowired CassandraBaseTimeseriesDao tsDao; - @MockBean(answer = Answers.RETURNS_MOCKS) + @MockitoBean(answers = Answers.RETURNS_MOCKS) @Qualifier("CassandraCluster") CassandraCluster cassandraCluster; - @MockBean + @MockitoBean CassandraBufferedRateReadExecutor cassandraBufferedRateReadExecutor; - @MockBean + @MockitoBean CassandraBufferedRateWriteExecutor cassandraBufferedRateWriteExecutor; @Test diff --git a/dao/src/test/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDaoPartitioningHoursAlwaysExistsTest.java b/dao/src/test/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDaoPartitioningHoursAlwaysExistsTest.java index 5deccec298..83bb802c85 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDaoPartitioningHoursAlwaysExistsTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDaoPartitioningHoursAlwaysExistsTest.java @@ -22,7 +22,7 @@ import org.mockito.Answers; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.springframework.test.context.TestPropertySource; import org.springframework.test.context.junit4.SpringRunner; import org.thingsboard.server.dao.cassandra.CassandraCluster; @@ -53,13 +53,13 @@ public class CassandraBaseTimeseriesDaoPartitioningHoursAlwaysExistsTest { @Autowired CassandraBaseTimeseriesDao tsDao; - @MockBean(answer = Answers.RETURNS_MOCKS) + @MockitoBean(answers = Answers.RETURNS_MOCKS) @Qualifier("CassandraCluster") CassandraCluster cassandraCluster; - @MockBean + @MockitoBean CassandraBufferedRateReadExecutor cassandraBufferedRateReadExecutor; - @MockBean + @MockitoBean CassandraBufferedRateWriteExecutor cassandraBufferedRateWriteExecutor; @Test diff --git a/dao/src/test/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDaoPartitioningIndefiniteAlwaysExistsTest.java b/dao/src/test/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDaoPartitioningIndefiniteAlwaysExistsTest.java index a742e6cd2c..4f78f5b864 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDaoPartitioningIndefiniteAlwaysExistsTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDaoPartitioningIndefiniteAlwaysExistsTest.java @@ -22,7 +22,7 @@ import org.mockito.Answers; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.springframework.test.context.TestPropertySource; import org.springframework.test.context.junit4.SpringRunner; import org.thingsboard.server.dao.cassandra.CassandraCluster; @@ -52,13 +52,13 @@ public class CassandraBaseTimeseriesDaoPartitioningIndefiniteAlwaysExistsTest { @Autowired CassandraBaseTimeseriesDao tsDao; - @MockBean(answer = Answers.RETURNS_MOCKS) + @MockitoBean(answers = Answers.RETURNS_MOCKS) @Qualifier("CassandraCluster") CassandraCluster cassandraCluster; - @MockBean + @MockitoBean CassandraBufferedRateReadExecutor cassandraBufferedRateReadExecutor; - @MockBean + @MockitoBean CassandraBufferedRateWriteExecutor cassandraBufferedRateWriteExecutor; @Test diff --git a/dao/src/test/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDaoPartitioningMinutesAlwaysExistsTest.java b/dao/src/test/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDaoPartitioningMinutesAlwaysExistsTest.java index dd106cb439..455cf2cc00 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDaoPartitioningMinutesAlwaysExistsTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDaoPartitioningMinutesAlwaysExistsTest.java @@ -22,7 +22,7 @@ import org.mockito.Answers; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.springframework.test.context.TestPropertySource; import org.springframework.test.context.junit4.SpringRunner; import org.thingsboard.server.dao.cassandra.CassandraCluster; @@ -53,13 +53,13 @@ public class CassandraBaseTimeseriesDaoPartitioningMinutesAlwaysExistsTest { @Autowired CassandraBaseTimeseriesDao tsDao; - @MockBean(answer = Answers.RETURNS_MOCKS) + @MockitoBean(answers = Answers.RETURNS_MOCKS) @Qualifier("CassandraCluster") CassandraCluster cassandraCluster; - @MockBean + @MockitoBean CassandraBufferedRateReadExecutor cassandraBufferedRateReadExecutor; - @MockBean + @MockitoBean CassandraBufferedRateWriteExecutor cassandraBufferedRateWriteExecutor; @Test diff --git a/dao/src/test/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDaoPartitioningMonthsAlwaysExistsTest.java b/dao/src/test/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDaoPartitioningMonthsAlwaysExistsTest.java index 5699f5d5f7..ce8b66215b 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDaoPartitioningMonthsAlwaysExistsTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDaoPartitioningMonthsAlwaysExistsTest.java @@ -22,7 +22,7 @@ import org.junit.runner.RunWith; import org.mockito.Answers; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.springframework.test.context.TestPropertySource; import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.springframework.test.context.junit4.SpringRunner; @@ -63,13 +63,13 @@ public class CassandraBaseTimeseriesDaoPartitioningMonthsAlwaysExistsTest { @MockitoSpyBean CassandraBaseTimeseriesDao tsDao; - @MockBean(answer = Answers.RETURNS_MOCKS) + @MockitoBean(answers = Answers.RETURNS_MOCKS) @Qualifier("CassandraCluster") CassandraCluster cassandraCluster; - @MockBean + @MockitoBean CassandraBufferedRateReadExecutor cassandraBufferedRateReadExecutor; - @MockBean + @MockitoBean CassandraBufferedRateWriteExecutor cassandraBufferedRateWriteExecutor; @Test diff --git a/dao/src/test/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDaoPartitioningYearsAlwaysExistsTest.java b/dao/src/test/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDaoPartitioningYearsAlwaysExistsTest.java index a68daf664a..90575d5b14 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDaoPartitioningYearsAlwaysExistsTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDaoPartitioningYearsAlwaysExistsTest.java @@ -22,7 +22,7 @@ import org.mockito.Answers; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.springframework.test.context.TestPropertySource; import org.springframework.test.context.junit4.SpringRunner; import org.thingsboard.server.dao.cassandra.CassandraCluster; @@ -53,13 +53,13 @@ public class CassandraBaseTimeseriesDaoPartitioningYearsAlwaysExistsTest { @Autowired CassandraBaseTimeseriesDao tsDao; - @MockBean(answer = Answers.RETURNS_MOCKS) + @MockitoBean(answers = Answers.RETURNS_MOCKS) @Qualifier("CassandraCluster") CassandraCluster cassandraCluster; - @MockBean + @MockitoBean CassandraBufferedRateReadExecutor cassandraBufferedRateReadExecutor; - @MockBean + @MockitoBean CassandraBufferedRateWriteExecutor cassandraBufferedRateWriteExecutor; @Test diff --git a/edqs/src/test/java/org/thingsboard/server/edqs/repo/AbstractEDQTest.java b/edqs/src/test/java/org/thingsboard/server/edqs/repo/AbstractEDQTest.java index adb42203e0..edf8832a33 100644 --- a/edqs/src/test/java/org/thingsboard/server/edqs/repo/AbstractEDQTest.java +++ b/edqs/src/test/java/org/thingsboard/server/edqs/repo/AbstractEDQTest.java @@ -20,7 +20,7 @@ import org.junit.Before; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.domain.EntityScan; -import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.test.context.TestExecutionListeners; @@ -81,7 +81,7 @@ public abstract class AbstractEDQTest { protected DefaultEdqsRepository repository; @Autowired protected EdqsMapper edqsMapper; - @MockBean + @MockitoBean private DummyEdqsStatsService edqsStatsService; protected final TenantId tenantId = TenantId.fromUUID(UUID.randomUUID()); From de0e8c70e312d91904ff77e707de26b4aa9f1212 Mon Sep 17 00:00:00 2001 From: Oleksandra Matviienko Date: Tue, 19 May 2026 15:05:27 +0200 Subject: [PATCH 28/91] Removed compiler warnings about raw types and unchecked casts --- .../service/notification/NotificationApiTest.java | 2 +- .../lwm2m/rpc/AbstractRpcLwM2MIntegrationTest.java | 10 +++++----- .../server/common/data/util/CollectionsUtil.java | 3 ++- .../org/thingsboard/script/api/tbel/TbUtils.java | 2 +- .../org/thingsboard/script/api/tbel/TbUtilsTest.java | 12 ++++++------ .../downlink/DefaultLwM2mDownlinkMsgHandler.java | 2 +- .../server/rpc/DefaultLwM2MRpcRequestHandler.java | 12 ++++++------ .../service/TransportActivityManagerTest.java | 4 ++-- .../org/thingsboard/common/util/ExceptionUtil.java | 1 + .../server/dao/AbstractRedisClusterContainer.java | 12 ++++++------ .../server/dao/AbstractRedisContainer.java | 2 +- .../org/thingsboard/server/dao/RedisJUnit5Test.java | 2 +- .../rule/engine/flow/TbCheckpointNodeTest.java | 2 +- .../rule/engine/kafka/TbKafkaNodeTest.java | 2 +- .../rule/engine/metadata/TbGetTelemetryNodeTest.java | 12 ++++++------ .../telemetry/TbMsgDeleteAttributesNodeTest.java | 2 +- .../engine/transform/TbMsgDeduplicationNodeTest.java | 10 +++++----- .../engine/transform/TbSplitArrayMsgNodeTest.java | 2 +- 18 files changed, 48 insertions(+), 46 deletions(-) diff --git a/application/src/test/java/org/thingsboard/server/service/notification/NotificationApiTest.java b/application/src/test/java/org/thingsboard/server/service/notification/NotificationApiTest.java index fc42ae247c..5d0fa31e8a 100644 --- a/application/src/test/java/org/thingsboard/server/service/notification/NotificationApiTest.java +++ b/application/src/test/java/org/thingsboard/server/service/notification/NotificationApiTest.java @@ -988,7 +988,7 @@ public class NotificationApiTest extends AbstractNotificationApiTest { String expectedSubject = "Comment on 'test' alarm"; String expectedBody = TENANT_ADMIN_EMAIL + " added comment: text"; - ArgumentCaptor> msgCaptor = ArgumentCaptor.forClass(Map.class); + ArgumentCaptor> msgCaptor = ArgumentCaptor.captor(); await().atMost(TIMEOUT, TimeUnit.SECONDS).untilAsserted(() -> { verify(firebaseService).sendMessage(eq(tenantId), eq("testCredentials"), eq(TEST_MOBILE_TOKEN), eq(expectedSubject), diff --git a/application/src/test/java/org/thingsboard/server/transport/lwm2m/rpc/AbstractRpcLwM2MIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/lwm2m/rpc/AbstractRpcLwM2MIntegrationTest.java index b511d8b1e2..af0fdf4c09 100644 --- a/application/src/test/java/org/thingsboard/server/transport/lwm2m/rpc/AbstractRpcLwM2MIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/lwm2m/rpc/AbstractRpcLwM2MIntegrationTest.java @@ -77,16 +77,16 @@ public abstract class AbstractRpcLwM2MIntegrationTest extends AbstractLwM2MInteg protected final LinkParser linkParser = new DefaultLwM2mLinkParser(); protected String CONFIG_PROFILE_WITH_PARAMS_RPC; - public Set expectedObjects; - public Set expectedObjectIdVers; - public Set expectedInstances; - public Set expectedObjectIdVerInstances; + public Set expectedObjects; + public Set expectedObjectIdVers; + public Set expectedInstances; + public Set expectedObjectIdVerInstances; protected String objectInstanceIdVer_1; protected String objectIdVer_0; protected String objectIdVer_1; protected String objectIdVer_2; - private static final Predicate PREDICATE_3 = path -> (!((String) path).startsWith("/" + TEMPERATURE_SENSOR) && ((String) path).startsWith("/" + DEVICE)); + private static final Predicate PREDICATE_3 = path -> (!((String) path).startsWith("/" + TEMPERATURE_SENSOR) && ((String) path).startsWith("/" + DEVICE)); protected String objectIdVer_3; protected String objectInstanceIdVer_3; protected String objectInstanceIdVer_5; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/util/CollectionsUtil.java b/common/data/src/main/java/org/thingsboard/server/common/data/util/CollectionsUtil.java index 7541be5078..f1bedc8659 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/util/CollectionsUtil.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/util/CollectionsUtil.java @@ -85,6 +85,7 @@ public class CollectionsUtil { return result; } + @SafeVarargs public static boolean isOneOf(V value, V... others) { if (value == null) { return false; @@ -134,7 +135,7 @@ public class CollectionsUtil { Set newSet = new HashSet<>(existing.size() + 1); newSet.addAll(existing); newSet.add(value); - return (Set) Set.of(newSet.toArray()); + return Set.copyOf(newSet); } public static boolean isEmpty(Map map) { diff --git a/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbUtils.java b/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbUtils.java index ec8eacbc67..26fe9ae99a 100644 --- a/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbUtils.java +++ b/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbUtils.java @@ -1332,7 +1332,7 @@ public class TbUtils { for (byte b : byteArray) { byteList.add(b); } - ExecutionArrayList list = new ExecutionArrayList(byteList, ctx); + ExecutionArrayList list = new ExecutionArrayList<>(byteList, ctx); return list; } diff --git a/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbUtilsTest.java b/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbUtilsTest.java index ef1729ab73..caefb40608 100644 --- a/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbUtilsTest.java +++ b/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbUtilsTest.java @@ -1281,13 +1281,13 @@ public class TbUtilsTest { } @Test public void setTest() throws ExecutionException, InterruptedException { - Set actual = TbUtils.newSet(ctx); - Set expected = toSet(new byte[]{(byte) 0xDD, (byte) 0xCC, (byte) 0xCC}); + Set actual = TbUtils.newSet(ctx); + Set expected = toSet(new byte[]{(byte) 0xDD, (byte) 0xCC, (byte) 0xCC}); actual.add((byte) 0xDD); actual.add((byte) 0xCC); actual.add((byte) 0xCC); assertTrue(expected.containsAll(actual)); - List list = toList(new byte[]{(byte) 0xDD, (byte) 0xCC, (byte) 0xBB, (byte) 0xAA}); + List list = toList(new byte[]{(byte) 0xDD, (byte) 0xCC, (byte) 0xBB, (byte) 0xAA}); actual.addAll(list); assertEquals(4, actual.size()); assertTrue(actual.containsAll(expected)); @@ -1301,9 +1301,9 @@ public class TbUtilsTest { actual.clear(); assertTrue(actual.isEmpty()); actual = TbUtils.toSet(ctx, list); - Set actualClone = TbUtils.toSet(ctx, list); - Set actualClone_asc = TbUtils.toSet(ctx, list); - Set actualClone_desc = TbUtils.toSet(ctx, list); + Set actualClone = TbUtils.toSet(ctx, list); + Set actualClone_asc = TbUtils.toSet(ctx, list); + Set actualClone_desc = TbUtils.toSet(ctx, list); ((ExecutionLinkedHashSet)actualClone).sort(); ((ExecutionLinkedHashSet)actualClone_asc).sort(true); ((ExecutionLinkedHashSet)actualClone_desc).sort(false); diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/DefaultLwM2mDownlinkMsgHandler.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/DefaultLwM2mDownlinkMsgHandler.java index 8f638cfa2a..6d6eea28ab 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/DefaultLwM2mDownlinkMsgHandler.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/DefaultLwM2mDownlinkMsgHandler.java @@ -815,7 +815,7 @@ public class DefaultLwM2mDownlinkMsgHandler extends LwM2MExecutorAwareService im LwM2mPath pathSingleOb = singleObs.getPath(); LwM2mPath pathObjectId = new LwM2mPath(objectId); if (!pathSingleOb.toString().equals(objectId)) { - List paths = Arrays.asList(pathSingleOb, pathObjectId); + List paths = Arrays.asList(pathSingleOb, pathObjectId); try { LwM2mPath.validateNotOverlapping(paths); } catch (IllegalArgumentException e){ diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/rpc/DefaultLwM2MRpcRequestHandler.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/rpc/DefaultLwM2MRpcRequestHandler.java index 6980fb6341..c363cd3da5 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/rpc/DefaultLwM2MRpcRequestHandler.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/rpc/DefaultLwM2MRpcRequestHandler.java @@ -212,7 +212,7 @@ public class DefaultLwM2MRpcRequestHandler implements LwM2MRpcRequestHandler { String[] versionedIds = getIdsFromParameters(client, requestMsg); TbLwM2MReadCompositeRequest request = TbLwM2MReadCompositeRequest.builder().versionedIds(versionedIds).timeout(clientContext.getRequestTimeout(client)).build(); var mainCallback = new TbLwM2MReadCompositeCallback(uplinkHandler, logService, client, versionedIds); - var rpcCallback = new RpcReadResponseCompositeCallback(transportService, client, requestMsg, mainCallback); + var rpcCallback = new RpcReadResponseCompositeCallback<>(transportService, client, requestMsg, mainCallback); downlinkHandler.sendReadCompositeRequest(client, request, rpcCallback); } @@ -323,7 +323,7 @@ public class DefaultLwM2MRpcRequestHandler implements LwM2MRpcRequestHandler { } else if (path.isResource()) { validateResource(client, newNodes, nodes, key , value); } else if (path.isObjectInstance() && value instanceof Map) { - ((Map) value).forEach((k, v) -> { + ((Map) value).forEach((k, v) -> { validateResource(client, newNodes, nodes, validateResourceId (key, k.toString(), nodes), v); }); } else { @@ -337,7 +337,7 @@ public class DefaultLwM2MRpcRequestHandler implements LwM2MRpcRequestHandler { return newNodes; } - private void validateResource(LwM2mClient client, Map newNodes, Map nodes, String resourceId , Object value) { + private void validateResource(LwM2mClient client, Map newNodes, Map nodes, String resourceId , Object value) { if (value instanceof Map) { ((Map) value).forEach((k, v) -> { setValueToCompositeNodes(client, newNodes, nodes, validateResourceId (resourceId, k.toString(), nodes), v); @@ -347,7 +347,7 @@ public class DefaultLwM2MRpcRequestHandler implements LwM2MRpcRequestHandler { } } - private String validateResourceId (String key, String id, Map nodes) { + private String validateResourceId (String key, String id, Map nodes) { try { Integer.parseInt(id); return key + "/" + id; @@ -357,7 +357,7 @@ public class DefaultLwM2MRpcRequestHandler implements LwM2MRpcRequestHandler { } } - private void setValueToCompositeNodes (LwM2mClient client, Map newNodes, Map nodes, String versionedId , Object value) { + private void setValueToCompositeNodes (LwM2mClient client, Map newNodes, Map nodes, String versionedId , Object value) { // validate value. Must be only primitive, not JsonObject or JsonArray try { JsonElement element = JsonUtils.parse(value); @@ -388,7 +388,7 @@ public class DefaultLwM2MRpcRequestHandler implements LwM2MRpcRequestHandler { String[] versionedIds = getIdsFromParameters(client, requestMsg); TbLwM2MObserveCompositeRequest request = TbLwM2MObserveCompositeRequest.builder().versionedIds(versionedIds).timeout(clientContext.getRequestTimeout(client)).build(); var mainCallback = new TbLwM2MObserveCompositeCallback(uplinkHandler, logService, client, versionedIds); - var rpcCallback = new RpcObserveResponseCompositeCallback(transportService, client, requestMsg, mainCallback); + var rpcCallback = new RpcObserveResponseCompositeCallback<>(transportService, client, requestMsg, mainCallback); downlinkHandler.sendObserveCompositeRequest(client, request, rpcCallback); } diff --git a/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/service/TransportActivityManagerTest.java b/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/service/TransportActivityManagerTest.java index 3b3ce6e600..35ddba5d90 100644 --- a/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/service/TransportActivityManagerTest.java +++ b/common/transport/transport-api/src/test/java/org/thingsboard/server/common/transport/service/TransportActivityManagerTest.java @@ -122,7 +122,7 @@ public class TransportActivityManagerTest { // THEN ArgumentCaptor sessionInfoCaptor = ArgumentCaptor.forClass(TransportProtos.SessionInfoProto.class); ArgumentCaptor subscriptionInfoCaptor = ArgumentCaptor.forClass(TransportProtos.SubscriptionInfoProto.class); - ArgumentCaptor> callbackCaptor = ArgumentCaptor.forClass(TransportServiceCallback.class); + ArgumentCaptor> callbackCaptor = ArgumentCaptor.captor(); verify(transportServiceMock).process(sessionInfoCaptor.capture(), subscriptionInfoCaptor.capture(), callbackCaptor.capture()); @@ -166,7 +166,7 @@ public class TransportActivityManagerTest { // THEN ArgumentCaptor sessionInfoCaptor = ArgumentCaptor.forClass(TransportProtos.SessionInfoProto.class); ArgumentCaptor subscriptionInfoCaptor = ArgumentCaptor.forClass(TransportProtos.SubscriptionInfoProto.class); - ArgumentCaptor> callbackCaptor = ArgumentCaptor.forClass(TransportServiceCallback.class); + ArgumentCaptor> callbackCaptor = ArgumentCaptor.captor(); verify(transportServiceMock).process(sessionInfoCaptor.capture(), subscriptionInfoCaptor.capture(), callbackCaptor.capture()); diff --git a/common/util/src/main/java/org/thingsboard/common/util/ExceptionUtil.java b/common/util/src/main/java/org/thingsboard/common/util/ExceptionUtil.java index e5eed02675..7dc1ddde60 100644 --- a/common/util/src/main/java/org/thingsboard/common/util/ExceptionUtil.java +++ b/common/util/src/main/java/org/thingsboard/common/util/ExceptionUtil.java @@ -37,6 +37,7 @@ public class ExceptionUtil { } } + @SafeVarargs public static Exception lookupExceptionInCause(Throwable source, Class... clazzes) { while (source != null) { for (Class clazz : clazzes) { diff --git a/dao/src/test/java/org/thingsboard/server/dao/AbstractRedisClusterContainer.java b/dao/src/test/java/org/thingsboard/server/dao/AbstractRedisClusterContainer.java index 827e50a5cc..1f057c802b 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/AbstractRedisClusterContainer.java +++ b/dao/src/test/java/org/thingsboard/server/dao/AbstractRedisClusterContainer.java @@ -40,17 +40,17 @@ public class AbstractRedisClusterContainer { ); @ClassRule(order = 1) - public static GenericContainer redis1 = new GenericContainer(IMAGE).withEnv(ENVS).withEnv("VALKEY_PORT_NUMBER", "6371").withNetworkMode("host").withLogConsumer(AbstractRedisClusterContainer::consumeLog); + public static GenericContainer redis1 = new GenericContainer<>(IMAGE).withEnv(ENVS).withEnv("VALKEY_PORT_NUMBER", "6371").withNetworkMode("host").withLogConsumer(AbstractRedisClusterContainer::consumeLog); @ClassRule(order = 2) - public static GenericContainer redis2 = new GenericContainer(IMAGE).withEnv(ENVS).withEnv("VALKEY_PORT_NUMBER", "6372").withNetworkMode("host").withLogConsumer(AbstractRedisClusterContainer::consumeLog); + public static GenericContainer redis2 = new GenericContainer<>(IMAGE).withEnv(ENVS).withEnv("VALKEY_PORT_NUMBER", "6372").withNetworkMode("host").withLogConsumer(AbstractRedisClusterContainer::consumeLog); @ClassRule(order = 3) - public static GenericContainer redis3 = new GenericContainer(IMAGE).withEnv(ENVS).withEnv("VALKEY_PORT_NUMBER", "6373").withNetworkMode("host").withLogConsumer(AbstractRedisClusterContainer::consumeLog); + public static GenericContainer redis3 = new GenericContainer<>(IMAGE).withEnv(ENVS).withEnv("VALKEY_PORT_NUMBER", "6373").withNetworkMode("host").withLogConsumer(AbstractRedisClusterContainer::consumeLog); @ClassRule(order = 4) - public static GenericContainer redis4 = new GenericContainer(IMAGE).withEnv(ENVS).withEnv("VALKEY_PORT_NUMBER", "6374").withNetworkMode("host").withLogConsumer(AbstractRedisClusterContainer::consumeLog); + public static GenericContainer redis4 = new GenericContainer<>(IMAGE).withEnv(ENVS).withEnv("VALKEY_PORT_NUMBER", "6374").withNetworkMode("host").withLogConsumer(AbstractRedisClusterContainer::consumeLog); @ClassRule(order = 5) - public static GenericContainer redis5 = new GenericContainer(IMAGE).withEnv(ENVS).withEnv("VALKEY_PORT_NUMBER", "6375").withNetworkMode("host").withLogConsumer(AbstractRedisClusterContainer::consumeLog); + public static GenericContainer redis5 = new GenericContainer<>(IMAGE).withEnv(ENVS).withEnv("VALKEY_PORT_NUMBER", "6375").withNetworkMode("host").withLogConsumer(AbstractRedisClusterContainer::consumeLog); @ClassRule(order = 6) - public static GenericContainer redis6 = new GenericContainer(IMAGE).withEnv(ENVS).withEnv("VALKEY_PORT_NUMBER", "6376").withNetworkMode("host").withLogConsumer(AbstractRedisClusterContainer::consumeLog); + public static GenericContainer redis6 = new GenericContainer<>(IMAGE).withEnv(ENVS).withEnv("VALKEY_PORT_NUMBER", "6376").withNetworkMode("host").withLogConsumer(AbstractRedisClusterContainer::consumeLog); @ClassRule(order = 100) diff --git a/dao/src/test/java/org/thingsboard/server/dao/AbstractRedisContainer.java b/dao/src/test/java/org/thingsboard/server/dao/AbstractRedisContainer.java index dc4a47b5a5..72074f60c8 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/AbstractRedisContainer.java +++ b/dao/src/test/java/org/thingsboard/server/dao/AbstractRedisContainer.java @@ -27,7 +27,7 @@ import java.util.List; public class AbstractRedisContainer { @ClassRule(order = 0) - public static GenericContainer redis = new GenericContainer("bitnamilegacy/valkey:8.0") + public static GenericContainer redis = new GenericContainer<>("bitnamilegacy/valkey:8.0") .withEnv("ALLOW_EMPTY_PASSWORD","yes") .withLogConsumer(s -> log.warn(((OutputFrame) s).getUtf8String().trim())) .withExposedPorts(6379); diff --git a/dao/src/test/java/org/thingsboard/server/dao/RedisJUnit5Test.java b/dao/src/test/java/org/thingsboard/server/dao/RedisJUnit5Test.java index 863eb95d90..9eea80a47f 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/RedisJUnit5Test.java +++ b/dao/src/test/java/org/thingsboard/server/dao/RedisJUnit5Test.java @@ -33,7 +33,7 @@ import static org.assertj.core.api.Assertions.assertThat; public class RedisJUnit5Test { @Container - private static final GenericContainer REDIS = new GenericContainer("bitnamilegacy/valkey:8.0") + private static final GenericContainer REDIS = new GenericContainer<>("bitnamilegacy/valkey:8.0") .withEnv("ALLOW_EMPTY_PASSWORD","yes") .withLogConsumer(s -> log.error(((OutputFrame) s).getUtf8String().trim())) .withExposedPorts(6379); diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/flow/TbCheckpointNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/flow/TbCheckpointNodeTest.java index ab0f358684..7c47477fee 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/flow/TbCheckpointNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/flow/TbCheckpointNodeTest.java @@ -114,7 +114,7 @@ public class TbCheckpointNodeTest extends AbstractRuleNodeUpgradeTest { .build(); node.onMsg(ctxMock, msg); - ArgumentCaptor> onFailure = ArgumentCaptor.forClass(Consumer.class); + ArgumentCaptor> onFailure = ArgumentCaptor.captor(); then(ctxMock).should().enqueueForTellNext(eq(msg), eq(DataConstants.HP_QUEUE_NAME), eq(TbNodeConnectionType.SUCCESS), any(), onFailure.capture()); String errorMsg = "Something went wrong."; onFailure.getValue().accept(new RuntimeException(errorMsg)); diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/kafka/TbKafkaNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/kafka/TbKafkaNodeTest.java index 5df7e1be7b..392821b767 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/kafka/TbKafkaNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/kafka/TbKafkaNodeTest.java @@ -420,7 +420,7 @@ public class TbKafkaNodeTest extends AbstractRuleNodeUpgradeTest { } private void verifyProducerRecord(String expectedTopic, String expectedKey, String expectedValue, Headers expectedHeaders) { - ArgumentCaptor> actualRecordCaptor = ArgumentCaptor.forClass(ProducerRecord.class); + ArgumentCaptor> actualRecordCaptor = ArgumentCaptor.captor(); then(producerMock).should().send(actualRecordCaptor.capture(), any()); ProducerRecord actualRecord = actualRecordCaptor.getValue(); assertThat(actualRecord.topic()).isEqualTo(expectedTopic); diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetTelemetryNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetTelemetryNodeTest.java index ce3a1b5b22..5de65535e7 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetTelemetryNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetTelemetryNodeTest.java @@ -219,7 +219,7 @@ public class TbGetTelemetryNodeTest extends AbstractRuleNodeUpgradeTest { node.onMsg(ctxMock, msg); // THEN - ArgumentCaptor> actualReadTsKvQueryList = ArgumentCaptor.forClass(List.class); + ArgumentCaptor> actualReadTsKvQueryList = ArgumentCaptor.captor(); then(timeseriesServiceMock).should().findAll(eq(TENANT_ID), eq(DEVICE_ID), actualReadTsKvQueryList.capture()); ReadTsKvQuery actualReadTsKvQuery = actualReadTsKvQueryList.getValue().get(0); assertThat(actualReadTsKvQuery.getStartTs()).isEqualTo(startTs); @@ -246,7 +246,7 @@ public class TbGetTelemetryNodeTest extends AbstractRuleNodeUpgradeTest { node.onMsg(ctxMock, msg); // THEN - ArgumentCaptor> actualReadTsKvQueryList = ArgumentCaptor.forClass(List.class); + ArgumentCaptor> actualReadTsKvQueryList = ArgumentCaptor.captor(); then(timeseriesServiceMock).should().findAll(eq(TENANT_ID), eq(DEVICE_ID), actualReadTsKvQueryList.capture()); ReadTsKvQuery actualReadTsKvQuery = actualReadTsKvQueryList.getValue().get(0); assertThat(actualReadTsKvQuery.getStartTs()).isEqualTo(ts - TimeUnit.MINUTES.toMillis(config.getStartInterval())); @@ -275,7 +275,7 @@ public class TbGetTelemetryNodeTest extends AbstractRuleNodeUpgradeTest { node.onMsg(ctxMock, msg); // THEN - ArgumentCaptor> actualReadTsKvQueryList = ArgumentCaptor.forClass(List.class); + ArgumentCaptor> actualReadTsKvQueryList = ArgumentCaptor.captor(); then(timeseriesServiceMock).should().findAll(eq(TENANT_ID), eq(DEVICE_ID), actualReadTsKvQueryList.capture()); List actualKeys = actualReadTsKvQueryList.getValue().stream().map(TsKvQuery::getKey).toList(); assertThat(actualKeys).containsExactlyInAnyOrder("temperature", "humidity", "pressure"); @@ -305,7 +305,7 @@ public class TbGetTelemetryNodeTest extends AbstractRuleNodeUpgradeTest { node.onMsg(ctxMock, msg); // THEN - ArgumentCaptor> actualReadTsKvQueryList = ArgumentCaptor.forClass(List.class); + ArgumentCaptor> actualReadTsKvQueryList = ArgumentCaptor.captor(); then(timeseriesServiceMock).should().findAll(eq(TENANT_ID), eq(DEVICE_ID), actualReadTsKvQueryList.capture()); ReadTsKvQuery actualReadTsKvQuery = actualReadTsKvQueryList.getValue().get(0); aggregationStepVerifier.accept(actualReadTsKvQuery); @@ -340,7 +340,7 @@ public class TbGetTelemetryNodeTest extends AbstractRuleNodeUpgradeTest { node.onMsg(ctxMock, msg); // THEN - ArgumentCaptor> actualReadTsKvQueryList = ArgumentCaptor.forClass(List.class); + ArgumentCaptor> actualReadTsKvQueryList = ArgumentCaptor.captor(); then(timeseriesServiceMock).should().findAll(eq(TENANT_ID), eq(DEVICE_ID), actualReadTsKvQueryList.capture()); ReadTsKvQuery actualReadTsKvQuery = actualReadTsKvQueryList.getValue().get(0); limitInQueryVerifier.accept(actualReadTsKvQuery); @@ -385,7 +385,7 @@ public class TbGetTelemetryNodeTest extends AbstractRuleNodeUpgradeTest { node.onMsg(ctxMock, msg); // THEN - ArgumentCaptor> actualReadTsKvQueryList = ArgumentCaptor.forClass(List.class); + ArgumentCaptor> actualReadTsKvQueryList = ArgumentCaptor.captor(); then(timeseriesServiceMock).should().findAll(eq(TENANT_ID), eq(DEVICE_ID), actualReadTsKvQueryList.capture()); ReadTsKvQuery actualReadTsKvQuery = actualReadTsKvQueryList.getValue().get(0); orderInQueryVerifier.accept(actualReadTsKvQuery); diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/telemetry/TbMsgDeleteAttributesNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/telemetry/TbMsgDeleteAttributesNodeTest.java index b03794c39d..105962fd1e 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/telemetry/TbMsgDeleteAttributesNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/telemetry/TbMsgDeleteAttributesNodeTest.java @@ -147,7 +147,7 @@ public class TbMsgDeleteAttributesNodeTest { node.onMsg(ctx, msg); ArgumentCaptor successCaptor = ArgumentCaptor.forClass(Runnable.class); - ArgumentCaptor> failureCaptor = ArgumentCaptor.forClass(Consumer.class); + ArgumentCaptor> failureCaptor = ArgumentCaptor.captor(); ArgumentCaptor newMsgCaptor = ArgumentCaptor.forClass(TbMsg.class); if (sendAttributesDeletedNotification) { diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/transform/TbMsgDeduplicationNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/transform/TbMsgDeduplicationNodeTest.java index ec71819878..8fd2868f61 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/transform/TbMsgDeduplicationNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/transform/TbMsgDeduplicationNodeTest.java @@ -192,7 +192,7 @@ public class TbMsgDeduplicationNodeTest extends AbstractRuleNodeUpgradeTest { ArgumentCaptor newMsgCaptor = ArgumentCaptor.forClass(TbMsg.class); ArgumentCaptor successCaptor = ArgumentCaptor.forClass(Runnable.class); - ArgumentCaptor> failureCaptor = ArgumentCaptor.forClass(Consumer.class); + ArgumentCaptor> failureCaptor = ArgumentCaptor.captor(); verify(ctx, times(msgCount)).ack(any()); verify(ctx, times(1)).tellFailure(eq(msgToReject), any()); @@ -248,7 +248,7 @@ public class TbMsgDeduplicationNodeTest extends AbstractRuleNodeUpgradeTest { ArgumentCaptor newMsgCaptor = ArgumentCaptor.forClass(TbMsg.class); ArgumentCaptor successCaptor = ArgumentCaptor.forClass(Runnable.class); - ArgumentCaptor> failureCaptor = ArgumentCaptor.forClass(Consumer.class); + ArgumentCaptor> failureCaptor = ArgumentCaptor.captor(); verify(ctx, times(msgCount)).ack(any()); verify(ctx, times(1)).tellFailure(eq(msgToReject), any()); @@ -293,7 +293,7 @@ public class TbMsgDeduplicationNodeTest extends AbstractRuleNodeUpgradeTest { ArgumentCaptor newMsgCaptor = ArgumentCaptor.forClass(TbMsg.class); ArgumentCaptor successCaptor = ArgumentCaptor.forClass(Runnable.class); - ArgumentCaptor> failureCaptor = ArgumentCaptor.forClass(Consumer.class); + ArgumentCaptor> failureCaptor = ArgumentCaptor.captor(); verify(ctx, times(msgCount)).ack(any()); verify(node, times(msgCount + wantedNumberOfTellSelfInvocation)).onMsg(eq(ctx), any()); @@ -339,7 +339,7 @@ public class TbMsgDeduplicationNodeTest extends AbstractRuleNodeUpgradeTest { ArgumentCaptor newMsgCaptor = ArgumentCaptor.forClass(TbMsg.class); ArgumentCaptor successCaptor = ArgumentCaptor.forClass(Runnable.class); - ArgumentCaptor> failureCaptor = ArgumentCaptor.forClass(Consumer.class); + ArgumentCaptor> failureCaptor = ArgumentCaptor.captor(); verify(ctx, times(msgCount)).ack(any()); verify(node, times(msgCount + wantedNumberOfTellSelfInvocation)).onMsg(eq(ctx), any()); @@ -393,7 +393,7 @@ public class TbMsgDeduplicationNodeTest extends AbstractRuleNodeUpgradeTest { ArgumentCaptor newMsgCaptor = ArgumentCaptor.forClass(TbMsg.class); ArgumentCaptor successCaptor = ArgumentCaptor.forClass(Runnable.class); - ArgumentCaptor> failureCaptor = ArgumentCaptor.forClass(Consumer.class); + ArgumentCaptor> failureCaptor = ArgumentCaptor.captor(); verify(ctx, times(msgCount)).ack(any()); verify(node, times(msgCount + wantedNumberOfTellSelfInvocation)).onMsg(eq(ctx), any()); diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/transform/TbSplitArrayMsgNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/transform/TbSplitArrayMsgNodeTest.java index 5cd88c8ea9..b178def66e 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/transform/TbSplitArrayMsgNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/transform/TbSplitArrayMsgNodeTest.java @@ -114,7 +114,7 @@ public class TbSplitArrayMsgNodeTest { if (dataNode.size() > 1) { ArgumentCaptor successCaptor = ArgumentCaptor.forClass(Runnable.class); - ArgumentCaptor> failureCaptor = ArgumentCaptor.forClass(Consumer.class); + ArgumentCaptor> failureCaptor = ArgumentCaptor.captor(); verify(ctx, times(dataNode.size())).enqueueForTellNext(any(), anyString(), successCaptor.capture(), failureCaptor.capture()); for (Runnable valueCaptor : successCaptor.getAllValues()) { valueCaptor.run(); From f8312352a06800c9ab314fe47e24754a1cce27bc Mon Sep 17 00:00:00 2001 From: Oleksandra Matviienko Date: Thu, 23 Apr 2026 15:11:11 +0200 Subject: [PATCH 29/91] Updated PEM credentials to the non-deprecated certificate API --- .../rule/engine/credentials/CertPemCredentials.java | 5 +++-- .../engine/credentials/CertPemCredentialsTest.java | 13 +++++++------ 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/credentials/CertPemCredentials.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/credentials/CertPemCredentials.java index 81def5a96b..46d844d2c4 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/credentials/CertPemCredentials.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/credentials/CertPemCredentials.java @@ -25,6 +25,7 @@ import org.thingsboard.server.common.data.StringUtils; import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.TrustManagerFactory; +import javax.security.auth.x500.X500Principal; import java.security.KeyStore; import java.security.PrivateKey; import java.security.cert.CertPath; @@ -77,7 +78,7 @@ public class CertPemCredentials implements ClientCredentials { KeyStore caKeyStore = KeyStore.getInstance(KeyStore.getDefaultType()); caKeyStore.load(null, null); for (X509Certificate caCert : caCerts) { - caKeyStore.setCertificateEntry(CA_CERT_CERT_ALIAS_PREFIX + caCert.getSubjectDN().getName(), caCert); + caKeyStore.setCertificateEntry(CA_CERT_CERT_ALIAS_PREFIX + caCert.getSubjectX500Principal().getName(X500Principal.RFC1779), caCert); } TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); @@ -99,7 +100,7 @@ public class CertPemCredentials implements ClientCredentials { keyStore.load(null); List unique = certificates.stream().distinct().collect(Collectors.toList()); for (X509Certificate cert : unique) { - keyStore.setCertificateEntry(CERT_ALIAS_PREFIX + cert.getSubjectDN().getName(), cert); + keyStore.setCertificateEntry(CERT_ALIAS_PREFIX + cert.getSubjectX500Principal().getName(X500Principal.RFC1779), cert); } if (privateKey != null) { diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/credentials/CertPemCredentialsTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/credentials/CertPemCredentialsTest.java index cd0d508fec..634b5d8754 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/credentials/CertPemCredentialsTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/credentials/CertPemCredentialsTest.java @@ -23,6 +23,7 @@ import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; import org.thingsboard.common.util.SslUtil; +import javax.security.auth.x500.X500Principal; import java.io.File; import java.io.IOException; import java.security.Key; @@ -49,13 +50,13 @@ public class CertPemCredentialsTest { Assertions.assertEquals(4, x509Certificates.size()); Assertions.assertEquals("CN=*.thingsboard.cloud, O=\"ThingsBoard, Inc.\", ST=New York, C=US", - x509Certificates.get(0).getSubjectDN().getName()); + x509Certificates.get(0).getSubjectX500Principal().getName(X500Principal.RFC1779)); Assertions.assertEquals("CN=Sectigo ECC Organization Validation Secure Server CA, O=Sectigo Limited, L=Salford, ST=Greater Manchester, C=GB", - x509Certificates.get(1).getSubjectDN().getName()); + x509Certificates.get(1).getSubjectX500Principal().getName(X500Principal.RFC1779)); Assertions.assertEquals("CN=USERTrust ECC Certification Authority, O=The USERTRUST Network, L=Jersey City, ST=New Jersey, C=US", - x509Certificates.get(2).getSubjectDN().getName()); + x509Certificates.get(2).getSubjectX500Principal().getName(X500Principal.RFC1779)); Assertions.assertEquals("CN=AAA Certificate Services, O=Comodo CA Limited, L=Salford, ST=Greater Manchester, C=GB", - x509Certificates.get(3).getSubjectDN().getName()); + x509Certificates.get(3).getSubjectX500Principal().getName(X500Principal.RFC1779)); } @Test @@ -66,7 +67,7 @@ public class CertPemCredentialsTest { Assertions.assertEquals(1, x509Certificates.size()); Assertions.assertEquals("CN=*.thingsboard.cloud, O=\"ThingsBoard, Inc.\", ST=New York, C=US", - x509Certificates.get(0).getSubjectDN().getName()); + x509Certificates.get(0).getSubjectX500Principal().getName(X500Principal.RFC1779)); } @Test @@ -103,7 +104,7 @@ public class CertPemCredentialsTest { List certs = SslUtil.readCertFile(certContent); for (X509Certificate cert : certs) { - String alias = CERT_ALIAS_PREFIX + cert.getIssuerDN().getName(); + String alias = CERT_ALIAS_PREFIX + cert.getIssuerX500Principal().getName(X500Principal.RFC1779); Certificate certificate = keyStore.getCertificate(alias); Assertions.assertNotNull(certificate); Assertions.assertEquals(new String(cert.getEncoded()), new String(certificate.getEncoded())); From acb21c6f7bba490af2d34fe8c16c1f8270d6ceb8 Mon Sep 17 00:00:00 2001 From: Oleksandra Matviienko Date: Fri, 24 Apr 2026 08:54:24 +0200 Subject: [PATCH 30/91] Removed warnings about ignored builder initializers in data models --- .../org/thingsboard/server/common/data/job/task/Task.java | 2 +- .../server/common/data/mobile/layout/MobileLayoutConfig.java | 1 + .../tenant/profile/DefaultTenantProfileConfiguration.java | 4 ++++ 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/job/task/Task.java b/common/data/src/main/java/org/thingsboard/server/common/data/job/task/Task.java index 8f3e0d814b..a881780012 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/job/task/Task.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/job/task/Task.java @@ -46,7 +46,7 @@ public abstract class Task { public Task() { } - private int attempt = 0; + private int attempt; public abstract R toFailed(Throwable error); diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/mobile/layout/MobileLayoutConfig.java b/common/data/src/main/java/org/thingsboard/server/common/data/mobile/layout/MobileLayoutConfig.java index 783d3f68a9..60a7710e65 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/mobile/layout/MobileLayoutConfig.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/mobile/layout/MobileLayoutConfig.java @@ -40,6 +40,7 @@ public class MobileLayoutConfig { @ArraySchema(schema = @Schema(implementation = MobilePage.class)) @JsonView(Views.Public.class) @Valid + @Builder.Default private List pages = new ArrayList<>(); } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/tenant/profile/DefaultTenantProfileConfiguration.java b/common/data/src/main/java/org/thingsboard/server/common/data/tenant/profile/DefaultTenantProfileConfiguration.java index 297f92cffb..ff1dd3450c 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/tenant/profile/DefaultTenantProfileConfiguration.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/tenant/profile/DefaultTenantProfileConfiguration.java @@ -169,8 +169,10 @@ public class DefaultTenantProfileConfiguration implements TenantProfileConfigura private double warnThreshold; + @Builder.Default @Schema(example = "5") private long maxCalculatedFieldsPerEntity = 5; + @Builder.Default @Schema(example = "10") private long maxArgumentsPerCF = 10; @Schema(example = "10") @@ -188,8 +190,10 @@ public class DefaultTenantProfileConfiguration implements TenantProfileConfigura @Positive @Schema(example = "1000") private long maxDataPointsPerRollingArg = 1000; + @Builder.Default @Schema(example = "32") private long maxStateSizeInKBytes = 32; + @Builder.Default @Schema(example = "2") private long maxSingleValueArgumentSizeInKBytes = 2; @Schema(example = "10") From d5eba3dd2d4538d5686c25901b77b4fc54aa7a36 Mon Sep 17 00:00:00 2001 From: Oleksandra Matviienko Date: Fri, 24 Apr 2026 10:09:17 +0200 Subject: [PATCH 31/91] Technical cleanup of generated-equality annotations --- .../main/java/org/thingsboard/server/common/data/EventInfo.java | 2 ++ .../java/org/thingsboard/server/common/data/HomeDashboard.java | 2 ++ .../java/org/thingsboard/server/common/data/TenantInfo.java | 2 ++ .../org/thingsboard/server/common/data/alarm/AlarmComment.java | 1 + .../data/device/data/CoapDeviceTransportConfiguration.java | 2 ++ .../data/device/data/Lwm2mDeviceTransportConfiguration.java | 2 ++ .../lwm2m/bootstrap/LwM2MServerSecurityConfigDefault.java | 2 ++ .../java/org/thingsboard/server/common/data/edge/EdgeInfo.java | 2 ++ .../thingsboard/server/common/data/edqs/fields/AssetFields.java | 2 ++ .../server/common/data/edqs/fields/AssetProfileFields.java | 2 ++ .../server/common/data/edqs/fields/CustomerFields.java | 2 ++ .../server/common/data/edqs/fields/DashboardFields.java | 2 ++ .../server/common/data/edqs/fields/DeviceFields.java | 2 ++ .../server/common/data/edqs/fields/DeviceProfileFields.java | 2 ++ .../thingsboard/server/common/data/edqs/fields/EdgeFields.java | 2 ++ .../server/common/data/edqs/fields/EntityViewFields.java | 2 ++ .../server/common/data/edqs/fields/QueueStatsFields.java | 2 ++ .../server/common/data/edqs/fields/RuleChainFields.java | 2 ++ .../server/common/data/edqs/fields/TenantFields.java | 2 ++ .../server/common/data/edqs/fields/TenantProfileFields.java | 2 ++ .../thingsboard/server/common/data/edqs/fields/UserFields.java | 2 ++ .../thingsboard/server/common/data/kv/BaseDeleteTsKvQuery.java | 2 ++ .../thingsboard/server/common/data/query/AlarmCountQuery.java | 2 ++ .../java/org/thingsboard/server/common/data/queue/Queue.java | 2 ++ .../org/thingsboard/server/common/data/rule/RuleNodeState.java | 2 ++ .../thingsboard/server/common/data/widget/WidgetTypeInfo.java | 2 ++ .../server/transport/mqtt/limits/GatewaySessionLimits.java | 2 ++ .../server/dao/model/sqlts/latest/TsKvLatestEntity.java | 2 ++ .../rule/engine/action/TbClearAlarmNodeConfiguration.java | 2 ++ .../rule/engine/action/TbCreateAlarmNodeConfiguration.java | 2 ++ .../rule/engine/geo/TbGpsGeofencingActionNodeConfiguration.java | 2 ++ .../rule/engine/mqtt/azure/AzureIotHubSasCredentials.java | 2 ++ .../rule/engine/mqtt/azure/TbAzureIotHubNodeConfiguration.java | 2 ++ 33 files changed, 65 insertions(+) diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/EventInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/EventInfo.java index 9ca3957050..e0bdde1dd8 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/EventInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/EventInfo.java @@ -18,6 +18,7 @@ package org.thingsboard.server.common.data; import com.fasterxml.jackson.databind.JsonNode; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; +import lombok.EqualsAndHashCode; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.EventId; import org.thingsboard.server.common.data.id.TenantId; @@ -26,6 +27,7 @@ import org.thingsboard.server.common.data.id.TenantId; * @author Andrew Shvayka */ @Data +@EqualsAndHashCode(callSuper = false) @Schema public class EventInfo extends BaseData { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/HomeDashboard.java b/common/data/src/main/java/org/thingsboard/server/common/data/HomeDashboard.java index ce9c8fce78..df2cdf2bf5 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/HomeDashboard.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/HomeDashboard.java @@ -17,9 +17,11 @@ package org.thingsboard.server.common.data; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; +import lombok.EqualsAndHashCode; @Schema @Data +@EqualsAndHashCode(callSuper = false) public class HomeDashboard extends Dashboard { public static final String HIDE_DASHBOARD_TOOLBAR_DESCRIPTION = "Hide dashboard toolbar flag. Useful for rendering dashboards on mobile."; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/TenantInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/TenantInfo.java index 4126b1acdd..8f38ecd750 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/TenantInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/TenantInfo.java @@ -17,10 +17,12 @@ package org.thingsboard.server.common.data; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; +import lombok.EqualsAndHashCode; import org.thingsboard.server.common.data.id.TenantId; @Schema @Data +@EqualsAndHashCode(callSuper = false) public class TenantInfo extends Tenant { @Schema(description = "Tenant Profile name", example = "Default") private String tenantProfileName; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/alarm/AlarmComment.java b/common/data/src/main/java/org/thingsboard/server/common/data/alarm/AlarmComment.java index ef7499fa33..20c1b218fc 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/alarm/AlarmComment.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/alarm/AlarmComment.java @@ -34,6 +34,7 @@ import java.io.Serial; @Schema @Data +@EqualsAndHashCode(callSuper = false) @Builder @AllArgsConstructor public class AlarmComment extends BaseData implements HasName { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/device/data/CoapDeviceTransportConfiguration.java b/common/data/src/main/java/org/thingsboard/server/common/data/device/data/CoapDeviceTransportConfiguration.java index 86a61e31b6..597cee3f1c 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/device/data/CoapDeviceTransportConfiguration.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/device/data/CoapDeviceTransportConfiguration.java @@ -20,6 +20,7 @@ import com.fasterxml.jackson.annotation.JsonAnySetter; import com.fasterxml.jackson.annotation.JsonIgnore; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; +import lombok.EqualsAndHashCode; import org.thingsboard.server.common.data.DeviceTransportType; import java.util.HashMap; @@ -27,6 +28,7 @@ import java.util.Map; @Data @Schema +@EqualsAndHashCode(callSuper = false) public class CoapDeviceTransportConfiguration extends PowerSavingConfiguration implements DeviceTransportConfiguration { private static final long serialVersionUID = 6061442236008925609L; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/device/data/Lwm2mDeviceTransportConfiguration.java b/common/data/src/main/java/org/thingsboard/server/common/data/device/data/Lwm2mDeviceTransportConfiguration.java index 656262ab45..513accfe7b 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/device/data/Lwm2mDeviceTransportConfiguration.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/device/data/Lwm2mDeviceTransportConfiguration.java @@ -20,6 +20,7 @@ import com.fasterxml.jackson.annotation.JsonAnySetter; import com.fasterxml.jackson.annotation.JsonIgnore; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; +import lombok.EqualsAndHashCode; import org.thingsboard.server.common.data.DeviceTransportType; import java.util.HashMap; @@ -27,6 +28,7 @@ import java.util.Map; @Schema @Data +@EqualsAndHashCode(callSuper = false) public class Lwm2mDeviceTransportConfiguration extends PowerSavingConfiguration implements DeviceTransportConfiguration { @JsonIgnore diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/lwm2m/bootstrap/LwM2MServerSecurityConfigDefault.java b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/lwm2m/bootstrap/LwM2MServerSecurityConfigDefault.java index 85c1e97e24..14ef402718 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/lwm2m/bootstrap/LwM2MServerSecurityConfigDefault.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/lwm2m/bootstrap/LwM2MServerSecurityConfigDefault.java @@ -17,9 +17,11 @@ package org.thingsboard.server.common.data.device.profile.lwm2m.bootstrap; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; +import lombok.EqualsAndHashCode; @Schema @Data +@EqualsAndHashCode(callSuper = false) public class LwM2MServerSecurityConfigDefault extends LwM2MServerSecurityConfig { @Schema(description = "Host for 'Security' mode (DTLS)", example = "0.0.0.0", accessMode = Schema.AccessMode.READ_ONLY) protected String securityHost; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/edge/EdgeInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/edge/EdgeInfo.java index dd751b8b9d..5dbd0212b3 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/edge/EdgeInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/edge/EdgeInfo.java @@ -16,9 +16,11 @@ package org.thingsboard.server.common.data.edge; import lombok.Data; +import lombok.EqualsAndHashCode; import org.thingsboard.server.common.data.id.EdgeId; @Data +@EqualsAndHashCode(callSuper = false) public class EdgeInfo extends Edge { private String customerTitle; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/AssetFields.java b/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/AssetFields.java index 40ad22ed19..d05147b4d7 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/AssetFields.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/AssetFields.java @@ -18,6 +18,7 @@ package org.thingsboard.server.common.data.edqs.fields; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.databind.JsonNode; import lombok.Data; +import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import lombok.experimental.SuperBuilder; @@ -26,6 +27,7 @@ import java.util.UUID; import static org.thingsboard.server.common.data.edqs.fields.FieldsUtil.getText; @Data +@EqualsAndHashCode(callSuper = false) @NoArgsConstructor @SuperBuilder public class AssetFields extends AbstractEntityFields implements ProfileAwareFields { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/AssetProfileFields.java b/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/AssetProfileFields.java index ce91aac9d0..c519daa800 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/AssetProfileFields.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/AssetProfileFields.java @@ -16,12 +16,14 @@ package org.thingsboard.server.common.data.edqs.fields; import lombok.Data; +import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import lombok.experimental.SuperBuilder; import java.util.UUID; @Data +@EqualsAndHashCode(callSuper = false) @NoArgsConstructor @SuperBuilder public class AssetProfileFields extends AbstractEntityFields { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/CustomerFields.java b/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/CustomerFields.java index e2cdf8f295..c324f0f1ab 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/CustomerFields.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/CustomerFields.java @@ -17,6 +17,7 @@ package org.thingsboard.server.common.data.edqs.fields; import com.fasterxml.jackson.databind.JsonNode; import lombok.Data; +import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import lombok.experimental.SuperBuilder; @@ -25,6 +26,7 @@ import java.util.UUID; import static org.thingsboard.server.common.data.edqs.fields.FieldsUtil.getText; @Data +@EqualsAndHashCode(callSuper = false) @NoArgsConstructor @SuperBuilder public class CustomerFields extends AbstractEntityFields { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/DashboardFields.java b/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/DashboardFields.java index 4131d58e98..608a64436e 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/DashboardFields.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/DashboardFields.java @@ -19,6 +19,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import lombok.Data; +import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import lombok.experimental.SuperBuilder; @@ -28,6 +29,7 @@ import java.util.UUID; @Data +@EqualsAndHashCode(callSuper = false) @NoArgsConstructor @SuperBuilder public class DashboardFields extends AbstractEntityFields { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/DeviceFields.java b/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/DeviceFields.java index 90400ae70d..ef8aee952b 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/DeviceFields.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/DeviceFields.java @@ -18,6 +18,7 @@ package org.thingsboard.server.common.data.edqs.fields; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.databind.JsonNode; import lombok.Data; +import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import lombok.experimental.SuperBuilder; @@ -26,6 +27,7 @@ import java.util.UUID; import static org.thingsboard.server.common.data.edqs.fields.FieldsUtil.getText; @Data +@EqualsAndHashCode(callSuper = false) @NoArgsConstructor @SuperBuilder public class DeviceFields extends AbstractEntityFields implements ProfileAwareFields { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/DeviceProfileFields.java b/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/DeviceProfileFields.java index 067c961b9e..2331829054 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/DeviceProfileFields.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/DeviceProfileFields.java @@ -16,6 +16,7 @@ package org.thingsboard.server.common.data.edqs.fields; import lombok.Data; +import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import lombok.experimental.SuperBuilder; import org.thingsboard.server.common.data.DeviceProfileType; @@ -23,6 +24,7 @@ import org.thingsboard.server.common.data.DeviceProfileType; import java.util.UUID; @Data +@EqualsAndHashCode(callSuper = false) @NoArgsConstructor @SuperBuilder public class DeviceProfileFields extends AbstractEntityFields { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/EdgeFields.java b/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/EdgeFields.java index 1d257b06e1..e048eb22a8 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/EdgeFields.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/EdgeFields.java @@ -17,6 +17,7 @@ package org.thingsboard.server.common.data.edqs.fields; import com.fasterxml.jackson.databind.JsonNode; import lombok.Data; +import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import lombok.experimental.SuperBuilder; @@ -25,6 +26,7 @@ import java.util.UUID; import static org.thingsboard.server.common.data.edqs.fields.FieldsUtil.getText; @Data +@EqualsAndHashCode(callSuper = false) @NoArgsConstructor @SuperBuilder public class EdgeFields extends AbstractEntityFields { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/EntityViewFields.java b/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/EntityViewFields.java index 4e326cf779..c5027dfc8f 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/EntityViewFields.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/EntityViewFields.java @@ -17,6 +17,7 @@ package org.thingsboard.server.common.data.edqs.fields; import com.fasterxml.jackson.databind.JsonNode; import lombok.Data; +import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import lombok.experimental.SuperBuilder; @@ -25,6 +26,7 @@ import java.util.UUID; import static org.thingsboard.server.common.data.edqs.fields.FieldsUtil.getText; @Data +@EqualsAndHashCode(callSuper = false) @NoArgsConstructor @SuperBuilder public class EntityViewFields extends AbstractEntityFields { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/QueueStatsFields.java b/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/QueueStatsFields.java index 13e05daad4..5c5a139364 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/QueueStatsFields.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/QueueStatsFields.java @@ -16,12 +16,14 @@ package org.thingsboard.server.common.data.edqs.fields; import lombok.Data; +import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import lombok.experimental.SuperBuilder; import java.util.UUID; @Data +@EqualsAndHashCode(callSuper = false) @NoArgsConstructor @SuperBuilder public class QueueStatsFields extends AbstractEntityFields { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/RuleChainFields.java b/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/RuleChainFields.java index 25b7db6aaa..d580f6b913 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/RuleChainFields.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/RuleChainFields.java @@ -17,6 +17,7 @@ package org.thingsboard.server.common.data.edqs.fields; import com.fasterxml.jackson.databind.JsonNode; import lombok.Data; +import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import lombok.experimental.SuperBuilder; @@ -25,6 +26,7 @@ import java.util.UUID; import static org.thingsboard.server.common.data.edqs.fields.FieldsUtil.getText; @Data +@EqualsAndHashCode(callSuper = false) @NoArgsConstructor @SuperBuilder public class RuleChainFields extends AbstractEntityFields { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/TenantFields.java b/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/TenantFields.java index 9b538511b2..ba350fec54 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/TenantFields.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/TenantFields.java @@ -17,6 +17,7 @@ package org.thingsboard.server.common.data.edqs.fields; import com.fasterxml.jackson.databind.JsonNode; import lombok.Data; +import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import lombok.experimental.SuperBuilder; @@ -25,6 +26,7 @@ import java.util.UUID; import static org.thingsboard.server.common.data.edqs.fields.FieldsUtil.getText; @Data +@EqualsAndHashCode(callSuper = false) @NoArgsConstructor @SuperBuilder public class TenantFields extends AbstractEntityFields { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/TenantProfileFields.java b/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/TenantProfileFields.java index f6a2889f67..5d1ff0e0e2 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/TenantProfileFields.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/TenantProfileFields.java @@ -16,6 +16,7 @@ package org.thingsboard.server.common.data.edqs.fields; import lombok.Data; +import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import lombok.experimental.SuperBuilder; import org.thingsboard.server.common.data.id.TenantId; @@ -23,6 +24,7 @@ import org.thingsboard.server.common.data.id.TenantId; import java.util.UUID; @Data +@EqualsAndHashCode(callSuper = false) @NoArgsConstructor @SuperBuilder public class TenantProfileFields extends AbstractEntityFields { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/UserFields.java b/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/UserFields.java index 225b85680f..70fde8bf9c 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/UserFields.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/UserFields.java @@ -17,6 +17,7 @@ package org.thingsboard.server.common.data.edqs.fields; import com.fasterxml.jackson.databind.JsonNode; import lombok.Data; +import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import lombok.experimental.SuperBuilder; @@ -25,6 +26,7 @@ import java.util.UUID; import static org.thingsboard.server.common.data.edqs.fields.FieldsUtil.getText; @Data +@EqualsAndHashCode(callSuper = false) @NoArgsConstructor @SuperBuilder public class UserFields extends AbstractEntityFields { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/kv/BaseDeleteTsKvQuery.java b/common/data/src/main/java/org/thingsboard/server/common/data/kv/BaseDeleteTsKvQuery.java index 233c53849c..f46339c15a 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/kv/BaseDeleteTsKvQuery.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/kv/BaseDeleteTsKvQuery.java @@ -16,8 +16,10 @@ package org.thingsboard.server.common.data.kv; import lombok.Data; +import lombok.EqualsAndHashCode; @Data +@EqualsAndHashCode(callSuper = false) public class BaseDeleteTsKvQuery extends BaseTsKvQuery implements DeleteTsKvQuery { private final Boolean rewriteLatestIfDeleted; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/query/AlarmCountQuery.java b/common/data/src/main/java/org/thingsboard/server/common/data/query/AlarmCountQuery.java index 8431d7a303..0f1138b02e 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/query/AlarmCountQuery.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/query/AlarmCountQuery.java @@ -19,6 +19,7 @@ import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; +import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import lombok.ToString; import org.thingsboard.server.common.data.alarm.AlarmSearchStatus; @@ -31,6 +32,7 @@ import java.util.List; @NoArgsConstructor @AllArgsConstructor @Data +@EqualsAndHashCode(callSuper = false) @ToString @Schema public class AlarmCountQuery extends EntityCountQuery { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/queue/Queue.java b/common/data/src/main/java/org/thingsboard/server/common/data/queue/Queue.java index 57e0e6af66..d6a4f2b12f 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/queue/Queue.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/queue/Queue.java @@ -18,6 +18,7 @@ package org.thingsboard.server.common.data.queue; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.databind.JsonNode; import lombok.Data; +import lombok.EqualsAndHashCode; import org.thingsboard.server.common.data.BaseDataWithAdditionalInfo; import org.thingsboard.server.common.data.HasName; import org.thingsboard.server.common.data.HasTenantId; @@ -30,6 +31,7 @@ import org.thingsboard.server.common.data.validation.NoXss; import java.util.Optional; @Data +@EqualsAndHashCode(callSuper = false) public class Queue extends BaseDataWithAdditionalInfo implements HasName, HasTenantId, QueueConfig { private TenantId tenantId; @NoXss diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleNodeState.java b/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleNodeState.java index cb861a6726..0624350d7e 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleNodeState.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleNodeState.java @@ -16,12 +16,14 @@ package org.thingsboard.server.common.data.rule; import lombok.Data; +import lombok.EqualsAndHashCode; import org.thingsboard.server.common.data.BaseData; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.RuleNodeId; import org.thingsboard.server.common.data.id.RuleNodeStateId; @Data +@EqualsAndHashCode(callSuper = false) public class RuleNodeState extends BaseData { private RuleNodeId ruleNodeId; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/widget/WidgetTypeInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/widget/WidgetTypeInfo.java index 9fe846796b..9acce93aa3 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/widget/WidgetTypeInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/widget/WidgetTypeInfo.java @@ -18,6 +18,7 @@ package org.thingsboard.server.common.data.widget; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.Valid; import lombok.Data; +import lombok.EqualsAndHashCode; import org.thingsboard.server.common.data.id.WidgetTypeId; import org.thingsboard.server.common.data.validation.NoXss; @@ -26,6 +27,7 @@ import java.util.Collections; import java.util.List; @Data +@EqualsAndHashCode(callSuper = false) public class WidgetTypeInfo extends BaseWidgetType { @Serial diff --git a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/limits/GatewaySessionLimits.java b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/limits/GatewaySessionLimits.java index 45d9e21e39..8356a17748 100644 --- a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/limits/GatewaySessionLimits.java +++ b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/limits/GatewaySessionLimits.java @@ -16,8 +16,10 @@ package org.thingsboard.server.transport.mqtt.limits; import lombok.Data; +import lombok.EqualsAndHashCode; @Data +@EqualsAndHashCode(callSuper = false) public class GatewaySessionLimits extends SessionLimits { private SessionRateLimits gatewayRateLimits; diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sqlts/latest/TsKvLatestEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sqlts/latest/TsKvLatestEntity.java index 971c06c7a0..f73b634f08 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sqlts/latest/TsKvLatestEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sqlts/latest/TsKvLatestEntity.java @@ -26,6 +26,7 @@ import jakarta.persistence.SqlResultSetMapping; import jakarta.persistence.SqlResultSetMappings; import jakarta.persistence.Table; import lombok.Data; +import lombok.EqualsAndHashCode; import org.thingsboard.server.common.data.kv.TsKvEntry; import org.thingsboard.server.dao.model.sql.AbstractTsKvEntity; import org.thingsboard.server.dao.sqlts.latest.SearchTsKvLatestRepository; @@ -35,6 +36,7 @@ import java.util.UUID; import static org.thingsboard.server.dao.model.ModelConstants.VERSION_COLUMN; @Data +@EqualsAndHashCode(callSuper = false) @Entity @Table(name = "ts_kv_latest") @IdClass(TsKvLatestCompositeKey.class) diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbClearAlarmNodeConfiguration.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbClearAlarmNodeConfiguration.java index a69a157241..ab305919fd 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbClearAlarmNodeConfiguration.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbClearAlarmNodeConfiguration.java @@ -16,10 +16,12 @@ package org.thingsboard.rule.engine.action; import lombok.Data; +import lombok.EqualsAndHashCode; import org.thingsboard.rule.engine.api.NodeConfiguration; import org.thingsboard.server.common.data.script.ScriptLanguage; @Data +@EqualsAndHashCode(callSuper = false) public class TbClearAlarmNodeConfiguration extends TbAbstractAlarmNodeConfiguration implements NodeConfiguration { @Override diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbCreateAlarmNodeConfiguration.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbCreateAlarmNodeConfiguration.java index 8c791e7634..bf305a55d1 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbCreateAlarmNodeConfiguration.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbCreateAlarmNodeConfiguration.java @@ -16,6 +16,7 @@ package org.thingsboard.rule.engine.action; import lombok.Data; +import lombok.EqualsAndHashCode; import org.thingsboard.rule.engine.api.NodeConfiguration; import org.thingsboard.server.common.data.alarm.AlarmSeverity; import org.thingsboard.server.common.data.script.ScriptLanguage; @@ -25,6 +26,7 @@ import java.util.Collections; import java.util.List; @Data +@EqualsAndHashCode(callSuper = false) public class TbCreateAlarmNodeConfiguration extends TbAbstractAlarmNodeConfiguration implements NodeConfiguration { @NoXss diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/geo/TbGpsGeofencingActionNodeConfiguration.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/geo/TbGpsGeofencingActionNodeConfiguration.java index 3b59d814f1..6551352823 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/geo/TbGpsGeofencingActionNodeConfiguration.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/geo/TbGpsGeofencingActionNodeConfiguration.java @@ -16,6 +16,7 @@ package org.thingsboard.rule.engine.geo; import lombok.Data; +import lombok.EqualsAndHashCode; import org.thingsboard.common.util.geo.PerimeterType; import java.util.concurrent.TimeUnit; @@ -24,6 +25,7 @@ import java.util.concurrent.TimeUnit; * Created by ashvayka on 19.01.18. */ @Data +@EqualsAndHashCode(callSuper = false) public class TbGpsGeofencingActionNodeConfiguration extends TbGpsGeofencingFilterNodeConfiguration { private int minInsideDuration; diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/mqtt/azure/AzureIotHubSasCredentials.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/mqtt/azure/AzureIotHubSasCredentials.java index fe17c659e1..93d1ef7ef8 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/mqtt/azure/AzureIotHubSasCredentials.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/mqtt/azure/AzureIotHubSasCredentials.java @@ -20,6 +20,7 @@ import io.netty.handler.ssl.ClientAuth; import io.netty.handler.ssl.SslContext; import io.netty.handler.ssl.SslContextBuilder; import lombok.Data; +import lombok.EqualsAndHashCode; import lombok.extern.slf4j.Slf4j; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.thingsboard.common.util.AzureIotHubUtil; @@ -29,6 +30,7 @@ import org.thingsboard.rule.engine.credentials.CredentialsType; import java.security.Security; @Data +@EqualsAndHashCode(callSuper = false) @Slf4j @JsonIgnoreProperties(ignoreUnknown = true) public class AzureIotHubSasCredentials extends CertPemCredentials { diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/mqtt/azure/TbAzureIotHubNodeConfiguration.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/mqtt/azure/TbAzureIotHubNodeConfiguration.java index c786478575..f11173f3f9 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/mqtt/azure/TbAzureIotHubNodeConfiguration.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/mqtt/azure/TbAzureIotHubNodeConfiguration.java @@ -17,9 +17,11 @@ package org.thingsboard.rule.engine.mqtt.azure; import io.netty.handler.codec.mqtt.MqttVersion; import lombok.Data; +import lombok.EqualsAndHashCode; import org.thingsboard.rule.engine.mqtt.TbMqttNodeConfiguration; @Data +@EqualsAndHashCode(callSuper = false) public class TbAzureIotHubNodeConfiguration extends TbMqttNodeConfiguration { @Override From f22a68fe41affa5be763acbbfa8701e4c7592f9f Mon Sep 17 00:00:00 2001 From: Oleksandra Matviienko Date: Fri, 24 Apr 2026 11:31:54 +0200 Subject: [PATCH 32/91] Modernized Redis access in LwM2M transport and OTA cache --- .../cache/ota/RedisOtaPackageDataCache.java | 8 +-- .../store/TbLwM2MDtlsSessionRedisStore.java | 6 +- .../store/TbLwM2mRedisClientOtaInfoStore.java | 4 +- .../store/TbLwM2mRedisRegistrationStore.java | 68 +++++++++---------- .../store/TbLwM2mRedisSecurityStore.java | 24 +++---- .../server/store/TbRedisLwM2MClientStore.java | 10 +-- .../store/TbRedisLwM2MModelConfigStore.java | 8 +-- .../store/TbRedisLwM2MClientStoreTest.java | 21 +++--- 8 files changed, 75 insertions(+), 74 deletions(-) diff --git a/common/cache/src/main/java/org/thingsboard/server/cache/ota/RedisOtaPackageDataCache.java b/common/cache/src/main/java/org/thingsboard/server/cache/ota/RedisOtaPackageDataCache.java index c3a9ff0385..1e13b1cfe9 100644 --- a/common/cache/src/main/java/org/thingsboard/server/cache/ota/RedisOtaPackageDataCache.java +++ b/common/cache/src/main/java/org/thingsboard/server/cache/ota/RedisOtaPackageDataCache.java @@ -39,26 +39,26 @@ public class RedisOtaPackageDataCache implements OtaPackageDataCache { public byte[] get(String key, int chunkSize, int chunk) { try (RedisConnection connection = redisConnectionFactory.getConnection()) { if (chunkSize == 0) { - return connection.get(toOtaPackageCacheKey(key)); + return connection.stringCommands().get(toOtaPackageCacheKey(key)); } int startIndex = chunkSize * chunk; int endIndex = startIndex + chunkSize - 1; - return connection.getRange(toOtaPackageCacheKey(key), startIndex, endIndex); + return connection.stringCommands().getRange(toOtaPackageCacheKey(key), startIndex, endIndex); } } @Override public void put(String key, byte[] value) { try (RedisConnection connection = redisConnectionFactory.getConnection()) { - connection.set(toOtaPackageCacheKey(key), value); + connection.stringCommands().set(toOtaPackageCacheKey(key), value); } } @Override public void evict(String key) { try (RedisConnection connection = redisConnectionFactory.getConnection()) { - connection.del(toOtaPackageCacheKey(key)); + connection.keyCommands().del(toOtaPackageCacheKey(key)); } } diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbLwM2MDtlsSessionRedisStore.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbLwM2MDtlsSessionRedisStore.java index ead9269108..fa78bbb7bb 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbLwM2MDtlsSessionRedisStore.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbLwM2MDtlsSessionRedisStore.java @@ -33,7 +33,7 @@ public class TbLwM2MDtlsSessionRedisStore implements TbLwM2MDtlsSessionStore { try (var c = connectionFactory.getConnection()) { var serializedMsg = JavaSerDesUtil.encode(msg); if (serializedMsg != null) { - c.set(getKey(endpoint), serializedMsg); + c.stringCommands().set(getKey(endpoint), serializedMsg); } else { throw new RuntimeException("Problem with serialization of message: " + msg); } @@ -43,7 +43,7 @@ public class TbLwM2MDtlsSessionRedisStore implements TbLwM2MDtlsSessionStore { @Override public TbX509DtlsSessionInfo get(String endpoint) { try (var c = connectionFactory.getConnection()) { - var data = c.get(getKey(endpoint)); + var data = c.stringCommands().get(getKey(endpoint)); if (data != null) { return JavaSerDesUtil.decode(data); } else { @@ -55,7 +55,7 @@ public class TbLwM2MDtlsSessionRedisStore implements TbLwM2MDtlsSessionStore { @Override public void remove(String endpoint) { try (var c = connectionFactory.getConnection()) { - c.del(getKey(endpoint)); + c.keyCommands().del(getKey(endpoint)); } } diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbLwM2mRedisClientOtaInfoStore.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbLwM2mRedisClientOtaInfoStore.java index 8301d4a448..c75a5ff8a0 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbLwM2mRedisClientOtaInfoStore.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbLwM2mRedisClientOtaInfoStore.java @@ -33,7 +33,7 @@ public class TbLwM2mRedisClientOtaInfoStore implements TbLwM2MClientOtaInfoStore private void put(OtaPackageType type, LwM2MClientOtaInfo info) { try (var connection = connectionFactory.getConnection()) { - connection.set((OTA_EP + type + info.getEndpoint()).getBytes(), JacksonUtil.toString(info).getBytes()); + connection.stringCommands().set((OTA_EP + type + info.getEndpoint()).getBytes(), JacksonUtil.toString(info).getBytes()); } } @@ -59,7 +59,7 @@ public class TbLwM2mRedisClientOtaInfoStore implements TbLwM2MClientOtaInfoStore private > T getLwM2MClientOtaInfo(OtaPackageType type, String endpoint, Class clazz) { try (var connection = connectionFactory.getConnection()) { - byte[] data = connection.get((OTA_EP + type + endpoint).getBytes()); + byte[] data = connection.stringCommands().get((OTA_EP + type + endpoint).getBytes()); return JacksonUtil.fromBytes(data, clazz); } } diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbLwM2mRedisRegistrationStore.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbLwM2mRedisRegistrationStore.java index 8158e82a81..06f91729e4 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbLwM2mRedisRegistrationStore.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbLwM2mRedisRegistrationStore.java @@ -163,15 +163,15 @@ public class TbLwM2mRedisRegistrationStore implements RegistrationStore, Startab lock.lock(); // add registration byte[] k = toEndpointKey(registration.getEndpoint()); - byte[] old = connection.getSet(k, serializeReg(registration)); + byte[] old = connection.stringCommands().getSet(k, serializeReg(registration)); // add registration: secondary indexes byte[] regid_idx = toRegIdKey(registration.getId()); - connection.set(regid_idx, registration.getEndpoint().getBytes(UTF_8)); + connection.stringCommands().set(regid_idx, registration.getEndpoint().getBytes(UTF_8)); byte[] addr_idx = toRegAddrKey(registration.getSocketAddress()); - connection.set(addr_idx, registration.getEndpoint().getBytes(UTF_8)); + connection.stringCommands().set(addr_idx, registration.getEndpoint().getBytes(UTF_8)); byte[] identity_idx = toRegIdentityKey(registration.getClientTransportData().getIdentity()); - connection.set(identity_idx, registration.getEndpoint().getBytes(UTF_8)); + connection.stringCommands().set(identity_idx, registration.getEndpoint().getBytes(UTF_8)); // Add or update expiration addOrUpdateExpiration(connection, registration); @@ -180,7 +180,7 @@ public class TbLwM2mRedisRegistrationStore implements RegistrationStore, Startab Registration oldRegistration = deserializeReg(old); // remove old secondary index if (!registration.getId().equals(oldRegistration.getId())) - connection.del(toRegIdKey(oldRegistration.getId())); + connection.keyCommands().del(toRegIdKey(oldRegistration.getId())); if (!oldRegistration.getSocketAddress().equals(registration.getSocketAddress())) { removeAddrIndex(connection, oldRegistration); } @@ -209,7 +209,7 @@ public class TbLwM2mRedisRegistrationStore implements RegistrationStore, Startab try (var connection = connectionFactory.getConnection()) { // Fetch the registration ep by registration ID index - byte[] ep = connection.get(toRegIdKey(update.getRegistrationId())); + byte[] ep = connection.stringCommands().get(toRegIdKey(update.getRegistrationId())); if (ep == null) { return null; } @@ -220,7 +220,7 @@ public class TbLwM2mRedisRegistrationStore implements RegistrationStore, Startab lock.lock(); // Fetch the registration - byte[] data = connection.get(toEndpointKey(ep)); + byte[] data = connection.stringCommands().get(toEndpointKey(ep)); if (data == null) { return null; } @@ -230,7 +230,7 @@ public class TbLwM2mRedisRegistrationStore implements RegistrationStore, Startab Registration updatedRegistration = update.update(r); // Store the new registration - connection.set(toEndpointKey(updatedRegistration.getEndpoint()), serializeReg(updatedRegistration)); + connection.stringCommands().set(toEndpointKey(updatedRegistration.getEndpoint()), serializeReg(updatedRegistration)); // Add or update expiration addOrUpdateExpiration(connection, updatedRegistration); @@ -239,7 +239,7 @@ public class TbLwM2mRedisRegistrationStore implements RegistrationStore, Startab * If registration is already associated to this address we don't care as we only want to keep the most * recent binding. */ byte[] addr_idx = toRegAddrKey(updatedRegistration.getSocketAddress()); - connection.set(addr_idx, updatedRegistration.getEndpoint().getBytes(UTF_8)); + connection.stringCommands().set(addr_idx, updatedRegistration.getEndpoint().getBytes(UTF_8)); if (!r.getSocketAddress().equals(updatedRegistration.getSocketAddress())) { removeAddrIndex(connection, r); } @@ -265,11 +265,11 @@ public class TbLwM2mRedisRegistrationStore implements RegistrationStore, Startab } private Registration getRegistration(RedisConnection connection, String registrationId) { - byte[] ep = connection.get(toRegIdKey(registrationId)); + byte[] ep = connection.stringCommands().get(toRegIdKey(registrationId)); if (ep == null) { return null; } - byte[] data = connection.get(toEndpointKey(ep)); + byte[] data = connection.stringCommands().get(toEndpointKey(ep)); if (data == null) { return null; } @@ -281,7 +281,7 @@ public class TbLwM2mRedisRegistrationStore implements RegistrationStore, Startab public Registration getRegistrationByEndpoint(String endpoint) { Validate.notNull(endpoint); try (var connection = connectionFactory.getConnection()) { - byte[] data = connection.get(toEndpointKey(endpoint)); + byte[] data = connection.stringCommands().get(toEndpointKey(endpoint)); if (data == null) { return null; } @@ -293,11 +293,11 @@ public class TbLwM2mRedisRegistrationStore implements RegistrationStore, Startab public Registration getRegistrationByAdress(InetSocketAddress address) { Validate.notNull(address); try (var connection = connectionFactory.getConnection()) { - byte[] ep = connection.get(toRegAddrKey(address)); + byte[] ep = connection.stringCommands().get(toRegAddrKey(address)); if (ep == null) { return null; } - byte[] data = connection.get(toEndpointKey(ep)); + byte[] data = connection.stringCommands().get(toEndpointKey(ep)); if (data == null) { return null; } @@ -309,11 +309,11 @@ public class TbLwM2mRedisRegistrationStore implements RegistrationStore, Startab public Registration getRegistrationByIdentity(LwM2mIdentity identity) { Validate.notNull(identity); try (var connection = connectionFactory.getConnection()) { - byte[] ep = connection.get(toRegIdentityKey(identity)); + byte[] ep = connection.stringCommands().get(toRegIdentityKey(identity)); if (ep == null) { return null; } - byte[] data = connection.get(toEndpointKey(ep)); + byte[] data = connection.stringCommands().get(toEndpointKey(ep)); if (data == null) { return null; } @@ -332,12 +332,12 @@ public class TbLwM2mRedisRegistrationStore implements RegistrationStore, Startab clusterConnection.clusterGetNodes().forEach(node -> scans.add(clusterConnection.scan(node, scanOptions))); } else { - scans.add(scanConnection.scan(scanOptions)); + scans.add(scanConnection.keyCommands().scan(scanOptions)); } scans.forEach(scan -> { scan.forEachRemaining(key -> { - byte[] element = getConnection.get(key); + byte[] element = getConnection.stringCommands().get(key); if (element != null) { list.add(deserializeReg(element)); } @@ -357,7 +357,7 @@ public class TbLwM2mRedisRegistrationStore implements RegistrationStore, Startab private Deregistration removeRegistration(RedisConnection connection, String registrationId, boolean removeOnlyIfNotAlive) { // fetch the client ep by registration ID index - byte[] ep = connection.get(toRegIdKey(registrationId)); + byte[] ep = connection.stringCommands().get(toRegIdKey(registrationId)); if (ep == null) { return null; } @@ -369,16 +369,16 @@ public class TbLwM2mRedisRegistrationStore implements RegistrationStore, Startab lock.lock(); // fetch the client - byte[] data = connection.get(toEndpointKey(ep)); + byte[] data = connection.stringCommands().get(toEndpointKey(ep)); if (data == null) { return null; } Registration r = deserializeReg(data); if (!removeOnlyIfNotAlive || !r.isAlive(gracePeriod)) { - long nbRemoved = connection.del(toRegIdKey(r.getId())); + long nbRemoved = connection.keyCommands().del(toRegIdKey(r.getId())); if (nbRemoved > 0) { - connection.del(toEndpointKey(r.getEndpoint())); + connection.keyCommands().del(toEndpointKey(r.getEndpoint())); Collection obsRemoved = unsafeRemoveAllObservations(connection, r.getId()); removeAddrIndex(connection, r); removeIdentityIndex(connection, r); @@ -407,12 +407,12 @@ public class TbLwM2mRedisRegistrationStore implements RegistrationStore, Startab // Watch the key to remove. // connection.watch(indexKey); - byte[] epFromAddr = connection.get(indexKey); + byte[] epFromAddr = connection.stringCommands().get(indexKey); // Delete the key if needed. if (Arrays.equals(epFromAddr, endpointName.getBytes(UTF_8))) { // Try to delete the key // connection.multi(); - connection.del(indexKey); + connection.keyCommands().del(indexKey); // connection.exec(); // if transaction failed this is not an issue as the index is probably reused and we don't need to // delete it anymore. @@ -423,11 +423,11 @@ public class TbLwM2mRedisRegistrationStore implements RegistrationStore, Startab } private void addOrUpdateExpiration(RedisConnection connection, Registration registration) { - connection.zAdd(EXP_EP, registration.getExpirationTimeStamp(gracePeriod), registration.getEndpoint().getBytes(UTF_8)); + connection.zSetCommands().zAdd(EXP_EP, registration.getExpirationTimeStamp(gracePeriod), registration.getEndpoint().getBytes(UTF_8)); } private void removeExpiration(RedisConnection connection, Registration registration) { - connection.zRem(EXP_EP, registration.getEndpoint().getBytes(UTF_8)); + connection.zSetCommands().zRem(EXP_EP, registration.getEndpoint().getBytes(UTF_8)); } private byte[] toRegIdKey(String registrationId) { @@ -556,7 +556,7 @@ public class TbLwM2mRedisRegistrationStore implements RegistrationStore, Startab @Override public Observation getObservation(ObservationIdentifier observationId) { try (var connection = connectionFactory.getConnection()) { - byte[] observationValue = connection.get(toKey(OBS_TKN, observationId.getBytes())); + byte[] observationValue = connection.stringCommands().get(toKey(OBS_TKN, observationId.getBytes())); return deserializeObs(observationValue); } } @@ -570,7 +570,7 @@ public class TbLwM2mRedisRegistrationStore implements RegistrationStore, Startab try (var connection = connectionFactory.getConnection()) { // fetch the client ep by registration ID index - byte[] ep = connection.get(toRegIdKey(registrationId)); + byte[] ep = connection.stringCommands().get(toRegIdKey(registrationId)); if (ep == null) { return null; } @@ -635,7 +635,7 @@ public class TbLwM2mRedisRegistrationStore implements RegistrationStore, Startab public Observation get(Token token) { try (var connection = connectionFactory.getConnection()) { - byte[] obs = connection.get(toKey(OBS_TKN, token.getBytes())); + byte[] obs = connection.stringCommands().get(toKey(OBS_TKN, token.getBytes())); if (obs == null) { return null; } else { @@ -664,14 +664,14 @@ public class TbLwM2mRedisRegistrationStore implements RegistrationStore, Startab byte[] regIdKey = toKey(OBS_TKNS_REGID_IDX, registrationId); // fetch all observations by token - for (byte[] token : connection.lRange(regIdKey, 0, -1)) { - byte[] obs = connection.get(toKey(OBS_TKN, token)); + for (byte[] token : connection.listCommands().lRange(regIdKey, 0, -1)) { + byte[] obs = connection.stringCommands().get(toKey(OBS_TKN, token)); if (obs != null) { removed.add(deserializeObs(obs)); } - connection.del(toKey(OBS_TKN, token)); + connection.keyCommands().del(toKey(OBS_TKN, token)); } - connection.del(regIdKey); + connection.keyCommands().del(regIdKey); return removed; } @@ -752,7 +752,7 @@ public class TbLwM2mRedisRegistrationStore implements RegistrationStore, Startab System.currentTimeMillis(), 0, cleanLimit); for (byte[] endpoint : endpointsExpired) { - byte[] data = connection.get(toEndpointKey(endpoint)); + byte[] data = connection.stringCommands().get(toEndpointKey(endpoint)); if (data != null && data.length > 0) { Registration r = deserializeReg(data); if (!r.isAlive(gracePeriod)) { diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbLwM2mRedisSecurityStore.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbLwM2mRedisSecurityStore.java index b07156d0ef..1e5d480c81 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbLwM2mRedisSecurityStore.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbLwM2mRedisSecurityStore.java @@ -52,7 +52,7 @@ public class TbLwM2mRedisSecurityStore implements TbEditableSecurityStore { try (var connection = connectionFactory.getConnection()) { lock = redisLock.obtain(toLockKey(endpoint)); lock.lock(); - byte[] data = connection.get((SEC_EP + endpoint).getBytes()); + byte[] data = connection.stringCommands().get((SEC_EP + endpoint).getBytes()); if (data == null || data.length == 0) { return null; } else { @@ -96,11 +96,11 @@ public class TbLwM2mRedisSecurityStore implements TbEditableSecurityStore { try (var connection = connectionFactory.getConnection()) { lock = redisLock.obtain(toLockKey(identity)); lock.lock(); - byte[] ep = connection.hGet(PSKID_SEC.getBytes(), identity.getBytes()); + byte[] ep = connection.hashCommands().hGet(PSKID_SEC.getBytes(), identity.getBytes()); if (ep == null) { return null; } else { - byte[] data = connection.get((SEC_EP + new String(ep)).getBytes()); + byte[] data = connection.stringCommands().get((SEC_EP + new String(ep)).getBytes()); if (data == null || data.length == 0) { return null; } else { @@ -128,17 +128,17 @@ public class TbLwM2mRedisSecurityStore implements TbEditableSecurityStore { lock = redisLock.obtain(tbSecurityInfo.getEndpoint()); lock.lock(); if (info != null && info.getPskIdentity() != null) { - byte[] oldEndpointBytes = connection.hGet(PSKID_SEC.getBytes(), info.getPskIdentity().getBytes()); + byte[] oldEndpointBytes = connection.hashCommands().hGet(PSKID_SEC.getBytes(), info.getPskIdentity().getBytes()); if (oldEndpointBytes != null) { String oldEndpoint = new String(oldEndpointBytes); if (!oldEndpoint.equals(info.getEndpoint())) { throw new NonUniqueSecurityInfoException("PSK Identity " + info.getPskIdentity() + " is already used"); } - connection.hSet(PSKID_SEC.getBytes(), info.getPskIdentity().getBytes(), info.getEndpoint().getBytes()); + connection.hashCommands().hSet(PSKID_SEC.getBytes(), info.getPskIdentity().getBytes(), info.getEndpoint().getBytes()); } } - byte[] previousData = connection.getSet((SEC_EP + tbSecurityInfo.getEndpoint()).getBytes(), tbSecurityInfoSerialized); + byte[] previousData = connection.stringCommands().getSet((SEC_EP + tbSecurityInfo.getEndpoint()).getBytes(), tbSecurityInfoSerialized); // for tests: redis connect NoSec (securityInfo == null) log.info("lwm2m redis connect. Endpoint: [{}], secMode: [{}] key: [{}], tbSecurityInfoSerialized [{}]", @@ -147,7 +147,7 @@ public class TbLwM2mRedisSecurityStore implements TbEditableSecurityStore { if (previousData != null && info != null) { String previousIdentity = ((TbLwM2MSecurityInfo) JavaSerDesUtil.decode(previousData)).getSecurityInfo().getPskIdentity(); if (previousIdentity != null && !previousIdentity.equals(info.getPskIdentity())) { - connection.hDel(PSKID_SEC.getBytes(), previousIdentity.getBytes()); + connection.hashCommands().hDel(PSKID_SEC.getBytes(), previousIdentity.getBytes()); } } } finally { @@ -163,7 +163,7 @@ public class TbLwM2mRedisSecurityStore implements TbEditableSecurityStore { try (var connection = connectionFactory.getConnection()) { lock = redisLock.obtain(endpoint); lock.lock(); - byte[] data = connection.get((SEC_EP + endpoint).getBytes()); + byte[] data = connection.stringCommands().get((SEC_EP + endpoint).getBytes()); if (data != null && data.length > 0) { return JavaSerDesUtil.decode(data); } else { @@ -182,13 +182,13 @@ public class TbLwM2mRedisSecurityStore implements TbEditableSecurityStore { try (var connection = connectionFactory.getConnection()) { lock = redisLock.obtain(endpoint); lock.lock(); - byte[] data = connection.get((SEC_EP + endpoint).getBytes()); + byte[] data = connection.stringCommands().get((SEC_EP + endpoint).getBytes()); if (data != null && data.length > 0) { SecurityInfo info = ((TbLwM2MSecurityInfo) JavaSerDesUtil.decode(data)).getSecurityInfo(); if (info != null && info.getPskIdentity() != null) { - connection.hDel(PSKID_SEC.getBytes(), info.getPskIdentity().getBytes()); + connection.hashCommands().hDel(PSKID_SEC.getBytes(), info.getPskIdentity().getBytes()); } - connection.del((SEC_EP + endpoint).getBytes()); + connection.keyCommands().del((SEC_EP + endpoint).getBytes()); } } finally { if (lock != null) { @@ -203,7 +203,7 @@ public class TbLwM2mRedisSecurityStore implements TbEditableSecurityStore { private SecurityMode getSecurityModeByRegistration (RedisConnection connection, String endpoint) { try { - byte[] data = connection.get((REG_EP + endpoint).getBytes()); + byte[] data = connection.stringCommands().get((REG_EP + endpoint).getBytes()); JsonNode registrationNode = JacksonUtil.fromString(new String(data != null ? data : new byte[0]), JsonNode.class); String typeModeStr = registrationNode.get("transportdata").get("identity").get("type").asText(); return "unsecure".equals(typeModeStr) ? SecurityMode.NO_SEC : null; diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbRedisLwM2MClientStore.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbRedisLwM2MClientStore.java index 4beefb4896..73d4bd95da 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbRedisLwM2MClientStore.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbRedisLwM2MClientStore.java @@ -45,7 +45,7 @@ public class TbRedisLwM2MClientStore implements TbLwM2MClientStore { @Override public LwM2mClient get(String endpoint) { try (var connection = connectionFactory.getConnection()) { - byte[] data = connection.get(getKey(endpoint)); + byte[] data = connection.stringCommands().get(getKey(endpoint)); if (data == null) { return null; } else { @@ -70,12 +70,12 @@ public class TbRedisLwM2MClientStore implements TbLwM2MClientStore { clusterConnection.clusterGetNodes().forEach(node -> scans.add(clusterConnection.scan(node, scanOptions))); } else { - scans.add(scanConnection.scan(scanOptions)); + scans.add(scanConnection.keyCommands().scan(scanOptions)); } scans.forEach(scan -> { scan.forEachRemaining(key -> { - byte[] element = getConnection.get(key); + byte[] element = getConnection.stringCommands().get(key); if (element != null) { try { clients.add(deserialize(element)); @@ -97,7 +97,7 @@ public class TbRedisLwM2MClientStore implements TbLwM2MClientStore { try { byte[] clientSerialized = serialize(client); try (var connection = connectionFactory.getConnection()) { - connection.getSet(getKey(client.getEndpoint()), clientSerialized); + connection.stringCommands().getSet(getKey(client.getEndpoint()), clientSerialized); } } catch (Exception e) { log.warn("Failed to serialize client: {}", client, e); @@ -108,7 +108,7 @@ public class TbRedisLwM2MClientStore implements TbLwM2MClientStore { @Override public void remove(String endpoint) { try (var connection = connectionFactory.getConnection()) { - connection.del(getKey(endpoint)); + connection.keyCommands().del(getKey(endpoint)); } } diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbRedisLwM2MModelConfigStore.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbRedisLwM2MModelConfigStore.java index 31a78234d0..65ed90d15d 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbRedisLwM2MModelConfigStore.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbRedisLwM2MModelConfigStore.java @@ -44,12 +44,12 @@ public class TbRedisLwM2MModelConfigStore implements TbLwM2MModelConfigStore { clusterConnection.clusterGetNodes().forEach(node -> scans.add(clusterConnection.scan(node, scanOptions))); } else { - scans.add(scanConnection.scan(scanOptions)); + scans.add(scanConnection.keyCommands().scan(scanOptions)); } scans.forEach(scan -> { scan.forEachRemaining(key -> { - byte[] element = getConnection.get(key); + byte[] element = getConnection.stringCommands().get(key); if (element != null) { configs.add(JacksonUtil.fromBytes(element, LwM2MModelConfig.class)); } @@ -63,14 +63,14 @@ public class TbRedisLwM2MModelConfigStore implements TbLwM2MModelConfigStore { public void put(LwM2MModelConfig modelConfig) { byte[] clientSerialized = JacksonUtil.writeValueAsBytes(modelConfig); try (var connection = connectionFactory.getConnection()) { - connection.getSet(getKey(modelConfig.getEndpoint()), clientSerialized); + connection.stringCommands().getSet(getKey(modelConfig.getEndpoint()), clientSerialized); } } @Override public void remove(String endpoint) { try (var connection = connectionFactory.getConnection()) { - connection.del(getKey(endpoint)); + connection.keyCommands().del(getKey(endpoint)); } } diff --git a/common/transport/lwm2m/src/test/java/org/thingsboard/server/transport/lwm2m/server/store/TbRedisLwM2MClientStoreTest.java b/common/transport/lwm2m/src/test/java/org/thingsboard/server/transport/lwm2m/server/store/TbRedisLwM2MClientStoreTest.java index 9fe29c1188..fe8d66365f 100644 --- a/common/transport/lwm2m/src/test/java/org/thingsboard/server/transport/lwm2m/server/store/TbRedisLwM2MClientStoreTest.java +++ b/common/transport/lwm2m/src/test/java/org/thingsboard/server/transport/lwm2m/server/store/TbRedisLwM2MClientStoreTest.java @@ -18,6 +18,7 @@ package org.thingsboard.server.transport.lwm2m.server.store; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Answers; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.data.redis.connection.RedisConnection; @@ -51,10 +52,10 @@ class TbRedisLwM2MClientStoreTest { @Mock RedisConnectionFactory connectionFactory; - @Mock + @Mock(answer = Answers.RETURNS_DEEP_STUBS) RedisConnection scanConnection; - @Mock + @Mock(answer = Answers.RETURNS_DEEP_STUBS) RedisConnection getConnection; TbRedisLwM2MClientStore store; @@ -77,8 +78,8 @@ class TbRedisLwM2MClientStoreTest { // Cursor created before thenReturn to avoid Mockito unfinished-stubbing error Cursor cursor = cursorOf(key); - when(scanConnection.scan(any(ScanOptions.class))).thenReturn(cursor); - when(getConnection.get(key)).thenReturn(value); + when(scanConnection.keyCommands().scan(any(ScanOptions.class))).thenReturn(cursor); + when(getConnection.stringCommands().get(key)).thenReturn(value); Set result = store.getAll(); @@ -89,29 +90,29 @@ class TbRedisLwM2MClientStoreTest { @Test void getAll_getIsNeverCalledOnScanConnection() { Cursor cursor = cursorOf(); - when(scanConnection.scan(any(ScanOptions.class))).thenReturn(cursor); + when(scanConnection.keyCommands().scan(any(ScanOptions.class))).thenReturn(cursor); store.getAll(); - verify(scanConnection, never()).get(any(byte[].class)); + verify(scanConnection.stringCommands(), never()).get(any(byte[].class)); } @Test void getAll_scanIsNeverCalledOnGetConnection() { Cursor cursor = cursorOf(); - when(scanConnection.scan(any(ScanOptions.class))).thenReturn(cursor); + when(scanConnection.keyCommands().scan(any(ScanOptions.class))).thenReturn(cursor); store.getAll(); - verify(getConnection, never()).scan(any(ScanOptions.class)); + verify(getConnection.keyCommands(), never()).scan(any(ScanOptions.class)); } @Test void getAll_skipsKeyWhenValueIsNull() { byte[] key = "CLIENT#EP#gone".getBytes(); Cursor cursor = cursorOf(key); - when(scanConnection.scan(any(ScanOptions.class))).thenReturn(cursor); - // getConnection.get(key) returns null by default — no stubbing needed + when(scanConnection.keyCommands().scan(any(ScanOptions.class))).thenReturn(cursor); + // getConnection.stringCommands().get(key) returns null by default — no stubbing needed Set result = store.getAll(); From fae07e914043cbd96d3a36bbbb1a650f87607917 Mon Sep 17 00:00:00 2001 From: Oleksandra Matviienko Date: Fri, 24 Apr 2026 15:00:26 +0200 Subject: [PATCH 33/91] Replaced deprecated string, number, and random-value helpers with modern equivalents --- .../DefaultSystemDataLoaderService.java | 2 +- .../mfa/provider/impl/TotpTwoFaProvider.java | 2 +- .../service/ws/WebSocketSessionType.java | 4 ++-- .../server/controller/AbstractWebTest.java | 2 +- .../controller/AdminControllerTest.java | 2 +- .../AlarmCommentControllerTest.java | 6 ++--- .../server/controller/AuthControllerTest.java | 8 +++---- .../controller/BaseQueueControllerTest.java | 2 +- .../controller/EntityQueryControllerTest.java | 4 ++-- .../server/controller/UserControllerTest.java | 4 ++-- .../server/controller/WebsocketApiTest.java | 4 ++-- .../discovery/HashPartitionServiceTest.java | 2 +- .../service/entitiy/EntityServiceTest.java | 6 ++--- .../housekeeper/HousekeeperServiceTest.java | 4 ++-- .../AbstractNotificationApiTest.java | 2 +- .../notification/NotificationApiWsClient.java | 2 +- .../NotificationTargetApiTest.java | 2 +- .../TbRuleEngineQueueConsumerManagerTest.java | 14 +++++------ .../service/sms/DefaultSmsServiceTest.java | 10 ++++---- ...DefaultTbLocalSubscriptionServiceTest.java | 6 ++--- .../subscription/TbEntityDataSubCtxTest.java | 10 ++++---- .../server/common/data/EntityType.java | 2 ++ .../common/data/util/TemplateUtils.java | 2 +- .../server/common/data/util/TypeCastUtil.java | 2 +- .../server/service/sync/vc/GitRepository.java | 5 ++-- .../server/dao/resource/BaseImageService.java | 2 +- .../dao/resource/BaseResourceService.java | 8 ++++--- .../dao/service/AdminSettingsServiceTest.java | 6 ++--- .../dao/service/AlarmCommentServiceTest.java | 8 +++---- .../server/dao/service/AssetServiceTest.java | 4 ++-- .../dao/sql/alarm/JpaAlarmCommentDaoTest.java | 4 ++-- .../dao/sql/user/JpaUserSettingsDaoTest.java | 4 ++-- .../dao/sqlts/SqlTimeseriesLatestDaoTest.java | 2 +- .../monitoring/client/WsClient.java | 2 +- .../service/MonitoringEntityService.java | 2 +- .../connectivity/MqttGatewayClientTest.java | 4 ++-- .../lwm2m/AbstractLwm2mClientTest.java | 6 ++--- .../lwm2m/rpc/Lwm2mObserveCompositeTest.java | 6 ++--- .../lwm2m/rpc/Lwm2mObserveTest.java | 6 ++--- .../lwm2m/security/Lwm2mClientNoSecTest.java | 4 ++-- .../lwm2m/security/Lwm2mClientPskTest.java | 4 ++-- .../msa/edqs/EdqsEntityDataQueryTest.java | 6 ++--- .../msa/prototypes/DevicePrototypes.java | 6 ++--- .../msa/ui/pages/CreateWidgetPopupHelper.java | 4 ++-- .../server/msa/ui/utils/EntityPrototypes.java | 24 +++++++++---------- .../client/tools/migrator/PgCaMigrator.java | 2 +- 46 files changed, 114 insertions(+), 109 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/service/install/DefaultSystemDataLoaderService.java b/application/src/main/java/org/thingsboard/server/service/install/DefaultSystemDataLoaderService.java index 965d7105a9..e88b390ca7 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/DefaultSystemDataLoaderService.java +++ b/application/src/main/java/org/thingsboard/server/service/install/DefaultSystemDataLoaderService.java @@ -335,7 +335,7 @@ public class DefaultSystemDataLoaderService implements SystemDataLoaderService { private String generateRandomKey() { return Base64.getEncoder().encodeToString( - RandomStringUtils.randomAlphanumeric(64).getBytes(StandardCharsets.UTF_8)); + RandomStringUtils.secure().nextAlphanumeric(64).getBytes(StandardCharsets.UTF_8)); } @Override diff --git a/application/src/main/java/org/thingsboard/server/service/security/auth/mfa/provider/impl/TotpTwoFaProvider.java b/application/src/main/java/org/thingsboard/server/service/security/auth/mfa/provider/impl/TotpTwoFaProvider.java index 23eda67a77..a7fbdb84e4 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/auth/mfa/provider/impl/TotpTwoFaProvider.java +++ b/application/src/main/java/org/thingsboard/server/service/security/auth/mfa/provider/impl/TotpTwoFaProvider.java @@ -62,7 +62,7 @@ public class TotpTwoFaProvider implements TwoFaProvider forName(String name) { return Arrays.stream(values()) - .filter(sessionType -> StringUtils.equals(sessionType.name, name)) + .filter(sessionType -> Objects.equals(sessionType.name, name)) .findFirst(); } diff --git a/application/src/test/java/org/thingsboard/server/controller/AbstractWebTest.java b/application/src/test/java/org/thingsboard/server/controller/AbstractWebTest.java index 055e1e19a0..7803b0c746 100644 --- a/application/src/test/java/org/thingsboard/server/controller/AbstractWebTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/AbstractWebTest.java @@ -1358,7 +1358,7 @@ public abstract class AbstractWebTest extends AbstractInMemoryStorageTest { protected NotificationTarget createNotificationTarget(UsersFilter usersFilter) { NotificationTarget notificationTarget = new NotificationTarget(); - notificationTarget.setName(usersFilter.toString() + RandomStringUtils.randomNumeric(5)); + notificationTarget.setName(usersFilter.toString() + RandomStringUtils.secure().nextNumeric(5)); PlatformUsersNotificationTargetConfig targetConfig = new PlatformUsersNotificationTargetConfig(); targetConfig.setUsersFilter(usersFilter); notificationTarget.setConfiguration(targetConfig); diff --git a/application/src/test/java/org/thingsboard/server/controller/AdminControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/AdminControllerTest.java index 21a8b3b2e9..ee09b9a98c 100644 --- a/application/src/test/java/org/thingsboard/server/controller/AdminControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/AdminControllerTest.java @@ -168,7 +168,7 @@ public class AdminControllerTest extends AbstractControllerTest { assertThat(jwtSettings).isEqualTo(defaultJwtSettings); jwtSettings.setTokenSigningKey(Base64.getEncoder().encodeToString( - RandomStringUtils.randomAlphanumeric(512 / Byte.SIZE).getBytes(StandardCharsets.UTF_8))); + RandomStringUtils.secure().nextAlphanumeric(512 / Byte.SIZE).getBytes(StandardCharsets.UTF_8))); doPost("/api/admin/jwtSettings", jwtSettings).andExpect(status().isOk()); diff --git a/application/src/test/java/org/thingsboard/server/controller/AlarmCommentControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/AlarmCommentControllerTest.java index 3bb5fd5647..89eb140c8b 100644 --- a/application/src/test/java/org/thingsboard/server/controller/AlarmCommentControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/AlarmCommentControllerTest.java @@ -28,7 +28,7 @@ import org.mockito.Mockito; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Primary; import org.springframework.test.context.ContextConfiguration; -import org.testcontainers.shaded.org.apache.commons.lang3.RandomStringUtils; +import org.apache.commons.lang3.RandomStringUtils; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.alarm.Alarm; @@ -292,7 +292,7 @@ public class AlarmCommentControllerTest extends AbstractControllerTest { final int size = 10; for (int i = 0; i < size; i++) { createdAlarmComments.add( - createAlarmComment(alarm.getId(), RandomStringUtils.randomAlphanumeric(10)) + createAlarmComment(alarm.getId(), RandomStringUtils.secure().nextAlphanumeric(10)) ); } @@ -323,7 +323,7 @@ public class AlarmCommentControllerTest extends AbstractControllerTest { List createdAlarmComments = new LinkedList<>(); for (int i = 0; i < size; i++) { createdAlarmComments.add( - createAlarmComment(alarm.getId(), RandomStringUtils.randomAlphanumeric(10)) + createAlarmComment(alarm.getId(), RandomStringUtils.secure().nextAlphanumeric(10)) ); } diff --git a/application/src/test/java/org/thingsboard/server/controller/AuthControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/AuthControllerTest.java index 419f442f87..a35e1f9af0 100644 --- a/application/src/test/java/org/thingsboard/server/controller/AuthControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/AuthControllerTest.java @@ -22,7 +22,7 @@ import org.junit.Test; import org.mockito.Mockito; import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.springframework.http.HttpHeaders; -import org.testcontainers.shaded.org.apache.commons.lang3.RandomStringUtils; +import org.apache.commons.lang3.RandomStringUtils; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.User; @@ -149,7 +149,7 @@ public class AuthControllerTest extends AbstractControllerTest { loginTenantAdmin(); ChangePasswordRequest changePasswordRequest = new ChangePasswordRequest(); changePasswordRequest.setCurrentPassword("tenant"); - changePasswordRequest.setNewPassword(RandomStringUtils.randomAlphanumeric(73)); + changePasswordRequest.setNewPassword(RandomStringUtils.secure().nextAlphanumeric(73)); doPost("/api/auth/changePassword", changePasswordRequest) .andExpect(status().isBadRequest()) .andExpect(jsonPath("$.message", is("Password must be no more than 72 characters in length."))); @@ -161,7 +161,7 @@ public class AuthControllerTest extends AbstractControllerTest { ChangePasswordRequest changePasswordRequest = new ChangePasswordRequest(); changePasswordRequest.setCurrentPassword("tenant"); - String newPassword = RandomStringUtils.randomAlphanumeric(16); + String newPassword = RandomStringUtils.secure().nextAlphanumeric(16); changePasswordRequest.setNewPassword(newPassword); doPost("/api/auth/changePassword", changePasswordRequest) .andExpect(status().isOk()); @@ -194,7 +194,7 @@ public class AuthControllerTest extends AbstractControllerTest { .andExpect(status().isSeeOther()) .andExpect(header().string(HttpHeaders.LOCATION, "/login/resetPassword?resetToken=" + this.currentResetPasswordToken)); - String newPassword = RandomStringUtils.randomAlphanumeric(73); + String newPassword = RandomStringUtils.secure().nextAlphanumeric(73); JsonNode resetPasswordRequest = JacksonUtil.newObjectNode() .put("resetToken", this.currentResetPasswordToken) .put("password", newPassword); diff --git a/application/src/test/java/org/thingsboard/server/controller/BaseQueueControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/BaseQueueControllerTest.java index 0d79882a94..b7507f5dec 100644 --- a/application/src/test/java/org/thingsboard/server/controller/BaseQueueControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/BaseQueueControllerTest.java @@ -236,7 +236,7 @@ public class BaseQueueControllerTest extends AbstractControllerTest { when(testProcessingResult.getFailedMap()).thenReturn(new ConcurrentHashMap<>()); when(testProcessingResult.getPendingMap()).thenReturn(new ConcurrentHashMap<>()); - String largeExceptionMessage = RandomStringUtils.randomAlphabetic(150); + String largeExceptionMessage = RandomStringUtils.secure().nextAlphabetic(150); RuleEngineException ruleEngineException = new RuleEngineException(largeExceptionMessage); when(testProcessingResult.getExceptionsMap()).thenReturn(new ConcurrentHashMap<>(Map.of( tenantId, ruleEngineException diff --git a/application/src/test/java/org/thingsboard/server/controller/EntityQueryControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/EntityQueryControllerTest.java index 835f00985b..f99fe4be6f 100644 --- a/application/src/test/java/org/thingsboard/server/controller/EntityQueryControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/EntityQueryControllerTest.java @@ -30,7 +30,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.TestPropertySource; import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.springframework.test.web.servlet.ResultActions; -import org.testcontainers.shaded.org.apache.commons.lang3.RandomStringUtils; +import org.apache.commons.lang3.RandomStringUtils; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.common.data.AttributeScope; import org.thingsboard.server.common.data.Customer; @@ -201,7 +201,7 @@ public class EntityQueryControllerTest extends AbstractControllerTest { loginTenantAdmin(); List devices = new ArrayList<>(); - String devicePrefix = "Device" + RandomStringUtils.randomAlphabetic(5); + String devicePrefix = "Device" + RandomStringUtils.secure().nextAlphabetic(5); for (int i = 0; i < 97; i++) { Device device = new Device(); device.setName(devicePrefix + i); diff --git a/application/src/test/java/org/thingsboard/server/controller/UserControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/UserControllerTest.java index 957b3721e0..751631aec2 100644 --- a/application/src/test/java/org/thingsboard/server/controller/UserControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/UserControllerTest.java @@ -1296,9 +1296,9 @@ public class UserControllerTest extends AbstractControllerTest { Assert.assertEquals(savedDashboard2.getTitle(), starred.getTitle()); //TEST renaming in the cache. - savedDashboard1.setTitle(RandomStringUtils.randomAlphanumeric(10)); + savedDashboard1.setTitle(RandomStringUtils.secure().nextAlphanumeric(10)); savedDashboard1 = doPost("/api/dashboard", savedDashboard1, Dashboard.class); - savedDashboard2.setTitle(RandomStringUtils.randomAlphanumeric(10)); + savedDashboard2.setTitle(RandomStringUtils.secure().nextAlphanumeric(10)); savedDashboard2 = doPost("/api/dashboard", savedDashboard2, Dashboard.class); newSettings = doGet("/api/user/dashboards/" + savedDashboard1.getId().getId() + "/unstar", UserDashboardsInfo.class); diff --git a/application/src/test/java/org/thingsboard/server/controller/WebsocketApiTest.java b/application/src/test/java/org/thingsboard/server/controller/WebsocketApiTest.java index e3b6a6efd8..ea34f428f3 100644 --- a/application/src/test/java/org/thingsboard/server/controller/WebsocketApiTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/WebsocketApiTest.java @@ -30,7 +30,7 @@ import org.mockito.Mockito; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.springframework.test.context.TestPropertySource; -import org.testcontainers.shaded.org.apache.commons.lang3.RandomStringUtils; +import org.apache.commons.lang3.RandomStringUtils; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.rule.engine.api.AttributesSaveRequest; import org.thingsboard.rule.engine.api.TimeseriesSaveRequest; @@ -556,7 +556,7 @@ public class WebsocketApiTest extends AbstractControllerTest { for (int i = 0; i < 6; i++) { Alarm alarm = new Alarm(); alarm.setOriginator(device.getId()); - alarm.setType(RandomStringUtils.randomAlphabetic(10)); + alarm.setType(RandomStringUtils.secure().nextAlphabetic(10)); alarm.setSeverity(AlarmSeverity.CRITICAL); alarm = doPost("/api/alarm", alarm, Alarm.class); alarms.add(alarm); 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 c361172b66..b1d59c031a 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 @@ -380,7 +380,7 @@ public class HashPartitionServiceTest { } Stream.concat(Stream.of(TenantId.SYS_TENANT_ID), Stream.generate(UUID::randomUUID).map(TenantId::new).limit(10)).forEach(tenantId -> { - List queues = Stream.generate(() -> RandomStringUtils.randomAlphabetic(10)) + List queues = Stream.generate(() -> RandomStringUtils.secure().nextAlphabetic(10)) .map(queueName -> new QueueKey(ServiceType.TB_RULE_ENGINE, queueName, tenantId)) .limit(100).toList(); diff --git a/application/src/test/java/org/thingsboard/server/service/entitiy/EntityServiceTest.java b/application/src/test/java/org/thingsboard/server/service/entitiy/EntityServiceTest.java index b3230b3d45..251f42bb3f 100644 --- a/application/src/test/java/org/thingsboard/server/service/entitiy/EntityServiceTest.java +++ b/application/src/test/java/org/thingsboard/server/service/entitiy/EntityServiceTest.java @@ -1004,7 +1004,7 @@ public class EntityServiceTest extends AbstractControllerTest { public void testFindEntityDataByQuery_filter_entity_name_ends_with() { List devices = new ArrayList<>(); - String suffixes = RandomStringUtils.randomAlphanumeric(5); + String suffixes = RandomStringUtils.secure().nextAlphanumeric(5); for (int i = 0; i < 10; i++) { Device device = new Device(); device.setTenantId(tenantId); @@ -1425,7 +1425,7 @@ public class EntityServiceTest extends AbstractControllerTest { Device device = new Device(); device.setTenantId(tenantId); device.setCustomerId(customerId); - device.setName("Device test " + RandomStringUtils.randomAlphabetic(5)); + device.setName("Device test " + RandomStringUtils.secure().nextAlphabetic(5)); device.setType("default"); return device; } @@ -1485,7 +1485,7 @@ public class EntityServiceTest extends AbstractControllerTest { device.setTenantId(tenantId); device.setName("Device " + i); device.setType("default"); - device.setLabel("label-" + RandomUtils.nextInt(100, 10000)); + device.setLabel("label-" + RandomUtils.secure().randomInt(100, 10000)); return device; }) .limit(count) diff --git a/application/src/test/java/org/thingsboard/server/service/housekeeper/HousekeeperServiceTest.java b/application/src/test/java/org/thingsboard/server/service/housekeeper/HousekeeperServiceTest.java index 0c12767b60..762f3946d4 100644 --- a/application/src/test/java/org/thingsboard/server/service/housekeeper/HousekeeperServiceTest.java +++ b/application/src/test/java/org/thingsboard/server/service/housekeeper/HousekeeperServiceTest.java @@ -25,7 +25,7 @@ import org.mockito.Mockito; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.TestPropertySource; import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; -import org.testcontainers.shaded.org.apache.commons.lang3.RandomStringUtils; +import org.apache.commons.lang3.RandomStringUtils; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.rule.engine.metadata.TbGetAttributesNode; import org.thingsboard.rule.engine.metadata.TbGetAttributesNodeConfiguration; @@ -570,7 +570,7 @@ public class HousekeeperServiceTest extends AbstractControllerTest { .tenantId(tenantId) .originator(entityId) .severity(AlarmSeverity.CRITICAL) - .type("test alarm for " + entityId + " " + RandomStringUtils.randomAlphabetic(10)) + .type("test alarm for " + entityId + " " + RandomStringUtils.secure().nextAlphabetic(10)) .build(), Alarm.class); assertThat(alarmService.findAlarmIdsByOriginatorId(tenantId, entityId, 0, null, 10)).isNotEmpty(); } diff --git a/application/src/test/java/org/thingsboard/server/service/notification/AbstractNotificationApiTest.java b/application/src/test/java/org/thingsboard/server/service/notification/AbstractNotificationApiTest.java index cf99669777..c7d5f0ea82 100644 --- a/application/src/test/java/org/thingsboard/server/service/notification/AbstractNotificationApiTest.java +++ b/application/src/test/java/org/thingsboard/server/service/notification/AbstractNotificationApiTest.java @@ -155,7 +155,7 @@ public abstract class AbstractNotificationApiTest extends AbstractControllerTest User user = new User(); user.setTenantId(tenantId); user.setAuthority(authority); - user.setEmail(RandomStringUtils.randomAlphabetic(20) + "@thingsboard.com"); + user.setEmail(RandomStringUtils.secure().nextAlphabetic(20) + "@thingsboard.com"); user = createUserAndLogin(user, "12345678"); NotificationApiWsClient wsClient = buildAndConnectWebSocketClient(); return Pair.of(user, wsClient); diff --git a/application/src/test/java/org/thingsboard/server/service/notification/NotificationApiWsClient.java b/application/src/test/java/org/thingsboard/server/service/notification/NotificationApiWsClient.java index b538972dd7..f6d94f5170 100644 --- a/application/src/test/java/org/thingsboard/server/service/notification/NotificationApiWsClient.java +++ b/application/src/test/java/org/thingsboard/server/service/notification/NotificationApiWsClient.java @@ -131,7 +131,7 @@ public class NotificationApiWsClient extends TbTestWebSocketClient { } private int newCmdId() { - return RandomUtils.nextInt(1, 1000); + return RandomUtils.secure().randomInt(1, 1000); } } diff --git a/application/src/test/java/org/thingsboard/server/service/notification/NotificationTargetApiTest.java b/application/src/test/java/org/thingsboard/server/service/notification/NotificationTargetApiTest.java index 2d865542a1..b68d30a4c6 100644 --- a/application/src/test/java/org/thingsboard/server/service/notification/NotificationTargetApiTest.java +++ b/application/src/test/java/org/thingsboard/server/service/notification/NotificationTargetApiTest.java @@ -187,7 +187,7 @@ public class NotificationTargetApiTest extends AbstractNotificationApiTest { NotificationTarget sysAdmins = createNotificationTarget(new SystemAdministratorsFilter()); NotificationTarget slack = new NotificationTarget(); - slack.setName(RandomStringUtils.randomNumeric(5)); + slack.setName(RandomStringUtils.secure().nextNumeric(5)); SlackNotificationTargetConfig slackConfig = new SlackNotificationTargetConfig(); SlackConversation slackConversation = new SlackConversation(); slackConversation.setType(SlackConversationType.DIRECT); diff --git a/application/src/test/java/org/thingsboard/server/service/queue/ruleengine/TbRuleEngineQueueConsumerManagerTest.java b/application/src/test/java/org/thingsboard/server/service/queue/ruleengine/TbRuleEngineQueueConsumerManagerTest.java index 228b987cf0..90816b6675 100644 --- a/application/src/test/java/org/thingsboard/server/service/queue/ruleengine/TbRuleEngineQueueConsumerManagerTest.java +++ b/application/src/test/java/org/thingsboard/server/service/queue/ruleengine/TbRuleEngineQueueConsumerManagerTest.java @@ -27,7 +27,7 @@ import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.junit.jupiter.MockitoSettings; import org.mockito.quality.Strictness; -import org.testcontainers.shaded.org.apache.commons.lang3.RandomUtils; +import org.apache.commons.lang3.RandomUtils; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.common.util.ThingsBoardExecutors; import org.thingsboard.common.util.ThingsBoardThreadFactory; @@ -542,18 +542,18 @@ public class TbRuleEngineQueueConsumerManagerTest { Queue oldConfig = consumerManager.getConfig(); Queue newConfig = JacksonUtil.clone(oldConfig); newConfig.setConsumerPerPartition(RandomUtils.nextBoolean()); - newConfig.setPollInterval(RandomUtils.nextInt(100, 501)); - newConfig.setPartitions(RandomUtils.nextInt(1, 10)); + newConfig.setPollInterval(RandomUtils.secure().randomInt(100, 501)); + newConfig.setPartitions(RandomUtils.secure().randomInt(1, 10)); newConfig.setPackProcessingTimeout(RandomUtils.nextLong(100, 5001)); - newConfig.getSubmitStrategy().setType(SubmitStrategyType.values()[RandomUtils.nextInt(0, SubmitStrategyType.values().length)]); - newConfig.getProcessingStrategy().setType(ProcessingStrategyType.values()[RandomUtils.nextInt(0, ProcessingStrategyType.values().length)]); + newConfig.getSubmitStrategy().setType(SubmitStrategyType.values()[RandomUtils.secure().randomInt(0, SubmitStrategyType.values().length)]); + newConfig.getProcessingStrategy().setType(ProcessingStrategyType.values()[RandomUtils.secure().randomInt(0, ProcessingStrategyType.values().length)]); log.info("Generated new config: consumerPerPartition={}, pollInterval={}, processingStrategy={}", newConfig.isConsumerPerPartition(), newConfig.getPollInterval(), newConfig.getProcessingStrategy().getType()); return newConfig; }; Supplier> partitionsUpdater = () -> { - int partitionsCount = RandomUtils.nextInt(0, 20); - int[] partitions = IntStream.generate(() -> RandomUtils.nextInt(0, 20)) + int partitionsCount = RandomUtils.secure().randomInt(0, 20); + int[] partitions = IntStream.generate(() -> RandomUtils.secure().randomInt(0, 20)) .distinct().limit(partitionsCount) .sorted().toArray(); log.info("Generated new partitions: {}", Arrays.toString(partitions)); diff --git a/application/src/test/java/org/thingsboard/server/service/sms/DefaultSmsServiceTest.java b/application/src/test/java/org/thingsboard/server/service/sms/DefaultSmsServiceTest.java index 8d27b07550..75a3423b98 100644 --- a/application/src/test/java/org/thingsboard/server/service/sms/DefaultSmsServiceTest.java +++ b/application/src/test/java/org/thingsboard/server/service/sms/DefaultSmsServiceTest.java @@ -24,7 +24,7 @@ import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.springframework.test.context.TestPropertySource; -import org.testcontainers.shaded.org.apache.commons.lang3.RandomStringUtils; +import org.apache.commons.lang3.RandomStringUtils; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.common.data.AdminSettings; import org.thingsboard.server.common.data.TenantProfile; @@ -84,13 +84,13 @@ public class DefaultSmsServiceTest extends AbstractControllerTest { for (int i = 0; i < 10; i++) { doReturn(1).when(defaultSmsService).sendSms(any(), any()); - defaultSmsService.sendSms(tenantId, null, new String[]{RandomStringUtils.randomNumeric(10)}, "Message"); + defaultSmsService.sendSms(tenantId, null, new String[]{RandomStringUtils.secure().nextNumeric(10)}, "Message"); } //wait 1 sec so that api usage state is updated TimeUnit.SECONDS.sleep(1); assertThrows(RuntimeException.class, () -> { - defaultSmsService.sendSms(tenantId, null, new String[]{RandomStringUtils.randomNumeric(10)}, "Message"); + defaultSmsService.sendSms(tenantId, null, new String[]{RandomStringUtils.secure().nextNumeric(10)}, "Message"); }, "SMS sending is disabled due to API limits!"); } @@ -103,7 +103,7 @@ public class DefaultSmsServiceTest extends AbstractControllerTest { TimeUnit.SECONDS.sleep(1); assertThrows(RuntimeException.class, () -> { - defaultSmsService.sendSms(tenantId, null, new String[]{RandomStringUtils.randomNumeric(10)}, "Message"); + defaultSmsService.sendSms(tenantId, null, new String[]{RandomStringUtils.secure().nextNumeric(10)}, "Message"); }, "SMS sending is disabled due to API limits!"); //enable sms messaging @@ -113,7 +113,7 @@ public class DefaultSmsServiceTest extends AbstractControllerTest { for (int i = 0; i < 10; i++) { doReturn(1).when(defaultSmsService).sendSms(any(), any()); - defaultSmsService.sendSms(tenantId, null, new String[]{RandomStringUtils.randomNumeric(10)}, "Message"); + defaultSmsService.sendSms(tenantId, null, new String[]{RandomStringUtils.secure().nextNumeric(10)}, "Message"); } } diff --git a/application/src/test/java/org/thingsboard/server/service/subscription/DefaultTbLocalSubscriptionServiceTest.java b/application/src/test/java/org/thingsboard/server/service/subscription/DefaultTbLocalSubscriptionServiceTest.java index 2eb7934792..aa17bf020a 100644 --- a/application/src/test/java/org/thingsboard/server/service/subscription/DefaultTbLocalSubscriptionServiceTest.java +++ b/application/src/test/java/org/thingsboard/server/service/subscription/DefaultTbLocalSubscriptionServiceTest.java @@ -126,13 +126,13 @@ public class DefaultTbLocalSubscriptionServiceTest { private TbSubscription createSubscription(TenantId tenantId, EntityId entityId) { Map keys = new HashMap<>(); for (int i = 0; i < 50; i++) { - keys.put(RandomStringUtils.randomAlphanumeric(5), 1L); + keys.put(RandomStringUtils.secure().nextAlphanumeric(5), 1L); } return TbAttributeSubscription.builder() .tenantId(tenantId) .entityId(entityId) .subscriptionId(1) - .sessionId(RandomStringUtils.randomAlphanumeric(5)) + .sessionId(RandomStringUtils.secure().nextAlphanumeric(5)) .keyStates(keys) .build(); } @@ -152,7 +152,7 @@ public class DefaultTbLocalSubscriptionServiceTest { .tenantId(tenantId) .entityId(deviceId) .subscriptionId(2) - .sessionId(RandomStringUtils.randomAlphanumeric(5)) + .sessionId(RandomStringUtils.secure().nextAlphanumeric(5)) .keyStates(keyStates) .allKeys(true) .latestValues(true) diff --git a/application/src/test/java/org/thingsboard/server/service/subscription/TbEntityDataSubCtxTest.java b/application/src/test/java/org/thingsboard/server/service/subscription/TbEntityDataSubCtxTest.java index 1d0e691c74..2c0594bd74 100644 --- a/application/src/test/java/org/thingsboard/server/service/subscription/TbEntityDataSubCtxTest.java +++ b/application/src/test/java/org/thingsboard/server/service/subscription/TbEntityDataSubCtxTest.java @@ -23,7 +23,7 @@ import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.test.util.ReflectionTestUtils; -import org.testcontainers.shaded.org.apache.commons.lang3.RandomUtils; +import org.apache.commons.lang3.RandomUtils; import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.kv.BasicTsKvEntry; @@ -55,10 +55,10 @@ public class TbEntityDataSubCtxTest { private final DeviceId deviceId = new DeviceId(UUID.randomUUID()); - private final Integer cmdId = RandomUtils.nextInt(); - private final Integer subscriptionId = RandomUtils.nextInt(); - private final String serviceId = RandomStringUtils.randomAlphanumeric(10); - private final String sessionId = RandomStringUtils.randomAlphanumeric(10); + private final Integer cmdId = RandomUtils.secure().randomInt(); + private final Integer subscriptionId = RandomUtils.secure().randomInt(); + private final String serviceId = RandomStringUtils.secure().nextAlphanumeric(10); + private final String sessionId = RandomStringUtils.secure().nextAlphanumeric(10); private final int maxEntitiesPerDataSubscription = 100; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/EntityType.java b/common/data/src/main/java/org/thingsboard/server/common/data/EntityType.java index deb0f8c66e..3ad1e3f25b 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/EntityType.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/EntityType.java @@ -23,6 +23,8 @@ import java.util.Arrays; import java.util.EnumSet; import java.util.List; +import static org.thingsboard.server.common.data.StringUtils.removeStart; + public enum EntityType { TENANT(1), diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/util/TemplateUtils.java b/common/data/src/main/java/org/thingsboard/server/common/data/util/TemplateUtils.java index beaec13748..d740a065ce 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/util/TemplateUtils.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/util/TemplateUtils.java @@ -23,7 +23,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import static com.google.common.base.Strings.nullToEmpty; -import static org.apache.commons.lang3.StringUtils.removeStart; +import static org.thingsboard.server.common.data.StringUtils.removeStart; public class TemplateUtils { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/util/TypeCastUtil.java b/common/data/src/main/java/org/thingsboard/server/common/data/util/TypeCastUtil.java index 9fec33b482..3c9f143d39 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/util/TypeCastUtil.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/util/TypeCastUtil.java @@ -69,7 +69,7 @@ public class TypeCastUtil { } private static boolean isNumber(String value) { - return NumberUtils.isNumber(value.replace(',', '.')); + return NumberUtils.isCreatable(value.replace(',', '.')); } private static boolean isSimpleDouble(String valueAsString) { diff --git a/common/version-control/src/main/java/org/thingsboard/server/service/sync/vc/GitRepository.java b/common/version-control/src/main/java/org/thingsboard/server/service/sync/vc/GitRepository.java index 3602dd55ca..15dd615111 100644 --- a/common/version-control/src/main/java/org/thingsboard/server/service/sync/vc/GitRepository.java +++ b/common/version-control/src/main/java/org/thingsboard/server/service/sync/vc/GitRepository.java @@ -99,6 +99,7 @@ import static org.eclipse.jgit.transport.RemoteRefUpdate.Status.REJECTED_NODELET import static org.eclipse.jgit.transport.RemoteRefUpdate.Status.REJECTED_NONFASTFORWARD; import static org.eclipse.jgit.transport.RemoteRefUpdate.Status.REJECTED_OTHER_REASON; import static org.eclipse.jgit.transport.RemoteRefUpdate.Status.REJECTED_REMOTE_CHANGED; +import static org.thingsboard.server.common.data.StringUtils.removeStart; @Slf4j public class GitRepository { @@ -448,7 +449,7 @@ public class GitRepository { private BranchInfo toBranchInfo(Ref ref) { String name = org.eclipse.jgit.lib.Repository.shortenRefName(ref.getName()); - String branchName = StringUtils.removeStart(name, "origin/"); + String branchName = removeStart(name, "origin/"); boolean isDefault = this.headId != null && this.headId.equals(ref.getObjectId()); return new BranchInfo(branchName, isDefault); } @@ -465,7 +466,7 @@ public class GitRepository { private ObjectId resolve(String rev) throws IOException { if (settings.isLocalOnly()) { - rev = StringUtils.removeStart(rev, "origin/"); + rev = removeStart(rev, "origin/"); } ObjectId result = git.getRepository().resolve(rev); if (result == null) { diff --git a/dao/src/main/java/org/thingsboard/server/dao/resource/BaseImageService.java b/dao/src/main/java/org/thingsboard/server/dao/resource/BaseImageService.java index 11bbe797cf..18023f653c 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/resource/BaseImageService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/resource/BaseImageService.java @@ -173,7 +173,7 @@ public class BaseImageService extends BaseResourceService implements ImageServic } private String generatePublicResourceKey() { - return RandomStringUtils.randomAlphanumeric(32); + return RandomStringUtils.secure().nextAlphanumeric(32); } @Override diff --git a/dao/src/main/java/org/thingsboard/server/dao/resource/BaseResourceService.java b/dao/src/main/java/org/thingsboard/server/dao/resource/BaseResourceService.java index 432329a621..d96a7516c2 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/resource/BaseResourceService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/resource/BaseResourceService.java @@ -74,6 +74,7 @@ import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Optional; import java.util.Set; import java.util.UUID; @@ -82,6 +83,7 @@ import java.util.function.UnaryOperator; import static com.google.common.util.concurrent.MoreExecutors.directExecutor; import static org.thingsboard.server.common.data.StringUtils.isNotEmpty; +import static org.thingsboard.server.common.data.StringUtils.removeStart; import static org.thingsboard.server.dao.device.DeviceServiceImpl.INCORRECT_TENANT_ID; import static org.thingsboard.server.dao.service.Validator.validateId; @@ -589,7 +591,7 @@ public class BaseResourceService extends AbstractCachedEntityService { Asset asset = new Asset(); asset.setTenantId(anotherTenantId); - asset.setName(RandomStringUtils.randomAlphabetic(10)); + asset.setName(RandomStringUtils.secure().nextAlphabetic(10)); asset.setType("default"); assetService.saveAsset(asset); }); diff --git a/dao/src/test/java/org/thingsboard/server/dao/sql/alarm/JpaAlarmCommentDaoTest.java b/dao/src/test/java/org/thingsboard/server/dao/sql/alarm/JpaAlarmCommentDaoTest.java index b207672004..72503c245b 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/sql/alarm/JpaAlarmCommentDaoTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/sql/alarm/JpaAlarmCommentDaoTest.java @@ -18,7 +18,7 @@ package org.thingsboard.server.dao.sql.alarm; import lombok.extern.slf4j.Slf4j; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.testcontainers.shaded.org.apache.commons.lang3.RandomStringUtils; +import org.apache.commons.lang3.RandomStringUtils; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.common.data.alarm.Alarm; import org.thingsboard.server.common.data.alarm.AlarmComment; @@ -84,7 +84,7 @@ public class JpaAlarmCommentDaoTest extends AbstractJpaDaoTest { alarmComment.setAlarmId(new AlarmId(alarmId)); alarmComment.setUserId(new UserId(userId)); alarmComment.setType(type); - alarmComment.setComment(JacksonUtil.newObjectNode().put("text", RandomStringUtils.randomAlphanumeric(10))); + alarmComment.setComment(JacksonUtil.newObjectNode().put("text", RandomStringUtils.secure().nextAlphanumeric(10))); alarmCommentDao.save(TenantId.fromUUID(UUID.randomUUID()), alarmComment); } } diff --git a/dao/src/test/java/org/thingsboard/server/dao/sql/user/JpaUserSettingsDaoTest.java b/dao/src/test/java/org/thingsboard/server/dao/sql/user/JpaUserSettingsDaoTest.java index 8c259a4965..bbe8940347 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/sql/user/JpaUserSettingsDaoTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/sql/user/JpaUserSettingsDaoTest.java @@ -21,7 +21,7 @@ import org.junit.After; import org.junit.Before; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.testcontainers.shaded.org.apache.commons.lang3.RandomStringUtils; +import org.apache.commons.lang3.RandomStringUtils; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.id.CustomerId; @@ -112,7 +112,7 @@ public class JpaUserSettingsDaoTest extends AbstractJpaDaoTest { private UserSettings createUserSettings(UserId userId) { UserSettings userSettings = new UserSettings(); userSettings.setType(UserSettingsType.GENERAL); - userSettings.setSettings(JacksonUtil.newObjectNode().put("text", RandomStringUtils.randomAlphanumeric(10))); + userSettings.setSettings(JacksonUtil.newObjectNode().put("text", RandomStringUtils.secure().nextAlphanumeric(10))); userSettings.setUserId(userId); return userSettingsDao.save(SYSTEM_TENANT_ID, userSettings); } diff --git a/dao/src/test/java/org/thingsboard/server/dao/sqlts/SqlTimeseriesLatestDaoTest.java b/dao/src/test/java/org/thingsboard/server/dao/sqlts/SqlTimeseriesLatestDaoTest.java index 02abf1e5fd..c67ef1bfb0 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/sqlts/SqlTimeseriesLatestDaoTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/sqlts/SqlTimeseriesLatestDaoTest.java @@ -171,7 +171,7 @@ public class SqlTimeseriesLatestDaoTest extends AbstractServiceTest { } private TsKvEntry createEntry(String key, long ts) { - return new BasicTsKvEntry(ts, new StringDataEntry(key, RandomStringUtils.random(10))); + return new BasicTsKvEntry(ts, new StringDataEntry(key, RandomStringUtils.secure().next(10))); } private void equalsIgnoreVersion(TsKvEntry expected, TsKvEntry actual) { diff --git a/monitoring/src/main/java/org/thingsboard/monitoring/client/WsClient.java b/monitoring/src/main/java/org/thingsboard/monitoring/client/WsClient.java index 7e2f669f6b..6a2c7f6d56 100644 --- a/monitoring/src/main/java/org/thingsboard/monitoring/client/WsClient.java +++ b/monitoring/src/main/java/org/thingsboard/monitoring/client/WsClient.java @@ -124,7 +124,7 @@ public class WsClient extends WebSocketClient implements AutoCloseable { public WsClient subscribeForTelemetry(List devices, List keys) { EntityDataCmd cmd = new EntityDataCmd(); - cmd.setCmdId(RandomUtils.nextInt(0, 1000)); + cmd.setCmdId(RandomUtils.secure().randomInt(0, 1000)); EntityListFilter devicesFilter = new EntityListFilter(); devicesFilter.setEntityType(EntityType.DEVICE); diff --git a/monitoring/src/main/java/org/thingsboard/monitoring/service/MonitoringEntityService.java b/monitoring/src/main/java/org/thingsboard/monitoring/service/MonitoringEntityService.java index d2c275945a..3469606943 100644 --- a/monitoring/src/main/java/org/thingsboard/monitoring/service/MonitoringEntityService.java +++ b/monitoring/src/main/java/org/thingsboard/monitoring/service/MonitoringEntityService.java @@ -180,7 +180,7 @@ public class MonitoringEntityService { device.setName(deviceName); DeviceCredentials credentials = new DeviceCredentials(); - credentials.setCredentialsId(RandomStringUtils.randomAlphabetic(20)); + credentials.setCredentialsId(RandomStringUtils.secure().nextAlphabetic(20)); DeviceData deviceData = new DeviceData(); deviceData.setConfiguration(new DefaultDeviceConfiguration()); diff --git a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/connectivity/MqttGatewayClientTest.java b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/connectivity/MqttGatewayClientTest.java index bb464ee52e..c9fa76cc9a 100644 --- a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/connectivity/MqttGatewayClientTest.java +++ b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/connectivity/MqttGatewayClientTest.java @@ -29,7 +29,7 @@ import io.netty.handler.codec.mqtt.MqttQoS; import lombok.Data; import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; -import org.testcontainers.shaded.org.apache.commons.lang3.RandomStringUtils; +import org.apache.commons.lang3.RandomStringUtils; import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; @@ -400,7 +400,7 @@ public class MqttGatewayClientTest extends AbstractContainerTest { TimeUnit.SECONDS.sleep(30); } - String deviceName = "mqtt_device" + RandomStringUtils.randomAlphabetic(5); + String deviceName = "mqtt_device" + RandomStringUtils.secure().nextAlphabetic(5); mqttClient.publish("v1/gateway/connect", Unpooled.wrappedBuffer(createGatewayConnectPayload(deviceName).toString().getBytes()), MqttQoS.AT_LEAST_ONCE).get(); if (timeoutMultiplier > 1) { diff --git a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/connectivity/lwm2m/AbstractLwm2mClientTest.java b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/connectivity/lwm2m/AbstractLwm2mClientTest.java index c5673ae667..ecd062a15e 100644 --- a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/connectivity/lwm2m/AbstractLwm2mClientTest.java +++ b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/connectivity/lwm2m/AbstractLwm2mClientTest.java @@ -25,7 +25,7 @@ import org.apache.commons.io.IOUtils; import org.eclipse.leshan.client.object.Security; import org.eclipse.leshan.core.ResponseCode; import org.eclipse.leshan.core.util.Hex; -import org.testcontainers.shaded.org.apache.commons.lang3.RandomStringUtils; +import org.apache.commons.lang3.RandomStringUtils; import org.testng.Assert; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.common.util.ThingsBoardThreadFactory; @@ -111,7 +111,7 @@ public class AbstractLwm2mClientTest extends AbstractContainerTest { public final Set expectedStatusesRegistrationLwm2mSuccess = new HashSet<>(Arrays.asList(ON_INIT, ON_REGISTRATION_STARTED, ON_REGISTRATION_SUCCESS)); public void createLwm2mDevicesForConnectNoSec(String name, Lwm2mDevicesForTest devicesForTest) throws Exception { - String clientEndpoint = name + "-" + RandomStringUtils.randomAlphanumeric(7); + String clientEndpoint = name + "-" + RandomStringUtils.secure().nextAlphanumeric(7); LwM2MDeviceCredentials deviceCredentials = getDeviceCredentialsNoSec(createNoSecClientCredentials(clientEndpoint)); Device lwM2MDeviceTest = createDeviceWithCredentials(deviceCredentials, clientEndpoint, devicesForTest.getLwm2mDeviceProfile().getId()); LwM2MTestClient lwM2MTestClient = createNewClient(SECURITY_NO_SEC, clientEndpoint, executor); @@ -120,7 +120,7 @@ public class AbstractLwm2mClientTest extends AbstractContainerTest { } public void createLwm2mDevicesForConnectPsk(Lwm2mDevicesForTest devicesForTest) throws Exception { - String clientEndpoint = CLIENT_ENDPOINT_PSK + "-" + RandomStringUtils.randomAlphanumeric(7); + String clientEndpoint = CLIENT_ENDPOINT_PSK + "-" + RandomStringUtils.secure().nextAlphanumeric(7); String identity = CLIENT_PSK_IDENTITY; String keyPsk = CLIENT_PSK_KEY; PSKClientCredential clientCredentials = new PSKClientCredential(); diff --git a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/connectivity/lwm2m/rpc/Lwm2mObserveCompositeTest.java b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/connectivity/lwm2m/rpc/Lwm2mObserveCompositeTest.java index 4ffc6f4c4f..2d77e43cd2 100644 --- a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/connectivity/lwm2m/rpc/Lwm2mObserveCompositeTest.java +++ b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/connectivity/lwm2m/rpc/Lwm2mObserveCompositeTest.java @@ -15,7 +15,7 @@ */ package org.thingsboard.server.msa.connectivity.lwm2m.rpc; -import org.testcontainers.shaded.org.apache.commons.lang3.RandomStringUtils; +import org.apache.commons.lang3.RandomStringUtils; import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; @@ -36,7 +36,7 @@ public class Lwm2mObserveCompositeTest extends AbstractLwm2mClientTest { @BeforeMethod public void setUp() throws Exception { testRestClient.login(TENANT_EMAIL, TENANT_PASSWORD); - this.lwm2mDevicesForTest = new Lwm2mDevicesForTest(initTest(name + "-profile" + RandomStringUtils.randomAlphanumeric(7))); + this.lwm2mDevicesForTest = new Lwm2mDevicesForTest(initTest(name + "-profile" + RandomStringUtils.secure().nextAlphanumeric(7))); } @AfterMethod @@ -46,7 +46,7 @@ public class Lwm2mObserveCompositeTest extends AbstractLwm2mClientTest { @Test public void testObserveResource_Update_AfterUpdateRegistration() throws Exception { - createLwm2mDevicesForConnectNoSec( name + "-" + RandomStringUtils.randomAlphanumeric(7), this.lwm2mDevicesForTest ); + createLwm2mDevicesForConnectNoSec( name + "-" + RandomStringUtils.secure().nextAlphanumeric(7), this.lwm2mDevicesForTest ); observeCompositeResource_Update_AfterUpdateRegistration_test(this.lwm2mDevicesForTest.getLwM2MTestClient(), this.lwm2mDevicesForTest.getLwM2MDeviceTest().getId()); } } diff --git a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/connectivity/lwm2m/rpc/Lwm2mObserveTest.java b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/connectivity/lwm2m/rpc/Lwm2mObserveTest.java index f47c328077..06b033391d 100644 --- a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/connectivity/lwm2m/rpc/Lwm2mObserveTest.java +++ b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/connectivity/lwm2m/rpc/Lwm2mObserveTest.java @@ -15,7 +15,7 @@ */ package org.thingsboard.server.msa.connectivity.lwm2m.rpc; -import org.testcontainers.shaded.org.apache.commons.lang3.RandomStringUtils; +import org.apache.commons.lang3.RandomStringUtils; import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; @@ -36,7 +36,7 @@ public class Lwm2mObserveTest extends AbstractLwm2mClientTest { @BeforeMethod public void setUp() throws Exception { testRestClient.login(TENANT_EMAIL, TENANT_PASSWORD); - this.lwm2mDevicesForTest = new Lwm2mDevicesForTest(initTest(name + "-profile" + RandomStringUtils.randomAlphanumeric(7))); + this.lwm2mDevicesForTest = new Lwm2mDevicesForTest(initTest(name + "-profile" + RandomStringUtils.secure().nextAlphanumeric(7))); } @AfterMethod @@ -46,7 +46,7 @@ public class Lwm2mObserveTest extends AbstractLwm2mClientTest { @Test public void testObserveResource_Update_AfterUpdateRegistration() throws Exception { - createLwm2mDevicesForConnectNoSec( name + "-" + RandomStringUtils.randomAlphanumeric(7), this.lwm2mDevicesForTest ); + createLwm2mDevicesForConnectNoSec( name + "-" + RandomStringUtils.secure().nextAlphanumeric(7), this.lwm2mDevicesForTest ); observeResource_Update_AfterUpdateRegistration_test(this.lwm2mDevicesForTest.getLwM2MTestClient(), this.lwm2mDevicesForTest.getLwM2MDeviceTest().getId()); } } diff --git a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/connectivity/lwm2m/security/Lwm2mClientNoSecTest.java b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/connectivity/lwm2m/security/Lwm2mClientNoSecTest.java index 2413094946..e579127a9c 100644 --- a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/connectivity/lwm2m/security/Lwm2mClientNoSecTest.java +++ b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/connectivity/lwm2m/security/Lwm2mClientNoSecTest.java @@ -15,7 +15,7 @@ */ package org.thingsboard.server.msa.connectivity.lwm2m.security; -import org.testcontainers.shaded.org.apache.commons.lang3.RandomStringUtils; +import org.apache.commons.lang3.RandomStringUtils; import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; @@ -34,7 +34,7 @@ public class Lwm2mClientNoSecTest extends AbstractLwm2mClientTest { @BeforeMethod public void setUp() throws Exception { testRestClient.login(TENANT_EMAIL, TENANT_PASSWORD); - this.lwm2mDevicesForTest = new Lwm2mDevicesForTest(initTest("lwm2m-NoSec-profile" + "-" + RandomStringUtils.randomAlphanumeric(7))); + this.lwm2mDevicesForTest = new Lwm2mDevicesForTest(initTest("lwm2m-NoSec-profile" + "-" + RandomStringUtils.secure().nextAlphanumeric(7))); } @AfterMethod diff --git a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/connectivity/lwm2m/security/Lwm2mClientPskTest.java b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/connectivity/lwm2m/security/Lwm2mClientPskTest.java index 268787794b..97712d96c0 100644 --- a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/connectivity/lwm2m/security/Lwm2mClientPskTest.java +++ b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/connectivity/lwm2m/security/Lwm2mClientPskTest.java @@ -15,7 +15,7 @@ */ package org.thingsboard.server.msa.connectivity.lwm2m.security; -import org.testcontainers.shaded.org.apache.commons.lang3.RandomStringUtils; +import org.apache.commons.lang3.RandomStringUtils; import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; @@ -33,7 +33,7 @@ public class Lwm2mClientPskTest extends AbstractLwm2mClientTest { @BeforeMethod public void setUp() throws Exception { testRestClient.login(TENANT_EMAIL, TENANT_PASSWORD); - this.lwm2mDevicesForTest = new Lwm2mDevicesForTest(initTest("lwm2m-Psk-profile" + "-" + RandomStringUtils.randomAlphanumeric(7))); + this.lwm2mDevicesForTest = new Lwm2mDevicesForTest(initTest("lwm2m-Psk-profile" + "-" + RandomStringUtils.secure().nextAlphanumeric(7))); } @AfterMethod diff --git a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/edqs/EdqsEntityDataQueryTest.java b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/edqs/EdqsEntityDataQueryTest.java index 2c266bb416..5bfd866056 100644 --- a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/edqs/EdqsEntityDataQueryTest.java +++ b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/edqs/EdqsEntityDataQueryTest.java @@ -16,7 +16,7 @@ package org.thingsboard.server.msa.edqs; import com.fasterxml.jackson.databind.node.ObjectNode; -import org.testcontainers.shaded.org.apache.commons.lang3.RandomStringUtils; +import org.apache.commons.lang3.RandomStringUtils; import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; import org.testng.annotations.BeforeMethod; @@ -68,7 +68,7 @@ public class EdqsEntityDataQueryTest extends AbstractContainerTest { private UserId customer2UserId; private final List tenantDevices = new ArrayList<>(); private final List tenant2Devices = new ArrayList<>(); - private final String deviceProfile = "LoRa-" + RandomStringUtils.randomAlphabetic(10); + private final String deviceProfile = "LoRa-" + RandomStringUtils.secure().nextAlphabetic(10); @BeforeClass public void beforeClass() throws Exception { @@ -188,7 +188,7 @@ public class EdqsEntityDataQueryTest extends AbstractContainerTest { device.setLabel("testLabel" + (int) (Math.random() * 1000)); //TO make sure devices have different created time Thread.sleep(1); - String token = RandomStringUtils.randomAlphabetic(10); + String token = RandomStringUtils.secure().nextAlphabetic(10); Device saved = testRestClient.postDevice(token, device); tenantDevices.add(saved); diff --git a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/prototypes/DevicePrototypes.java b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/prototypes/DevicePrototypes.java index 3ba78b0171..c0f6af9443 100644 --- a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/prototypes/DevicePrototypes.java +++ b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/prototypes/DevicePrototypes.java @@ -16,14 +16,14 @@ package org.thingsboard.server.msa.prototypes; import com.fasterxml.jackson.databind.JsonNode; -import org.testcontainers.shaded.org.apache.commons.lang3.RandomStringUtils; +import org.apache.commons.lang3.RandomStringUtils; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.common.data.Device; public class DevicePrototypes { public static Device defaultDevicePrototype(String name){ Device device = new Device(); - device.setName(name + RandomStringUtils.randomAlphanumeric(7)); + device.setName(name + RandomStringUtils.secure().nextAlphanumeric(7)); device.setType("DEFAULT"); return device; } @@ -32,7 +32,7 @@ public class DevicePrototypes { String isGateway = "{\"gateway\":true}"; JsonNode additionalInfo = JacksonUtil.toJsonNode(isGateway); Device gatewayDeviceTemplate = new Device(); - gatewayDeviceTemplate.setName("mqtt_gateway_" + RandomStringUtils.randomAlphanumeric(5)); + gatewayDeviceTemplate.setName("mqtt_gateway_" + RandomStringUtils.secure().nextAlphanumeric(5)); gatewayDeviceTemplate.setType("gateway"); gatewayDeviceTemplate.setAdditionalInfo(additionalInfo); return gatewayDeviceTemplate; diff --git a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/pages/CreateWidgetPopupHelper.java b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/pages/CreateWidgetPopupHelper.java index 9741ae9da6..66d7788073 100644 --- a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/pages/CreateWidgetPopupHelper.java +++ b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/pages/CreateWidgetPopupHelper.java @@ -17,7 +17,7 @@ package org.thingsboard.server.msa.ui.pages; import org.openqa.selenium.Keys; import org.openqa.selenium.WebDriver; -import org.testcontainers.shaded.org.apache.commons.lang3.RandomStringUtils; +import org.apache.commons.lang3.RandomStringUtils; public class CreateWidgetPopupHelper extends CreateWidgetPopupElements { public CreateWidgetPopupHelper(WebDriver driver) { @@ -25,7 +25,7 @@ public class CreateWidgetPopupHelper extends CreateWidgetPopupElements { } public void goToCreateEntityAliasPopup(String aliasName) { - entityAlias().sendKeys(aliasName + RandomStringUtils.randomAlphanumeric(7)); + entityAlias().sendKeys(aliasName + RandomStringUtils.secure().nextAlphanumeric(7)); createNewAliasBtn().click(); } diff --git a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/utils/EntityPrototypes.java b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/utils/EntityPrototypes.java index d6e5f12c1b..d80ea5551a 100644 --- a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/utils/EntityPrototypes.java +++ b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/utils/EntityPrototypes.java @@ -15,7 +15,7 @@ */ package org.thingsboard.server.msa.ui.utils; -import org.testcontainers.shaded.org.apache.commons.lang3.RandomStringUtils; +import org.apache.commons.lang3.RandomStringUtils; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.common.data.Customer; import org.thingsboard.server.common.data.Dashboard; @@ -212,14 +212,14 @@ public class EntityPrototypes { public static Device defaultDevicePrototype(String name) { Device device = new Device(); - device.setName(name + RandomStringUtils.randomAlphanumeric(7)); + device.setName(name + RandomStringUtils.secure().nextAlphanumeric(7)); device.setType("DEFAULT"); return device; } public static Device defaultDevicePrototype(String name, CustomerId id) { Device device = new Device(); - device.setName(name + RandomStringUtils.randomAlphanumeric(7)); + device.setName(name + RandomStringUtils.secure().nextAlphanumeric(7)); device.setCustomerId(id); device.setType("DEFAULT"); return device; @@ -227,7 +227,7 @@ public class EntityPrototypes { public static Device defaultDevicePrototype(String name, String description) { Device device = new Device(); - device.setName(name + RandomStringUtils.randomAlphanumeric(7)); + device.setName(name + RandomStringUtils.secure().nextAlphanumeric(7)); device.setType("DEFAULT"); device.setAdditionalInfo(JacksonUtil.newObjectNode().put("description", description)); return device; @@ -235,7 +235,7 @@ public class EntityPrototypes { public static Device defaultDevicePrototype(String name, String description, String label) { Device device = new Device(); - device.setName(name + RandomStringUtils.randomAlphanumeric(7)); + device.setName(name + RandomStringUtils.secure().nextAlphanumeric(7)); device.setType("DEFAULT"); device.setAdditionalInfo(JacksonUtil.newObjectNode().put("description", description)); device.setLabel(label); @@ -244,7 +244,7 @@ public class EntityPrototypes { public static Device defaultDevicePrototype(String name, boolean gateway) { Device device = new Device(); - device.setName(name + RandomStringUtils.randomAlphanumeric(7)); + device.setName(name + RandomStringUtils.secure().nextAlphanumeric(7)); device.setType("DEFAULT"); device.setAdditionalInfo(JacksonUtil.newObjectNode().put("gateway", gateway)); return device; @@ -252,7 +252,7 @@ public class EntityPrototypes { public static Device defaultDevicePrototype(String name, boolean gateway, boolean overwriteActivityTime) { Device device = new Device(); - device.setName(name + RandomStringUtils.randomAlphanumeric(7)); + device.setName(name + RandomStringUtils.secure().nextAlphanumeric(7)); device.setType("DEFAULT"); device.setAdditionalInfo(JacksonUtil.newObjectNode() .put("gateway", gateway) @@ -262,7 +262,7 @@ public class EntityPrototypes { public static Device defaultDevicePrototype(String name, DeviceProfileId deviceProfileId) { Device device = new Device(); - device.setName(name + RandomStringUtils.randomAlphanumeric(7)); + device.setName(name + RandomStringUtils.secure().nextAlphanumeric(7)); device.setType("DEFAULT"); device.setDeviceProfileId(deviceProfileId); return device; @@ -270,7 +270,7 @@ public class EntityPrototypes { public static Asset defaultAssetPrototype(String name, CustomerId id) { Asset asset = new Asset(); - asset.setName(name + RandomStringUtils.randomAlphanumeric(7)); + asset.setName(name + RandomStringUtils.secure().nextAlphanumeric(7)); asset.setCustomerId(id); asset.setType("DEFAULT"); return asset; @@ -278,15 +278,15 @@ public class EntityPrototypes { public static EntityView defaultEntityViewPrototype(String name, String type, String entityType) { EntityView entityView = new EntityView(); - entityView.setName(name + RandomStringUtils.randomAlphanumeric(7)); - entityView.setType(type + RandomStringUtils.randomAlphanumeric(7)); + entityView.setName(name + RandomStringUtils.secure().nextAlphanumeric(7)); + entityView.setType(type + RandomStringUtils.secure().nextAlphanumeric(7)); entityView.setAdditionalInfo(JacksonUtil.newObjectNode().put("entityType", entityType)); return entityView; } public static Dashboard defaultDashboardPrototype(String title) { Dashboard dashboard = new Dashboard(); - dashboard.setTitle(title + RandomStringUtils.randomAlphanumeric(7)); + dashboard.setTitle(title + RandomStringUtils.secure().nextAlphanumeric(7)); return dashboard; } } diff --git a/tools/src/main/java/org/thingsboard/client/tools/migrator/PgCaMigrator.java b/tools/src/main/java/org/thingsboard/client/tools/migrator/PgCaMigrator.java index b88012c00e..2ef202dc9f 100644 --- a/tools/src/main/java/org/thingsboard/client/tools/migrator/PgCaMigrator.java +++ b/tools/src/main/java/org/thingsboard/client/tools/migrator/PgCaMigrator.java @@ -249,7 +249,7 @@ public class PgCaMigrator { private List castToNumericIfPossible(List values) { try { - if (values.get(6) != null && NumberUtils.isNumber(values.get(6).toString())) { + if (values.get(6) != null && NumberUtils.isCreatable(values.get(6).toString())) { Double casted = NumberUtils.createDouble(values.get(6).toString()); List numeric = Lists.newArrayList(); numeric.addAll(values); From abdae16da2214c0fc19a4bad49199b8095c803f5 Mon Sep 17 00:00:00 2001 From: Oleksandra Matviienko Date: Fri, 24 Apr 2026 23:18:47 +0200 Subject: [PATCH 34/91] Technical cleanup of TenantId construction in tests and production code --- .../discovery/HashPartitionServiceTest.java | 6 +-- .../cf/DefaultCalculatedFieldCacheTest.java | 52 +++++++++---------- .../provision/DeviceProvisionServiceTest.java | 2 +- .../DefaultTbAssetProfileCacheTest.java | 14 ++--- .../DefaultTbDeviceProfileCacheTest.java | 14 ++--- .../queue/DefaultTbClusterServiceTest.java | 4 +- .../TbEntityLocalSubsInfoTest.java | 2 +- .../ws/DefaultWebSocketServiceTest.java | 2 +- .../session/GatewaySessionHandlerTest.java | 2 +- .../dao/service/TbCacheSerializationTest.java | 2 +- .../attributes/BaseAttributesServiceTest.java | 16 +++--- .../service/event/BaseEventServiceTest.java | 2 +- .../dao/sql/event/JpaBaseEventDaoTest.java | 2 +- .../query/DefaultQueryLogComponentTest.java | 2 +- .../dao/sql/tenant/JpaTenantDaoTest.java | 2 +- .../sql/widget/JpaWidgetsBundleDaoTest.java | 4 +- .../action/TbAssignToCustomerNodeTest.java | 2 +- .../action/TbCreateRelationNodeTest.java | 2 +- .../action/TbDeleteRelationNodeTest.java | 2 +- .../TbUnassignFromCustomerNodeTest.java | 2 +- .../filter/TbAssetTypeSwitchNodeTest.java | 2 +- .../filter/TbCheckAlarmStatusNodeTest.java | 2 +- .../filter/TbCheckRelationNodeTest.java | 2 +- .../filter/TbDeviceTypeSwitchNodeTest.java | 2 +- .../engine/flow/TbRuleChainInputNodeTest.java | 2 +- .../TbGetCustomerDetailsNodeTest.java | 2 +- .../metadata/TbGetDeviceAttrNodeTest.java | 2 +- .../TbGetOriginatorFieldsNodeTest.java | 2 +- .../TbGetRelatedAttributeNodeTest.java | 4 +- .../TbGetTenantAttributeNodeTest.java | 2 +- .../metadata/TbGetTenantDetailsNodeTest.java | 2 +- .../util/EntitiesFieldsAsyncLoaderTest.java | 4 +- ...ntitiesRelatedDeviceIdAsyncLoaderTest.java | 2 +- ...ntitiesRelatedEntityIdAsyncLoaderTest.java | 2 +- 34 files changed, 84 insertions(+), 84 deletions(-) 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 b1d59c031a..727a9c1aa5 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 @@ -149,7 +149,7 @@ public class HashPartitionServiceTest { Random random = new Random(); long ts = new SimpleDateFormat("dd-MM-yyyy").parse("06-12-2016").getTime() - TimeUnit.DAYS.toMillis(tenantCount); for (int tenantIndex = 0; tenantIndex < tenantCount; tenantIndex++) { - TenantId tenantId = new TenantId(Uuids.startOf(ts)); + TenantId tenantId = TenantId.fromUUID(Uuids.startOf(ts)); ts += TimeUnit.DAYS.toMillis(1) + random.nextInt(1000); for (int queueIndex = 0; queueIndex < queueCount; queueIndex++) { QueueKey queueKey = new QueueKey(ServiceType.TB_RULE_ENGINE, "queue" + queueIndex, tenantId); @@ -190,7 +190,7 @@ public class HashPartitionServiceTest { Map tenants = new HashMap<>(); for (TenantProfileId tenantProfileId : isolatedTenantProfiles) { for (int i = 0; i < tenantsCountPerProfile; i++) { - tenants.put(new TenantId(UUID.randomUUID()), tenantProfileId); + tenants.put(TenantId.fromUUID(UUID.randomUUID()), tenantProfileId); } } @@ -299,7 +299,7 @@ public class HashPartitionServiceTest { Queue systemQueue = createQueue(TenantId.SYS_TENANT_ID, 10); queues.add(systemQueue); - TenantId tenantId = new TenantId(UUID.randomUUID()); + TenantId tenantId = TenantId.fromUUID(UUID.randomUUID()); mockRoutingInfo(tenantId, tenantProfileId, false); // not isolated yet mockQueues(queues); diff --git a/application/src/test/java/org/thingsboard/server/service/cf/DefaultCalculatedFieldCacheTest.java b/application/src/test/java/org/thingsboard/server/service/cf/DefaultCalculatedFieldCacheTest.java index 3ee229e7a0..853c7f6127 100644 --- a/application/src/test/java/org/thingsboard/server/service/cf/DefaultCalculatedFieldCacheTest.java +++ b/application/src/test/java/org/thingsboard/server/service/cf/DefaultCalculatedFieldCacheTest.java @@ -92,8 +92,8 @@ public class DefaultCalculatedFieldCacheTest { @Test public void onComponentLifecycleEvent_tenantDeleted_evictsAllTenantCfsFromAllMaps() { - TenantId tenant1 = new TenantId(UUID.randomUUID()); - TenantId tenant2 = new TenantId(UUID.randomUUID()); + TenantId tenant1 = TenantId.fromUUID(UUID.randomUUID()); + TenantId tenant2 = TenantId.fromUUID(UUID.randomUUID()); DeviceId device1 = new DeviceId(UUID.randomUUID()); DeviceId device2 = new DeviceId(UUID.randomUUID()); @@ -110,7 +110,7 @@ public class DefaultCalculatedFieldCacheTest { @Test public void onComponentLifecycleEvent_tenantDeleted_evictsOwnerEntities() { - TenantId tenant = new TenantId(UUID.randomUUID()); + TenantId tenant = TenantId.fromUUID(UUID.randomUUID()); DeviceId device = new DeviceId(UUID.randomUUID()); stubDeviceOwner(tenant, device, tenant); @@ -125,7 +125,7 @@ public class DefaultCalculatedFieldCacheTest { @Test public void onComponentLifecycleEvent_tenantDeleted_removesLinksToLinkedEntities() { - TenantId tenant = new TenantId(UUID.randomUUID()); + TenantId tenant = TenantId.fromUUID(UUID.randomUUID()); DeviceId cfEntity = new DeviceId(UUID.randomUUID()); DeviceId linkedDevice = new DeviceId(UUID.randomUUID()); @@ -139,7 +139,7 @@ public class DefaultCalculatedFieldCacheTest { @Test public void onComponentLifecycleEvent_tenantUpdated_doesNotEvictCfs() { - TenantId tenant = new TenantId(UUID.randomUUID()); + TenantId tenant = TenantId.fromUUID(UUID.randomUUID()); DeviceId device = new DeviceId(UUID.randomUUID()); CalculatedField cf = addCfToCache(tenant, device); @@ -152,7 +152,7 @@ public class DefaultCalculatedFieldCacheTest { @Test public void onComponentLifecycleEvent_deviceDeleted_evictsCfsForThatDevice() { - TenantId tenant = new TenantId(UUID.randomUUID()); + TenantId tenant = TenantId.fromUUID(UUID.randomUUID()); DeviceId device = new DeviceId(UUID.randomUUID()); CalculatedField cf = addCfToCache(tenant, device); @@ -164,7 +164,7 @@ public class DefaultCalculatedFieldCacheTest { @Test public void onComponentLifecycleEvent_deviceDeleted_removesLinksForLinkedEntities() { - TenantId tenant = new TenantId(UUID.randomUUID()); + TenantId tenant = TenantId.fromUUID(UUID.randomUUID()); DeviceId device = new DeviceId(UUID.randomUUID()); DeviceId linkedDevice = new DeviceId(UUID.randomUUID()); addCfToCache(tenant, device, linkedDevice); @@ -176,7 +176,7 @@ public class DefaultCalculatedFieldCacheTest { @Test public void onComponentLifecycleEvent_deviceDeleted_evictsDeviceFromOwnerEntities() { - TenantId tenant = new TenantId(UUID.randomUUID()); + TenantId tenant = TenantId.fromUUID(UUID.randomUUID()); CustomerId customer = new CustomerId(UUID.randomUUID()); DeviceId device = new DeviceId(UUID.randomUUID()); stubDeviceOwner(tenant, device, customer); @@ -191,7 +191,7 @@ public class DefaultCalculatedFieldCacheTest { @Test public void onComponentLifecycleEvent_assetDeleted_evictsCfsForThatAsset() { - TenantId tenant = new TenantId(UUID.randomUUID()); + TenantId tenant = TenantId.fromUUID(UUID.randomUUID()); AssetId asset = new AssetId(UUID.randomUUID()); CalculatedField cf = addCfToCache(tenant, asset); @@ -203,7 +203,7 @@ public class DefaultCalculatedFieldCacheTest { @Test public void onComponentLifecycleEvent_deviceCreated_addsDeviceToOwnerEntities() { - TenantId tenant = new TenantId(UUID.randomUUID()); + TenantId tenant = TenantId.fromUUID(UUID.randomUUID()); CustomerId customer = new CustomerId(UUID.randomUUID()); DeviceId device = new DeviceId(UUID.randomUUID()); stubDeviceOwner(tenant, device, customer); @@ -217,7 +217,7 @@ public class DefaultCalculatedFieldCacheTest { @Test public void onComponentLifecycleEvent_customerDeleted_evictsCustomerOwnerEntries() { - TenantId tenant = new TenantId(UUID.randomUUID()); + TenantId tenant = TenantId.fromUUID(UUID.randomUUID()); CustomerId customer = new CustomerId(UUID.randomUUID()); DeviceId device = new DeviceId(UUID.randomUUID()); stubDeviceOwner(tenant, device, customer); @@ -235,7 +235,7 @@ public class DefaultCalculatedFieldCacheTest { @Test public void onComponentLifecycleEvent_deviceProfileDeleted_evictsCfsForThatProfile() { - TenantId tenant = new TenantId(UUID.randomUUID()); + TenantId tenant = TenantId.fromUUID(UUID.randomUUID()); DeviceProfileId profileId = new DeviceProfileId(UUID.randomUUID()); CalculatedField cf = addCfToCache(tenant, profileId); @@ -247,7 +247,7 @@ public class DefaultCalculatedFieldCacheTest { @Test public void onComponentLifecycleEvent_deviceProfileDeleted_removesLinksForLinkedEntities() { - TenantId tenant = new TenantId(UUID.randomUUID()); + TenantId tenant = TenantId.fromUUID(UUID.randomUUID()); DeviceProfileId profileId = new DeviceProfileId(UUID.randomUUID()); DeviceId linkedDevice = new DeviceId(UUID.randomUUID()); addCfToCache(tenant, profileId, linkedDevice); @@ -259,7 +259,7 @@ public class DefaultCalculatedFieldCacheTest { @Test public void onComponentLifecycleEvent_deviceProfileDeleted_doesNotEvictOtherProfilesCfs() { - TenantId tenant = new TenantId(UUID.randomUUID()); + TenantId tenant = TenantId.fromUUID(UUID.randomUUID()); DeviceProfileId profile1 = new DeviceProfileId(UUID.randomUUID()); DeviceProfileId profile2 = new DeviceProfileId(UUID.randomUUID()); CalculatedField cf1 = addCfToCache(tenant, profile1); @@ -275,7 +275,7 @@ public class DefaultCalculatedFieldCacheTest { @Test public void onComponentLifecycleEvent_deviceProfileUpdated_doesNotEvictCfs() { - TenantId tenant = new TenantId(UUID.randomUUID()); + TenantId tenant = TenantId.fromUUID(UUID.randomUUID()); DeviceProfileId profileId = new DeviceProfileId(UUID.randomUUID()); CalculatedField cf = addCfToCache(tenant, profileId); @@ -287,7 +287,7 @@ public class DefaultCalculatedFieldCacheTest { @Test public void onComponentLifecycleEvent_assetProfileDeleted_evictsCfsForThatProfile() { - TenantId tenant = new TenantId(UUID.randomUUID()); + TenantId tenant = TenantId.fromUUID(UUID.randomUUID()); AssetProfileId profileId = new AssetProfileId(UUID.randomUUID()); CalculatedField cf = addCfToCache(tenant, profileId); @@ -299,7 +299,7 @@ public class DefaultCalculatedFieldCacheTest { @Test public void onComponentLifecycleEvent_assetProfileDeleted_removesLinksForLinkedEntities() { - TenantId tenant = new TenantId(UUID.randomUUID()); + TenantId tenant = TenantId.fromUUID(UUID.randomUUID()); AssetProfileId profileId = new AssetProfileId(UUID.randomUUID()); AssetId linkedAsset = new AssetId(UUID.randomUUID()); addCfToCache(tenant, profileId, linkedAsset); @@ -311,7 +311,7 @@ public class DefaultCalculatedFieldCacheTest { @Test public void onComponentLifecycleEvent_assetProfileDeleted_doesNotEvictOtherProfilesCfs() { - TenantId tenant = new TenantId(UUID.randomUUID()); + TenantId tenant = TenantId.fromUUID(UUID.randomUUID()); AssetProfileId profile1 = new AssetProfileId(UUID.randomUUID()); AssetProfileId profile2 = new AssetProfileId(UUID.randomUUID()); CalculatedField cf1 = addCfToCache(tenant, profile1); @@ -327,7 +327,7 @@ public class DefaultCalculatedFieldCacheTest { @Test public void onComponentLifecycleEvent_assetProfileUpdated_doesNotEvictCfs() { - TenantId tenant = new TenantId(UUID.randomUUID()); + TenantId tenant = TenantId.fromUUID(UUID.randomUUID()); AssetProfileId profileId = new AssetProfileId(UUID.randomUUID()); CalculatedField cf = addCfToCache(tenant, profileId); @@ -341,7 +341,7 @@ public class DefaultCalculatedFieldCacheTest { @Test public void onComponentLifecycleEvent_calculatedFieldCreated_addsCfToCache() { - TenantId tenant = new TenantId(UUID.randomUUID()); + TenantId tenant = TenantId.fromUUID(UUID.randomUUID()); DeviceId device = new DeviceId(UUID.randomUUID()); CalculatedFieldId cfId = new CalculatedFieldId(UUID.randomUUID()); CalculatedField cf = buildCalculatedField(cfId, tenant, device, simpleCfConfig()); @@ -355,7 +355,7 @@ public class DefaultCalculatedFieldCacheTest { @Test public void onComponentLifecycleEvent_calculatedFieldDeleted_evictsCfFromCache() { - TenantId tenant = new TenantId(UUID.randomUUID()); + TenantId tenant = TenantId.fromUUID(UUID.randomUUID()); DeviceId device = new DeviceId(UUID.randomUUID()); CalculatedField cf = addCfToCache(tenant, device); @@ -367,7 +367,7 @@ public class DefaultCalculatedFieldCacheTest { @Test public void onComponentLifecycleEvent_calculatedFieldUpdated_refreshesCfInCache() { - TenantId tenant = new TenantId(UUID.randomUUID()); + TenantId tenant = TenantId.fromUUID(UUID.randomUUID()); DeviceId device = new DeviceId(UUID.randomUUID()); CalculatedField cf = addCfToCache(tenant, device); @@ -384,7 +384,7 @@ public class DefaultCalculatedFieldCacheTest { @Test public void evictOwner_customerDeleted_recursivelyEvictsDevicesOwnedByThatCustomer() { - TenantId tenant = new TenantId(UUID.randomUUID()); + TenantId tenant = TenantId.fromUUID(UUID.randomUUID()); CustomerId customer = new CustomerId(UUID.randomUUID()); DeviceId device = new DeviceId(UUID.randomUUID()); @@ -406,7 +406,7 @@ public class DefaultCalculatedFieldCacheTest { @Test public void evictOwner_tenantDeleted_recursivelyEvictsCustomerAndItsOwnedDevices() { - TenantId tenant = new TenantId(UUID.randomUUID()); + TenantId tenant = TenantId.fromUUID(UUID.randomUUID()); CustomerId customer = new CustomerId(UUID.randomUUID()); DeviceId device = new DeviceId(UUID.randomUUID()); @@ -431,7 +431,7 @@ public class DefaultCalculatedFieldCacheTest { @Test public void onComponentLifecycleEvent_tenantProfileUpdated_callsHandleTenantProfileUpdate() { - TenantId tenant = new TenantId(UUID.randomUUID()); + TenantId tenant = TenantId.fromUUID(UUID.randomUUID()); TenantProfileId profileId = new TenantProfileId(UUID.randomUUID()); DefaultCalculatedFieldCache spyCache = spy(cache); @@ -442,7 +442,7 @@ public class DefaultCalculatedFieldCacheTest { @Test public void onComponentLifecycleEvent_tenantProfileDeleted_doesNotCallHandleTenantProfileUpdate() { - TenantId tenant = new TenantId(UUID.randomUUID()); + TenantId tenant = TenantId.fromUUID(UUID.randomUUID()); TenantProfileId profileId = new TenantProfileId(UUID.randomUUID()); DefaultCalculatedFieldCache spyCache = spy(cache); diff --git a/application/src/test/java/org/thingsboard/server/service/device/provision/DeviceProvisionServiceTest.java b/application/src/test/java/org/thingsboard/server/service/device/provision/DeviceProvisionServiceTest.java index 4f2eaa5147..839fbd9557 100644 --- a/application/src/test/java/org/thingsboard/server/service/device/provision/DeviceProvisionServiceTest.java +++ b/application/src/test/java/org/thingsboard/server/service/device/provision/DeviceProvisionServiceTest.java @@ -235,7 +235,7 @@ public class DeviceProvisionServiceTest { private Tenant createTenant() { Tenant tenant = new Tenant(); - tenant.setId(new TenantId(UUID.randomUUID())); + tenant.setId(TenantId.fromUUID(UUID.randomUUID())); return tenant; } diff --git a/application/src/test/java/org/thingsboard/server/service/profile/DefaultTbAssetProfileCacheTest.java b/application/src/test/java/org/thingsboard/server/service/profile/DefaultTbAssetProfileCacheTest.java index f9b8d428d7..666ae37c6e 100644 --- a/application/src/test/java/org/thingsboard/server/service/profile/DefaultTbAssetProfileCacheTest.java +++ b/application/src/test/java/org/thingsboard/server/service/profile/DefaultTbAssetProfileCacheTest.java @@ -57,8 +57,8 @@ public class DefaultTbAssetProfileCacheTest { @Test public void onComponentLifecycleEvent_tenantDeleted_evictsAssetProfilesForThatTenant() { - TenantId tenant1 = new TenantId(UUID.randomUUID()); - TenantId tenant2 = new TenantId(UUID.randomUUID()); + TenantId tenant1 = TenantId.fromUUID(UUID.randomUUID()); + TenantId tenant2 = TenantId.fromUUID(UUID.randomUUID()); AssetProfileId profileId1 = new AssetProfileId(UUID.randomUUID()); AssetProfileId profileId2 = new AssetProfileId(UUID.randomUUID()); @@ -75,7 +75,7 @@ public class DefaultTbAssetProfileCacheTest { @Test public void onComponentLifecycleEvent_tenantDeleted_evictsAssetMappingsForThatTenant() { - TenantId tenant = new TenantId(UUID.randomUUID()); + TenantId tenant = TenantId.fromUUID(UUID.randomUUID()); AssetProfileId profileId = new AssetProfileId(UUID.randomUUID()); AssetId assetId = new AssetId(UUID.randomUUID()); @@ -92,7 +92,7 @@ public class DefaultTbAssetProfileCacheTest { @Test public void onComponentLifecycleEvent_tenantDeleted_removesListenersForThatTenant() { - TenantId tenant = new TenantId(UUID.randomUUID()); + TenantId tenant = TenantId.fromUUID(UUID.randomUUID()); EntityId listenerId = new AssetId(UUID.randomUUID()); AtomicInteger callCount = new AtomicInteger(); @@ -110,7 +110,7 @@ public class DefaultTbAssetProfileCacheTest { @Test public void onComponentLifecycleEvent_tenantUpdated_doesNotEvictProfiles() { - TenantId tenant = new TenantId(UUID.randomUUID()); + TenantId tenant = TenantId.fromUUID(UUID.randomUUID()); AssetProfileId profileId = new AssetProfileId(UUID.randomUUID()); loadProfileIntoCache(tenant, profileId); @@ -123,8 +123,8 @@ public class DefaultTbAssetProfileCacheTest { @Test public void onComponentLifecycleEvent_differentTenantDeleted_keepsOtherTenantsProfiles() { - TenantId tenant1 = new TenantId(UUID.randomUUID()); - TenantId tenant2 = new TenantId(UUID.randomUUID()); + TenantId tenant1 = TenantId.fromUUID(UUID.randomUUID()); + TenantId tenant2 = TenantId.fromUUID(UUID.randomUUID()); AssetProfileId profileId1 = new AssetProfileId(UUID.randomUUID()); AssetProfileId profileId2 = new AssetProfileId(UUID.randomUUID()); diff --git a/application/src/test/java/org/thingsboard/server/service/profile/DefaultTbDeviceProfileCacheTest.java b/application/src/test/java/org/thingsboard/server/service/profile/DefaultTbDeviceProfileCacheTest.java index a26413514c..fc900b88e4 100644 --- a/application/src/test/java/org/thingsboard/server/service/profile/DefaultTbDeviceProfileCacheTest.java +++ b/application/src/test/java/org/thingsboard/server/service/profile/DefaultTbDeviceProfileCacheTest.java @@ -57,8 +57,8 @@ public class DefaultTbDeviceProfileCacheTest { @Test public void onComponentLifecycleEvent_tenantDeleted_evictsDeviceProfilesForThatTenant() { - TenantId tenant1 = new TenantId(UUID.randomUUID()); - TenantId tenant2 = new TenantId(UUID.randomUUID()); + TenantId tenant1 = TenantId.fromUUID(UUID.randomUUID()); + TenantId tenant2 = TenantId.fromUUID(UUID.randomUUID()); DeviceProfileId profileId1 = new DeviceProfileId(UUID.randomUUID()); DeviceProfileId profileId2 = new DeviceProfileId(UUID.randomUUID()); @@ -76,7 +76,7 @@ public class DefaultTbDeviceProfileCacheTest { @Test public void onComponentLifecycleEvent_tenantDeleted_evictsDeviceMappingsForThatTenant() { - TenantId tenant = new TenantId(UUID.randomUUID()); + TenantId tenant = TenantId.fromUUID(UUID.randomUUID()); DeviceProfileId profileId = new DeviceProfileId(UUID.randomUUID()); DeviceId deviceId = new DeviceId(UUID.randomUUID()); @@ -93,7 +93,7 @@ public class DefaultTbDeviceProfileCacheTest { @Test public void onComponentLifecycleEvent_tenantDeleted_removesListenersForThatTenant() { - TenantId tenant = new TenantId(UUID.randomUUID()); + TenantId tenant = TenantId.fromUUID(UUID.randomUUID()); EntityId listenerId = new DeviceId(UUID.randomUUID()); AtomicInteger callCount = new AtomicInteger(); @@ -111,7 +111,7 @@ public class DefaultTbDeviceProfileCacheTest { @Test public void onComponentLifecycleEvent_tenantUpdated_doesNotEvictProfiles() { - TenantId tenant = new TenantId(UUID.randomUUID()); + TenantId tenant = TenantId.fromUUID(UUID.randomUUID()); DeviceProfileId profileId = new DeviceProfileId(UUID.randomUUID()); loadProfileIntoCache(tenant, profileId); @@ -124,8 +124,8 @@ public class DefaultTbDeviceProfileCacheTest { @Test public void onComponentLifecycleEvent_differentTenantDeleted_keepsOtherTenantsProfiles() { - TenantId tenant1 = new TenantId(UUID.randomUUID()); - TenantId tenant2 = new TenantId(UUID.randomUUID()); + TenantId tenant1 = TenantId.fromUUID(UUID.randomUUID()); + TenantId tenant2 = TenantId.fromUUID(UUID.randomUUID()); DeviceProfileId profileId1 = new DeviceProfileId(UUID.randomUUID()); DeviceProfileId profileId2 = new DeviceProfileId(UUID.randomUUID()); diff --git a/application/src/test/java/org/thingsboard/server/service/queue/DefaultTbClusterServiceTest.java b/application/src/test/java/org/thingsboard/server/service/queue/DefaultTbClusterServiceTest.java index 79b31acf78..09225216ca 100644 --- a/application/src/test/java/org/thingsboard/server/service/queue/DefaultTbClusterServiceTest.java +++ b/application/src/test/java/org/thingsboard/server/service/queue/DefaultTbClusterServiceTest.java @@ -410,7 +410,7 @@ public class DefaultTbClusterServiceTest { @Test public void testGetRuleEngineProfileForUpdatedAndDeletedDevice() { DeviceId deviceId = new DeviceId(UUID.randomUUID()); - TenantId tenantId = new TenantId(UUID.randomUUID()); + TenantId tenantId = TenantId.fromUUID(UUID.randomUUID()); DeviceProfileId deviceProfileId = new DeviceProfileId(UUID.randomUUID()); Device device = new Device(deviceId); @@ -430,7 +430,7 @@ public class DefaultTbClusterServiceTest { @Test public void testGetRuleEngineProfileForUpdatedAndDeletedAsset() { AssetId assetId = new AssetId(UUID.randomUUID()); - TenantId tenantId = new TenantId(UUID.randomUUID()); + TenantId tenantId = TenantId.fromUUID(UUID.randomUUID()); AssetProfileId assetProfileId = new AssetProfileId(UUID.randomUUID()); Asset asset = new Asset(assetId); diff --git a/application/src/test/java/org/thingsboard/server/service/subscription/TbEntityLocalSubsInfoTest.java b/application/src/test/java/org/thingsboard/server/service/subscription/TbEntityLocalSubsInfoTest.java index ba1a89eb38..1ab2a54319 100644 --- a/application/src/test/java/org/thingsboard/server/service/subscription/TbEntityLocalSubsInfoTest.java +++ b/application/src/test/java/org/thingsboard/server/service/subscription/TbEntityLocalSubsInfoTest.java @@ -161,7 +161,7 @@ public class TbEntityLocalSubsInfoTest { } private TbEntityLocalSubsInfo createSubsInfo() { - return new TbEntityLocalSubsInfo(new TenantId(UUID.randomUUID()), new DeviceId(UUID.randomUUID())); + return new TbEntityLocalSubsInfo(TenantId.fromUUID(UUID.randomUUID()), new DeviceId(UUID.randomUUID())); } private void checkEvent(TbEntitySubEvent event, Set expectedSubs, ComponentLifecycleEvent expectedType) { diff --git a/application/src/test/java/org/thingsboard/server/service/ws/DefaultWebSocketServiceTest.java b/application/src/test/java/org/thingsboard/server/service/ws/DefaultWebSocketServiceTest.java index a533e0369f..673062256f 100644 --- a/application/src/test/java/org/thingsboard/server/service/ws/DefaultWebSocketServiceTest.java +++ b/application/src/test/java/org/thingsboard/server/service/ws/DefaultWebSocketServiceTest.java @@ -113,7 +113,7 @@ class DefaultWebSocketServiceTest { assertThat(publicUserSubscriptionsMap).as("map should contain tenant1").containsKey(tenant1); assertThat(publicUserSubscriptionsMap).as("map should contain tenant2").containsKey(tenant2); assertThat(publicUserSubscriptionsMap).as("map must not have a single NULL_UUID entry for all tenants") - .doesNotContainKey(new TenantId(EntityId.NULL_UUID)); + .doesNotContainKey(TenantId.fromUUID(EntityId.NULL_UUID)); assertThat(publicUserSubscriptionsMap.get(tenant1)) .as("tenant1 should have exactly %d subscriptions", maxPublicSubscriptions) diff --git a/common/transport/mqtt/src/test/java/org/thingsboard/server/transport/mqtt/session/GatewaySessionHandlerTest.java b/common/transport/mqtt/src/test/java/org/thingsboard/server/transport/mqtt/session/GatewaySessionHandlerTest.java index 6b4e5e9925..30dc825a9b 100644 --- a/common/transport/mqtt/src/test/java/org/thingsboard/server/transport/mqtt/session/GatewaySessionHandlerTest.java +++ b/common/transport/mqtt/src/test/java/org/thingsboard/server/transport/mqtt/session/GatewaySessionHandlerTest.java @@ -75,7 +75,7 @@ public class GatewaySessionHandlerTest { ConcurrentHashMap devices = new ConcurrentHashMap<>(); TransportDeviceInfo deviceInfo = new TransportDeviceInfo(); deviceInfo.setDeviceId(new DeviceId(UUID.randomUUID())); - deviceInfo.setTenantId(new TenantId(UUID.randomUUID())); + deviceInfo.setTenantId(TenantId.fromUUID(UUID.randomUUID())); deviceInfo.setCustomerId(new CustomerId(UUID.randomUUID())); deviceInfo.setDeviceName("device1"); deviceInfo.setDeviceType("default"); diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/TbCacheSerializationTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/TbCacheSerializationTest.java index e1654678a0..b0ae8fb6ae 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/TbCacheSerializationTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/TbCacheSerializationTest.java @@ -37,7 +37,7 @@ public class TbCacheSerializationTest extends AbstractServiceTest { @Test public void AlarmTypesSerializationTest() { var typesCount = 13; - TenantId tenantId = new TenantId(UUID.randomUUID()); + TenantId tenantId = TenantId.fromUUID(UUID.randomUUID()); List types = new ArrayList<>(typesCount); for (int i = 0; i < typesCount; i++) { types.add(new EntitySubtype(tenantId, EntityType.ALARM, "alarm_type_" + i)); diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/attributes/BaseAttributesServiceTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/attributes/BaseAttributesServiceTest.java index 373112293d..da1e57e348 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/attributes/BaseAttributesServiceTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/attributes/BaseAttributesServiceTest.java @@ -122,7 +122,7 @@ public abstract class BaseAttributesServiceTest extends AbstractServiceTest { @Test public void testDummyRequestWithEmptyResult() throws Exception { - var future = attributesService.find(new TenantId(UUID.randomUUID()), new DeviceId(UUID.randomUUID()), AttributeScope.SERVER_SCOPE, "TEST"); + var future = attributesService.find(TenantId.fromUUID(UUID.randomUUID()), new DeviceId(UUID.randomUUID()), AttributeScope.SERVER_SCOPE, "TEST"); Assert.assertNotNull(future); var result = future.get(10, TimeUnit.SECONDS); Assert.assertTrue(result.isEmpty()); @@ -130,7 +130,7 @@ public abstract class BaseAttributesServiceTest extends AbstractServiceTest { @Test public void testConcurrentFetchAndUpdate() throws Exception { - var tenantId = new TenantId(UUID.randomUUID()); + var tenantId = TenantId.fromUUID(UUID.randomUUID()); ListeningExecutorService pool = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(2)); try { for (int i = 0; i < 100; i++) { @@ -144,7 +144,7 @@ public abstract class BaseAttributesServiceTest extends AbstractServiceTest { @Test public void testConcurrentFetchAndUpdateMulti() throws Exception { - var tenantId = new TenantId(UUID.randomUUID()); + var tenantId = TenantId.fromUUID(UUID.randomUUID()); ListeningExecutorService pool = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(2)); try { for (int i = 0; i < 100; i++) { @@ -158,7 +158,7 @@ public abstract class BaseAttributesServiceTest extends AbstractServiceTest { @Test public void testFetchAndUpdateEmpty() throws Exception { - var tenantId = new TenantId(UUID.randomUUID()); + var tenantId = TenantId.fromUUID(UUID.randomUUID()); var deviceId = new DeviceId(UUID.randomUUID()); var scope = AttributeScope.SERVER_SCOPE; var key = "TEST"; @@ -172,7 +172,7 @@ public abstract class BaseAttributesServiceTest extends AbstractServiceTest { @Test public void testFetchAndUpdateMulti() throws Exception { - var tenantId = new TenantId(UUID.randomUUID()); + var tenantId = TenantId.fromUUID(UUID.randomUUID()); var deviceId = new DeviceId(UUID.randomUUID()); var scope = AttributeScope.SERVER_SCOPE; var key1 = "TEST1"; @@ -204,7 +204,7 @@ public abstract class BaseAttributesServiceTest extends AbstractServiceTest { @Test public void testFindAllKeysByEntityId() { - var tenantId = new TenantId(UUID.randomUUID()); + var tenantId = TenantId.fromUUID(UUID.randomUUID()); var deviceId = new DeviceId(UUID.randomUUID()); saveAttribute(tenantId, deviceId, AttributeScope.SERVER_SCOPE, "key1", "123"); saveAttribute(tenantId, deviceId, AttributeScope.SERVER_SCOPE, "key2", "123"); @@ -217,7 +217,7 @@ public abstract class BaseAttributesServiceTest extends AbstractServiceTest { @Test public void testFindAllKeysByEntityIdAndAttributeType() { - var tenantId = new TenantId(UUID.randomUUID()); + var tenantId = TenantId.fromUUID(UUID.randomUUID()); var deviceId = new DeviceId(UUID.randomUUID()); saveAttribute(tenantId, deviceId, AttributeScope.SERVER_SCOPE, "key1", "123"); saveAttribute(tenantId, deviceId, AttributeScope.SERVER_SCOPE, "key2", "123"); @@ -230,7 +230,7 @@ public abstract class BaseAttributesServiceTest extends AbstractServiceTest { @Test public void testFindAllByEntityIdAndAttributeType() { - var tenantId = new TenantId(UUID.randomUUID()); + var tenantId = TenantId.fromUUID(UUID.randomUUID()); var deviceId = new DeviceId(UUID.randomUUID()); saveAttribute(tenantId, deviceId, AttributeScope.SERVER_SCOPE, "key1", "123"); saveAttribute(tenantId, deviceId, AttributeScope.SERVER_SCOPE, "key2", "123"); diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/event/BaseEventServiceTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/event/BaseEventServiceTest.java index 9d754f6150..2f33fae122 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/event/BaseEventServiceTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/event/BaseEventServiceTest.java @@ -62,7 +62,7 @@ public abstract class BaseEventServiceTest extends AbstractServiceTest { @Test public void saveEvent() throws Exception { - TenantId tenantId = new TenantId(Uuids.timeBased()); + TenantId tenantId = TenantId.fromUUID(Uuids.timeBased()); DeviceId devId = new DeviceId(Uuids.timeBased()); RuleNodeDebugEvent event = generateEvent(tenantId, devId); eventService.saveAsync(event).get(); diff --git a/dao/src/test/java/org/thingsboard/server/dao/sql/event/JpaBaseEventDaoTest.java b/dao/src/test/java/org/thingsboard/server/dao/sql/event/JpaBaseEventDaoTest.java index 3ddf318e2f..e03b161692 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/sql/event/JpaBaseEventDaoTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/sql/event/JpaBaseEventDaoTest.java @@ -132,7 +132,7 @@ public class JpaBaseEventDaoTest extends AbstractJpaDaoTest { StatisticsEvent.StatisticsEventBuilder event = StatisticsEvent.builder(); event.id(eventId); event.ts(System.currentTimeMillis()); - event.tenantId(new TenantId(tenantId)); + event.tenantId(TenantId.fromUUID(tenantId)); event.entityId(entityId); event.serviceId("server A"); event.messagesProcessed(1); diff --git a/dao/src/test/java/org/thingsboard/server/dao/sql/query/DefaultQueryLogComponentTest.java b/dao/src/test/java/org/thingsboard/server/dao/sql/query/DefaultQueryLogComponentTest.java index e47ed5bfbf..a25d85aae6 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/sql/query/DefaultQueryLogComponentTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/sql/query/DefaultQueryLogComponentTest.java @@ -57,7 +57,7 @@ public class DefaultQueryLogComponentTest { @Before public void setUp() { - tenantId = new TenantId(UUID.fromString("97275c1c-9cf2-4d25-a68d-933031158f84")); + tenantId = TenantId.fromUUID(UUID.fromString("97275c1c-9cf2-4d25-a68d-933031158f84")); ctx = new SqlQueryContext(new QueryContext(tenantId, null, EntityType.ALARM)); } diff --git a/dao/src/test/java/org/thingsboard/server/dao/sql/tenant/JpaTenantDaoTest.java b/dao/src/test/java/org/thingsboard/server/dao/sql/tenant/JpaTenantDaoTest.java index dd0bedbf5a..31e4ab2ac8 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/sql/tenant/JpaTenantDaoTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/sql/tenant/JpaTenantDaoTest.java @@ -103,7 +103,7 @@ public class JpaTenantDaoTest extends AbstractJpaDaoTest { //@DatabaseSetup("classpath:dbunit/empty_dataset.xml") public void testIsExistsTenantById() { final UUID uuid = Uuids.timeBased(); - final TenantId tenantId = new TenantId(uuid); + final TenantId tenantId = TenantId.fromUUID(uuid); assertThat(tenantDao.existsById(tenantId, uuid)).as("Is tenant exists before save").isFalse(); final Tenant tenant = new Tenant(); diff --git a/dao/src/test/java/org/thingsboard/server/dao/sql/widget/JpaWidgetsBundleDaoTest.java b/dao/src/test/java/org/thingsboard/server/dao/sql/widget/JpaWidgetsBundleDaoTest.java index 164d59ecc0..0b6236196a 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/sql/widget/JpaWidgetsBundleDaoTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/sql/widget/JpaWidgetsBundleDaoTest.java @@ -276,8 +276,8 @@ public class JpaWidgetsBundleDaoTest extends AbstractJpaDaoTest { widgetsBundles = widgetsBundleDao.find(TenantId.SYS_TENANT_ID).stream().sorted(Comparator.comparing(WidgetsBundle::getTitle)).collect(Collectors.toList());; assertEquals(100, widgetsBundles.size()); - var widgetType1 = createAndSaveWidgetType(new TenantId(tenantId1), 1, "Test widget type 1", "This is the widget type 1", new String[]{"tag1", "Tag2", "TEST_TAG"}); - var widgetType2 = createAndSaveWidgetType(new TenantId(tenantId2), 2, "Test widget type 2", "This is the widget type 2", new String[]{"tag3", "Tag5", "TEST_Tag2"}); + var widgetType1 = createAndSaveWidgetType(TenantId.fromUUID(tenantId1), 1, "Test widget type 1", "This is the widget type 1", new String[]{"tag1", "Tag2", "TEST_TAG"}); + var widgetType2 = createAndSaveWidgetType(TenantId.fromUUID(tenantId2), 2, "Test widget type 2", "This is the widget type 2", new String[]{"tag3", "Tag5", "TEST_Tag2"}); var widgetsBundle1 = widgetsBundles.stream().filter(widgetsBundle -> widgetsBundle.getTenantId().getId().equals(tenantId1)).collect(Collectors.toList()).get(10); widgetTypeDao.saveWidgetsBundleWidget(new WidgetsBundleWidget(widgetsBundle1.getId(), widgetType1.getId(), 0)); diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/action/TbAssignToCustomerNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/action/TbAssignToCustomerNodeTest.java index 0db2d77c01..7f329b1411 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/action/TbAssignToCustomerNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/action/TbAssignToCustomerNodeTest.java @@ -97,7 +97,7 @@ class TbAssignToCustomerNodeTest extends AbstractRuleNodeUpgradeTest { private final Edge EDGE = new Edge(); private final Dashboard DASHBOARD = new Dashboard(); - private final TenantId TENANT_ID = new TenantId(UUID.fromString("c818385f-e661-407f-8c52-daf2dddf406d")); + private final TenantId TENANT_ID = TenantId.fromUUID(UUID.fromString("c818385f-e661-407f-8c52-daf2dddf406d")); private final RuleNodeId RULE_NODE_ID = new RuleNodeId(UUID.fromString("c3570bd0-c0bc-4609-97a4-6f57d7c8b809")); private static Stream givenUnsupportedOriginatorType_whenOnMsg_thenVerifyExceptionThrown() { diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/action/TbCreateRelationNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/action/TbCreateRelationNodeTest.java index 60924002da..50c54b91de 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/action/TbCreateRelationNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/action/TbCreateRelationNodeTest.java @@ -111,7 +111,7 @@ public class TbCreateRelationNodeTest extends AbstractRuleNodeUpgradeTest { return supportedEntityTypes.stream().filter(entityType -> !entityType.equals(EntityType.TENANT)).map(Arguments::of); } - private static final TenantId tenantId = new TenantId(UUID.fromString("6fc86fc9-b25c-4893-b340-51cf4e101ab2")); + private static final TenantId tenantId = TenantId.fromUUID(UUID.fromString("6fc86fc9-b25c-4893-b340-51cf4e101ab2")); private static final DeviceId deviceId = new DeviceId(UUID.fromString("191ab124-1d8d-4749-97c6-fc84c113c1f5")); private static final AssetId assetId = new AssetId(UUID.fromString("a47a5867-deab-4333-b845-88cb1695990c")); private static final CustomerId customerId = new CustomerId(UUID.fromString("4af69229-273d-40de-9fba-f49f87373d23")); diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/action/TbDeleteRelationNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/action/TbDeleteRelationNodeTest.java index a8087cc40b..f6ef490aba 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/action/TbDeleteRelationNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/action/TbDeleteRelationNodeTest.java @@ -108,7 +108,7 @@ public class TbDeleteRelationNodeTest extends AbstractRuleNodeUpgradeTest { return supportedEntityTypes.stream().filter(entityType -> !entityType.equals(EntityType.TENANT)).map(Arguments::of); } - private static final TenantId tenantId = new TenantId(UUID.fromString("6fdb457d-0910-401c-8880-abc251e6a1e2")); + private static final TenantId tenantId = TenantId.fromUUID(UUID.fromString("6fdb457d-0910-401c-8880-abc251e6a1e2")); private static final DeviceId deviceId = new DeviceId(UUID.fromString("4eef91a7-8865-4c3c-837d-ed6f6577508b")); private static final AssetId assetId = new AssetId(UUID.fromString("f4fd3b10-3f36-4d46-a162-5e62050774cc")); private static final CustomerId customerId = new CustomerId(UUID.fromString("ab890af2-3622-41e0-ac94-14d50af84348")); diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/action/TbUnassignFromCustomerNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/action/TbUnassignFromCustomerNodeTest.java index de891c13d4..dd1307b10a 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/action/TbUnassignFromCustomerNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/action/TbUnassignFromCustomerNodeTest.java @@ -98,7 +98,7 @@ class TbUnassignFromCustomerNodeTest extends AbstractRuleNodeUpgradeTest { private final Edge EDGE = new Edge(); private final Dashboard DASHBOARD = new Dashboard(); - private final TenantId TENANT_ID = new TenantId(UUID.fromString("06fcc15f-2677-436d-a1cb-7754bd0bcccf")); + private final TenantId TENANT_ID = TenantId.fromUUID(UUID.fromString("06fcc15f-2677-436d-a1cb-7754bd0bcccf")); private final ListeningExecutor DB_EXECUTOR = DirectListeningExecutor.INSTANCE; diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/filter/TbAssetTypeSwitchNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/filter/TbAssetTypeSwitchNodeTest.java index 557fb5b71d..b0788a1817 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/filter/TbAssetTypeSwitchNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/filter/TbAssetTypeSwitchNodeTest.java @@ -58,7 +58,7 @@ class TbAssetTypeSwitchNodeTest { @BeforeEach void setUp() throws TbNodeException { - TenantId tenantId = new TenantId(UUID.randomUUID()); + TenantId tenantId = TenantId.fromUUID(UUID.randomUUID()); assetId = new AssetId(UUID.randomUUID()); assetIdDeleted = new AssetId(UUID.randomUUID()); diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/filter/TbCheckAlarmStatusNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/filter/TbCheckAlarmStatusNodeTest.java index d8a302ae92..9155221a26 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/filter/TbCheckAlarmStatusNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/filter/TbCheckAlarmStatusNodeTest.java @@ -50,7 +50,7 @@ import static org.mockito.Mockito.when; class TbCheckAlarmStatusNodeTest { - private static final TenantId TENANT_ID = new TenantId(UUID.randomUUID()); + private static final TenantId TENANT_ID = TenantId.fromUUID(UUID.randomUUID()); private static final DeviceId DEVICE_ID = new DeviceId(UUID.randomUUID()); private static final AlarmId ALARM_ID = new AlarmId(UUID.randomUUID()); private static final DirectListeningExecutor DB_EXECUTOR = DirectListeningExecutor.INSTANCE; diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/filter/TbCheckRelationNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/filter/TbCheckRelationNodeTest.java index e6011c74d8..fb8ad655c0 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/filter/TbCheckRelationNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/filter/TbCheckRelationNodeTest.java @@ -63,7 +63,7 @@ import static org.mockito.Mockito.when; class TbCheckRelationNodeTest extends AbstractRuleNodeUpgradeTest { - private final TenantId TENANT_ID = new TenantId(UUID.randomUUID()); + private final TenantId TENANT_ID = TenantId.fromUUID(UUID.randomUUID()); private final DeviceId ORIGINATOR_ID = new DeviceId(UUID.randomUUID()); private final DirectListeningExecutor DB_EXECUTOR = DirectListeningExecutor.INSTANCE; private final TbMsg EMPTY_POST_ATTRIBUTES_MSG = TbMsg.newMsg() diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/filter/TbDeviceTypeSwitchNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/filter/TbDeviceTypeSwitchNodeTest.java index 55e9c33b7e..ebbdbe14c7 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/filter/TbDeviceTypeSwitchNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/filter/TbDeviceTypeSwitchNodeTest.java @@ -58,7 +58,7 @@ class TbDeviceTypeSwitchNodeTest { @BeforeEach void setUp() throws TbNodeException { - TenantId tenantId = new TenantId(UUID.randomUUID()); + TenantId tenantId = TenantId.fromUUID(UUID.randomUUID()); deviceId = new DeviceId(UUID.randomUUID()); deviceIdDeleted = new DeviceId(UUID.randomUUID()); diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/flow/TbRuleChainInputNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/flow/TbRuleChainInputNodeTest.java index 3ae26e6560..963e25f6b6 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/flow/TbRuleChainInputNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/flow/TbRuleChainInputNodeTest.java @@ -64,7 +64,7 @@ import static org.mockito.Mockito.when; @ExtendWith(MockitoExtension.class) public class TbRuleChainInputNodeTest extends AbstractRuleNodeUpgradeTest { - private final TenantId TENANT_ID = new TenantId(UUID.fromString("4ba69ea5-6b27-42df-ab66-e7a727a67027")); + private final TenantId TENANT_ID = TenantId.fromUUID(UUID.fromString("4ba69ea5-6b27-42df-ab66-e7a727a67027")); private final DeviceId DEVICE_ID = new DeviceId(UUID.fromString("97731954-2147-4176-8f1a-d14f1b73e4e6")); private final AssetId ASSET_ID = new AssetId(UUID.fromString("841a47bd-4e8e-4ea5-88e6-420da0d70e51")); // A stable "current" rule chain ID: this node lives here. Must differ from any target used in tests. diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetCustomerDetailsNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetCustomerDetailsNodeTest.java index 5e9726ec97..3940ab56c4 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetCustomerDetailsNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetCustomerDetailsNodeTest.java @@ -76,7 +76,7 @@ import static org.mockito.Mockito.when; public class TbGetCustomerDetailsNodeTest { private static final DeviceId DUMMY_DEVICE_ORIGINATOR = new DeviceId(UUID.randomUUID()); - private static final TenantId TENANT_ID = new TenantId(UUID.randomUUID()); + private static final TenantId TENANT_ID = TenantId.fromUUID(UUID.randomUUID()); private static final ListeningExecutor DB_EXECUTOR = DirectListeningExecutor.INSTANCE; @Mock private TbContext ctxMock; diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetDeviceAttrNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetDeviceAttrNodeTest.java index 4f267c0dfb..f9a230a437 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetDeviceAttrNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetDeviceAttrNodeTest.java @@ -60,7 +60,7 @@ import static org.mockito.BDDMockito.then; @ExtendWith(MockitoExtension.class) public class TbGetDeviceAttrNodeTest extends AbstractRuleNodeUpgradeTest { - private final TenantId TENANT_ID = new TenantId(UUID.fromString("5aea576c-66c4-4732-86b8-dc6bfcde7443")); + private final TenantId TENANT_ID = TenantId.fromUUID(UUID.fromString("5aea576c-66c4-4732-86b8-dc6bfcde7443")); private final DeviceId DEVICE_ID = new DeviceId(UUID.fromString("40b6b393-6ddf-47f9-973a-18550ca70384")); private final ListeningExecutor executor = DirectListeningExecutor.INSTANCE; diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetOriginatorFieldsNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetOriginatorFieldsNodeTest.java index fff7437fdf..a0d0a5a957 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetOriginatorFieldsNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetOriginatorFieldsNodeTest.java @@ -59,7 +59,7 @@ import static org.mockito.Mockito.when; public class TbGetOriginatorFieldsNodeTest { private static final DeviceId DUMMY_DEVICE_ORIGINATOR = new DeviceId(UUID.randomUUID()); - private static final TenantId DUMMY_TENANT_ID = new TenantId(UUID.randomUUID()); + private static final TenantId DUMMY_TENANT_ID = TenantId.fromUUID(UUID.randomUUID()); private static final ListeningExecutor DB_EXECUTOR = DirectListeningExecutor.INSTANCE; @Mock private TbContext ctxMock; diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttributeNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttributeNodeTest.java index a31d23db55..88195973e6 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttributeNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttributeNodeTest.java @@ -91,7 +91,7 @@ import static org.mockito.Mockito.when; public class TbGetRelatedAttributeNodeTest { private static final EntityId DUMMY_DEVICE_ORIGINATOR = new DeviceId(UUID.randomUUID()); - private static final TenantId TENANT_ID = new TenantId(UUID.randomUUID()); + private static final TenantId TENANT_ID = TenantId.fromUUID(UUID.randomUUID()); private static final ListeningExecutor DB_EXECUTOR = DirectListeningExecutor.INSTANCE; @Mock private TbContext ctxMock; @@ -427,7 +427,7 @@ public class TbGetRelatedAttributeNodeTest { @Test public void givenFetchTelemetryToMetaData_whenOnMsg_thenShouldFetchTelemetryToMetaData() { // GIVEN - var tenant = new Tenant(new TenantId(UUID.randomUUID())); + var tenant = new Tenant(TenantId.fromUUID(UUID.randomUUID())); var device = new Device(new DeviceId(UUID.randomUUID())); prepareMsgAndConfig(TbMsgSource.METADATA, DataToFetch.LATEST_TELEMETRY, tenant.getId()); diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetTenantAttributeNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetTenantAttributeNodeTest.java index 88db3dc0cd..fa528a724c 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetTenantAttributeNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetTenantAttributeNodeTest.java @@ -70,7 +70,7 @@ import static org.mockito.Mockito.when; public class TbGetTenantAttributeNodeTest { private static final DeviceId DUMMY_DEVICE_ORIGINATOR = new DeviceId(UUID.randomUUID()); - private static final TenantId TENANT_ID = new TenantId(UUID.randomUUID()); + private static final TenantId TENANT_ID = TenantId.fromUUID(UUID.randomUUID()); private static final DirectListeningExecutor DB_EXECUTOR = DirectListeningExecutor.INSTANCE; @Mock private TbContext ctxMock; diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetTenantDetailsNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetTenantDetailsNodeTest.java index b77bd263f8..7f476ea775 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetTenantDetailsNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetTenantDetailsNodeTest.java @@ -73,7 +73,7 @@ public class TbGetTenantDetailsNodeTest { config = new TbGetTenantDetailsNodeConfiguration().defaultConfiguration(); nodeConfiguration = new TbNodeConfiguration(JacksonUtil.valueToTree(config)); tenant = new Tenant(); - tenant.setId(new TenantId(UUID.randomUUID())); + tenant.setId(TenantId.fromUUID(UUID.randomUUID())); tenant.setTitle("Tenant title"); tenant.setCountry("Tenant country"); tenant.setCity("Tenant city"); diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/util/EntitiesFieldsAsyncLoaderTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/util/EntitiesFieldsAsyncLoaderTest.java index d1bcc4559e..75dc8d227a 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/util/EntitiesFieldsAsyncLoaderTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/util/EntitiesFieldsAsyncLoaderTest.java @@ -104,7 +104,7 @@ public class EntitiesFieldsAsyncLoaderTest { @BeforeAll public static void setup() { RANDOM_UUID = UUID.randomUUID(); - TENANT_ID = new TenantId(UUID.randomUUID()); + TENANT_ID = TenantId.fromUUID(UUID.randomUUID()); SUPPORTED_ENTITY_TYPES = EnumSet.of( EntityType.TENANT, EntityType.CUSTOMER, @@ -172,7 +172,7 @@ public class EntitiesFieldsAsyncLoaderTest { private void initMocks(EntityType entityType, boolean entityDoesNotExist) { switch (entityType) { case TENANT: - var tenant = Futures.immediateFuture(entityDoesNotExist ? null : new Tenant(new TenantId(RANDOM_UUID))); + var tenant = Futures.immediateFuture(entityDoesNotExist ? null : new Tenant(TenantId.fromUUID(RANDOM_UUID))); when(ctxMock.getDbCallbackExecutor()).thenReturn(DB_EXECUTOR); when(ctxMock.getTenantService()).thenReturn(tenantServiceMock); diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/util/EntitiesRelatedDeviceIdAsyncLoaderTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/util/EntitiesRelatedDeviceIdAsyncLoaderTest.java index 23e98dfc58..6a840a1ae3 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/util/EntitiesRelatedDeviceIdAsyncLoaderTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/util/EntitiesRelatedDeviceIdAsyncLoaderTest.java @@ -48,7 +48,7 @@ import static org.mockito.Mockito.when; public class EntitiesRelatedDeviceIdAsyncLoaderTest { private static final EntityId DUMMY_ORIGINATOR = new DeviceId(UUID.randomUUID()); - private static final TenantId TENANT_ID = new TenantId(UUID.randomUUID()); + private static final TenantId TENANT_ID = TenantId.fromUUID(UUID.randomUUID()); private static final ListeningExecutor DB_EXECUTOR = DirectListeningExecutor.INSTANCE; @Mock private TbContext ctxMock; diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/util/EntitiesRelatedEntityIdAsyncLoaderTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/util/EntitiesRelatedEntityIdAsyncLoaderTest.java index 1131586a07..edeb72ba59 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/util/EntitiesRelatedEntityIdAsyncLoaderTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/util/EntitiesRelatedEntityIdAsyncLoaderTest.java @@ -55,7 +55,7 @@ import static org.thingsboard.common.util.DonAsynchron.withCallback; public class EntitiesRelatedEntityIdAsyncLoaderTest { private static final EntityId ASSET_ORIGINATOR_ID = new AssetId(UUID.randomUUID()); - private static final TenantId TENANT_ID = new TenantId(UUID.randomUUID()); + private static final TenantId TENANT_ID = TenantId.fromUUID(UUID.randomUUID()); private static final ListeningExecutor DB_EXECUTOR = DirectListeningExecutor.INSTANCE; private TbContext ctxMock; From 4927efa07763d4b623410df0dfb2de51fcf8f2bd Mon Sep 17 00:00:00 2001 From: Oleksandra Matviienko Date: Sat, 25 Apr 2026 00:09:18 +0200 Subject: [PATCH 35/91] Technical cleanup of deprecated validator API calls --- .../BaseComponentDescriptorService.java | 2 +- .../server/dao/rule/BaseRuleChainService.java | 28 +++++++++---------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/dao/src/main/java/org/thingsboard/server/dao/component/BaseComponentDescriptorService.java b/dao/src/main/java/org/thingsboard/server/dao/component/BaseComponentDescriptorService.java index 5e9292af5f..4f2228fe57 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/component/BaseComponentDescriptorService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/component/BaseComponentDescriptorService.java @@ -60,7 +60,7 @@ public class BaseComponentDescriptorService implements ComponentDescriptorServic @Override public ComponentDescriptor findById(TenantId tenantId, ComponentDescriptorId componentId) { - Validator.validateId(componentId, "Incorrect component id for search request."); + Validator.validateId(componentId, id -> "Incorrect component id for search request."); return componentDescriptorDao.findById(tenantId, componentId); } diff --git a/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java b/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java index 6b90b6fac6..d78c8cf780 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java @@ -187,7 +187,7 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC @Transactional @Override public RuleChainUpdateResult saveRuleChainMetaData(TenantId tenantId, RuleChainMetaData ruleChainMetaData, Function ruleNodeUpdater, boolean publishSaveEvent) { - Validator.validateId(ruleChainMetaData.getRuleChainId(), "Incorrect rule chain id."); + Validator.validateId(ruleChainMetaData.getRuleChainId(), id -> "Incorrect rule chain id."); RuleChain ruleChain = findRuleChainById(tenantId, ruleChainMetaData.getRuleChainId()); if (ruleChain == null) { return RuleChainUpdateResult.failed(); @@ -340,7 +340,7 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC @Override public RuleChainMetaData loadRuleChainMetaData(TenantId tenantId, RuleChainId ruleChainId) { - Validator.validateId(ruleChainId, "Incorrect rule chain id."); + Validator.validateId(ruleChainId, id -> "Incorrect rule chain id."); RuleChain ruleChain = findRuleChainById(tenantId, ruleChainId); if (ruleChain == null) { return null; @@ -381,37 +381,37 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC @Override public RuleChain findRuleChainById(TenantId tenantId, RuleChainId ruleChainId) { - Validator.validateId(ruleChainId, "Incorrect rule chain id for search request."); + Validator.validateId(ruleChainId, id -> "Incorrect rule chain id for search request."); return ruleChainDao.findById(tenantId, ruleChainId.getId()); } @Override public RuleNode findRuleNodeById(TenantId tenantId, RuleNodeId ruleNodeId) { - Validator.validateId(ruleNodeId, "Incorrect rule node id for search request."); + Validator.validateId(ruleNodeId, id -> "Incorrect rule node id for search request."); return ruleNodeDao.findById(tenantId, ruleNodeId.getId()); } @Override public ListenableFuture findRuleChainByIdAsync(TenantId tenantId, RuleChainId ruleChainId) { - Validator.validateId(ruleChainId, "Incorrect rule chain id for search request."); + Validator.validateId(ruleChainId, id -> "Incorrect rule chain id for search request."); return ruleChainDao.findByIdAsync(tenantId, ruleChainId.getId()); } @Override public ListenableFuture findRuleNodeByIdAsync(TenantId tenantId, RuleNodeId ruleNodeId) { - Validator.validateId(ruleNodeId, "Incorrect rule node id for search request."); + Validator.validateId(ruleNodeId, id -> "Incorrect rule node id for search request."); return ruleNodeDao.findByIdAsync(tenantId, ruleNodeId.getId()); } @Override public RuleChain getRootTenantRuleChain(TenantId tenantId) { - Validator.validateId(tenantId, "Incorrect tenant id for search request."); + Validator.validateId(tenantId, id -> "Incorrect tenant id for search request."); return ruleChainDao.findRootRuleChainByTenantIdAndType(tenantId.getId(), RuleChainType.CORE); } @Override public List getRuleChainNodes(TenantId tenantId, RuleChainId ruleChainId) { - Validator.validateId(ruleChainId, "Incorrect rule chain id for search request."); + Validator.validateId(ruleChainId, id -> "Incorrect rule chain id for search request."); List relations = getRuleChainToNodeRelations(tenantId, ruleChainId); List ruleNodes = new ArrayList<>(); for (EntityRelation relation : relations) { @@ -427,7 +427,7 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC @Override public List getReferencingRuleChainNodes(TenantId tenantId, RuleChainId ruleChainId) { - Validator.validateId(ruleChainId, "Incorrect rule chain id for search request."); + Validator.validateId(ruleChainId, id -> "Incorrect rule chain id for search request."); List relations = getNodeToRuleChainRelations(tenantId, ruleChainId); List ruleNodes = new ArrayList<>(); for (EntityRelation relation : relations) { @@ -441,7 +441,7 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC @Override public List getRuleNodeRelations(TenantId tenantId, RuleNodeId ruleNodeId) { - Validator.validateId(ruleNodeId, "Incorrect rule node id for search request."); + Validator.validateId(ruleNodeId, id -> "Incorrect rule node id for search request."); List relations = relationService.findByFrom(tenantId, ruleNodeId, RelationTypeGroup.RULE_NODE); List validRelations = new ArrayList<>(); for (EntityRelation relation : relations) { @@ -468,7 +468,7 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC @Override public PageData findTenantRuleChainsByType(TenantId tenantId, RuleChainType type, PageLink pageLink) { - Validator.validateId(tenantId, "Incorrect tenant id for search rule chain request."); + Validator.validateId(tenantId, id -> "Incorrect tenant id for search rule chain request."); Validator.validatePageLink(pageLink); return ruleChainDao.findRuleChainsByTenantIdAndType(tenantId.getId(), type, pageLink); } @@ -481,7 +481,7 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC @Override @Transactional public void deleteRuleChainById(TenantId tenantId, RuleChainId ruleChainId) { - Validator.validateId(ruleChainId, "Incorrect rule chain id for delete request."); + Validator.validateId(ruleChainId, id -> "Incorrect rule chain id for delete request."); RuleChain ruleChain = ruleChainDao.findById(tenantId, ruleChainId.getId()); if (ruleChain == null) { return; @@ -520,7 +520,7 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC @Transactional @Override public void deleteRuleChainsByTenantId(TenantId tenantId) { - Validator.validateId(tenantId, "Incorrect tenant id for delete rule chains request."); + Validator.validateId(tenantId, id -> "Incorrect tenant id for delete rule chains request."); tenantRuleChainsRemover.removeEntities(tenantId, tenantId); } @@ -532,7 +532,7 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC @Override public RuleChainData exportTenantRuleChains(TenantId tenantId, PageLink pageLink) { - Validator.validateId(tenantId, "Incorrect tenant id for search rule chain request."); + Validator.validateId(tenantId, id -> "Incorrect tenant id for search rule chain request."); Validator.validatePageLink(pageLink); PageData ruleChainData = ruleChainDao.findRuleChainsByTenantId(tenantId.getId(), pageLink); List ruleChains = ruleChainData.getData(); From 1d2b27450ed5f7d6902b51a6a07cc48a4b97b19c Mon Sep 17 00:00:00 2001 From: Oleksandra Matviienko Date: Tue, 19 May 2026 15:25:43 +0200 Subject: [PATCH 36/91] Technical cleanup of deprecated Curator API in ZooKeeper discovery --- .../queue/discovery/ZkDiscoveryService.java | 48 ++++++++++--------- .../discovery/ZkDiscoveryServiceTest.java | 31 ++++++------ 2 files changed, 41 insertions(+), 38 deletions(-) diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/discovery/ZkDiscoveryService.java b/common/queue/src/main/java/org/thingsboard/server/queue/discovery/ZkDiscoveryService.java index ccc242a1a3..47c2761020 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/discovery/ZkDiscoveryService.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/discovery/ZkDiscoveryService.java @@ -26,9 +26,8 @@ import org.apache.curator.framework.CuratorFramework; import org.apache.curator.framework.CuratorFrameworkFactory; import org.apache.curator.framework.imps.CuratorFrameworkState; import org.apache.curator.framework.recipes.cache.ChildData; -import org.apache.curator.framework.recipes.cache.PathChildrenCache; -import org.apache.curator.framework.recipes.cache.PathChildrenCacheEvent; -import org.apache.curator.framework.recipes.cache.PathChildrenCacheListener; +import org.apache.curator.framework.recipes.cache.CuratorCache; +import org.apache.curator.framework.recipes.cache.CuratorCacheListener; import org.apache.curator.framework.state.ConnectionState; import org.apache.curator.framework.state.ConnectionStateListener; import org.apache.curator.retry.RetryForever; @@ -54,12 +53,12 @@ import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; -import static org.apache.curator.framework.recipes.cache.PathChildrenCacheEvent.Type.CHILD_REMOVED; +import static org.apache.curator.framework.recipes.cache.CuratorCacheAccessor.parentPathFilter; @Service @ConditionalOnProperty(prefix = "zk", value = "enabled", havingValue = "true", matchIfMissing = false) @Slf4j -public class ZkDiscoveryService implements DiscoveryService, PathChildrenCacheListener { +public class ZkDiscoveryService implements DiscoveryService { @Value("${zk.url}") private String zkUrl; @@ -84,7 +83,7 @@ public class ZkDiscoveryService implements DiscoveryService, PathChildrenCacheLi private ScheduledExecutorService zkExecutorService; @Getter private CuratorFramework client; - private PathChildrenCache cache; + private CuratorCache cache; private String nodePath; private String zkNodesDir; @@ -117,7 +116,8 @@ public class ZkDiscoveryService implements DiscoveryService, PathChildrenCacheLi @Override public List getOtherServers() { - return cache.getCurrentData().stream() + return cache.stream() + .filter(parentPathFilter(zkNodesDir)) .filter(cd -> !cd.getPath().equals(nodePath)) .map(cd -> { try { @@ -241,7 +241,8 @@ public class ZkDiscoveryService implements DiscoveryService, PathChildrenCacheLi client = CuratorFrameworkFactory.newClient(zkUrl, zkSessionTimeout, zkConnectionTimeout, new RetryForever(zkRetryInterval)); client.start(); client.blockUntilConnected(); - cache = new PathChildrenCache(client, zkNodesDir, true); + client.createContainers(zkNodesDir); + cache = CuratorCache.builder(client, zkNodesDir).build(); cache.start(); stopped = false; log.info("ZK client connected"); @@ -254,7 +255,7 @@ public class ZkDiscoveryService implements DiscoveryService, PathChildrenCacheLi } private void subscribeToEvents() { - cache.getListenable().addListener(this); + cache.listenable().addListener(this::onCacheEvent); } private void unpublishCurrentServer() { @@ -286,29 +287,32 @@ public class ZkDiscoveryService implements DiscoveryService, PathChildrenCacheLi return "The " + propertyName + " property need to be set!"; } - @Override - public void childEvent(CuratorFramework curatorFramework, PathChildrenCacheEvent pathChildrenCacheEvent) throws Exception { + @SneakyThrows + void onCacheEvent(CuratorCacheListener.Type type, ChildData oldData, ChildData newData) { if (stopped) { - log.debug("Ignoring {}. Service is stopped.", pathChildrenCacheEvent); + log.debug("Ignoring {}. Service is stopped.", type); return; } if (client.getState() != CuratorFrameworkState.STARTED) { - log.debug("Ignoring {}, ZK client is not started, ZK client state [{}]", pathChildrenCacheEvent, client.getState()); + log.debug("Ignoring {}, ZK client is not started, ZK client state [{}]", type, client.getState()); return; } - ChildData data = pathChildrenCacheEvent.getData(); + ChildData data = type == CuratorCacheListener.Type.NODE_DELETED ? oldData : newData; if (data == null) { - log.debug("Ignoring {} due to empty child data", pathChildrenCacheEvent); + log.debug("Ignoring {} due to empty child data", type); return; } else if (data.getData() == null) { - log.debug("Ignoring {} due to empty child's data", pathChildrenCacheEvent); + log.debug("Ignoring {} due to empty child's data", type); + return; + } else if (zkNodesDir.equals(data.getPath())) { + log.debug("Ignoring event about parent node {}", data.getPath()); return; } else if (nodePath != null && nodePath.equals(data.getPath())) { - if (pathChildrenCacheEvent.getType() == CHILD_REMOVED) { + if (type == CuratorCacheListener.Type.NODE_DELETED) { log.info("ZK node for current instance is somehow deleted."); publishCurrentServer(); } - log.debug("Ignoring event about current server {}", pathChildrenCacheEvent); + log.debug("Ignoring event about current server {}", data.getPath()); return; } TransportProtos.ServiceInfo instance; @@ -322,9 +326,9 @@ public class ZkDiscoveryService implements DiscoveryService, PathChildrenCacheLi String serviceId = instance.getServiceId(); ProtocolStringList serviceTypesList = instance.getServiceTypesList(); - log.trace("Processing [{}] event for [{}]", pathChildrenCacheEvent.getType(), serviceId); - switch (pathChildrenCacheEvent.getType()) { - case CHILD_ADDED: + log.trace("Processing [{}] event for [{}]", type, serviceId); + switch (type) { + case NODE_CREATED: ScheduledFuture task = delayedTasks.remove(serviceId); if (task != null) { if (task.cancel(false)) { @@ -341,7 +345,7 @@ public class ZkDiscoveryService implements DiscoveryService, PathChildrenCacheLi recalculatePartitions(); } break; - case CHILD_REMOVED: + case NODE_DELETED: zkExecutorService.submit(() -> applicationEventPublisher.publishEvent(new OtherServiceShutdownEvent(this, serviceId, serviceTypesList))); ScheduledFuture future = zkExecutorService.schedule(() -> { log.debug("[{}] Going to recalculate partitions due to removed node [{}]", diff --git a/common/queue/src/test/java/org/thingsboard/server/queue/discovery/ZkDiscoveryServiceTest.java b/common/queue/src/test/java/org/thingsboard/server/queue/discovery/ZkDiscoveryServiceTest.java index 74bf30dca6..a7be216f66 100644 --- a/common/queue/src/test/java/org/thingsboard/server/queue/discovery/ZkDiscoveryServiceTest.java +++ b/common/queue/src/test/java/org/thingsboard/server/queue/discovery/ZkDiscoveryServiceTest.java @@ -18,8 +18,8 @@ package org.thingsboard.server.queue.discovery; import org.apache.curator.framework.CuratorFramework; import org.apache.curator.framework.imps.CuratorFrameworkState; import org.apache.curator.framework.recipes.cache.ChildData; -import org.apache.curator.framework.recipes.cache.PathChildrenCache; -import org.apache.curator.framework.recipes.cache.PathChildrenCacheEvent; +import org.apache.curator.framework.recipes.cache.CuratorCache; +import org.apache.curator.framework.recipes.cache.CuratorCacheListener; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -36,8 +36,8 @@ import java.util.Collections; import java.util.List; import java.util.concurrent.ScheduledExecutorService; -import static org.apache.curator.framework.recipes.cache.PathChildrenCacheEvent.Type.CHILD_ADDED; -import static org.apache.curator.framework.recipes.cache.PathChildrenCacheEvent.Type.CHILD_REMOVED; +import static org.apache.curator.framework.recipes.cache.CuratorCacheListener.Type.NODE_CREATED; +import static org.apache.curator.framework.recipes.cache.CuratorCacheListener.Type.NODE_DELETED; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.ArgumentMatchers.any; @@ -63,12 +63,10 @@ public class ZkDiscoveryServiceTest { private CuratorFramework client; @Mock - private PathChildrenCache cache; - - @Mock - private CuratorFramework curatorFramework; + private CuratorCache cache; private ZkDiscoveryService zkDiscoveryService; + private List dataList; private static final long RECALCULATE_DELAY = 100L; @@ -89,12 +87,13 @@ public class ZkDiscoveryServiceTest { ReflectionTestUtils.setField(zkDiscoveryService, "zkExecutorService", zkExecutorService); ReflectionTestUtils.setField(zkDiscoveryService, "recalculateDelay", RECALCULATE_DELAY); ReflectionTestUtils.setField(zkDiscoveryService, "zkDir", "/thingsboard"); + ReflectionTestUtils.setField(zkDiscoveryService, "zkNodesDir", "/thingsboard/nodes"); when(serviceInfoProvider.getServiceInfo()).thenReturn(currentInfo); - List dataList = new ArrayList<>(); + dataList = new ArrayList<>(); dataList.add(currentData); - when(cache.getCurrentData()).thenReturn(dataList); + when(cache.stream()).thenAnswer(inv -> dataList.stream()); } @Test @@ -178,14 +177,14 @@ public class ZkDiscoveryServiceTest { verify(partitionService, times(1)).recalculatePartitions(eq(currentInfo), eq(List.of(anotherInfo, childInfo))); } - private void startNode(ChildData data) throws Exception { - cache.getCurrentData().add(data); - zkDiscoveryService.childEvent(curatorFramework, new PathChildrenCacheEvent(CHILD_ADDED, data)); + private void startNode(ChildData data) { + dataList.add(data); + zkDiscoveryService.onCacheEvent(NODE_CREATED, null, data); } - private void stopNode(ChildData data) throws Exception { - cache.getCurrentData().remove(data); - zkDiscoveryService.childEvent(curatorFramework, new PathChildrenCacheEvent(CHILD_REMOVED, data)); + private void stopNode(ChildData data) { + dataList.remove(data); + zkDiscoveryService.onCacheEvent(NODE_DELETED, data, null); } } From 189cb17852ce5f5af95160ff31b84039b70faa2e Mon Sep 17 00:00:00 2001 From: Oleksandra Matviienko Date: Mon, 27 Apr 2026 09:45:21 +0200 Subject: [PATCH 37/91] Updated REST client timeout API to non-deprecated variants --- .../channels/MicrosoftTeamsNotificationChannel.java | 4 ++-- .../main/java/org/thingsboard/monitoring/client/TbClient.java | 4 ++-- .../notification/channels/impl/SlackNotificationChannel.java | 4 ++-- .../service/transport/impl/HttpTransportHealthChecker.java | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/service/notification/channels/MicrosoftTeamsNotificationChannel.java b/application/src/main/java/org/thingsboard/server/service/notification/channels/MicrosoftTeamsNotificationChannel.java index d023ed9b53..459c857d02 100644 --- a/application/src/main/java/org/thingsboard/server/service/notification/channels/MicrosoftTeamsNotificationChannel.java +++ b/application/src/main/java/org/thingsboard/server/service/notification/channels/MicrosoftTeamsNotificationChannel.java @@ -54,8 +54,8 @@ public class MicrosoftTeamsNotificationChannel implements NotificationChannel Date: Mon, 27 Apr 2026 15:08:24 +0200 Subject: [PATCH 38/91] Replaced 5 deprecated APIs with non-deprecated variants --- .../service/security/model/token/JwtTokenFactory.java | 2 +- .../server/service/sync/vc/VersionControlTest.java | 2 +- .../transport/lwm2m/AbstractLwM2MIntegrationTest.java | 2 +- .../server/transport/http/DeviceApiControllerTest.java | 7 ++++--- .../java/org/thingsboard/common/util/JacksonUtil.java | 7 ++----- .../java/org/thingsboard/common/util/TbStopWatch.java | 6 +++--- .../rule/engine/ai/Langchain4jJsonSchemaAdapter.java | 2 +- .../rule/engine/transform/TbCopyKeysNode.java | 5 +---- .../thingsboard/client/tools/i18n/TranslationPruner.java | 9 ++------- 9 files changed, 16 insertions(+), 26 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/service/security/model/token/JwtTokenFactory.java b/application/src/main/java/org/thingsboard/server/service/security/model/token/JwtTokenFactory.java index 051e061857..026673a1ed 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/model/token/JwtTokenFactory.java +++ b/application/src/main/java/org/thingsboard/server/service/security/model/token/JwtTokenFactory.java @@ -23,9 +23,9 @@ import io.jsonwebtoken.JwtBuilder; import io.jsonwebtoken.JwtParser; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.MalformedJwtException; -import io.jsonwebtoken.SignatureException; import io.jsonwebtoken.UnsupportedJwtException; import io.jsonwebtoken.security.Keys; +import io.jsonwebtoken.security.SignatureException; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.context.annotation.Lazy; diff --git a/application/src/test/java/org/thingsboard/server/service/sync/vc/VersionControlTest.java b/application/src/test/java/org/thingsboard/server/service/sync/vc/VersionControlTest.java index 0305d031b8..e182a510c5 100644 --- a/application/src/test/java/org/thingsboard/server/service/sync/vc/VersionControlTest.java +++ b/application/src/test/java/org/thingsboard/server/service/sync/vc/VersionControlTest.java @@ -477,7 +477,7 @@ public class VersionControlTest extends AbstractControllerTest { Dashboard importedOtherDashboard = findDashboard(otherDashboard.getName()); Dashboard importedDashboard = findDashboard(dashboard.getName()); - Map.Entry entityAlias = importedDashboard.getConfiguration().get("entityAliases").fields().next(); + Map.Entry entityAlias = importedDashboard.getConfiguration().get("entityAliases").properties().iterator().next(); assertThat(entityAlias.getKey()).isEqualTo(aliasId); assertThat(entityAlias.getValue().get("id").asText()).isEqualTo(aliasId); diff --git a/application/src/test/java/org/thingsboard/server/transport/lwm2m/AbstractLwM2MIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/lwm2m/AbstractLwM2MIntegrationTest.java index 4d5114425f..258a173451 100644 --- a/application/src/test/java/org/thingsboard/server/transport/lwm2m/AbstractLwM2MIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/lwm2m/AbstractLwM2MIntegrationTest.java @@ -102,10 +102,10 @@ import java.util.concurrent.atomic.AtomicLong; import static org.awaitility.Awaitility.await; import static org.eclipse.leshan.client.object.Security.noSec; +import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.core.IsInstanceOf.instanceOf; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.timeout; diff --git a/common/transport/http/src/test/java/org/thingsboard/server/transport/http/DeviceApiControllerTest.java b/common/transport/http/src/test/java/org/thingsboard/server/transport/http/DeviceApiControllerTest.java index 397ea791c6..fcdb2b04ea 100644 --- a/common/transport/http/src/test/java/org/thingsboard/server/transport/http/DeviceApiControllerTest.java +++ b/common/transport/http/src/test/java/org/thingsboard/server/transport/http/DeviceApiControllerTest.java @@ -18,6 +18,7 @@ package org.thingsboard.server.transport.http; import com.google.gson.JsonParseException; import org.junit.jupiter.api.Test; import org.mockito.Mockito; +import org.springframework.http.HttpInputMessage; import org.springframework.http.ResponseEntity; import org.springframework.http.converter.HttpMessageNotReadableException; import org.springframework.web.context.request.async.DeferredResult; @@ -37,7 +38,7 @@ class DeviceApiControllerTest { }; var callback = new DeviceApiController.DeviceAuthCallback(transportContext, responseWriter, onSuccess); - callback.onError(new HttpMessageNotReadableException("JSON incorrect syntax")); + callback.onError(new HttpMessageNotReadableException("JSON incorrect syntax", (HttpInputMessage) null)); callback.onError(new JsonParseException("Json ; expected")); @@ -51,7 +52,7 @@ class DeviceApiControllerTest { DeferredResult responseWriter = Mockito.mock(DeferredResult.class); var callback = new DeviceApiController.DeviceProvisionCallback(responseWriter); - callback.onError(new HttpMessageNotReadableException("JSON incorrect syntax")); + callback.onError(new HttpMessageNotReadableException("JSON incorrect syntax", (HttpInputMessage) null)); callback.onError(new JsonParseException("Json ; expected")); @@ -71,7 +72,7 @@ class DeviceApiControllerTest { var callback = new DeviceApiController.GetOtaPackageCallback(transportContext, responseWriter, title, version, chunkSize, chunk); - callback.onError(new HttpMessageNotReadableException("JSON incorrect syntax")); + callback.onError(new HttpMessageNotReadableException("JSON incorrect syntax", (HttpInputMessage) null)); callback.onError(new JsonParseException("Json ; expected")); diff --git a/common/util/src/main/java/org/thingsboard/common/util/JacksonUtil.java b/common/util/src/main/java/org/thingsboard/common/util/JacksonUtil.java index cf547cb9d4..ee57d31129 100644 --- a/common/util/src/main/java/org/thingsboard/common/util/JacksonUtil.java +++ b/common/util/src/main/java/org/thingsboard/common/util/JacksonUtil.java @@ -447,10 +447,8 @@ public class JacksonUtil { private static void toFlatMap(JsonNode node, String currentPath, Map map) { if (node.isObject()) { - Iterator> fields = node.fields(); currentPath = currentPath.isEmpty() ? "" : currentPath + "."; - while (fields.hasNext()) { - Map.Entry entry = fields.next(); + for (Map.Entry entry : node.properties()) { toFlatMap(entry.getValue(), currentPath + entry.getKey(), map); } } else if (node.isValueNode()) { @@ -554,8 +552,7 @@ public class JacksonUtil { } } else if (node.isObject()) { ObjectNode on = (ObjectNode) node; - for (Iterator> it = on.fields(); it.hasNext(); ) { - var kv = it.next(); + for (Map.Entry kv : on.properties()) { if (variableName != null) { tasks.add(task.next(kv.getValue(), variableName, kv.getKey())); } else { diff --git a/common/util/src/main/java/org/thingsboard/common/util/TbStopWatch.java b/common/util/src/main/java/org/thingsboard/common/util/TbStopWatch.java index 3a8b94c56e..fab0a72d3d 100644 --- a/common/util/src/main/java/org/thingsboard/common/util/TbStopWatch.java +++ b/common/util/src/main/java/org/thingsboard/common/util/TbStopWatch.java @@ -52,17 +52,17 @@ public class TbStopWatch extends StopWatch { public long stopAndGetTotalTimeNanos(){ stop(); - return getLastTaskTimeNanos(); + return lastTaskInfo().getTimeNanos(); } public long stopAndGetLastTaskTimeMillis(){ stop(); - return getLastTaskTimeMillis(); + return lastTaskInfo().getTimeMillis(); } public long stopAndGetLastTaskTimeNanos(){ stop(); - return getLastTaskTimeNanos(); + return lastTaskInfo().getTimeNanos(); } } diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/ai/Langchain4jJsonSchemaAdapter.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/ai/Langchain4jJsonSchemaAdapter.java index afe4372101..a6d1c60730 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/ai/Langchain4jJsonSchemaAdapter.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/ai/Langchain4jJsonSchemaAdapter.java @@ -94,7 +94,7 @@ final class Langchain4jJsonSchemaAdapter { JsonNode propertiesNode = objectSchema.get("properties"); if (propertiesNode != null) { - propertiesNode.fields().forEachRemaining(entry -> { + propertiesNode.properties().forEach(entry -> { String key = entry.getKey(); JsonNode value = entry.getValue(); builder.addProperty(key, parse(value)); diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transform/TbCopyKeysNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transform/TbCopyKeysNode.java index 08919f37fe..f9e732a53d 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transform/TbCopyKeysNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transform/TbCopyKeysNode.java @@ -29,7 +29,6 @@ import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.msg.TbMsg; import java.util.Arrays; -import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.concurrent.ExecutionException; @@ -87,9 +86,7 @@ public class TbCopyKeysNode extends TbAbstractTransformNodeWithTbMsgSource { msgData = JacksonUtil.toString(msgDataNode); break; case DATA: - Iterator> iteratorNode = dataNode.fields(); - while (iteratorNode.hasNext()) { - Map.Entry entry = iteratorNode.next(); + for (Map.Entry entry : dataNode.properties()) { String msgKey = entry.getKey(); JsonNode msgValue = entry.getValue(); if (matches(msgKey)) { diff --git a/tools/src/main/java/org/thingsboard/client/tools/i18n/TranslationPruner.java b/tools/src/main/java/org/thingsboard/client/tools/i18n/TranslationPruner.java index 4181180521..6467c72114 100644 --- a/tools/src/main/java/org/thingsboard/client/tools/i18n/TranslationPruner.java +++ b/tools/src/main/java/org/thingsboard/client/tools/i18n/TranslationPruner.java @@ -25,7 +25,6 @@ import com.fasterxml.jackson.databind.node.ObjectNode; import java.io.File; import java.io.IOException; import java.util.HashSet; -import java.util.Iterator; import java.util.Map; import java.util.Set; @@ -37,9 +36,7 @@ public class TranslationPruner { */ private static void collectKeys(JsonNode node, String prefix, Set keys) { if (!node.isObject()) return; - Iterator> fields = node.fields(); - while (fields.hasNext()) { - Map.Entry entry = fields.next(); + for (Map.Entry entry : node.properties()) { String key = entry.getKey(); String fullKey = prefix.isEmpty() ? key : prefix + "." + key; keys.add(fullKey); @@ -52,9 +49,7 @@ public class TranslationPruner { */ private static ObjectNode pruneNode(ObjectNode node, Set keys, String prefix, ObjectMapper mapper) { ObjectNode pruned = mapper.createObjectNode(); - Iterator> fields = node.fields(); - while (fields.hasNext()) { - Map.Entry entry = fields.next(); + for (Map.Entry entry : node.properties()) { String key = entry.getKey(); JsonNode value = entry.getValue(); String fullKey = prefix.isEmpty() ? key : prefix + "." + key; From 5858dd0b390b0f3e5f59e2c20f1035ae416f3a8d Mon Sep 17 00:00:00 2001 From: dashevchenko Date: Fri, 6 Mar 2026 15:47:21 +0200 Subject: [PATCH 39/91] added env section description # Conflicts: # application/src/main/resources/thingsboard.yml # msa/js-executor/config/default.yml --- .../src/main/resources/thingsboard.yml | 42 +++++++++++- msa/js-executor/config/default.yml | 64 +++++++++++-------- .../src/main/resources/tb-vc-executor.yml | 9 +++ .../src/main/resources/tb-coap-transport.yml | 16 ++++- .../src/main/resources/tb-http-transport.yml | 11 ++++ .../src/main/resources/tb-lwm2m-transport.yml | 11 ++++ .../src/main/resources/tb-mqtt-transport.yml | 12 ++++ .../src/main/resources/tb-snmp-transport.yml | 12 ++++ 8 files changed, 147 insertions(+), 30 deletions(-) diff --git a/application/src/main/resources/thingsboard.yml b/application/src/main/resources/thingsboard.yml index 2c24caa1f2..812b296790 100644 --- a/application/src/main/resources/thingsboard.yml +++ b/application/src/main/resources/thingsboard.yml @@ -15,6 +15,7 @@ # # Server common parameters +# Configures HTTP/HTTPS bind address, port, SSL, WebSocket, and REST API settings. server: # Server bind-address address: "${HTTP_BIND_ADDRESS:0.0.0.0}" @@ -114,11 +115,13 @@ server: reset_password_per_user: "${RESET_PASSWORD_PER_USER_RATE_LIMIT_CONFIGURATION:5:3600}" # Application info parameters +# Exposes application metadata such as version string injected at build time. app: # Application version version: "@project.version@" # Zookeeper connection parameters +# Controls ZooKeeper-based service discovery and cluster coordination for microservice deployments. zk: # Enable/disable zookeeper discovery service. enabled: "${ZOOKEEPER_ENABLED:false}" @@ -138,6 +141,7 @@ zk: recalculate_delay: "${ZOOKEEPER_RECALCULATE_DELAY_MS:0}" # Cluster parameters +# Controls inter-node communication statistics within a ThingsBoard cluster. cluster: stats: # Enable/Disable the cluster statistics. Calculates the number of messages sent between cluster nodes based on each type @@ -146,11 +150,13 @@ cluster: print_interval_ms: "${TB_CLUSTER_STATS_PRINT_INTERVAL_MS:10000}" # Plugins configuration parameters +# Defines classpath scan packages used to discover and register ThingsBoard extension plugins. plugins: # Comma-separated package list used during classpath scanning for plugins scan_packages: "${PLUGINS_SCAN_PACKAGES:org.thingsboard.server.extensions,org.thingsboard.rule.engine}" # Security parameters +# Configures JWT tokens, user login, device claiming, OAuth2, and CA certificate trust store. security: # JWT Token parameters jwt: # Since 3.4.2 values are persisted in the database during installation or upgrade. On Install, the key will be generated randomly if no custom value set. You can change it later from Web UI under SYS_ADMIN @@ -237,6 +243,7 @@ security: report-only: "${SECURITY_HEADERS_CONTENT_SECURITY_POLICY_REPORT_ONLY:false}" # Mail settings parameters +# Configures mail service OAuth2 token refresh and per-tenant sending rate limits. mail: oauth2: # Interval for checking refresh token expiration in seconds(by default, 1 day). @@ -245,6 +252,7 @@ mail: per_tenant_rate_limits: "${MAIL_PER_TENANT_RATE_LIMITS:}" # Usage statistics parameters +# Controls collection and reporting intervals for API usage stats at system, tenant, and customer levels. usage: stats: report: @@ -266,6 +274,7 @@ usage: report_interval: "${DEVICES_STATS_REPORT_INTERVAL:60}" # UI settings parameters +# Configures dashboard data limits and base URL for UI help assets. ui: # Dashboard parameters dashboard: @@ -277,6 +286,7 @@ ui: base-url: "${UI_HELP_BASE_URL:https://raw.githubusercontent.com/thingsboard/thingsboard-ui-help/release-4.2.2}" # Database telemetry parameters +# Selects the storage backend (SQL, Cassandra, or TimescaleDB) for time-series and latest telemetry data. database: ts_max_intervals: "${DATABASE_TS_MAX_INTERVALS:700}" # Max number of DB queries generated by a single API call to fetch telemetry records ts: @@ -285,6 +295,7 @@ database: type: "${DATABASE_TS_LATEST_TYPE:sql}" # cassandra, sql, or timescale (for hybrid mode, DATABASE_TS_TYPE value should be cassandra, or timescale) # Cassandra driver configuration parameters +# Configures cluster name, keyspace, SSL, credentials, socket, and query settings for the Cassandra driver. cassandra: # Thingsboard cluster name cluster_name: "${CASSANDRA_CLUSTER_NAME:Thingsboard Cluster}" @@ -403,6 +414,7 @@ cassandra: print_tenant_names: "${CASSANDRA_QUERY_TENANT_RATE_LIMITS_PRINT_TENANT_NAMES:false}" # SQL configuration parameters +# Tunes batch sizes, delays, thread counts, TTL, and partitioning for SQL-backed persistence of telemetry, events, and audit logs. sql: # Specify batch size for persisting attribute updates attributes: @@ -504,6 +516,7 @@ sql: query_timeout: "${SQL_RELATIONS_QUERY_TIMEOUT_SEC:20}" # This value has to be reasonably small to prevent the relation query from blocking all other DB calls # Actor system parameters +# Configures thread pools, timeouts, and behavior for the internal actor system processing devices, rules, and RPCs. actors: system: throughput: "${ACTORS_SYSTEM_THROUGHPUT:5}" # Number of messages the actor system will process per actor before switching to processing of messages for the next actor @@ -620,6 +633,8 @@ actors: # Time in seconds to receive calculation result. calculation_timeout: "${ACTORS_CALCULATION_TIMEOUT_SEC:5}" +# Debug settings parameters +# Configures the global default duration for debug mode used by rule chains and calculated fields. debug: settings: # Default duration (in minutes) for debug mode. Min value is 1 minute. Tenant profile settings override this one. @@ -627,6 +642,7 @@ debug: default_duration: "${DEBUG_SETTINGS_DEFAULT_DURATION_MINUTES:15}" # Cache settings parameters +# Configures cache type (Caffeine or Redis), pool size, and per-entity TTL and max-size limits for all caches. cache: # caffeine or redis(7.2 - latest compatible version) type: "${CACHE_TYPE:caffeine}" @@ -780,6 +796,7 @@ cache: spring.data.redis.repositories.enabled: false # Disable this because it is not required. # Redis/Valkey configuration parameters +# Configures standalone, cluster, or sentinel Redis connection, SSL, and connection pool settings used for caching. redis: # standalone or cluster or sentinel connection: @@ -863,6 +880,7 @@ redis: # Update version parameters +# Controls whether the platform periodically checks for new ThingsBoard releases. updates: # Enable/disable checks for the new version enabled: "${UPDATES_ENABLED:true}" @@ -891,6 +909,7 @@ spring.mvc.cors: allow-credentials: "${TB_CORS_ALLOW_CREDENTIALS:true}" # General spring parameters +# Miscellaneous Spring Boot settings for circular references, Freemarker, MVC, multipart, and JPA dialect. spring.main.allow-circular-references: "true" # Spring Boot configuration property that controls whether circular dependencies between beans are allowed. spring.freemarker.checkTemplateLocation: "false" # spring freemarker configuration spring.mvc.async.request-timeout: "${SPRING_MVC_ASYNC_REQUEST_TIMEOUT:30000}" # The default timeout for asynchronous requests in milliseconds @@ -909,6 +928,7 @@ spring.jpa.properties.hibernate.order_by.default_null_ordering: "${SPRING_JPA_PR spring.jpa.properties.hibernate.dialect: "${SPRING_JPA_DIALECT:org.thingsboard.server.dao.ThingsboardPostgreSQLDialect}" # we use custom dialect that contains ilike(arg1, arg2) function (is interpreted to postgres ILIKE operator) # SQL DAO Configuration parameters +# Configures Spring JPA, Hibernate DDL, and HikariCP datasource connections for the primary and events databases. spring: data: jpa: @@ -959,6 +979,7 @@ spring: registerMbeans: "${SPRING_EVENTS_DATASOURCE_HIKARI_REGISTER_MBEANS:false}" # Audit log parameters +# Configures audit logging levels per entity type and optional forwarding to an external sink such as Elasticsearch. audit-log: # Enable/disable audit log functionality. enabled: "${AUDIT_LOG_ENABLED:true}" @@ -1001,6 +1022,7 @@ audit-log: password: "${AUDIT_LOG_SINK_PASSWORD:}" # Password used to access external sink system # Device state parameters +# Configures device inactivity detection, state persistence strategy, and rate limits for state rule nodes. state: # Device inactivity timeout is a global configuration parameter that defines when the device will be marked as "inactive" by the server. # The parameter value is in seconds. A user can overwrite this parameter for an individual device by setting the “inactivityTimeout” server-side attribute (NOTE: expects value in milliseconds). @@ -1031,7 +1053,8 @@ state: # Refill is set to be greedy. Please refer to Bucket4j library documentation for more details. rateLimit: "${DEVICE_STATE_NODE_RATE_LIMIT_CONFIGURATION:1:1,30:60,60:3600}" -# Tbel parameters +# TBEL parameters +# Configures the ThingsBoard Expression Language (TBEL) engine: limits, timeouts, thread pool, and blacklisting. tbel: # Enable/Disable TBEL feature. enabled: "${TBEL_ENABLED:true}" @@ -1060,6 +1083,7 @@ tbel: print_interval_ms: "${TB_TBEL_STATS_PRINT_INTERVAL_MS:10000}" # JS parameters +# Configures the JavaScript execution engine (local Nashorn or remote Node.js): limits, sandboxing, and thread pools. js: # local (Nashorn Engine, deprecated) OR remote JS-Executors (NodeJS) evaluator: "${JS_EVALUATOR:local}" @@ -1107,6 +1131,7 @@ js: print_interval_ms: "${TB_JS_REMOTE_STATS_PRINT_INTERVAL_MS:10000}" # Transport configuration parameters +# Configures session management, rate limits, and protocol-specific settings for HTTP, MQTT, CoAP, LwM2M, and SNMP transports. transport: sessions: # Session inactivity timeout is a global configuration parameter that defines how long the device transport session will be opened after the last message arrives from the device. @@ -1426,6 +1451,7 @@ transport: check_interval_seconds: "${TB_TRANSPORT_SSL_CERTIFICATE_RELOAD_CHECK_INTERVAL_SECONDS:60}" # CoAP server parameters +# Configures the standalone CoAP server bind address, port, DTLS encryption, and credential settings. coap: server: # Enable/disable coap server. @@ -1510,6 +1536,7 @@ coap: dtls_session_report_timeout: "${TB_COAP_X509_DTLS_SESSION_REPORT_TIMEOUT:1800000}" # Device connectivity parameters +# Specifies the hosts, ports, and credentials exposed to the UI for generating device connection check commands. device: connectivity: http: @@ -1563,6 +1590,7 @@ device: image_version: "${DEVICE_CONNECTIVITY_GATEWAY_IMAGE_VERSION:3.8-stable}" # Edges parameters +# Controls Edge instance gRPC communication, event storage, state persistence, and statistics reporting. edges: # Enable/disable Edge instance enabled: "${EDGES_ENABLED:true}" @@ -1626,6 +1654,7 @@ edges: report-interval-millis: "${EDGES_STATS_REPORT_INTERVAL_MS:600000}" # Spring doc common parameters +# Enables or disables the OpenAPI/Swagger documentation endpoint and sets the default media type. springdoc: # If false swagger API docs will be unavailable api-docs.enabled: "${SWAGGER_ENABLED:true}" @@ -1633,6 +1662,7 @@ springdoc: default-produces-media-type: "${SWAGGER_DEFAULT_PRODUCES_MEDIA_TYPE:application/json}" # Swagger common parameters +# Configures Swagger UI metadata: title, description, contact, license, version, and API path patterns. swagger: # General swagger match pattern of swagger UI links api_path: "${SWAGGER_API_PATH:/api/**}" @@ -1662,6 +1692,7 @@ swagger: group_name: "${SWAGGER_GROUP_NAME:thingsboard}" # Queue configuration parameters +# Configures the message queue backend (in-memory or Kafka) and all topic/partition/consumer settings for each service. queue: type: "${TB_QUEUE_TYPE:in-memory}" # in-memory or kafka (Apache Kafka) prefix: "${TB_QUEUE_PREFIX:}" # Global queue prefix. If specified, prefix is added before default topic name: 'prefix.default_topic_name'. Prefix is applied to all topics (and consumer groups for kafka). @@ -2072,12 +2103,14 @@ queue: processing_interval: "${TB_QUEUE_TASKS_STATS_PROCESSING_INTERVAL_MS:1000}" # Event configuration parameters +# Controls limits on debug event content size stored for rule chain and rule node execution. event: debug: # Maximum number of symbols per debug event. The event content will be truncated if needed max-symbols: "${TB_MAX_DEBUG_EVENT_SYMBOLS:4096}" # General service parameters +# Sets the deployment type (monolith or microservice) and assigns tenant profiles to specific Rule Engine instances. service: type: "${TB_SERVICE_TYPE:monolith}" # monolith or tb-core or tb-rule-engine # Unique id for this service (autogenerated if empty) @@ -2091,6 +2124,7 @@ service: executor_thread_pool_size: "${TB_RULE_ENGINE_PUBSUB_EXECUTOR_THREAD_POOL_SIZE:0}" # Metrics parameters +# Enables actuator metrics endpoint and configures system info (CPU, memory) persistence frequency and TTL. metrics: # Enable/disable actuator metrics. enabled: "${METRICS_ENABLED:false}" @@ -2104,6 +2138,7 @@ metrics: ttl: "${METRICS_SYSTEM_INFO_TTL_DAYS:7}" # Version control parameters +# Configures thread pools and Git repository folder for entity version control (export/import) operations. vc: # Pool size for handling export tasks thread_pool_size: "${TB_VC_POOL_SIZE:6}" @@ -2114,6 +2149,7 @@ vc: repositories-folder: "${TB_VC_GIT_REPOSITORIES_FOLDER:${java.io.tmpdir}/repositories}" # Notification system parameters +# Configures thread pool size and deduplication intervals for the notification rule processing engine. notification_system: # Specify thread pool size for Notification System processing notification rules and notification sending. Recommend value <= 10 thread_pool_size: "${TB_NOTIFICATION_SYSTEM_THREAD_POOL_SIZE:10}" @@ -2122,6 +2158,7 @@ notification_system: deduplication_durations: "${TB_NOTIFICATION_RULES_DEDUPLICATION_DURATIONS:NEW_PLATFORM_VERSION:0;RATE_LIMITS:14400000;}" # General management parameters +# Configures Spring Boot Actuator endpoint exposure and health indicator settings. management: endpoints: web: @@ -2134,6 +2171,7 @@ management: enabled: "false" # Mobile application settings for Thingsboard mobile application +# Specifies domain name and store links used for the ThingsBoard Live mobile application QR code and deep links. mobileApp: # Server domain name for Thingsboard Live mobile application domain: "${TB_MOBILE_APP_DOMAIN:demo.thingsboard.io}" @@ -2142,6 +2180,8 @@ mobileApp: # Link to App Store for Thingsboard Live mobile application appStoreLink: "${TB_MOBILE_APP_APP_STORE_LINK:https://apps.apple.com/us/app/thingsboard-live/id1594355695}" +# MQTT client settings +# Configures MQTT client retransmission behavior including max attempts, initial delay, and jitter factor. mqtt: # MQTT client configuration parameters client: diff --git a/msa/js-executor/config/default.yml b/msa/js-executor/config/default.yml index 9a33190069..bde09551ac 100644 --- a/msa/js-executor/config/default.yml +++ b/msa/js-executor/config/default.yml @@ -14,41 +14,51 @@ # limitations under the License. # -queue_type: "kafka" -request_topic: "js_eval.requests" -queue_prefix: "" -http_port: "8888" # /livenessProbe +# Queue configuration +# Defines the messaging queue backend used to dispatch JS evaluation requests to the executor and receive results. +queue_type: "kafka" # Queue type used for JS evaluation requests: kafka or in-memory +request_topic: "js_eval.requests" # Kafka topic name for incoming JS evaluation requests +queue_prefix: "" # Optional prefix applied to all queue/topic names; useful for environment isolation +http_port: "8888" # HTTP port exposing the /livenessProbe health check endpoint +# JavaScript execution configuration +# Controls response polling behavior and output size limits for individual JS script executions. js: - response_poll_interval: "25" - max_result_size: "300000" + response_poll_interval: "25" # Interval in milliseconds to poll for JS execution responses + max_result_size: "300000" # Maximum allowed size in bytes of a JS execution result +# Kafka configuration +# Connection, producer, and topic settings for the Kafka message broker used as the JS evaluation queue. kafka: bootstrap: # Kafka Bootstrap Servers servers: "localhost:9092" - replication_factor: "1" + replication_factor: "1" # Number of replicas for each Kafka topic partition acks: "1" # -1 = all; 0 = no acknowledgments; 1 = only waits for the leader to acknowledge - batch_size: "128" # for producer - linger_ms: "5" # for producer + batch_size: "128" # Maximum number of bytes the producer batches per partition before sending + linger_ms: "5" # Time in milliseconds the producer waits before sending a batch, allowing more messages to accumulate partitions_consumed_concurrently: "1" # (EXPERIMENTAL) increase this value if you are planning to handle more than one partition (scale up, scale down) - this will decrease the latency - requestTimeout: "30000" # The default value in kafkajs is: 30000 - connectionTimeout: "1000" # The default value in kafkajs is: 1000 - compression: "none" # gzip, lz4 or none - topic_properties: "retention.ms:604800000;segment.bytes:52428800;retention.bytes:104857600;partitions:100;min.insync.replicas:1" - use_confluent_cloud: false - client_id: "kafkajs" #inject pod name to easy identify the client using /opt/kafka/bin/kafka-consumer-groups.sh + requestTimeout: "30000" # Time in milliseconds to wait for a response to a Kafka request before timing out + connectionTimeout: "1000" # Time in milliseconds to wait when establishing a connection to a Kafka broker + compression: "none" # Message compression codec for the producer: gzip, lz4 or none + topic_properties: "retention.ms:604800000;segment.bytes:52428800;retention.bytes:104857600;partitions:100;min.insync.replicas:1" # Semicolon-separated Kafka topic configuration properties applied on topic creation + use_confluent_cloud: false # Set to true to enable Confluent Cloud-specific configuration (SSL + SASL) + client_id: "kafkajs" # Kafka client identifier; inject the pod name to easily identify the client via kafka-consumer-groups.sh ssl: - enabled: false + enabled: false # Enable SSL/TLS for Kafka broker connections confluent: sasl: - mechanism: "PLAIN" + mechanism: "PLAIN" # SASL mechanism for Confluent Cloud authentication: PLAIN, SCRAM-SHA-256, or SCRAM-SHA-512 +# Logging configuration +# Controls log verbosity, output directory, and log file naming pattern for the JS executor service. logger: - level: "info" - path: "logs" - filename: "tb-js-executor-%DATE%.log" + level: "info" # Log level: trace, debug, info, warn, or error + path: "logs" # Directory path where log files are written + filename: "tb-js-executor-%DATE%.log" # Log file name pattern; %DATE% is replaced with the current date +# JavaScript execution and monitoring configuration +# Sandboxing, script caching, and observability settings for the JS script runtime. script: # WARNING: setting this to "false" is DANGEROUS BY DESIGN. The non-sandbox # path compiles and runs user-supplied scripts in the host realm via @@ -56,10 +66,10 @@ script: # (file system, environment variables, child_process, etc.) to script # authors. Use "false" only as a performance trade-off in trusted, # non-public clusters where every script author is fully trusted. - use_sandbox: "true" - memory_usage_trace_frequency: "1000" - script_body_trace_frequency: "10000" - stat_print_frequency: "10000" - max_active_scripts: "1000" - slow_query_log_ms: "5.000000" #millis - slow_query_log_body: "false" + use_sandbox: "true" # Run scripts inside an isolated sandbox to prevent access to Node.js internals + memory_usage_trace_frequency: "1000" # Log memory usage every N script executions + script_body_trace_frequency: "10000" # Log the script body every N script executions + stat_print_frequency: "10000" # Print execution statistics every N script executions + max_active_scripts: "1000" # Maximum number of compiled scripts kept in the cache + slow_query_log_ms: "5.000000" # Execution time threshold in milliseconds above which a script is considered slow and logged + slow_query_log_body: "false" # Log the script body when execution time exceeds slow_query_log_ms threshold diff --git a/msa/vc-executor/src/main/resources/tb-vc-executor.yml b/msa/vc-executor/src/main/resources/tb-vc-executor.yml index 9ed3299606..0fe37abf22 100644 --- a/msa/vc-executor/src/main/resources/tb-vc-executor.yml +++ b/msa/vc-executor/src/main/resources/tb-vc-executor.yml @@ -15,11 +15,13 @@ # # Spring common parameters +# Controls Spring Boot startup mode, web environment type, and bean wiring behaviour. spring.main.web-environment: "${WEB_APPLICATION_ENABLE:false}" # If you enabled process metrics you should also enable 'web-environment'. spring.main.web-application-type: "${WEB_APPLICATION_TYPE:none}" # If you enabled process metrics you should set 'web-application-type' to 'servlet' value. spring.main.allow-circular-references: "true" # Spring Boot configuration property that controls whether circular dependencies between beans are allowed. # Server common parameters +# Configures the embedded HTTP server bind address and port used for actuator and metrics endpoints. server: # Server bind address (has no effect if web-environment is disabled). address: "${HTTP_BIND_ADDRESS:0.0.0.0}" @@ -46,6 +48,7 @@ zk: recalculate_delay: "${ZOOKEEPER_RECALCULATE_DELAY_MS:0}" # Queue configuration parameters +# Defines the message queue type (Kafka or in-memory) and all related producer, consumer, and topic settings. queue: type: "${TB_QUEUE_TYPE:kafka}" # kafka (Apache Kafka) prefix: "${TB_QUEUE_PREFIX:}" # Global queue prefix. If specified, prefix is added before default topic name: 'prefix.default_topic_name'. Prefix is applied to all topics (and consumer groups for kafka). @@ -196,6 +199,7 @@ queue: msg-chunk-size: "${TB_QUEUE_VC_MSG_CHUNK_SIZE:250000}" # Version control parameters +# Configures the Git-based version control executor, including thread pools and local repository storage. vc: # Pool size for handling export tasks thread_pool_size: "${TB_VC_POOL_SIZE:6}" @@ -206,6 +210,7 @@ vc: repositories-folder: "${TB_VC_GIT_REPOSITORIES_FOLDER:${java.io.tmpdir}/repositories}" # Usage statistics parameters +# Controls collection and reporting of API usage statistics at system, tenant, and customer levels. usage: stats: report: @@ -219,6 +224,7 @@ usage: pack_size: "${USAGE_STATS_REPORT_PACK_SIZE:1024}" # Metrics parameters +# Enables actuator-based metrics collection and configures histogram/timer percentile exports. metrics: # Enable/disable actuator metrics. enabled: "${METRICS_ENABLED:false}" @@ -227,6 +233,7 @@ metrics: percentiles: "${METRICS_TIMER_PERCENTILES:0.5}" # General management parameters +# Configures Spring Boot Actuator endpoint exposure, including the metrics and info endpoints. management: endpoints: web: @@ -235,12 +242,14 @@ management: include: "${METRICS_ENDPOINTS_EXPOSE:info}" # Service common properties +# Identifies this microservice instance by type and optional unique ID for cluster coordination. service: type: "${TB_SERVICE_TYPE:tb-vc-executor}" # service type # Unique id for this service (autogenerated if empty) id: "${TB_SERVICE_ID:}" # Notification system parameters +# Defines deduplication rules for notification triggers to prevent repeated alerts within a time window. notification_system: rules: # Semicolon-separated deduplication durations (in millis) for trigger types. Format: 'NotificationRuleTriggerType1:123;NotificationRuleTriggerType2:456' diff --git a/transport/coap/src/main/resources/tb-coap-transport.yml b/transport/coap/src/main/resources/tb-coap-transport.yml index 1554b3fc24..f84dc04907 100644 --- a/transport/coap/src/main/resources/tb-coap-transport.yml +++ b/transport/coap/src/main/resources/tb-coap-transport.yml @@ -15,11 +15,13 @@ # # Spring common parameters +# Controls core Spring Boot application settings such as web environment and application type. spring.main.web-environment: "${WEB_APPLICATION_ENABLE:false}" # If you enabled process metrics you should also enable 'web-environment'. spring.main.web-application-type: "${WEB_APPLICATION_TYPE:none}" # If you enabled process metrics you should set 'web-application-type' to 'servlet' value. spring.main.allow-circular-references: "true" # Spring Boot configuration property that controls whether circular dependencies between beans are allowed. # Server common parameters +# Configures the HTTP server bind address and port for the actuator/metrics web endpoint. server: # Server bind address (has no effect if web-environment is disabled). address: "${HTTP_BIND_ADDRESS:0.0.0.0}" @@ -27,6 +29,7 @@ server: port: "${HTTP_BIND_PORT:8083}" # Zookeeper connection parameters. Used for service discovery. +# Defines how this service registers itself and discovers other nodes via Apache ZooKeeper. zk: # Enable/disable zookeeper discovery service. enabled: "${ZOOKEEPER_ENABLED:false}" @@ -46,6 +49,7 @@ zk: recalculate_delay: "${ZOOKEEPER_RECALCULATE_DELAY_MS:0}" # Cache parameters +# Configures the caching backend and per-entity cache settings used by the transport service. cache: # caffeine or redis type: "${CACHE_TYPE:redis}" @@ -55,6 +59,7 @@ cache: maxSize: "${CACHE_SPECS_ENTITY_LIMITS_MAX_SIZE:100000}" # 0 means the cache is disabled # Redis/Valkey configuration parameters +# Defines connection mode, authentication, SSL, and connection pool settings for Redis or Valkey. redis: connection: # standalone or cluster or sentinel @@ -90,9 +95,9 @@ redis: password: "${REDIS_SENTINEL_PASSWORD:}" # if set false will be used pool config build from values of the pool config section useDefaultPoolConfig: "${REDIS_USE_DEFAULT_POOL_CONFIG:true}" - # db index + # Redis logical database index to select after connecting. db: "${REDIS_DB:0}" - # db password + # Password for Redis authentication (leave empty if not required). password: "${REDIS_PASSWORD:}" # Redis username for ACL authentication (Redis 6.0+). Leave empty for legacy password-only auth username: "${REDIS_USERNAME:}" @@ -181,6 +186,7 @@ transport: check_interval_seconds: "${TB_TRANSPORT_SSL_CERTIFICATE_RELOAD_CHECK_INTERVAL_SECONDS:60}" # CoAP server parameters +# Configures the CoAP and CoAP/DTLS server endpoints, including bind addresses, timeouts, and TLS credentials. coap: # CoAP bind-address bind_address: "${COAP_BIND_ADDRESS:0.0.0.0}" @@ -262,6 +268,7 @@ coap: dtls_session_report_timeout: "${TB_COAP_X509_DTLS_SESSION_REPORT_TIMEOUT:1800000}" # Queue configuration parameters +# Defines the message queue backend (Kafka) and all topic, partition, and consumer settings for inter-service communication. queue: type: "${TB_QUEUE_TYPE:kafka}" # kafka (Apache Kafka) prefix: "${TB_QUEUE_PREFIX:}" # Global queue prefix. If specified, prefix is added before default topic name: 'prefix.default_topic_name'. Prefix is applied to all topics (and consumer groups for kafka). @@ -415,12 +422,14 @@ queue: poll_interval: "${TB_QUEUE_TRANSPORT_NOTIFICATIONS_POLL_INTERVAL_MS:25}" # Service common properties +# Identifies this service instance within the ThingsBoard cluster. service: type: "${TB_SERVICE_TYPE:tb-transport}" # service type # Unique id for this service (autogenerated if empty) id: "${TB_SERVICE_ID:}" # Usage statistics parameters +# Controls reporting of API usage metrics at system, tenant, and customer levels. usage: stats: report: @@ -434,11 +443,13 @@ usage: pack_size: "${USAGE_STATS_REPORT_PACK_SIZE:1024}" # Metrics parameters +# Enables Micrometer/Actuator metrics collection and configures the exposed management endpoints. metrics: # Enable/disable actuator metrics. enabled: "${METRICS_ENABLED:false}" # General management parameters +# Configures Spring Boot Actuator endpoint exposure for health checks and metrics scraping. management: endpoints: web: @@ -447,6 +458,7 @@ management: include: "${METRICS_ENDPOINTS_EXPOSE:info}" # Notification system parameters +# Configures deduplication rules for platform notifications to prevent repeated alerts within a time window. notification_system: rules: # Semicolon-separated deduplication durations (in millis) for trigger types. Format: 'NotificationRuleTriggerType1:123;NotificationRuleTriggerType2:456' diff --git a/transport/http/src/main/resources/tb-http-transport.yml b/transport/http/src/main/resources/tb-http-transport.yml index c878887a01..44adcf6e14 100644 --- a/transport/http/src/main/resources/tb-http-transport.yml +++ b/transport/http/src/main/resources/tb-http-transport.yml @@ -15,6 +15,7 @@ # # Server common properties +# Configures the HTTP server bind address, port, SSL/TLS settings, and HTTP/2 support. server: # Server bind address address: "${HTTP_BIND_ADDRESS:0.0.0.0}" @@ -54,6 +55,7 @@ server: enabled: "${HTTP2_ENABLED:true}" # Spring common parameters +# Controls Spring Boot framework-level settings such as circular references and multipart upload limits. spring.main.allow-circular-references: "true" # Spring Boot configuration property that controls whether circular dependencies between beans are allowed. spring.servlet.multipart.max-file-size: "${SPRING_SERVLET_MULTIPART_MAX_FILE_SIZE:50MB}" # Total file size cannot exceed 50MB when configuring file uploads spring.servlet.multipart.max-request-size: "${SPRING_SERVLET_MULTIPART_MAX_REQUEST_SIZE:50MB}" # Total request size for a multipart/form-data cannot exceed 50MB @@ -78,6 +80,7 @@ zk: recalculate_delay: "${ZOOKEEPER_RECALCULATE_DELAY_MS:0}" # Cache parameters +# Defines the cache backend type and per-entity cache configuration such as TTL and maximum size. cache: # caffeine or redis type: "${CACHE_TYPE:redis}" @@ -87,6 +90,7 @@ cache: maxSize: "${CACHE_SPECS_ENTITY_LIMITS_MAX_SIZE:100000}" # 0 means the cache is disabled # Redis/Valkey configuration parameters +# Configures connection mode (standalone, cluster, sentinel), credentials, SSL, and connection pool settings. redis: # standalone or cluster or sentinel connection: @@ -166,6 +170,7 @@ redis: blockWhenExhausted: "${REDIS_POOL_CONFIG_BLOCK_WHEN_EXHAUSTED:true}" # HTTP server parameters +# Configures HTTP transport request timeouts, payload limits, session management, JSON processing, logging, and statistics. transport: http: # HTTP request processing timeout in milliseconds @@ -212,6 +217,7 @@ transport: check_interval_seconds: "${TB_TRANSPORT_SSL_CERTIFICATE_RELOAD_CHECK_INTERVAL_SECONDS:60}" # Queue configuration parameters +# Configures the messaging queue backend (Kafka), topic definitions, partitioning, and per-service consumer settings. queue: type: "${TB_QUEUE_TYPE:kafka}" # kafka (Apache Kafka) prefix: "${TB_QUEUE_PREFIX:}" # Global queue prefix. If specified, prefix is added before default topic name: 'prefix.default_topic_name'. Prefix is applied to all topics (and consumer groups for kafka) . @@ -364,12 +370,14 @@ queue: poll_interval: "${TB_QUEUE_TRANSPORT_NOTIFICATIONS_POLL_INTERVAL_MS:25}" # General service parameters +# Defines the service type and unique identifier used for service discovery and cluster coordination. service: type: "${TB_SERVICE_TYPE:tb-transport}" # type of service # Unique id for this service (autogenerated if empty) id: "${TB_SERVICE_ID:}" # Usage statistics parameters +# Controls reporting of API usage statistics at the system, tenant, and optional customer level. usage: stats: report: @@ -383,11 +391,13 @@ usage: pack_size: "${USAGE_STATS_REPORT_PACK_SIZE:1024}" # Metrics parameters +# Enables or disables actuator metrics collection and exposure for monitoring integrations such as Prometheus. metrics: # Enable/disable actuator metrics. enabled: "${METRICS_ENABLED:false}" # General management parameters +# Configures Spring Boot Actuator management endpoints, including which endpoints are exposed over HTTP. management: endpoints: web: @@ -396,6 +406,7 @@ management: include: "${METRICS_ENDPOINTS_EXPOSE:info}" # Notification system parameters +# Configures notification rules, including deduplication windows to prevent repeated alerts for the same trigger. notification_system: rules: # Semicolon-separated deduplication durations (in millis) for trigger types. Format: 'NotificationRuleTriggerType1:123;NotificationRuleTriggerType2:456' diff --git a/transport/lwm2m/src/main/resources/tb-lwm2m-transport.yml b/transport/lwm2m/src/main/resources/tb-lwm2m-transport.yml index 51b1ad0a2b..cb554fb705 100644 --- a/transport/lwm2m/src/main/resources/tb-lwm2m-transport.yml +++ b/transport/lwm2m/src/main/resources/tb-lwm2m-transport.yml @@ -15,11 +15,13 @@ # # Spring common parameters +# Controls Spring Boot web environment and application type settings used for optional metrics exposure. spring.main.web-environment: "${WEB_APPLICATION_ENABLE:false}" # If you enabled process metrics you should also enable 'web-environment'. spring.main.web-application-type: "${WEB_APPLICATION_TYPE:none}" # If you enabled process metrics you should set 'web-application-type' to 'servlet' value. spring.main.allow-circular-references: "true" # Spring Boot configuration property that controls whether circular dependencies between beans are allowed. # Server common parameters +# HTTP server bind address and port, effective only when the web environment is enabled. server: # Server bind address (has no effect if web-environment is disabled). address: "${HTTP_BIND_ADDRESS:0.0.0.0}" @@ -46,6 +48,7 @@ zk: recalculate_delay: "${ZOOKEEPER_RECALCULATE_DELAY_MS:0}" # Cache parameters +# Configures the cache backend type and per-entity cache specifications such as TTL and maximum size. cache: # caffeine or redis type: "${CACHE_TYPE:redis}" @@ -55,6 +58,7 @@ cache: maxSize: "${CACHE_SPECS_ENTITY_LIMITS_MAX_SIZE:100000}" # 0 means the cache is disabled # Redis/Valkey configuration parameters +# Connection, authentication, SSL, and connection pool settings for the Redis or Valkey cache backend. redis: connection: # standalone or cluster or sentinel @@ -133,6 +137,7 @@ redis: blockWhenExhausted: "${REDIS_POOL_CONFIG_BLOCK_WHEN_EXHAUSTED:true}" # LWM2M server parameters +# Session, JSON processing, RPC, logging, and LwM2M-specific transport settings including DTLS, bootstrap, and OTA. transport: sessions: # Session inactivity timeout is a global configuration parameter that defines how long the device transport session will be opened after the last message arrives from the device. @@ -312,6 +317,7 @@ transport: check_interval_seconds: "${TB_TRANSPORT_SSL_CERTIFICATE_RELOAD_CHECK_INTERVAL_SECONDS:60}" # Queue configuration properties +# Defines the message queue backend (Kafka) and per-topic settings for transport, core, rule-engine, and JS evaluation. queue: type: "${TB_QUEUE_TYPE:kafka}" # kafka (Apache Kafka) prefix: "${TB_QUEUE_PREFIX:}" # Global queue prefix. If specified, prefix is added before default topic name: 'prefix.default_topic_name'. Prefix is applied to all topics (and consumer groups for kafka). @@ -465,12 +471,14 @@ queue: poll_interval: "${TB_QUEUE_TRANSPORT_NOTIFICATIONS_POLL_INTERVAL_MS:25}" # Service common parameters +# Identifies the service type and its unique instance ID within a ThingsBoard cluster. service: type: "${TB_SERVICE_TYPE:tb-transport}" # service type # Unique id for this service (autogenerated if empty) id: "${TB_SERVICE_ID:}" # Usage statistics parameters +# Controls reporting of API usage statistics at system, tenant, and optionally customer level. usage: stats: report: @@ -484,11 +492,13 @@ usage: pack_size: "${USAGE_STATS_REPORT_PACK_SIZE:1024}" # Metrics parameters +# Enables or disables Actuator-based metrics collection (e.g., Prometheus endpoint). metrics: # Enable/disable actuator metrics. enabled: "${METRICS_ENABLED:false}" # General management parameters +# Configures Spring Boot Actuator endpoint exposure, e.g. for Prometheus metrics scraping. management: endpoints: web: @@ -497,6 +507,7 @@ management: include: "${METRICS_ENDPOINTS_EXPOSE:info}" # Notification system parameters +# Configures deduplication rules for notification triggers to prevent repeated alerts within a time window. notification_system: rules: # Semicolon-separated deduplication durations (in millis) for trigger types. Format: 'NotificationRuleTriggerType1:123;NotificationRuleTriggerType2:456' diff --git a/transport/mqtt/src/main/resources/tb-mqtt-transport.yml b/transport/mqtt/src/main/resources/tb-mqtt-transport.yml index dfe35db29c..fcdc9000bd 100644 --- a/transport/mqtt/src/main/resources/tb-mqtt-transport.yml +++ b/transport/mqtt/src/main/resources/tb-mqtt-transport.yml @@ -15,11 +15,13 @@ # # Spring common parameters +# Controls Spring Boot application type, web environment, and bean dependency settings. spring.main.web-environment: "${WEB_APPLICATION_ENABLE:false}" # If you enabled process metrics you should also enable 'web-environment'. spring.main.web-application-type: "${WEB_APPLICATION_TYPE:none}" # If you enabled process metrics you should set 'web-application-type' to 'servlet' value. spring.main.allow-circular-references: "true" # Spring Boot configuration property that controls whether circular dependencies between beans are allowed. # Server common parameters +# Configures the embedded HTTP server bind address and port for actuator/metrics endpoints. server: # Server bind address (has no effect if web-environment is disabled). address: "${HTTP_BIND_ADDRESS:0.0.0.0}" @@ -27,6 +29,7 @@ server: port: "${HTTP_BIND_PORT:8083}" # Zookeeper connection parameters. Used for service discovery. +# Defines connection, session, retry settings and the node directory path for Zookeeper-based cluster coordination. zk: # Enable/disable zookeeper discovery service. enabled: "${ZOOKEEPER_ENABLED:false}" @@ -46,6 +49,7 @@ zk: recalculate_delay: "${ZOOKEEPER_RECALCULATE_DELAY_MS:0}" # Cache parameters +# Configures the cache backend type (Caffeine or Redis) and per-cache TTL and size limits. cache: # caffeine or redis type: "${CACHE_TYPE:redis}" @@ -55,6 +59,7 @@ cache: maxSize: "${CACHE_SPECS_ENTITY_LIMITS_MAX_SIZE:100000}" # 0 means the cache is disabled # Redis/Valkey configuration parameters +# Covers connection mode (standalone, cluster, sentinel), SSL, credentials, and connection pool tuning. redis: # standalone or cluster or sentinel connection: @@ -134,6 +139,7 @@ redis: blockWhenExhausted: "${REDIS_POOL_CONFIG_BLOCK_WHEN_EXHAUSTED:true}" # MQTT server parameters +# Configures the MQTT transport layer including bind address/port, SSL, Netty tuning, session management, rate limits, and message processing options. transport: mqtt: # MQTT bind-address @@ -245,6 +251,7 @@ transport: check_interval_seconds: "${TB_TRANSPORT_SSL_CERTIFICATE_RELOAD_CHECK_INTERVAL_SECONDS:60}" # Queue configuration parameters +# Defines the messaging queue backend (Kafka), topic names, partitioning, and poll/processing settings for all platform microservices. queue: type: "${TB_QUEUE_TYPE:kafka}" # kafka (Apache Kafka) prefix: "${TB_QUEUE_PREFIX:}" # Global queue prefix. If specified, prefix is added before default topic name: 'prefix.default_topic_name'. Prefix is applied to all topics (and consumer groups for kafka). @@ -398,12 +405,14 @@ queue: poll_interval: "${TB_QUEUE_TRANSPORT_NOTIFICATIONS_POLL_INTERVAL_MS:25}" # Service common properties +# Identifies this service instance within the cluster by type and optional unique ID. service: type: "${TB_SERVICE_TYPE:tb-transport}" # service type # Unique id for this service (autogenerated if empty) id: "${TB_SERVICE_ID:}" # Usage statistics parameters +# Controls reporting of API usage statistics at system, tenant, and customer levels with configurable intervals. usage: stats: report: @@ -417,11 +426,13 @@ usage: pack_size: "${USAGE_STATS_REPORT_PACK_SIZE:1024}" # Metrics parameters +# Enables or disables Micrometer actuator metrics collection for monitoring this service. metrics: # Enable/disable actuator metrics. enabled: "${METRICS_ENABLED:false}" # General management parameters +# Configures Spring Boot Actuator endpoint exposure, including which endpoints are accessible over HTTP. management: endpoints: web: @@ -430,6 +441,7 @@ management: include: "${METRICS_ENDPOINTS_EXPOSE:info}" # Notification system parameters +# Configures deduplication rules for notification triggers to prevent repeated alerts within a defined time window. notification_system: rules: # Semicolon-separated deduplication durations (in millis) for trigger types. Format: 'NotificationRuleTriggerType1:123;NotificationRuleTriggerType2:456' diff --git a/transport/snmp/src/main/resources/tb-snmp-transport.yml b/transport/snmp/src/main/resources/tb-snmp-transport.yml index d021030a91..4df225778e 100644 --- a/transport/snmp/src/main/resources/tb-snmp-transport.yml +++ b/transport/snmp/src/main/resources/tb-snmp-transport.yml @@ -15,11 +15,13 @@ # # Spring common parameters +# Controls Spring Boot application type and web environment settings for the SNMP transport service. spring.main.web-environment: "${WEB_APPLICATION_ENABLE:false}" # If you enabled process metrics you should also enable 'web-environment'. spring.main.web-application-type: "${WEB_APPLICATION_TYPE:none}" # If you enabled process metrics you should set 'web-application-type' to 'servlet' value. spring.main.allow-circular-references: "true" # Spring Boot configuration property that controls whether circular dependencies between beans are allowed. # Server common parameters +# Configures the embedded HTTP server bind address and port (used when web environment is enabled). server: # Server bind address (has no effect if web-environment is disabled). address: "${HTTP_BIND_ADDRESS:0.0.0.0}" @@ -27,6 +29,7 @@ server: port: "${HTTP_BIND_PORT:8083}" # Zookeeper connection parameters. Used for service discovery. +# Defines ZooKeeper connectivity, timeouts, and cluster node registration settings for service coordination. zk: # Enable/disable zookeeper discovery service. enabled: "${ZOOKEEPER_ENABLED:false}" @@ -46,6 +49,7 @@ zk: recalculate_delay: "${ZOOKEEPER_RECALCULATE_DELAY_MS:0}" # Cache parameters +# Specifies the caching backend (Caffeine or Redis) and per-entity cache TTL and size limits. cache: # caffeine or redis type: "${CACHE_TYPE:redis}" @@ -55,6 +59,7 @@ cache: maxSize: "${CACHE_SPECS_ENTITY_LIMITS_MAX_SIZE:100000}" # 0 means the cache is disabled # Redis/Valkey configuration parameters +# Covers standalone, cluster, and sentinel Redis connection modes, SSL, authentication, and connection pool tuning. redis: connection: # standalone or cluster or sentinel @@ -133,6 +138,7 @@ redis: blockWhenExhausted: "${REDIS_POOL_CONFIG_BLOCK_WHEN_EXHAUSTED:true}" # Snmp server parameters +# Configures the SNMP transport protocol, bind port, PDU limits, session management, JSON handling, logging, and statistics. transport: snmp: # Enable/disable SNMP transport protocol @@ -184,6 +190,7 @@ transport: print-interval-ms: "${TB_TRANSPORT_STATS_PRINT_INTERVAL_MS:60000}" # Queue configuration parameters +# Defines the message queue backend (Kafka) and topic/consumer settings for transport, core, rule-engine, and JS evaluation. queue: type: "${TB_QUEUE_TYPE:kafka}" # kafka (Apache Kafka) prefix: "${TB_QUEUE_PREFIX:}" # Global queue prefix. If specified, prefix is added before default topic name: 'prefix.default_topic_name'. Prefix is applied to all topics (and consumer groups for kafka). @@ -344,12 +351,14 @@ queue: poll_interval: "${TB_QUEUE_TRANSPORT_NOTIFICATIONS_POLL_INTERVAL_MS:25}" # Service common parameters +# Identifies this service instance by type and unique ID within a ThingsBoard cluster. service: type: "${TB_SERVICE_TYPE:tb-transport}" # service type # Unique id for this service (autogenerated if empty) id: "${TB_SERVICE_ID:}" # Usage statistics parameters +# Controls collection and reporting intervals for API usage statistics at system, tenant, and customer levels. usage: stats: report: @@ -363,11 +372,13 @@ usage: pack_size: "${USAGE_STATS_REPORT_PACK_SIZE:1024}" # Metrics parameters +# Enables or disables actuator-based metrics collection (e.g., Prometheus) for the SNMP transport service. metrics: # Enable/disable actuator metrics. enabled: "${METRICS_ENABLED:false}" # General management parameters +# Configures Spring Boot Actuator endpoint exposure, including which management endpoints are accessible over HTTP. management: endpoints: web: @@ -376,6 +387,7 @@ management: include: "${METRICS_ENDPOINTS_EXPOSE:info}" # Notification system parameters +# Defines deduplication rules for notification triggers to prevent duplicate alerts within configured time windows. notification_system: rules: # Semicolon-separated deduplication durations (in millis) for trigger types. Format: 'NotificationRuleTriggerType1:123;NotificationRuleTriggerType2:456' From e5c7ecc82acb96e0355d01cb5eb3ddc952bd8889 Mon Sep 17 00:00:00 2001 From: dashevchenko Date: Mon, 1 Jun 2026 17:31:27 +0300 Subject: [PATCH 40/91] added section description --- .../src/main/resources/thingsboard.yml | 92 +++++++++---------- edqs/src/main/resources/edqs.yml | 14 +-- msa/js-executor/config/default.yml | 4 +- .../src/main/resources/tb-vc-executor.yml | 15 +-- .../src/main/resources/tb-coap-transport.yml | 30 +++--- .../src/main/resources/tb-http-transport.yml | 19 ++-- .../src/main/resources/tb-lwm2m-transport.yml | 37 ++++---- .../src/main/resources/tb-mqtt-transport.yml | 20 ++-- .../src/main/resources/tb-snmp-transport.yml | 18 ++-- 9 files changed, 126 insertions(+), 123 deletions(-) diff --git a/application/src/main/resources/thingsboard.yml b/application/src/main/resources/thingsboard.yml index 812b296790..6540888ba1 100644 --- a/application/src/main/resources/thingsboard.yml +++ b/application/src/main/resources/thingsboard.yml @@ -120,20 +120,20 @@ app: # Application version version: "@project.version@" -# Zookeeper connection parameters +# ZooKeeper connection parameters # Controls ZooKeeper-based service discovery and cluster coordination for microservice deployments. zk: - # Enable/disable zookeeper discovery service. + # Enable/disable ZooKeeper discovery service. enabled: "${ZOOKEEPER_ENABLED:false}" - # Zookeeper connect string + # ZooKeeper connect string url: "${ZOOKEEPER_URL:localhost:2181}" - # Zookeeper retry interval in milliseconds + # ZooKeeper retry interval in milliseconds retry_interval_ms: "${ZOOKEEPER_RETRY_INTERVAL_MS:3000}" - # Zookeeper connection timeout in milliseconds + # ZooKeeper connection timeout in milliseconds connection_timeout_ms: "${ZOOKEEPER_CONNECTION_TIMEOUT_MS:3000}" - # Zookeeper session timeout in milliseconds + # ZooKeeper session timeout in milliseconds session_timeout_ms: "${ZOOKEEPER_SESSION_TIMEOUT_MS:3000}" - # Name of the directory in zookeeper 'filesystem' + # Name of the directory in ZooKeeper 'filesystem' zk_dir: "${ZOOKEEPER_NODES_DIR:/thingsboard}" # The recalculate_delay property is recommended in a microservices architecture setup for rule-engine services. # This property provides a pause to ensure that when a rule-engine service is restarted, other nodes don't immediately attempt to recalculate their partitions. @@ -141,7 +141,7 @@ zk: recalculate_delay: "${ZOOKEEPER_RECALCULATE_DELAY_MS:0}" # Cluster parameters -# Controls inter-node communication statistics within a ThingsBoard cluster. +# Controls cluster statistics — tracks the number of messages exchanged between cluster nodes. cluster: stats: # Enable/Disable the cluster statistics. Calculates the number of messages sent between cluster nodes based on each type @@ -610,14 +610,14 @@ actors: response_timeout_ms: "${ACTORS_RPC_RESPONSE_TIMEOUT_MS:30000}" # Close transport session if RPC delivery timed out. If enabled, RPC will be reverted to the queued state. # Note: - # - For MQTT transport: - # - QoS level 0: This feature does not apply, as no acknowledgment is expected, and therefore no timeout is triggered. - # - QoS level 1: This feature applies, as an acknowledgment is expected. - # - QoS level 2: Unsupported. - # - For CoAP transport: - # - Confirmable requests: This feature applies, as delivery confirmation is expected. - # - Non-confirmable requests: This feature does not apply, as no delivery acknowledgment is expected. - # - For HTTP and SNPM transports: RPC is considered delivered immediately, and there is no logic to await acknowledgment. + #
  • For MQTT transport: + #
    • QoS level 0: This feature does not apply, as no acknowledgment is expected, and therefore no timeout is triggered.
    • + #
    • QoS level 1: This feature applies, as an acknowledgment is expected.
    • + #
    • QoS level 2: Unsupported.
  • + #
  • For CoAP transport: + #
    • Confirmable requests: This feature applies, as delivery confirmation is expected.
    • + #
    • Non-confirmable requests: This feature does not apply, as no delivery acknowledgment is expected.
  • + #
  • For HTTP and SNPM transports: RPC is considered delivered immediately, and there is no logic to await acknowledgment.
close_session_on_rpc_delivery_timeout: "${ACTORS_RPC_CLOSE_SESSION_ON_RPC_DELIVERY_TIMEOUT:false}" statistics: # Enable/disable actor statistics @@ -825,17 +825,17 @@ redis: # if set false will be used pool config build from values of the pool config section useDefaultPoolConfig: "${REDIS_USE_DEFAULT_POOL_CONFIG:true}" sentinel: - # name of the master node + # Name of the master node master: "${REDIS_MASTER:}" - # comma-separated list of "host:port" pairs of sentinels + # Comma-separated list of "host:port" pairs of sentinels sentinels: "${REDIS_SENTINELS:}" - # password to authenticate with sentinel + # Password to authenticate with sentinel password: "${REDIS_SENTINEL_PASSWORD:}" - # if set false will be used pool config build from values of the pool config section + # If set false will be used pool config build from values of the pool config section useDefaultPoolConfig: "${REDIS_USE_DEFAULT_POOL_CONFIG:true}" - # db index + # Redis logical database index to select after connecting. db: "${REDIS_DB:0}" - # db password + # Password for Redis authentication (leave empty if not required). password: "${REDIS_PASSWORD:}" # Redis username for ACL authentication (Redis 6.0+). Leave empty for legacy password-only auth username: "${REDIS_USERNAME:}" @@ -1148,10 +1148,10 @@ transport: activity: # This property specifies the strategy for reporting activity events within each reporting period. # The accepted values are 'FIRST', 'LAST', 'FIRST_AND_LAST' and 'ALL'. - # - 'FIRST': Only the first activity event in each reporting period is reported. - # - 'LAST': Only the last activity event in the reporting period is reported. - # - 'FIRST_AND_LAST': Both the first and last activity events in the reporting period are reported. - # - 'ALL': All activity events in the reporting period are reported. + #
  • 'FIRST': Only the first activity event in each reporting period is reported.
  • + #
  • 'LAST': Only the last activity event in the reporting period is reported.
  • + #
  • 'FIRST_AND_LAST': Both the first and last activity events in the reporting period are reported.
  • + #
  • 'ALL': All activity events in the reporting period are reported.
reporting_strategy: "${TB_TRANSPORT_ACTIVITY_REPORTING_STRATEGY:LAST}" json: # Cast String data types to Numeric if possible when processing Telemetry/Attributes JSON @@ -1269,16 +1269,16 @@ transport: dtls: # RFC7925_RETRANSMISSION_TIMEOUT_IN_MILLISECONDS = 9000 retransmission_timeout: "${LWM2M_DTLS_RETRANSMISSION_TIMEOUT_MS:9000}" - # CoAP DTLS connection ID length for LWM2M. RFC 9146, Connection Identifier for DTLS 1.2 - # Default: off + # LWM2M DTLS connection ID length for LWM2M. RFC 9146, Connection Identifier for DTLS 1.2 + # Default: off.
# Control usage of DTLS connection ID length (CID). - # - 'off' to deactivate it. - # - 'on' to activate Connection ID support (same as CID 0 or more 0). - # - A positive value defines generated CID size in bytes. - # - A value of 0 means we accept using CID but will not generate one for foreign peer (enables support but not for incoming traffic). - # - A value between 0 and <= 4: SingleNodeConnectionIdGenerator is used - # - A value that are > 4: MultiNodeConnectionIdGenerator is used - connection_id_length: "${LWM2M_DTLS_CONNECTION_ID_LENGTH:}" + #
  • 'off' to deactivate it.
  • + #
  • 'on' to activate Connection ID support (same as CID 0 or more 0).
  • + #
  • A positive value defines generated CID size in bytes.
  • + #
  • A value of 0 means we accept using CID but will not generate one for foreign peer (enables support but not for incoming traffic).
  • + #
  • A value between 0 and <= 4: SingleNodeConnectionIdGenerator is used
  • + #
  • A value that are > 4: MultiNodeConnectionIdGenerator is used
+ connection_id_length: "${LWM2M_DTLS_CONNECTION_ID_LENGTH:8}" server: # LwM2M Server ID id: "${LWM2M_SERVER_ID:123}" @@ -1470,15 +1470,15 @@ coap: # CoAP DTLS bind port bind_port: "${COAP_DTLS_BIND_PORT:5684}" # CoAP DTLS connection ID length. RFC 9146, Connection Identifier for DTLS 1.2 - # Default: off + # Default: off.
# Control usage of DTLS connection ID length (CID). - # - 'off' to deactivate it. - # - 'on' to activate Connection ID support (same as CID 0 or more 0). - # - A positive value defines generated CID size in bytes. - # - A value of 0 means we accept using CID but will not generate one for foreign peer (enables support but not for incoming traffic). - # - A value between 0 and <= 4: SingleNodeConnectionIdGenerator is used - # - A value that are > 4: MultiNodeConnectionIdGenerator is used - connection_id_length: "${COAP_DTLS_CONNECTION_ID_LENGTH:}" + #
  • 'off' to deactivate it.
  • + #
  • 'on' to activate Connection ID support (same as CID 0 or more 0).
  • + #
  • A positive value defines generated CID size in bytes.
  • + #
  • A value of 0 means we accept using CID but will not generate one for foreign peer (enables support but not for incoming traffic).
  • + #
  • A value between 0 and <= 4: SingleNodeConnectionIdGenerator is used
  • + #
  • A value that are > 4: MultiNodeConnectionIdGenerator is used
+ connection_id_length: "${COAP_DTLS_CONNECTION_ID_LENGTH:8}" # Specify the MTU (Maximum Transmission Unit). # Should be used if LAN MTU is not used, e.g. if IP tunnels are used or if the client uses a smaller value than the LAN MTU. # Default = 1024 @@ -1494,13 +1494,13 @@ coap: # In order to negotiate smaller maximum fragment lengths, # clients MAY include an extension of type "max_fragment_length" in the (extended) client hello. # The "extension_data" field of this extension SHALL contain: - # enum { + #
 enum {
     #   2^9(1) == 512,
     #   2^10(2) == 1024,
     #   2^11(3) == 2048,
     #   2^12(4) == 4096,
     #   (255)
-    # } MaxFragmentLength;
+    # } MaxFragmentLength; 
# TLS already requires clients and servers to support fragmentation of handshake messages. max_fragment_length: "${COAP_DTLS_MAX_FRAGMENT_LENGTH:1024}" # Server DTLS credentials @@ -2180,7 +2180,7 @@ mobileApp: # Link to App Store for Thingsboard Live mobile application appStoreLink: "${TB_MOBILE_APP_APP_STORE_LINK:https://apps.apple.com/us/app/thingsboard-live/id1594355695}" -# MQTT client settings +# MQTT client parameters # Configures MQTT client retransmission behavior including max attempts, initial delay, and jitter factor. mqtt: # MQTT client configuration parameters diff --git a/edqs/src/main/resources/edqs.yml b/edqs/src/main/resources/edqs.yml index 4dc404e2ca..cad0fcaccc 100644 --- a/edqs/src/main/resources/edqs.yml +++ b/edqs/src/main/resources/edqs.yml @@ -25,19 +25,19 @@ app: # Application version version: "@project.version@" -# Zookeeper connection parameters +# ZooKeeper connection parameters zk: - # Enable/disable zookeeper discovery service. + # Enable/disable ZooKeeper discovery service. enabled: "${ZOOKEEPER_ENABLED:true}" - # Zookeeper connect string + # ZooKeeper connect string url: "${ZOOKEEPER_URL:localhost:2181}" - # Zookeeper retry interval in milliseconds + # ZooKeeper retry interval in milliseconds retry_interval_ms: "${ZOOKEEPER_RETRY_INTERVAL_MS:3000}" - # Zookeeper connection timeout in milliseconds + # ZooKeeper connection timeout in milliseconds connection_timeout_ms: "${ZOOKEEPER_CONNECTION_TIMEOUT_MS:3000}" - # Zookeeper session timeout in milliseconds + # ZooKeeper session timeout in milliseconds session_timeout_ms: "${ZOOKEEPER_SESSION_TIMEOUT_MS:3000}" - # Name of the directory in zookeeper 'filesystem' + # Name of the directory in ZooKeeper 'filesystem' zk_dir: "${ZOOKEEPER_NODES_DIR:/thingsboard}" # The recalculate_delay property is recommended in a microservices architecture setup for rule-engine services. # This property provides a pause to ensure that when a rule-engine service is restarted, other nodes don't immediately attempt to recalculate their partitions. diff --git a/msa/js-executor/config/default.yml b/msa/js-executor/config/default.yml index bde09551ac..feae8edc4a 100644 --- a/msa/js-executor/config/default.yml +++ b/msa/js-executor/config/default.yml @@ -35,7 +35,7 @@ kafka: servers: "localhost:9092" replication_factor: "1" # Number of replicas for each Kafka topic partition acks: "1" # -1 = all; 0 = no acknowledgments; 1 = only waits for the leader to acknowledge - batch_size: "128" # Maximum number of bytes the producer batches per partition before sending + batch_size: "128" # Maximum number of messages to accumulate before triggering a batch send linger_ms: "5" # Time in milliseconds the producer waits before sending a batch, allowing more messages to accumulate partitions_consumed_concurrently: "1" # (EXPERIMENTAL) increase this value if you are planning to handle more than one partition (scale up, scale down) - this will decrease the latency requestTimeout: "30000" # Time in milliseconds to wait for a response to a Kafka request before timing out @@ -66,7 +66,7 @@ script: # (file system, environment variables, child_process, etc.) to script # authors. Use "false" only as a performance trade-off in trusted, # non-public clusters where every script author is fully trusted. - use_sandbox: "true" # Run scripts inside an isolated sandbox to prevent access to Node.js internals + use_sandbox: "true" memory_usage_trace_frequency: "1000" # Log memory usage every N script executions script_body_trace_frequency: "10000" # Log the script body every N script executions stat_print_frequency: "10000" # Print execution statistics every N script executions diff --git a/msa/vc-executor/src/main/resources/tb-vc-executor.yml b/msa/vc-executor/src/main/resources/tb-vc-executor.yml index 0fe37abf22..e540182c06 100644 --- a/msa/vc-executor/src/main/resources/tb-vc-executor.yml +++ b/msa/vc-executor/src/main/resources/tb-vc-executor.yml @@ -28,19 +28,20 @@ server: # Server bind port (has no effect if web-environment is disabled). port: "${HTTP_BIND_PORT:8086}" -# Zookeeper connection parameters. Used for service discovery. +# ZooKeeper connection parameters +# Controls ZooKeeper-based service discovery and cluster coordination for microservice deployments. zk: - # Enable/disable zookeeper discovery service. + # Enable/disable ZooKeeper discovery service. enabled: "${ZOOKEEPER_ENABLED:true}" - # Zookeeper connect string + # ZooKeeper connect string url: "${ZOOKEEPER_URL:localhost:2181}" - # Zookeeper retry interval in milliseconds + # ZooKeeper retry interval in milliseconds retry_interval_ms: "${ZOOKEEPER_RETRY_INTERVAL_MS:3000}" - # Zookeeper connection timeout in milliseconds + # ZooKeeper connection timeout in milliseconds connection_timeout_ms: "${ZOOKEEPER_CONNECTION_TIMEOUT_MS:3000}" - # Zookeeper session timeout in milliseconds + # ZooKeeper session timeout in milliseconds session_timeout_ms: "${ZOOKEEPER_SESSION_TIMEOUT_MS:3000}" - # Name of the directory in zookeeper 'filesystem' + # Name of the directory in ZooKeeper 'filesystem' zk_dir: "${ZOOKEEPER_NODES_DIR:/thingsboard}" # The recalculate_delay property is recommended in a microservices architecture setup for rule-engine services. # This property provides a pause to ensure that when a rule-engine service is restarted, other nodes don't immediately attempt to recalculate their partitions. diff --git a/transport/coap/src/main/resources/tb-coap-transport.yml b/transport/coap/src/main/resources/tb-coap-transport.yml index f84dc04907..dd5b77ab00 100644 --- a/transport/coap/src/main/resources/tb-coap-transport.yml +++ b/transport/coap/src/main/resources/tb-coap-transport.yml @@ -28,20 +28,20 @@ server: # Server bind port (has no effect if web-environment is disabled). port: "${HTTP_BIND_PORT:8083}" -# Zookeeper connection parameters. Used for service discovery. +# ZooKeeper connection parameters. Used for service discovery. # Defines how this service registers itself and discovers other nodes via Apache ZooKeeper. zk: - # Enable/disable zookeeper discovery service. + # Enable/disable ZooKeeper discovery service. enabled: "${ZOOKEEPER_ENABLED:false}" - # Zookeeper connect string + # ZooKeeper connect string url: "${ZOOKEEPER_URL:localhost:2181}" - # Zookeeper retry interval in milliseconds + # ZooKeeper retry interval in milliseconds retry_interval_ms: "${ZOOKEEPER_RETRY_INTERVAL_MS:3000}" - # Zookeeper connection timeout in milliseconds + # ZooKeeper connection timeout in milliseconds connection_timeout_ms: "${ZOOKEEPER_CONNECTION_TIMEOUT_MS:3000}" - # Zookeeper session timeout in milliseconds + # ZooKeeper session timeout in milliseconds session_timeout_ms: "${ZOOKEEPER_SESSION_TIMEOUT_MS:3000}" - # Name of the directory in zookeeper 'filesystem' + # Name of the directory in ZooKeeper 'filesystem' zk_dir: "${ZOOKEEPER_NODES_DIR:/thingsboard}" # The recalculate_delay property is recommended in a microservices architecture setup for rule-engine services. # This property provides a pause to ensure that when a rule-engine service is restarted, other nodes don't immediately attempt to recalculate their partitions. @@ -202,15 +202,15 @@ coap: # CoAP DTLS bind port bind_port: "${COAP_DTLS_BIND_PORT:5684}" # CoAP DTLS connection ID length. RFC 9146, Connection Identifier for DTLS 1.2 - # Default: off + # Default: off.
# Control usage of DTLS connection ID length (CID). - # - 'off' to deactivate it. - # - 'on' to activate Connection ID support (same as CID 0 or more 0). - # - A positive value defines generated CID size in bytes. - # - A value of 0 means we accept using CID but will not generate one for foreign peer (enables support but not for incoming traffic). - # - A value between 0 and <= 4: SingleNodeConnectionIdGenerator is used - # - A value that are > 4: MultiNodeConnectionIdGenerator is used - connection_id_length: "${COAP_DTLS_CONNECTION_ID_LENGTH:}" + #
  • 'off' to deactivate it.
  • + #
  • 'on' to activate Connection ID support (same as CID 0 or more 0).
  • + #
  • A positive value defines generated CID size in bytes.
  • + #
  • A value of 0 means we accept using CID but will not generate one for foreign peer (enables support but not for incoming traffic).
  • + #
  • A value between 0 and <= 4: SingleNodeConnectionIdGenerator is used
  • + #
  • A value that are > 4: MultiNodeConnectionIdGenerator is used
+ connection_id_length: "${COAP_DTLS_CONNECTION_ID_LENGTH:8}" # Specify the MTU (Maximum Transmission Unit). # Should be used if LAN MTU is not used, e.g. if IP tunnels are used or if the client uses a smaller value than the LAN MTU. # Default = 1024 diff --git a/transport/http/src/main/resources/tb-http-transport.yml b/transport/http/src/main/resources/tb-http-transport.yml index 44adcf6e14..9fe5b50db8 100644 --- a/transport/http/src/main/resources/tb-http-transport.yml +++ b/transport/http/src/main/resources/tb-http-transport.yml @@ -60,19 +60,20 @@ spring.main.allow-circular-references: "true" # Spring Boot configuration proper spring.servlet.multipart.max-file-size: "${SPRING_SERVLET_MULTIPART_MAX_FILE_SIZE:50MB}" # Total file size cannot exceed 50MB when configuring file uploads spring.servlet.multipart.max-request-size: "${SPRING_SERVLET_MULTIPART_MAX_REQUEST_SIZE:50MB}" # Total request size for a multipart/form-data cannot exceed 50MB -# Zookeeper connection parameters. Used for service discovery. +# ZooKeeper connection parameters +# Controls ZooKeeper-based service discovery and cluster coordination for microservice deployments. zk: - # Enable/disable zookeeper discovery service. + # Enable/disable ZooKeeper discovery service. enabled: "${ZOOKEEPER_ENABLED:false}" - # Zookeeper connect string + # ZooKeeper connect string url: "${ZOOKEEPER_URL:localhost:2181}" - # Zookeeper retry interval in milliseconds + # ZooKeeper retry interval in milliseconds retry_interval_ms: "${ZOOKEEPER_RETRY_INTERVAL_MS:3000}" - # Zookeeper connection timeout in milliseconds + # ZooKeeper connection timeout in milliseconds connection_timeout_ms: "${ZOOKEEPER_CONNECTION_TIMEOUT_MS:3000}" - # Zookeeper session timeout in milliseconds + # ZooKeeper session timeout in milliseconds session_timeout_ms: "${ZOOKEEPER_SESSION_TIMEOUT_MS:3000}" - # Name of the directory in zookeeper 'filesystem' + # Name of the directory in ZooKeeper 'filesystem' zk_dir: "${ZOOKEEPER_NODES_DIR:/thingsboard}" # The recalculate_delay property is recommended in a microservices architecture setup for rule-engine services. # This property provides a pause to ensure that when a rule-engine service is restarted, other nodes don't immediately attempt to recalculate their partitions. @@ -127,9 +128,9 @@ redis: password: "${REDIS_SENTINEL_PASSWORD:}" # if set false will be used pool config build from values of the pool config section useDefaultPoolConfig: "${REDIS_USE_DEFAULT_POOL_CONFIG:true}" - # db index + # Redis logical database index to select after connecting. db: "${REDIS_DB:0}" - # db password + # Password for Redis authentication (leave empty if not required). password: "${REDIS_PASSWORD:}" # Redis username for ACL authentication (Redis 6.0+). Leave empty for legacy password-only auth username: "${REDIS_USERNAME:}" diff --git a/transport/lwm2m/src/main/resources/tb-lwm2m-transport.yml b/transport/lwm2m/src/main/resources/tb-lwm2m-transport.yml index cb554fb705..161e1a39fb 100644 --- a/transport/lwm2m/src/main/resources/tb-lwm2m-transport.yml +++ b/transport/lwm2m/src/main/resources/tb-lwm2m-transport.yml @@ -28,19 +28,20 @@ server: # Server bind port (has no effect if web-environment is disabled). port: "${HTTP_BIND_PORT:8083}" -# Zookeeper connection parameters. Used for service discovery. +# ZooKeeper connection parameters +# Controls ZooKeeper-based service discovery and cluster coordination for microservice deployments. zk: - # Enable/disable zookeeper discovery service. + # Enable/disable ZooKeeper discovery service. enabled: "${ZOOKEEPER_ENABLED:false}" - # Zookeeper connect string + # ZooKeeper connect string url: "${ZOOKEEPER_URL:localhost:2181}" - # Zookeeper retry interval in milliseconds + # ZooKeeper retry interval in milliseconds retry_interval_ms: "${ZOOKEEPER_RETRY_INTERVAL_MS:3000}" - # Zookeeper connection timeout in milliseconds + # ZooKeeper connection timeout in milliseconds connection_timeout_ms: "${ZOOKEEPER_CONNECTION_TIMEOUT_MS:3000}" - # Zookeeper session timeout in milliseconds + # ZooKeeper session timeout in milliseconds session_timeout_ms: "${ZOOKEEPER_SESSION_TIMEOUT_MS:3000}" - # Name of the directory in zookeeper 'filesystem' + # Name of the directory in ZooKeeper 'filesystem' zk_dir: "${ZOOKEEPER_NODES_DIR:/thingsboard}" # The recalculate_delay property is recommended in a microservices architecture setup for rule-engine services. # This property provides a pause to ensure that when a rule-engine service is restarted, other nodes don't immediately attempt to recalculate their partitions. @@ -94,9 +95,9 @@ redis: password: "${REDIS_SENTINEL_PASSWORD:}" # if set false will be used pool config build from values of the pool config section useDefaultPoolConfig: "${REDIS_USE_DEFAULT_POOL_CONFIG:true}" - # db index + # Redis logical database index to select after connecting. db: "${REDIS_DB:0}" - # db password + # Password for Redis authentication (leave empty if not required). password: "${REDIS_PASSWORD:}" # Redis username for ACL authentication (Redis 6.0+). Leave empty for legacy password-only auth username: "${REDIS_USERNAME:}" @@ -171,16 +172,16 @@ transport: dtls: # RFC7925_RETRANSMISSION_TIMEOUT_IN_MILLISECONDS = 9000 retransmission_timeout: "${LWM2M_DTLS_RETRANSMISSION_TIMEOUT_MS:9000}" - # CoAP DTLS connection ID length for LWM2M. RFC 9146, Connection Identifier for DTLS 1.2 - # Default: off + # LWM2M DTLS connection ID length for LWM2M. RFC 9146, Connection Identifier for DTLS 1.2 + # Default: off.
# Control usage of DTLS connection ID length (CID). - # - 'off' to deactivate it. - # - 'on' to activate Connection ID support (same as CID 0 or more 0). - # - A positive value defines generated CID size in bytes. - # - A value of 0 means we accept using CID but will not generate one for foreign peer (enables support but not for incoming traffic). - # - A value between 0 and <= 4: SingleNodeConnectionIdGenerator is used - # - A value that are > 4: MultiNodeConnectionIdGenerator is used - connection_id_length: "${LWM2M_DTLS_CONNECTION_ID_LENGTH:}" + #
  • 'off' to deactivate it.
  • + #
  • 'on' to activate Connection ID support (same as CID 0 or more 0).
  • + #
  • A positive value defines generated CID size in bytes.
  • + #
  • A value of 0 means we accept using CID but will not generate one for foreign peer (enables support but not for incoming traffic).
  • + #
  • A value between 0 and <= 4: SingleNodeConnectionIdGenerator is used
  • + #
  • A value that are > 4: MultiNodeConnectionIdGenerator is used
+ connection_id_length: "${LWM2M_DTLS_CONNECTION_ID_LENGTH:8}" server: # LwM2M Server ID id: "${LWM2M_SERVER_ID:123}" diff --git a/transport/mqtt/src/main/resources/tb-mqtt-transport.yml b/transport/mqtt/src/main/resources/tb-mqtt-transport.yml index fcdc9000bd..35bb11d039 100644 --- a/transport/mqtt/src/main/resources/tb-mqtt-transport.yml +++ b/transport/mqtt/src/main/resources/tb-mqtt-transport.yml @@ -28,20 +28,20 @@ server: # Server bind port (has no effect if web-environment is disabled). port: "${HTTP_BIND_PORT:8083}" -# Zookeeper connection parameters. Used for service discovery. -# Defines connection, session, retry settings and the node directory path for Zookeeper-based cluster coordination. +# ZooKeeper connection parameters. Used for service discovery. +# Defines connection, session, retry settings and the node directory path for ZooKeeper-based cluster coordination. zk: - # Enable/disable zookeeper discovery service. + # Enable/disable ZooKeeper discovery service. enabled: "${ZOOKEEPER_ENABLED:false}" - # Zookeeper connect string + # ZooKeeper connect string url: "${ZOOKEEPER_URL:localhost:2181}" - # Zookeeper retry interval in milliseconds + # ZooKeeper retry interval in milliseconds retry_interval_ms: "${ZOOKEEPER_RETRY_INTERVAL_MS:3000}" - # Zookeeper connection timeout in milliseconds + # ZooKeeper connection timeout in milliseconds connection_timeout_ms: "${ZOOKEEPER_CONNECTION_TIMEOUT_MS:3000}" - # Zookeeper session timeout in milliseconds + # ZooKeeper session timeout in milliseconds session_timeout_ms: "${ZOOKEEPER_SESSION_TIMEOUT_MS:3000}" - # Name of the directory in zookeeper 'filesystem' + # Name of the directory in ZooKeeper 'filesystem' zk_dir: "${ZOOKEEPER_NODES_DIR:/thingsboard}" # The recalculate_delay property is recommended in a microservices architecture setup for rule-engine services. # This property provides a pause to ensure that when a rule-engine service is restarted, other nodes don't immediately attempt to recalculate their partitions. @@ -96,9 +96,9 @@ redis: password: "${REDIS_SENTINEL_PASSWORD:}" # if set false will be used pool config build from values of the pool config section useDefaultPoolConfig: "${REDIS_USE_DEFAULT_POOL_CONFIG:true}" - # db index + # Redis logical database index to select after connecting. db: "${REDIS_DB:0}" - # db password + # Password for Redis authentication (leave empty if not required). password: "${REDIS_PASSWORD:}" # Redis username for ACL authentication (Redis 6.0+). Leave empty for legacy password-only auth username: "${REDIS_USERNAME:}" diff --git a/transport/snmp/src/main/resources/tb-snmp-transport.yml b/transport/snmp/src/main/resources/tb-snmp-transport.yml index 4df225778e..3816068d35 100644 --- a/transport/snmp/src/main/resources/tb-snmp-transport.yml +++ b/transport/snmp/src/main/resources/tb-snmp-transport.yml @@ -28,20 +28,20 @@ server: # Server bind port (has no effect if web-environment is disabled). port: "${HTTP_BIND_PORT:8083}" -# Zookeeper connection parameters. Used for service discovery. +# ZooKeeper connection parameters. Used for service discovery. # Defines ZooKeeper connectivity, timeouts, and cluster node registration settings for service coordination. zk: - # Enable/disable zookeeper discovery service. + # Enable/disable ZooKeeper discovery service. enabled: "${ZOOKEEPER_ENABLED:false}" - # Zookeeper connect string + # ZooKeeper connect string url: "${ZOOKEEPER_URL:localhost:2181}" - # Zookeeper retry interval in milliseconds + # ZooKeeper retry interval in milliseconds retry_interval_ms: "${ZOOKEEPER_RETRY_INTERVAL_MS:3000}" - # Zookeeper connection timeout in milliseconds + # ZooKeeper connection timeout in milliseconds connection_timeout_ms: "${ZOOKEEPER_CONNECTION_TIMEOUT_MS:3000}" - # Zookeeper session timeout in milliseconds + # ZooKeeper session timeout in milliseconds session_timeout_ms: "${ZOOKEEPER_SESSION_TIMEOUT_MS:3000}" - # Name of the directory in zookeeper 'filesystem' + # Name of the directory in ZooKeeper 'filesystem' zk_dir: "${ZOOKEEPER_NODES_DIR:/thingsboard}" # The recalculate_delay property is recommended in a microservices architecture setup for rule-engine services. # This property provides a pause to ensure that when a rule-engine service is restarted, other nodes don't immediately attempt to recalculate their partitions. @@ -95,9 +95,9 @@ redis: password: "${REDIS_SENTINEL_PASSWORD:}" # if set false will be used pool config build from values of the pool config section useDefaultPoolConfig: "${REDIS_USE_DEFAULT_POOL_CONFIG:true}" - # db index + # Redis logical database index to select after connecting. db: "${REDIS_DB:0}" - # db password + # Password for Redis authentication (leave empty if not required). password: "${REDIS_PASSWORD:}" # Redis username for ACL authentication (Redis 6.0+). Leave empty for legacy password-only auth username: "${REDIS_USERNAME:}" From eae065aa74408d4ecec7f61125e64090a113b760 Mon Sep 17 00:00:00 2001 From: Nikita Mazurenko Date: Fri, 26 Jun 2026 09:58:20 +0300 Subject: [PATCH 41/91] Fix dashboard config changes not syncing to edge by removing transient from Dashboard.configuration --- .../rpc/processor/BaseEdgeProcessorTest.java | 236 ++++++++++++++++++ .../server/common/data/Dashboard.java | 2 +- 2 files changed, 237 insertions(+), 1 deletion(-) create mode 100644 application/src/test/java/org/thingsboard/server/service/edge/rpc/processor/BaseEdgeProcessorTest.java diff --git a/application/src/test/java/org/thingsboard/server/service/edge/rpc/processor/BaseEdgeProcessorTest.java b/application/src/test/java/org/thingsboard/server/service/edge/rpc/processor/BaseEdgeProcessorTest.java new file mode 100644 index 0000000000..55f975b1ea --- /dev/null +++ b/application/src/test/java/org/thingsboard/server/service/edge/rpc/processor/BaseEdgeProcessorTest.java @@ -0,0 +1,236 @@ +/** + * ThingsBoard, Inc. ("COMPANY") CONFIDENTIAL + * + * Copyright © 2016-2026 ThingsBoard, Inc. All Rights Reserved. + * + * NOTICE: All information contained herein is, and remains + * the property of ThingsBoard, Inc. and its suppliers, + * if any. The intellectual and technical concepts contained + * herein are proprietary to ThingsBoard, Inc. + * and its suppliers and may be covered by U.S. and Foreign Patents, + * patents in process, and are protected by trade secret or copyright law. + * + * Dissemination of this information or reproduction of this material is strictly forbidden + * unless prior written permission is obtained from COMPANY. + * + * Access to the source code contained herein is hereby forbidden to anyone except current COMPANY employees, + * managers or contractors who have executed Confidentiality and Non-disclosure agreements + * explicitly covering such access. + * + * The copyright notice above does not evidence any actual or intended publication + * or disclosure of this source code, which includes + * information that is confidential and/or proprietary, and is a trade secret, of COMPANY. + * ANY REPRODUCTION, MODIFICATION, DISTRIBUTION, PUBLIC PERFORMANCE, + * OR PUBLIC DISPLAY OF OR THROUGH USE OF THIS SOURCE CODE WITHOUT + * THE EXPRESS WRITTEN CONSENT OF COMPANY IS STRICTLY PROHIBITED, + * AND IN VIOLATION OF APPLICABLE LAWS AND INTERNATIONAL TREATIES. + * THE RECEIPT OR POSSESSION OF THIS SOURCE CODE AND/OR RELATED INFORMATION + * DOES NOT CONVEY OR IMPLY ANY RIGHTS TO REPRODUCE, DISCLOSE OR DISTRIBUTE ITS CONTENTS, + * OR TO MANUFACTURE, USE, OR SELL ANYTHING THAT IT MAY DESCRIBE, IN WHOLE OR IN PART. + */ +package org.thingsboard.server.service.edge.rpc.processor; + +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListenableFuture; +import org.junit.jupiter.api.Test; +import org.thingsboard.common.util.JacksonUtil; +import org.thingsboard.server.common.data.Dashboard; +import org.thingsboard.server.common.data.Device; +import org.thingsboard.server.common.data.EntityView; +import org.thingsboard.server.common.data.User; +import org.thingsboard.server.common.data.asset.Asset; +import org.thingsboard.server.common.data.device.data.DeviceData; +import org.thingsboard.server.common.data.device.data.DefaultDeviceConfiguration; +import org.thingsboard.server.common.data.device.data.DefaultDeviceTransportConfiguration; +import org.thingsboard.server.common.data.id.AssetId; +import org.thingsboard.server.common.data.id.DashboardId; +import org.thingsboard.server.common.data.id.DeviceId; +import org.thingsboard.server.common.data.id.EntityViewId; +import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.common.data.id.UserId; +import org.thingsboard.server.gen.transport.TransportProtos; + +import java.util.UUID; + +import static org.assertj.core.api.Assertions.assertThat; + +public class BaseEdgeProcessorTest { + + private final BaseEdgeProcessor processor = new BaseEdgeProcessor() { + @Override + public ListenableFuture processEntityNotification(TenantId tenantId, TransportProtos.EdgeNotificationMsgProto msg) { + return Futures.immediateFuture(null); + } + }; + + @Test + public void dashboardSaveRequiredWhenConfigurationChanges() { + DashboardId dashboardId = new DashboardId(UUID.randomUUID()); + Dashboard current = new Dashboard(dashboardId); + current.setTitle("Dashboard"); + current.setConfiguration(JacksonUtil.toJsonNode("{\"widgets\":{\"w1\":{\"type\":\"timeseries\"}}}")); + + Dashboard updated = new Dashboard(current); + updated.setConfiguration(JacksonUtil.toJsonNode("{\"widgets\":{\"w1\":{\"type\":\"latest\"}}}")); + + assertThat(processor.isSaveRequired(current, updated)).isTrue(); + } + + @Test + public void dashboardSaveNotRequiredWhenOnlyVersionChanges() { + DashboardId dashboardId = new DashboardId(UUID.randomUUID()); + Dashboard current = new Dashboard(dashboardId); + current.setTitle("Dashboard"); + current.setConfiguration(JacksonUtil.toJsonNode("{\"widgets\":{\"w1\":{\"type\":\"timeseries\"}}}")); + current.setVersion(1L); + + Dashboard updated = new Dashboard(current); + updated.setVersion(2L); + + assertThat(processor.isSaveRequired(current, updated)).isFalse(); + } + + @Test + public void dashboardSaveNotRequiredWhenIdentical() { + DashboardId dashboardId = new DashboardId(UUID.randomUUID()); + Dashboard current = new Dashboard(dashboardId); + current.setTitle("Dashboard"); + current.setConfiguration(JacksonUtil.toJsonNode("{\"widgets\":{\"w1\":{\"type\":\"timeseries\"}}}")); + + Dashboard updated = new Dashboard(current); + + assertThat(processor.isSaveRequired(current, updated)).isFalse(); + } + + @Test + public void deviceSaveRequiredWhenDeviceDataChanges() { + DeviceId deviceId = new DeviceId(UUID.randomUUID()); + Device current = new Device(deviceId); + current.setName("Device"); + current.setDeviceData(deviceDataWithTransport()); + + Device updated = new Device(current); + DeviceData withoutTransport = new DeviceData(); + withoutTransport.setConfiguration(new DefaultDeviceConfiguration()); + updated.setDeviceData(withoutTransport); + + assertThat(processor.isSaveRequired(current, updated)).isTrue(); + } + + @Test + public void deviceSaveRequiredWhenAdditionalInfoChanges() { + DeviceId deviceId = new DeviceId(UUID.randomUUID()); + Device current = new Device(deviceId); + current.setName("Device"); + current.setAdditionalInfo(JacksonUtil.toJsonNode("{\"description\":\"old\"}")); + + Device updated = new Device(current); + updated.setAdditionalInfo(JacksonUtil.toJsonNode("{\"description\":\"new\"}")); + + assertThat(processor.isSaveRequired(current, updated)).isTrue(); + } + + @Test + public void deviceSaveNotRequiredWhenOnlyVersionChanges() { + DeviceId deviceId = new DeviceId(UUID.randomUUID()); + Device current = new Device(deviceId); + current.setName("Device"); + current.setDeviceData(deviceDataWithTransport()); + current.setAdditionalInfo(JacksonUtil.toJsonNode("{\"description\":\"same\"}")); + current.setVersion(1L); + + Device updated = new Device(current); + updated.setVersion(2L); + + assertThat(processor.isSaveRequired(current, updated)).isFalse(); + } + + @Test + public void assetSaveRequiredWhenAdditionalInfoChanges() { + AssetId assetId = new AssetId(UUID.randomUUID()); + Asset current = new Asset(assetId); + current.setName("Asset"); + current.setAdditionalInfo(JacksonUtil.toJsonNode("{\"description\":\"old\"}")); + + Asset updated = new Asset(current); + updated.setAdditionalInfo(JacksonUtil.toJsonNode("{\"description\":\"new\"}")); + + assertThat(processor.isSaveRequired(current, updated)).isTrue(); + } + + @Test + public void assetSaveNotRequiredWhenOnlyVersionChanges() { + AssetId assetId = new AssetId(UUID.randomUUID()); + Asset current = new Asset(assetId); + current.setName("Asset"); + current.setAdditionalInfo(JacksonUtil.toJsonNode("{\"description\":\"same\"}")); + current.setVersion(1L); + + Asset updated = new Asset(current); + updated.setVersion(2L); + + assertThat(processor.isSaveRequired(current, updated)).isFalse(); + } + + @Test + public void entityViewSaveRequiredWhenAdditionalInfoChanges() { + EntityViewId entityViewId = new EntityViewId(UUID.randomUUID()); + EntityView current = new EntityView(entityViewId); + current.setName("EntityView"); + current.setAdditionalInfo(JacksonUtil.toJsonNode("{\"description\":\"old\"}")); + + EntityView updated = new EntityView(current); + updated.setAdditionalInfo(JacksonUtil.toJsonNode("{\"description\":\"new\"}")); + + assertThat(processor.isSaveRequired(current, updated)).isTrue(); + } + + @Test + public void entityViewSaveNotRequiredWhenOnlyVersionChanges() { + EntityViewId entityViewId = new EntityViewId(UUID.randomUUID()); + EntityView current = new EntityView(entityViewId); + current.setName("EntityView"); + current.setAdditionalInfo(JacksonUtil.toJsonNode("{\"description\":\"same\"}")); + current.setVersion(1L); + + EntityView updated = new EntityView(current); + updated.setVersion(2L); + + assertThat(processor.isSaveRequired(current, updated)).isFalse(); + } + + @Test + public void userSaveRequiredWhenAdditionalInfoChanges() { + UserId userId = new UserId(UUID.randomUUID()); + User current = new User(userId); + current.setEmail("user@thingsboard.io"); + current.setAdditionalInfo(JacksonUtil.toJsonNode("{\"description\":\"old\"}")); + + User updated = new User(current); + updated.setAdditionalInfo(JacksonUtil.toJsonNode("{\"description\":\"new\"}")); + + assertThat(processor.isSaveRequired(current, updated)).isTrue(); + } + + @Test + public void userSaveNotRequiredWhenOnlyVersionChanges() { + UserId userId = new UserId(UUID.randomUUID()); + User current = new User(userId); + current.setEmail("user@thingsboard.io"); + current.setAdditionalInfo(JacksonUtil.toJsonNode("{\"description\":\"same\"}")); + current.setVersion(1L); + + User updated = new User(current); + updated.setVersion(2L); + + assertThat(processor.isSaveRequired(current, updated)).isFalse(); + } + + private static DeviceData deviceDataWithTransport() { + DeviceData deviceData = new DeviceData(); + deviceData.setConfiguration(new DefaultDeviceConfiguration()); + deviceData.setTransportConfiguration(new DefaultDeviceTransportConfiguration()); + return deviceData; + } + +} diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/Dashboard.java b/common/data/src/main/java/org/thingsboard/server/common/data/Dashboard.java index 2c65a3dfc8..2666663d97 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/Dashboard.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/Dashboard.java @@ -38,7 +38,7 @@ public class Dashboard extends DashboardInfo implements ExportableEntity Date: Fri, 26 Jun 2026 10:56:01 +0300 Subject: [PATCH 42/91] Fix license header on BaseEdgeProcessorTest --- .../rpc/processor/BaseEdgeProcessorTest.java | 35 ++++++------------- 1 file changed, 10 insertions(+), 25 deletions(-) diff --git a/application/src/test/java/org/thingsboard/server/service/edge/rpc/processor/BaseEdgeProcessorTest.java b/application/src/test/java/org/thingsboard/server/service/edge/rpc/processor/BaseEdgeProcessorTest.java index 55f975b1ea..430df22548 100644 --- a/application/src/test/java/org/thingsboard/server/service/edge/rpc/processor/BaseEdgeProcessorTest.java +++ b/application/src/test/java/org/thingsboard/server/service/edge/rpc/processor/BaseEdgeProcessorTest.java @@ -1,32 +1,17 @@ /** - * ThingsBoard, Inc. ("COMPANY") CONFIDENTIAL + * Copyright © 2016-2026 The Thingsboard Authors * - * Copyright © 2016-2026 ThingsBoard, Inc. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at * - * NOTICE: All information contained herein is, and remains - * the property of ThingsBoard, Inc. and its suppliers, - * if any. The intellectual and technical concepts contained - * herein are proprietary to ThingsBoard, Inc. - * and its suppliers and may be covered by U.S. and Foreign Patents, - * patents in process, and are protected by trade secret or copyright law. + * http://www.apache.org/licenses/LICENSE-2.0 * - * Dissemination of this information or reproduction of this material is strictly forbidden - * unless prior written permission is obtained from COMPANY. - * - * Access to the source code contained herein is hereby forbidden to anyone except current COMPANY employees, - * managers or contractors who have executed Confidentiality and Non-disclosure agreements - * explicitly covering such access. - * - * The copyright notice above does not evidence any actual or intended publication - * or disclosure of this source code, which includes - * information that is confidential and/or proprietary, and is a trade secret, of COMPANY. - * ANY REPRODUCTION, MODIFICATION, DISTRIBUTION, PUBLIC PERFORMANCE, - * OR PUBLIC DISPLAY OF OR THROUGH USE OF THIS SOURCE CODE WITHOUT - * THE EXPRESS WRITTEN CONSENT OF COMPANY IS STRICTLY PROHIBITED, - * AND IN VIOLATION OF APPLICABLE LAWS AND INTERNATIONAL TREATIES. - * THE RECEIPT OR POSSESSION OF THIS SOURCE CODE AND/OR RELATED INFORMATION - * DOES NOT CONVEY OR IMPLY ANY RIGHTS TO REPRODUCE, DISCLOSE OR DISTRIBUTE ITS CONTENTS, - * OR TO MANUFACTURE, USE, OR SELL ANYTHING THAT IT MAY DESCRIBE, IN WHOLE OR IN PART. + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package org.thingsboard.server.service.edge.rpc.processor; From 632193cbdfb5cfac54dfcfb3bc79882e556111f8 Mon Sep 17 00:00:00 2001 From: Viacheslav Klimov Date: Tue, 30 Jun 2026 12:30:42 +0300 Subject: [PATCH 43/91] Reserve dynamic ports for OpenAPI spec generation to avoid port conflicts --- application/pom.xml | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/application/pom.xml b/application/pom.xml index f6ceba95a1..6a976bf846 100644 --- a/application/pom.xml +++ b/application/pom.xml @@ -507,12 +507,31 @@ + + org.codehaus.mojo + build-helper-maven-plugin + + + + reserve-openapi-ports + initialize + reserve-network-port + + + jmx.port + http.port + + + + + org.springframework.boot spring-boot-maven-plugin org.thingsboard.server.ThingsboardServerApplication - 9001 + ${jmx.port} @@ -532,6 +551,7 @@ --spring.config.name=thingsboard --spring.profiles.active=openapi + --server.port=${http.port} 180 2000 @@ -557,7 +577,7 @@ - http://localhost:8080/v3/api-docs/thingsboard + http://localhost:${http.port}/v3/api-docs/thingsboard openapi.json ${project.build.directory} From 42e3c8de6a36454c696a5be63f1d304a28aa9007 Mon Sep 17 00:00:00 2001 From: Maksym Tsymbarov Date: Tue, 30 Jun 2026 12:22:22 +0200 Subject: [PATCH 44/91] Remove redundant [disabled] binding on reactive-form fields to fix NG01001 warning --- .../basic/button/power-button-basic-config.component.html | 1 - .../basic/button/toggle-button-basic-config.component.html | 1 - .../cards/aggregated-value-card-basic-config.component.html | 2 -- .../basic/cards/label-value-card-basic-config.component.html | 1 - .../config/basic/cards/progress-bar-basic-config.component.html | 1 - .../basic/cards/timeseries-table-basic-config.component.html | 1 - .../config/basic/cards/value-card-basic-config.component.html | 1 - .../basic/cards/value-chart-card-basic-config.component.html | 1 - .../chart/bar-chart-with-labels-basic-config.component.html | 1 - .../widget/config/basic/chart/flot-basic-config.component.html | 1 - .../config/basic/chart/latest-chart-basic-config.component.html | 1 - .../config/basic/chart/range-chart-basic-config.component.html | 1 - .../basic/chart/time-series-chart-basic-config.component.html | 1 - .../basic/entity/entities-table-basic-config.component.html | 1 - .../basic/indicator/battery-level-basic-config.component.html | 1 - .../indicator/liquid-level-card-basic-config.component.html | 1 - .../basic/indicator/signal-strength-basic-config.component.html | 1 - .../widget/config/basic/map/map-basic-config.component.html | 1 - .../widget/config/basic/rpc/slider-basic-config.component.html | 1 - .../config/basic/scada/scada-symbol-basic-config.component.html | 1 - .../weather/wind-speed-direction-basic-config.component.html | 1 - .../cards/aggregated-value-card-widget-settings.component.html | 1 - .../cards/label-value-card-widget-settings.component.html | 1 - .../common/button/widget-button-appearance.component.html | 1 - .../lib/settings/common/count-widget-settings.component.html | 1 - .../indicator/status-widget-state-settings.component.html | 1 - .../control/single-switch-widget-settings.component.html | 1 - .../modules/home/components/widget/widget-config.component.html | 1 - 28 files changed, 29 deletions(-) diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/button/power-button-basic-config.component.html b/ui-ngx/src/app/modules/home/components/widget/config/basic/button/power-button-basic-config.component.html index 51ebab7a92..75e3bad0f5 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/basic/button/power-button-basic-config.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/button/power-button-basic-config.component.html @@ -88,7 +88,6 @@ subscriptSizing="dynamic" predefinedValuesButton="true" [predefinedValues]="predefinedValues" - [disabled]="!powerButtonWidgetConfigForm.get('showTitle').value" placeholderText="{{ 'widget-config.set' | translate }}" formControlName="title" > diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/button/toggle-button-basic-config.component.html b/ui-ngx/src/app/modules/home/components/widget/config/basic/button/toggle-button-basic-config.component.html index d506fe4e8b..7bd2974678 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/basic/button/toggle-button-basic-config.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/button/toggle-button-basic-config.component.html @@ -98,7 +98,6 @@ subscriptSizing="dynamic" predefinedValuesButton="true" [predefinedValues]="predefinedValues" - [disabled]="!toggleButtonWidgetConfigForm.get('showTitle').value" placeholderText="{{ 'widget-config.set' | translate }}" formControlName="title" > diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/cards/aggregated-value-card-basic-config.component.html b/ui-ngx/src/app/modules/home/components/widget/config/basic/cards/aggregated-value-card-basic-config.component.html index f0897ae55c..a7192a3c1b 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/basic/cards/aggregated-value-card-basic-config.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/cards/aggregated-value-card-basic-config.component.html @@ -45,7 +45,6 @@ subscriptSizing="dynamic" predefinedValuesButton="true" [predefinedValues]="predefinedValues" - [disabled]="!aggregatedValueCardWidgetConfigForm.get('showTitle').value" placeholderText="{{ 'widget-config.set' | translate }}" formControlName="title" > @@ -91,7 +90,6 @@ subscriptSizing="dynamic" [predefinedValuesButton]="true" [predefinedValues]="predefinedValues" - [disabled]="!aggregatedValueCardWidgetConfigForm.get('showSubtitle').value" placeholderText="{{ 'widget-config.set' | translate }}" formControlName="subtitle" > diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/cards/label-value-card-basic-config.component.html b/ui-ngx/src/app/modules/home/components/widget/config/basic/cards/label-value-card-basic-config.component.html index 90cb150339..b2d186724b 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/basic/cards/label-value-card-basic-config.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/cards/label-value-card-basic-config.component.html @@ -46,7 +46,6 @@ brackets="curly" subscriptSizing="dynamic" predefinedValuesButton="true" - [disabled]="!labelValueCardWidgetConfigForm.get('showLabel').value" [predefinedValues]="predefinedValues" placeholderText="{{ 'widget-config.set' | translate }}" formControlName="label" diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/cards/progress-bar-basic-config.component.html b/ui-ngx/src/app/modules/home/components/widget/config/basic/cards/progress-bar-basic-config.component.html index 120ccf6457..a6212379c6 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/basic/cards/progress-bar-basic-config.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/cards/progress-bar-basic-config.component.html @@ -58,7 +58,6 @@ subscriptSizing="dynamic" predefinedValuesButton="true" [predefinedValues]="predefinedValues" - [disabled]="!progressBarWidgetConfigForm.get('showTitle').value" placeholderText="{{ 'widget-config.set' | translate }}" formControlName="title" > diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/cards/timeseries-table-basic-config.component.html b/ui-ngx/src/app/modules/home/components/widget/config/basic/cards/timeseries-table-basic-config.component.html index 43777d596e..fe63bb8591 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/basic/cards/timeseries-table-basic-config.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/cards/timeseries-table-basic-config.component.html @@ -49,7 +49,6 @@ brackets="curly" subscriptSizing="dynamic" predefinedValuesButton="true" - [disabled]="!timeseriesTableWidgetConfigForm.get('showTitle').value" [predefinedValues]="predefinedValues" placeholderText="{{ 'widget-config.set' | translate }}" formControlName="title" diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/cards/value-card-basic-config.component.html b/ui-ngx/src/app/modules/home/components/widget/config/basic/cards/value-card-basic-config.component.html index 9a4a6196c8..1ab422f7ec 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/basic/cards/value-card-basic-config.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/cards/value-card-basic-config.component.html @@ -58,7 +58,6 @@ brackets="curly" subscriptSizing="dynamic" predefinedValuesButton="true" - [disabled]="!valueCardWidgetConfigForm.get('showLabel').value" [predefinedValues]="predefinedValues" placeholderText="{{ 'widget-config.set' | translate }}" formControlName="label" diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/cards/value-chart-card-basic-config.component.html b/ui-ngx/src/app/modules/home/components/widget/config/basic/cards/value-chart-card-basic-config.component.html index c7943ec0a7..406ae88d2e 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/basic/cards/value-chart-card-basic-config.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/cards/value-chart-card-basic-config.component.html @@ -56,7 +56,6 @@ brackets="curly" subscriptSizing="dynamic" predefinedValuesButton="true" - [disabled]="!valueChartCardWidgetConfigForm.get('showTitle').value" [predefinedValues]="predefinedValues" placeholderText="{{ 'widget-config.set' | translate }}" formControlName="title" diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/bar-chart-with-labels-basic-config.component.html b/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/bar-chart-with-labels-basic-config.component.html index 1aa4c2be3d..98c0884da4 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/bar-chart-with-labels-basic-config.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/bar-chart-with-labels-basic-config.component.html @@ -54,7 +54,6 @@ brackets="curly" subscriptSizing="dynamic" predefinedValuesButton="true" - [disabled]="!barChartWidgetConfigForm.get('showTitle').value" [predefinedValues]="predefinedValues" placeholderText="{{ 'widget-config.set' | translate }}" formControlName="title" diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/flot-basic-config.component.html b/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/flot-basic-config.component.html index 029a1a8cb3..12c538dae4 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/flot-basic-config.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/flot-basic-config.component.html @@ -49,7 +49,6 @@ brackets="curly" subscriptSizing="dynamic" predefinedValuesButton="true" - [disabled]="!flotWidgetConfigForm.get('showTitle').value" [predefinedValues]="predefinedValues" placeholderText="{{ 'widget-config.set' | translate }}" formControlName="title" diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/latest-chart-basic-config.component.html b/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/latest-chart-basic-config.component.html index b0f108ba58..a1b3b97ee7 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/latest-chart-basic-config.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/latest-chart-basic-config.component.html @@ -55,7 +55,6 @@ brackets="curly" subscriptSizing="dynamic" predefinedValuesButton="true" - [disabled]="!latestChartWidgetConfigForm.get('showTitle').value" [predefinedValues]="predefinedValues" placeholderText="{{ 'widget-config.set' | translate }}" formControlName="title" diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/range-chart-basic-config.component.html b/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/range-chart-basic-config.component.html index 7d3195e7f4..45acefab12 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/range-chart-basic-config.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/range-chart-basic-config.component.html @@ -38,7 +38,6 @@ brackets="curly" subscriptSizing="dynamic" predefinedValuesButton="true" - [disabled]="!rangeChartWidgetConfigForm.get('showTitle').value" [predefinedValues]="predefinedValues" placeholderText="{{ 'widget-config.set' | translate }}" formControlName="title" diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/time-series-chart-basic-config.component.html b/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/time-series-chart-basic-config.component.html index 85ef776718..ac0017929b 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/time-series-chart-basic-config.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/time-series-chart-basic-config.component.html @@ -131,7 +131,6 @@ brackets="curly" subscriptSizing="dynamic" predefinedValuesButton="true" - [disabled]="!timeSeriesChartWidgetConfigForm.get('showTitle').value" [predefinedValues]="predefinedValues" placeholderText="{{ 'widget-config.set' | translate }}" formControlName="title" diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/entity/entities-table-basic-config.component.html b/ui-ngx/src/app/modules/home/components/widget/config/basic/entity/entities-table-basic-config.component.html index 27ad183dfa..34579f1b3a 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/basic/entity/entities-table-basic-config.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/entity/entities-table-basic-config.component.html @@ -49,7 +49,6 @@ brackets="curly" subscriptSizing="dynamic" predefinedValuesButton="true" - [disabled]="!entitiesTableWidgetConfigForm.get('showTitle').value" [predefinedValues]="predefinedValues" placeholderText="{{ 'widget-config.set' | translate }}" formControlName="title" diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/indicator/battery-level-basic-config.component.html b/ui-ngx/src/app/modules/home/components/widget/config/basic/indicator/battery-level-basic-config.component.html index e36e315b3e..894b13788b 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/basic/indicator/battery-level-basic-config.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/indicator/battery-level-basic-config.component.html @@ -58,7 +58,6 @@ brackets="curly" subscriptSizing="dynamic" predefinedValuesButton="true" - [disabled]="!batteryLevelWidgetConfigForm.get('showTitle').value" [predefinedValues]="predefinedValues" placeholderText="{{ 'widget-config.set' | translate }}" formControlName="title" diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/indicator/liquid-level-card-basic-config.component.html b/ui-ngx/src/app/modules/home/components/widget/config/basic/indicator/liquid-level-card-basic-config.component.html index 473bdb0b4b..396441ce2f 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/basic/indicator/liquid-level-card-basic-config.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/indicator/liquid-level-card-basic-config.component.html @@ -40,7 +40,6 @@ brackets="curly" subscriptSizing="dynamic" predefinedValuesButton="true" - [disabled]="!levelCardWidgetConfigForm.get('showTitle').value" [predefinedValues]="predefinedValues" placeholderText="{{ 'widget-config.set' | translate }}" formControlName="title" diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/indicator/signal-strength-basic-config.component.html b/ui-ngx/src/app/modules/home/components/widget/config/basic/indicator/signal-strength-basic-config.component.html index ed034aaf89..c3ac497ae5 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/basic/indicator/signal-strength-basic-config.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/indicator/signal-strength-basic-config.component.html @@ -52,7 +52,6 @@ brackets="curly" subscriptSizing="dynamic" predefinedValuesButton="true" - [disabled]="!signalStrengthWidgetConfigForm.get('showTitle').value" [predefinedValues]="predefinedValues" placeholderText="{{ 'widget-config.set' | translate }}" formControlName="title" diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/map/map-basic-config.component.html b/ui-ngx/src/app/modules/home/components/widget/config/basic/map/map-basic-config.component.html index 3d1f05fb4b..fb1246a9cc 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/basic/map/map-basic-config.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/map/map-basic-config.component.html @@ -40,7 +40,6 @@ brackets="curly" subscriptSizing="dynamic" predefinedValuesButton="true" - [disabled]="!mapWidgetConfigForm.get('showTitle').value" [predefinedValues]="predefinedValues" placeholderText="{{ 'widget-config.set' | translate }}" formControlName="title" diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/rpc/slider-basic-config.component.html b/ui-ngx/src/app/modules/home/components/widget/config/basic/rpc/slider-basic-config.component.html index b6566c181e..918af02557 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/basic/rpc/slider-basic-config.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/rpc/slider-basic-config.component.html @@ -81,7 +81,6 @@ brackets="curly" subscriptSizing="dynamic" predefinedValuesButton="true" - [disabled]="!sliderWidgetConfigForm.get('showTitle').value" [predefinedValues]="predefinedValues" placeholderText="{{ 'widget-config.set' | translate }}" formControlName="title" diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/scada/scada-symbol-basic-config.component.html b/ui-ngx/src/app/modules/home/components/widget/config/basic/scada/scada-symbol-basic-config.component.html index 03cdee6b95..224e45354e 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/basic/scada/scada-symbol-basic-config.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/scada/scada-symbol-basic-config.component.html @@ -40,7 +40,6 @@ brackets="curly" subscriptSizing="dynamic" predefinedValuesButton="true" - [disabled]="!scadaSymbolWidgetConfigForm.get('showTitle').value" [predefinedValues]="predefinedValues" placeholderText="{{ 'widget-config.set' | translate }}" formControlName="title" diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/weather/wind-speed-direction-basic-config.component.html b/ui-ngx/src/app/modules/home/components/widget/config/basic/weather/wind-speed-direction-basic-config.component.html index 3727cd0952..fc673b8baa 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/basic/weather/wind-speed-direction-basic-config.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/weather/wind-speed-direction-basic-config.component.html @@ -100,7 +100,6 @@ brackets="curly" subscriptSizing="dynamic" predefinedValuesButton="true" - [disabled]="!windSpeedDirectionWidgetConfigForm.get('showTitle').value" [predefinedValues]="predefinedValues" placeholderText="{{ 'widget-config.set' | translate }}" formControlName="title" diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/aggregated-value-card-widget-settings.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/aggregated-value-card-widget-settings.component.html index d2bda36ab2..ba54d83173 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/aggregated-value-card-widget-settings.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/aggregated-value-card-widget-settings.component.html @@ -33,7 +33,6 @@ brackets="curly" subscriptSizing="dynamic" [predefinedValuesButton]="true" - [disabled]="!aggregatedValueCardWidgetSettingsForm.get('showSubtitle').value" [predefinedValues]="predefinedValues" placeholderText="{{ 'widget-config.set' | translate }}" formControlName="subtitle" diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/label-value-card-widget-settings.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/label-value-card-widget-settings.component.html index b4520590b6..cd11b4f10f 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/label-value-card-widget-settings.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/label-value-card-widget-settings.component.html @@ -33,7 +33,6 @@ brackets="curly" subscriptSizing="dynamic" [predefinedValuesButton]="true" - [disabled]="!labelValueCardWidgetSettingsForm.get('showLabel').value" [predefinedValues]="predefinedValues" placeholderText="{{ 'widget-config.set' | translate }}" formControlName="label" diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/button/widget-button-appearance.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/button/widget-button-appearance.component.html index 26835e857a..d54cd71c00 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/button/widget-button-appearance.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/button/widget-button-appearance.component.html @@ -42,7 +42,6 @@ brackets="curly" subscriptSizing="dynamic" predefinedValuesButton="true" - [disabled]="!appearanceFormGroup.get('showLabel').value" [predefinedValues]="predefinedValues" placeholderText="{{ 'widget-config.set' | translate }}" formControlName="label" diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/count-widget-settings.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/count-widget-settings.component.html index 08a0246217..ee79216190 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/count-widget-settings.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/count-widget-settings.component.html @@ -48,7 +48,6 @@ brackets="curly" subscriptSizing="dynamic" predefinedValuesButton="true" - [disabled]="!countWidgetConfigForm.get('showLabel').value" [predefinedValues]="predefinedValues" placeholderText="{{ 'widget-config.set' | translate }}" formControlName="label" diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/indicator/status-widget-state-settings.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/indicator/status-widget-state-settings.component.html index 485f6d0af4..11b99f411a 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/indicator/status-widget-state-settings.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/indicator/status-widget-state-settings.component.html @@ -26,7 +26,6 @@ brackets="curly" subscriptSizing="dynamic" predefinedValuesButton="true" - [disabled]="!stateSettingsFormGroup.get('showLabel').value" [predefinedValues]="predefinedValues" placeholderText="{{ 'widget-config.set' | translate }}" formControlName="label" diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/single-switch-widget-settings.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/single-switch-widget-settings.component.html index 330433141e..cf3a77c38d 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/single-switch-widget-settings.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/single-switch-widget-settings.component.html @@ -91,7 +91,6 @@ brackets="curly" subscriptSizing="dynamic" predefinedValuesButton="true" - [disabled]="!singleSwitchWidgetSettingsForm.get('showLabel').value" [predefinedValues]="predefinedValues" placeholderText="{{ 'widget-config.set' | translate }}" formControlName="label" diff --git a/ui-ngx/src/app/modules/home/components/widget/widget-config.component.html b/ui-ngx/src/app/modules/home/components/widget/widget-config.component.html index 641755b810..1bf65c61a0 100644 --- a/ui-ngx/src/app/modules/home/components/widget/widget-config.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/widget-config.component.html @@ -51,7 +51,6 @@ brackets="curly" subscriptSizing="dynamic" [predefinedValuesButton]="true" - [disabled]="!widgetSettings.get('showTitle').value" [predefinedValues]="predefinedValues" placeholderText="{{ 'widget-config.set' | translate }}" formControlName="title" From c435bcdf6f10fae8ae029bce8ba593989ecf9c2b Mon Sep 17 00:00:00 2001 From: Maksym Tsymbarov Date: Tue, 30 Jun 2026 14:54:23 +0200 Subject: [PATCH 45/91] Used shared ShortNumberPipe for API usage value formatting --- .../lib/cards/api-usage-widget.component.ts | 29 ++++--------------- .../usage-info-widget.component.html | 10 +++---- 2 files changed, 10 insertions(+), 29 deletions(-) diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/cards/api-usage-widget.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/cards/api-usage-widget.component.ts index b41f5ed02a..af315b226a 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/cards/api-usage-widget.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/cards/api-usage-widget.component.ts @@ -30,6 +30,7 @@ import { ApiUsageWidgetSettings, getUniqueDataKeys } from '@home/components/widget/lib/settings/cards/api-usage-settings.component.models'; +import { ShortNumberPipe } from '@shared/pipe/short-number.pipe'; @Component({ selector: 'tb-api-usage-widget', @@ -57,18 +58,12 @@ export class ApiUsageWidgetComponent implements OnInit, OnDestroy { noDataDisplayMessageText: string; private contentResize$: ResizeObserver; - private powers: {key: string, value: number}[] = [ - { key: 'Q', value: 1e15 }, - { key: 'T', value: 1e12 }, - { key: 'B', value: 1e9 }, - { key: 'M', value: 1e6 }, - { key: 'K', value: 1e3 } - ]; constructor(private imagePipe: ImagePipe, private utils: UtilsService, private sanitizer: DomSanitizer, - private cd: ChangeDetectorRef) { + private cd: ChangeDetectorRef, + private shortNumberPipe: ShortNumberPipe) { } ngOnInit(): void { @@ -95,8 +90,8 @@ export class ApiUsageWidgetComponent implements OnInit, OnDestroy { const progress = (this.isFiniteNumber(data[0][key.maxLimit.key]) && data[0][key.maxLimit.key] !== 0) ? Math.min(100, ((data[0][key.current.key] / data[0][key.maxLimit.key]) * 100)) : 0; key.progress = isFinite(progress) ? progress : 0; key.status.value = data[0][key.status.key] ? data[0][key.status.key].toLowerCase() : 'enabled'; - key.maxLimit.value = this.isFiniteNumber(data[0][key.maxLimit.key]) && data[0][key.maxLimit.key] !== 0 ? this.toShortNumber(data[0][key.maxLimit.key]) : '∞'; - key.current.value = this.isFiniteNumber(data[0][key.current.key]) ? this.toShortNumber(data[0][key.current.key]) : 0; + key.maxLimit.value = this.isFiniteNumber(data[0][key.maxLimit.key]) && data[0][key.maxLimit.key] !== 0 ? this.shortNumberPipe.transform(data[0][key.maxLimit.key]) : '∞'; + key.current.value = this.isFiniteNumber(data[0][key.current.key]) ? this.shortNumberPipe.transform(data[0][key.current.key], {roundDown: true}) : 0; }); this.cd.detectChanges(); } @@ -145,20 +140,6 @@ export class ApiUsageWidgetComponent implements OnInit, OnDestroy { } } - private toShortNumber(number: any, decimals = 1) { - if (!Number.isFinite(number) || number < 0) { - return '0'; - } - for (const power of this.powers) { - if (number >= power.value) { - const reduced = number / power.value; - const rounded = Number(reduced.toFixed(decimals)); - return `${rounded}${power.key}`; - } - } - return `${Number(number.toFixed(decimals))}`; - } - public onInit() { const borderRadius = this.ctx.$widgetElement.css('borderRadius'); this.overlayStyle = {...this.overlayStyle, ...{borderRadius}}; diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/home-page/usage-info-widget.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/home-page/usage-info-widget.component.html index d23b7b8e50..92ef58c640 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/home-page/usage-info-widget.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/home-page/usage-info-widget.component.html @@ -63,11 +63,11 @@
-
{{ usageInfo?.transportMessages | shortNumber }} / {{ maxValue(usageInfo?.maxTransportMessages) }}
-
{{ usageInfo?.jsExecutions | shortNumber }} / {{ maxValue(usageInfo?.maxJsExecutions) }}
-
{{ usageInfo?.alarms | shortNumber }} / {{ maxValue(usageInfo?.maxAlarms) }}
-
{{ usageInfo?.emails | shortNumber }} / {{ maxValue(usageInfo?.maxEmails) }}
-
{{ usageInfo?.sms | shortNumber }} / {{ maxValue(usageInfo?.maxSms) }}
+
{{ usageInfo?.transportMessages | shortNumber: {roundDown: true} }} / {{ maxValue(usageInfo?.maxTransportMessages) }}
+
{{ usageInfo?.jsExecutions | shortNumber: {roundDown: true} }} / {{ maxValue(usageInfo?.maxJsExecutions) }}
+
{{ usageInfo?.alarms | shortNumber: {roundDown: true} }} / {{ maxValue(usageInfo?.maxAlarms) }}
+
{{ usageInfo?.emails | shortNumber: {roundDown: true} }} / {{ maxValue(usageInfo?.maxEmails) }}
+
{{ usageInfo?.sms | shortNumber: {roundDown: true} }} / {{ maxValue(usageInfo?.maxSms) }}
From 091eebb40c4e9a0638fc2be900916de23ee34405 Mon Sep 17 00:00:00 2001 From: Vladyslav_Prykhodko Date: Tue, 30 Jun 2026 18:58:36 +0300 Subject: [PATCH 46/91] Fix stray double space in api-usage-widget ternary --- .../components/widget/lib/cards/api-usage-widget.component.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/cards/api-usage-widget.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/cards/api-usage-widget.component.ts index af315b226a..65829ea723 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/cards/api-usage-widget.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/cards/api-usage-widget.component.ts @@ -90,7 +90,7 @@ export class ApiUsageWidgetComponent implements OnInit, OnDestroy { const progress = (this.isFiniteNumber(data[0][key.maxLimit.key]) && data[0][key.maxLimit.key] !== 0) ? Math.min(100, ((data[0][key.current.key] / data[0][key.maxLimit.key]) * 100)) : 0; key.progress = isFinite(progress) ? progress : 0; key.status.value = data[0][key.status.key] ? data[0][key.status.key].toLowerCase() : 'enabled'; - key.maxLimit.value = this.isFiniteNumber(data[0][key.maxLimit.key]) && data[0][key.maxLimit.key] !== 0 ? this.shortNumberPipe.transform(data[0][key.maxLimit.key]) : '∞'; + key.maxLimit.value = this.isFiniteNumber(data[0][key.maxLimit.key]) && data[0][key.maxLimit.key] !== 0 ? this.shortNumberPipe.transform(data[0][key.maxLimit.key]) : '∞'; key.current.value = this.isFiniteNumber(data[0][key.current.key]) ? this.shortNumberPipe.transform(data[0][key.current.key], {roundDown: true}) : 0; }); this.cd.detectChanges(); From 9d3897764377b629f4d49efac5e3b5a44e95500c Mon Sep 17 00:00:00 2001 From: Maksym Tsymbarov Date: Wed, 1 Jul 2026 09:28:17 +0200 Subject: [PATCH 47/91] Minor fixes --- .../lib/home-page/usage-info-widget.component.html | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/home-page/usage-info-widget.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/home-page/usage-info-widget.component.html index 92ef58c640..0f3f35f172 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/home-page/usage-info-widget.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/home-page/usage-info-widget.component.html @@ -36,11 +36,11 @@
-
{{ usageInfo?.devices | shortNumber }} / {{ maxValue(usageInfo?.maxDevices) }}
-
{{ usageInfo?.assets | shortNumber }} / {{ maxValue(usageInfo?.maxAssets) }}
-
{{ usageInfo?.users | shortNumber }} / {{ maxValue(usageInfo?.maxUsers) }}
-
{{ usageInfo?.dashboards | shortNumber }} / {{ maxValue(usageInfo?.maxDashboards) }}
-
{{ usageInfo?.customers | shortNumber }} / {{ maxValue(usageInfo?.maxCustomers) }}
+
{{ usageInfo?.devices | shortNumber: {roundDown: true} }} / {{ maxValue(usageInfo?.maxDevices) }}
+
{{ usageInfo?.assets | shortNumber: {roundDown: true} }} / {{ maxValue(usageInfo?.maxAssets) }}
+
{{ usageInfo?.users | shortNumber: {roundDown: true} }} / {{ maxValue(usageInfo?.maxUsers) }}
+
{{ usageInfo?.dashboards | shortNumber: {roundDown: true} }} / {{ maxValue(usageInfo?.maxDashboards) }}
+
{{ usageInfo?.customers | shortNumber: {roundDown: true} }} / {{ maxValue(usageInfo?.maxCustomers) }}
From ec5be9bfef1a56a5605bffcfbadd8ca00c19d45e Mon Sep 17 00:00:00 2001 From: Valeriia Koriavikova Date: Thu, 2 Jul 2026 18:21:15 +0300 Subject: [PATCH 48/91] Merge pull request #15847 from LeoMorgan113/feature/ticks-label-fix Fix chart axis ticks font size --- .../widget/lib/chart/time-series-chart.ts | 25 +++++++++++++++---- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/chart/time-series-chart.ts b/ui-ngx/src/app/modules/home/components/widget/lib/chart/time-series-chart.ts index ca2456e109..763c8d612d 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/chart/time-series-chart.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/chart/time-series-chart.ts @@ -846,15 +846,29 @@ export class TbTimeSeriesChart { } } + private maxTickLabelHalfHeight(): number { + const axes = this.yAxisList.filter(a => a.settings.show && a.settings.showTickLabels); + if (!axes.length) { + return 0; + } + + const defaultSize = defaultTimeSeriesChartYAxisSettings.tickLabelFont.size; + const maxFontSize = Math.max(...axes.map(a => a.settings.tickLabelFont?.size || defaultSize)); + return Math.ceil(maxFontSize / 2); + } + private minTopOffset(): number { - const showTickLabels = - !!this.yAxisList.find(yAxis => yAxis.settings.show && yAxis.settings.showTickLabels); - return (this.topPointLabels) ? 25 : - (showTickLabels ? 10 : 5); + if (this.topPointLabels) { + return 25; + } + const half = this.maxTickLabelHalfHeight(); + return half ? Math.max(10, half) : 5; } private minBottomOffset(): number { - return this.settings.dataZoom ? 45 : 5; + const half = this.maxTickLabelHalfHeight(); + const minOffset = half ? Math.max(5, half) : 5; + return this.settings.dataZoom ? Math.max(45, minOffset) : minOffset; } private _onParentScroll() { @@ -883,6 +897,7 @@ export class TbTimeSeriesChart { this.updateBarsAnimation(barItems, false); } this.timeSeriesChart.resize(); + this.updateAxes(); if (this.animationEnabled()) { this.updateBarsAnimation(barItems, true); } From 751730acd3d4970bd9dc0fd7ba0c64f5af1e436f Mon Sep 17 00:00:00 2001 From: Maksym Tsymbarov Date: Thu, 2 Jul 2026 10:48:21 +0200 Subject: [PATCH 49/91] Added missing translation for Label and Value Card widget --- .../widget/lib/cards/label-value-card-widget.component.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/cards/label-value-card-widget.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/cards/label-value-card-widget.component.html index 289b54bb56..930fef4d42 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/cards/label-value-card-widget.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/cards/label-value-card-widget.component.html @@ -28,7 +28,7 @@
-
{{ valueText }}
+
{{ valueText | customTranslate }}
From 5493ac7da50a506693a5b5f1ac69d6eb27842b33 Mon Sep 17 00:00:00 2001 From: Maksym Tsymbarov Date: Thu, 2 Jul 2026 17:54:39 +0200 Subject: [PATCH 50/91] Fixed validation for Digital Gauge widget maxValue when it is zero (#15893) * Fixed validation for Digital Gauge widget maxValue when it is zero * Fixed check --- .../digital-simple-gauge-basic-config.component.ts | 11 +++++------ .../gauge/digital-gauge-widget-settings.component.ts | 11 +++++------ 2 files changed, 10 insertions(+), 12 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 e0ca65cdea..6d837f476c 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, isDefined, isUndefined } from '@core/utils'; +import { formatValue, isDefined, isDefinedAndNotNull, isNumeric, isUndefined } from '@core/utils'; import { Component } from '@angular/core'; import { convertLevelColorsSettingsToColorProcessor, @@ -189,11 +189,10 @@ export class DigitalSimpleGaugeBasicConfigComponent extends BasicWidgetConfigCom private maxValueValidation(): ValidatorFn { return (control: AbstractControl): ValidationErrors | null => { - const value: string = control.value; - if (value) { - if (value < control.parent?.get('minValue').value) { - return {maxValue: true}; - } + const value: number = control.value; + const minValue = control.parent?.get('minValue').value; + if (isNumeric(value) && isDefinedAndNotNull(minValue) && value < minValue) { + return {maxValue: true}; } return null; }; 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 ff22abd28a..fe7eeb7305 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, isDefined } from '@core/utils'; +import { formatValue, isDefined, isDefinedAndNotNull, isNumeric } from '@core/utils'; import { ColorSettings, ColorType, @@ -218,11 +218,10 @@ export class DigitalGaugeWidgetSettingsComponent extends WidgetSettingsComponent private maxValueValidation(): ValidatorFn { return (control: AbstractControl): ValidationErrors | null => { - const value: string = control.value; - if (value) { - if (value < control.parent?.get('minValue').value) { - return {maxValue: true}; - } + const value: number = control.value; + const minValue = control.parent?.get('minValue').value; + if (isNumeric(value) && isDefinedAndNotNull(minValue) && value < minValue) { + return {maxValue: true}; } return null; }; From 1302a67ee83b8b2b2f3e93bbf789a387d1c40acc Mon Sep 17 00:00:00 2001 From: Maksym Tsymbarov Date: Mon, 29 Jun 2026 14:17:52 +0200 Subject: [PATCH 51/91] Fixed Calculated Field test script running against stale entity values instead of current form input --- .../components/calculated-fields/calculated-field.component.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui-ngx/src/app/modules/home/components/calculated-fields/calculated-field.component.ts b/ui-ngx/src/app/modules/home/components/calculated-fields/calculated-field.component.ts index 4790789080..a80eb3439f 100644 --- a/ui-ngx/src/app/modules/home/components/calculated-fields/calculated-field.component.ts +++ b/ui-ngx/src/app/modules/home/components/calculated-fields/calculated-field.component.ts @@ -132,7 +132,7 @@ export class CalculatedFieldComponent extends EntityComponent { return this.cfFormService.testScript( this.entity?.id?.id, - this.entityValue, + this.entityFormValue(), this.entitiesTableConfig.getTestScriptDialog.bind(this.entitiesTableConfig), this.destroyRef, expression From 655d4ed55e7aeb88a8fcb2be9903a4ec99432b06 Mon Sep 17 00:00:00 2001 From: Viacheslav Klimov Date: Fri, 3 Jul 2026 12:16:41 +0300 Subject: [PATCH 52/91] Fix invalid `callSuper = false` usages for EqualsAndHashCode --- .../server/service/cf/ctx/state/ScriptCalculatedFieldState.java | 2 +- .../server/service/cf/ctx/state/SimpleCalculatedFieldState.java | 2 +- .../main/java/org/thingsboard/server/common/data/EventInfo.java | 2 +- .../java/org/thingsboard/server/common/data/HomeDashboard.java | 2 +- .../java/org/thingsboard/server/common/data/TenantInfo.java | 2 +- .../org/thingsboard/server/common/data/alarm/AlarmComment.java | 2 +- .../data/device/data/CoapDeviceTransportConfiguration.java | 2 +- .../data/device/data/Lwm2mDeviceTransportConfiguration.java | 2 +- .../lwm2m/bootstrap/LwM2MServerSecurityConfigDefault.java | 2 +- .../java/org/thingsboard/server/common/data/edge/EdgeInfo.java | 2 +- .../thingsboard/server/common/data/edqs/fields/AssetFields.java | 2 +- .../server/common/data/edqs/fields/AssetProfileFields.java | 2 +- .../server/common/data/edqs/fields/CustomerFields.java | 2 +- .../server/common/data/edqs/fields/DashboardFields.java | 2 +- .../server/common/data/edqs/fields/DeviceFields.java | 2 +- .../server/common/data/edqs/fields/DeviceProfileFields.java | 2 +- .../thingsboard/server/common/data/edqs/fields/EdgeFields.java | 2 +- .../server/common/data/edqs/fields/EntityViewFields.java | 2 +- .../server/common/data/edqs/fields/QueueStatsFields.java | 2 +- .../server/common/data/edqs/fields/RuleChainFields.java | 2 +- .../server/common/data/edqs/fields/TenantFields.java | 2 +- .../server/common/data/edqs/fields/TenantProfileFields.java | 2 +- .../thingsboard/server/common/data/edqs/fields/UserFields.java | 2 +- .../thingsboard/server/common/data/kv/BaseDeleteTsKvQuery.java | 2 +- .../thingsboard/server/common/data/query/AlarmCountQuery.java | 2 +- .../java/org/thingsboard/server/common/data/queue/Queue.java | 2 +- .../org/thingsboard/server/common/data/rule/RuleNodeState.java | 2 +- .../thingsboard/server/common/data/widget/WidgetTypeInfo.java | 2 +- .../server/transport/mqtt/limits/GatewaySessionLimits.java | 2 +- .../server/dao/model/sqlts/latest/TsKvLatestEntity.java | 2 +- .../rule/engine/action/TbClearAlarmNodeConfiguration.java | 2 +- .../rule/engine/action/TbCreateAlarmNodeConfiguration.java | 2 +- .../rule/engine/geo/TbGpsGeofencingActionNodeConfiguration.java | 2 +- .../rule/engine/mqtt/azure/AzureIotHubSasCredentials.java | 2 +- .../rule/engine/mqtt/azure/TbAzureIotHubNodeConfiguration.java | 2 +- 35 files changed, 35 insertions(+), 35 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/service/cf/ctx/state/ScriptCalculatedFieldState.java b/application/src/main/java/org/thingsboard/server/service/cf/ctx/state/ScriptCalculatedFieldState.java index be95922dbb..4bb5e4eca2 100644 --- a/application/src/main/java/org/thingsboard/server/service/cf/ctx/state/ScriptCalculatedFieldState.java +++ b/application/src/main/java/org/thingsboard/server/service/cf/ctx/state/ScriptCalculatedFieldState.java @@ -36,7 +36,7 @@ import java.util.List; import java.util.Map; @Data -@EqualsAndHashCode(callSuper = false) +@EqualsAndHashCode(callSuper = true) @Slf4j @NoArgsConstructor public class ScriptCalculatedFieldState extends BaseCalculatedFieldState { diff --git a/application/src/main/java/org/thingsboard/server/service/cf/ctx/state/SimpleCalculatedFieldState.java b/application/src/main/java/org/thingsboard/server/service/cf/ctx/state/SimpleCalculatedFieldState.java index e797376c55..7c54cefdcc 100644 --- a/application/src/main/java/org/thingsboard/server/service/cf/ctx/state/SimpleCalculatedFieldState.java +++ b/application/src/main/java/org/thingsboard/server/service/cf/ctx/state/SimpleCalculatedFieldState.java @@ -34,7 +34,7 @@ import java.util.List; import java.util.Map; @Data -@EqualsAndHashCode(callSuper = false) +@EqualsAndHashCode(callSuper = true) @NoArgsConstructor public class SimpleCalculatedFieldState extends BaseCalculatedFieldState { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/EventInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/EventInfo.java index e0bdde1dd8..e81ea75d93 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/EventInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/EventInfo.java @@ -27,7 +27,7 @@ import org.thingsboard.server.common.data.id.TenantId; * @author Andrew Shvayka */ @Data -@EqualsAndHashCode(callSuper = false) +@EqualsAndHashCode(callSuper = true) @Schema public class EventInfo extends BaseData { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/HomeDashboard.java b/common/data/src/main/java/org/thingsboard/server/common/data/HomeDashboard.java index df2cdf2bf5..8d9ee2104b 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/HomeDashboard.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/HomeDashboard.java @@ -21,7 +21,7 @@ import lombok.EqualsAndHashCode; @Schema @Data -@EqualsAndHashCode(callSuper = false) +@EqualsAndHashCode(callSuper = true) public class HomeDashboard extends Dashboard { public static final String HIDE_DASHBOARD_TOOLBAR_DESCRIPTION = "Hide dashboard toolbar flag. Useful for rendering dashboards on mobile."; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/TenantInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/TenantInfo.java index 8f38ecd750..6f44874a9c 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/TenantInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/TenantInfo.java @@ -22,7 +22,7 @@ import org.thingsboard.server.common.data.id.TenantId; @Schema @Data -@EqualsAndHashCode(callSuper = false) +@EqualsAndHashCode(callSuper = true) public class TenantInfo extends Tenant { @Schema(description = "Tenant Profile name", example = "Default") private String tenantProfileName; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/alarm/AlarmComment.java b/common/data/src/main/java/org/thingsboard/server/common/data/alarm/AlarmComment.java index 29269e5bd8..17211ed617 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/alarm/AlarmComment.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/alarm/AlarmComment.java @@ -34,7 +34,7 @@ import java.io.Serial; @Schema @Data -@EqualsAndHashCode(callSuper = false) +@EqualsAndHashCode(callSuper = true) @Builder @AllArgsConstructor public class AlarmComment extends BaseData implements HasName { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/device/data/CoapDeviceTransportConfiguration.java b/common/data/src/main/java/org/thingsboard/server/common/data/device/data/CoapDeviceTransportConfiguration.java index 662887c08c..b365686064 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/device/data/CoapDeviceTransportConfiguration.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/device/data/CoapDeviceTransportConfiguration.java @@ -26,7 +26,7 @@ import java.util.HashMap; import java.util.Map; @Data -@EqualsAndHashCode(callSuper = false) +@EqualsAndHashCode(callSuper = true) public class CoapDeviceTransportConfiguration extends PowerSavingConfiguration implements DeviceTransportConfiguration { private static final long serialVersionUID = 6061442236008925609L; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/device/data/Lwm2mDeviceTransportConfiguration.java b/common/data/src/main/java/org/thingsboard/server/common/data/device/data/Lwm2mDeviceTransportConfiguration.java index 1c53412ef9..dc9e22fe80 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/device/data/Lwm2mDeviceTransportConfiguration.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/device/data/Lwm2mDeviceTransportConfiguration.java @@ -26,7 +26,7 @@ import java.util.HashMap; import java.util.Map; @Data -@EqualsAndHashCode(callSuper = false) +@EqualsAndHashCode(callSuper = true) public class Lwm2mDeviceTransportConfiguration extends PowerSavingConfiguration implements DeviceTransportConfiguration { @JsonIgnore diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/lwm2m/bootstrap/LwM2MServerSecurityConfigDefault.java b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/lwm2m/bootstrap/LwM2MServerSecurityConfigDefault.java index 14ef402718..ad5703637c 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/lwm2m/bootstrap/LwM2MServerSecurityConfigDefault.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/lwm2m/bootstrap/LwM2MServerSecurityConfigDefault.java @@ -21,7 +21,7 @@ import lombok.EqualsAndHashCode; @Schema @Data -@EqualsAndHashCode(callSuper = false) +@EqualsAndHashCode(callSuper = true) public class LwM2MServerSecurityConfigDefault extends LwM2MServerSecurityConfig { @Schema(description = "Host for 'Security' mode (DTLS)", example = "0.0.0.0", accessMode = Schema.AccessMode.READ_ONLY) protected String securityHost; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/edge/EdgeInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/edge/EdgeInfo.java index 5dbd0212b3..66ad9f1d85 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/edge/EdgeInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/edge/EdgeInfo.java @@ -20,7 +20,7 @@ import lombok.EqualsAndHashCode; import org.thingsboard.server.common.data.id.EdgeId; @Data -@EqualsAndHashCode(callSuper = false) +@EqualsAndHashCode(callSuper = true) public class EdgeInfo extends Edge { private String customerTitle; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/AssetFields.java b/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/AssetFields.java index d05147b4d7..18b410a581 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/AssetFields.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/AssetFields.java @@ -27,7 +27,7 @@ import java.util.UUID; import static org.thingsboard.server.common.data.edqs.fields.FieldsUtil.getText; @Data -@EqualsAndHashCode(callSuper = false) +@EqualsAndHashCode(callSuper = true) @NoArgsConstructor @SuperBuilder public class AssetFields extends AbstractEntityFields implements ProfileAwareFields { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/AssetProfileFields.java b/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/AssetProfileFields.java index c519daa800..3e336023a3 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/AssetProfileFields.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/AssetProfileFields.java @@ -23,7 +23,7 @@ import lombok.experimental.SuperBuilder; import java.util.UUID; @Data -@EqualsAndHashCode(callSuper = false) +@EqualsAndHashCode(callSuper = true) @NoArgsConstructor @SuperBuilder public class AssetProfileFields extends AbstractEntityFields { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/CustomerFields.java b/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/CustomerFields.java index c324f0f1ab..ad5e87134e 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/CustomerFields.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/CustomerFields.java @@ -26,7 +26,7 @@ import java.util.UUID; import static org.thingsboard.server.common.data.edqs.fields.FieldsUtil.getText; @Data -@EqualsAndHashCode(callSuper = false) +@EqualsAndHashCode(callSuper = true) @NoArgsConstructor @SuperBuilder public class CustomerFields extends AbstractEntityFields { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/DashboardFields.java b/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/DashboardFields.java index 608a64436e..786a27fce9 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/DashboardFields.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/DashboardFields.java @@ -29,7 +29,7 @@ import java.util.UUID; @Data -@EqualsAndHashCode(callSuper = false) +@EqualsAndHashCode(callSuper = true) @NoArgsConstructor @SuperBuilder public class DashboardFields extends AbstractEntityFields { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/DeviceFields.java b/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/DeviceFields.java index ef8aee952b..df72525990 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/DeviceFields.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/DeviceFields.java @@ -27,7 +27,7 @@ import java.util.UUID; import static org.thingsboard.server.common.data.edqs.fields.FieldsUtil.getText; @Data -@EqualsAndHashCode(callSuper = false) +@EqualsAndHashCode(callSuper = true) @NoArgsConstructor @SuperBuilder public class DeviceFields extends AbstractEntityFields implements ProfileAwareFields { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/DeviceProfileFields.java b/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/DeviceProfileFields.java index 2331829054..d7f6cf13bb 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/DeviceProfileFields.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/DeviceProfileFields.java @@ -24,7 +24,7 @@ import org.thingsboard.server.common.data.DeviceProfileType; import java.util.UUID; @Data -@EqualsAndHashCode(callSuper = false) +@EqualsAndHashCode(callSuper = true) @NoArgsConstructor @SuperBuilder public class DeviceProfileFields extends AbstractEntityFields { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/EdgeFields.java b/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/EdgeFields.java index e048eb22a8..24ac1fcd35 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/EdgeFields.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/EdgeFields.java @@ -26,7 +26,7 @@ import java.util.UUID; import static org.thingsboard.server.common.data.edqs.fields.FieldsUtil.getText; @Data -@EqualsAndHashCode(callSuper = false) +@EqualsAndHashCode(callSuper = true) @NoArgsConstructor @SuperBuilder public class EdgeFields extends AbstractEntityFields { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/EntityViewFields.java b/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/EntityViewFields.java index c5027dfc8f..d21d495cf1 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/EntityViewFields.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/EntityViewFields.java @@ -26,7 +26,7 @@ import java.util.UUID; import static org.thingsboard.server.common.data.edqs.fields.FieldsUtil.getText; @Data -@EqualsAndHashCode(callSuper = false) +@EqualsAndHashCode(callSuper = true) @NoArgsConstructor @SuperBuilder public class EntityViewFields extends AbstractEntityFields { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/QueueStatsFields.java b/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/QueueStatsFields.java index 5c5a139364..3e8a1136bc 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/QueueStatsFields.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/QueueStatsFields.java @@ -23,7 +23,7 @@ import lombok.experimental.SuperBuilder; import java.util.UUID; @Data -@EqualsAndHashCode(callSuper = false) +@EqualsAndHashCode(callSuper = true) @NoArgsConstructor @SuperBuilder public class QueueStatsFields extends AbstractEntityFields { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/RuleChainFields.java b/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/RuleChainFields.java index d580f6b913..d8dd1c8a43 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/RuleChainFields.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/RuleChainFields.java @@ -26,7 +26,7 @@ import java.util.UUID; import static org.thingsboard.server.common.data.edqs.fields.FieldsUtil.getText; @Data -@EqualsAndHashCode(callSuper = false) +@EqualsAndHashCode(callSuper = true) @NoArgsConstructor @SuperBuilder public class RuleChainFields extends AbstractEntityFields { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/TenantFields.java b/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/TenantFields.java index ba350fec54..3fda35d969 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/TenantFields.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/TenantFields.java @@ -26,7 +26,7 @@ import java.util.UUID; import static org.thingsboard.server.common.data.edqs.fields.FieldsUtil.getText; @Data -@EqualsAndHashCode(callSuper = false) +@EqualsAndHashCode(callSuper = true) @NoArgsConstructor @SuperBuilder public class TenantFields extends AbstractEntityFields { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/TenantProfileFields.java b/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/TenantProfileFields.java index 5d1ff0e0e2..28f257bbf2 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/TenantProfileFields.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/TenantProfileFields.java @@ -24,7 +24,7 @@ import org.thingsboard.server.common.data.id.TenantId; import java.util.UUID; @Data -@EqualsAndHashCode(callSuper = false) +@EqualsAndHashCode(callSuper = true) @NoArgsConstructor @SuperBuilder public class TenantProfileFields extends AbstractEntityFields { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/UserFields.java b/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/UserFields.java index 70fde8bf9c..723b618d7c 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/UserFields.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/edqs/fields/UserFields.java @@ -26,7 +26,7 @@ import java.util.UUID; import static org.thingsboard.server.common.data.edqs.fields.FieldsUtil.getText; @Data -@EqualsAndHashCode(callSuper = false) +@EqualsAndHashCode(callSuper = true) @NoArgsConstructor @SuperBuilder public class UserFields extends AbstractEntityFields { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/kv/BaseDeleteTsKvQuery.java b/common/data/src/main/java/org/thingsboard/server/common/data/kv/BaseDeleteTsKvQuery.java index f46339c15a..8ca4070671 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/kv/BaseDeleteTsKvQuery.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/kv/BaseDeleteTsKvQuery.java @@ -19,7 +19,7 @@ import lombok.Data; import lombok.EqualsAndHashCode; @Data -@EqualsAndHashCode(callSuper = false) +@EqualsAndHashCode(callSuper = true) public class BaseDeleteTsKvQuery extends BaseTsKvQuery implements DeleteTsKvQuery { private final Boolean rewriteLatestIfDeleted; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/query/AlarmCountQuery.java b/common/data/src/main/java/org/thingsboard/server/common/data/query/AlarmCountQuery.java index 1599413c1c..77003a9452 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/query/AlarmCountQuery.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/query/AlarmCountQuery.java @@ -31,7 +31,7 @@ import java.util.List; @NoArgsConstructor @AllArgsConstructor @Data -@EqualsAndHashCode(callSuper = false) +@EqualsAndHashCode(callSuper = true) @ToString public class AlarmCountQuery extends EntityCountQuery { private long startTs; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/queue/Queue.java b/common/data/src/main/java/org/thingsboard/server/common/data/queue/Queue.java index d6a4f2b12f..1e48b66c92 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/queue/Queue.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/queue/Queue.java @@ -31,7 +31,7 @@ import org.thingsboard.server.common.data.validation.NoXss; import java.util.Optional; @Data -@EqualsAndHashCode(callSuper = false) +@EqualsAndHashCode(callSuper = true) public class Queue extends BaseDataWithAdditionalInfo implements HasName, HasTenantId, QueueConfig { private TenantId tenantId; @NoXss diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleNodeState.java b/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleNodeState.java index 0624350d7e..77c2b2068c 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleNodeState.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleNodeState.java @@ -23,7 +23,7 @@ import org.thingsboard.server.common.data.id.RuleNodeId; import org.thingsboard.server.common.data.id.RuleNodeStateId; @Data -@EqualsAndHashCode(callSuper = false) +@EqualsAndHashCode(callSuper = true) public class RuleNodeState extends BaseData { private RuleNodeId ruleNodeId; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/widget/WidgetTypeInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/widget/WidgetTypeInfo.java index 9acce93aa3..34f397f0ed 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/widget/WidgetTypeInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/widget/WidgetTypeInfo.java @@ -27,7 +27,7 @@ import java.util.Collections; import java.util.List; @Data -@EqualsAndHashCode(callSuper = false) +@EqualsAndHashCode(callSuper = true) public class WidgetTypeInfo extends BaseWidgetType { @Serial diff --git a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/limits/GatewaySessionLimits.java b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/limits/GatewaySessionLimits.java index 8356a17748..641f52bbd3 100644 --- a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/limits/GatewaySessionLimits.java +++ b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/limits/GatewaySessionLimits.java @@ -19,7 +19,7 @@ import lombok.Data; import lombok.EqualsAndHashCode; @Data -@EqualsAndHashCode(callSuper = false) +@EqualsAndHashCode(callSuper = true) public class GatewaySessionLimits extends SessionLimits { private SessionRateLimits gatewayRateLimits; diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sqlts/latest/TsKvLatestEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sqlts/latest/TsKvLatestEntity.java index 421a22a9d2..4d8a7de22a 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sqlts/latest/TsKvLatestEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sqlts/latest/TsKvLatestEntity.java @@ -36,7 +36,7 @@ import java.util.UUID; import static org.thingsboard.server.dao.model.ModelConstants.VERSION_COLUMN; @Data -@EqualsAndHashCode(callSuper = false) +@EqualsAndHashCode(callSuper = true) @Entity @Table(name = "ts_kv_latest") @IdClass(TsKvLatestCompositeKey.class) diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbClearAlarmNodeConfiguration.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbClearAlarmNodeConfiguration.java index ab305919fd..a98e04e591 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbClearAlarmNodeConfiguration.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbClearAlarmNodeConfiguration.java @@ -21,7 +21,7 @@ import org.thingsboard.rule.engine.api.NodeConfiguration; import org.thingsboard.server.common.data.script.ScriptLanguage; @Data -@EqualsAndHashCode(callSuper = false) +@EqualsAndHashCode(callSuper = true) public class TbClearAlarmNodeConfiguration extends TbAbstractAlarmNodeConfiguration implements NodeConfiguration { @Override diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbCreateAlarmNodeConfiguration.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbCreateAlarmNodeConfiguration.java index bf305a55d1..c97ef31e73 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbCreateAlarmNodeConfiguration.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbCreateAlarmNodeConfiguration.java @@ -26,7 +26,7 @@ import java.util.Collections; import java.util.List; @Data -@EqualsAndHashCode(callSuper = false) +@EqualsAndHashCode(callSuper = true) public class TbCreateAlarmNodeConfiguration extends TbAbstractAlarmNodeConfiguration implements NodeConfiguration { @NoXss diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/geo/TbGpsGeofencingActionNodeConfiguration.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/geo/TbGpsGeofencingActionNodeConfiguration.java index 6551352823..bafc4fb64e 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/geo/TbGpsGeofencingActionNodeConfiguration.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/geo/TbGpsGeofencingActionNodeConfiguration.java @@ -25,7 +25,7 @@ import java.util.concurrent.TimeUnit; * Created by ashvayka on 19.01.18. */ @Data -@EqualsAndHashCode(callSuper = false) +@EqualsAndHashCode(callSuper = true) public class TbGpsGeofencingActionNodeConfiguration extends TbGpsGeofencingFilterNodeConfiguration { private int minInsideDuration; diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/mqtt/azure/AzureIotHubSasCredentials.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/mqtt/azure/AzureIotHubSasCredentials.java index 93d1ef7ef8..4b9550b1d9 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/mqtt/azure/AzureIotHubSasCredentials.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/mqtt/azure/AzureIotHubSasCredentials.java @@ -30,7 +30,7 @@ import org.thingsboard.rule.engine.credentials.CredentialsType; import java.security.Security; @Data -@EqualsAndHashCode(callSuper = false) +@EqualsAndHashCode(callSuper = true) @Slf4j @JsonIgnoreProperties(ignoreUnknown = true) public class AzureIotHubSasCredentials extends CertPemCredentials { diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/mqtt/azure/TbAzureIotHubNodeConfiguration.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/mqtt/azure/TbAzureIotHubNodeConfiguration.java index f11173f3f9..3362526e70 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/mqtt/azure/TbAzureIotHubNodeConfiguration.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/mqtt/azure/TbAzureIotHubNodeConfiguration.java @@ -21,7 +21,7 @@ import lombok.EqualsAndHashCode; import org.thingsboard.rule.engine.mqtt.TbMqttNodeConfiguration; @Data -@EqualsAndHashCode(callSuper = false) +@EqualsAndHashCode(callSuper = true) public class TbAzureIotHubNodeConfiguration extends TbMqttNodeConfiguration { @Override From c0dead85520dcdecc5ee0435e48b16d8fcc0265b Mon Sep 17 00:00:00 2001 From: Viacheslav Klimov Date: Fri, 3 Jul 2026 12:42:58 +0300 Subject: [PATCH 53/91] Address review comments: rename test config class and drop inline FQN annotations --- .../device/provision/DeviceProvisionServiceTest.java | 10 ++++++---- .../service/queue/DefaultTbClusterServiceTest.java | 3 ++- .../transport/DefaultTransportApiServiceTest.java | 10 ++++++---- 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/application/src/test/java/org/thingsboard/server/service/device/provision/DeviceProvisionServiceTest.java b/application/src/test/java/org/thingsboard/server/service/device/provision/DeviceProvisionServiceTest.java index 4f2eaa5147..4d0195c816 100644 --- a/application/src/test/java/org/thingsboard/server/service/device/provision/DeviceProvisionServiceTest.java +++ b/application/src/test/java/org/thingsboard/server/service/device/provision/DeviceProvisionServiceTest.java @@ -21,6 +21,8 @@ import org.assertj.core.api.Assertions; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.springframework.test.context.ContextConfiguration; @@ -73,12 +75,12 @@ import static org.mockito.Mockito.when; @Slf4j @RunWith(SpringRunner.class) -@ContextConfiguration(classes = DeviceProvisionServiceTest.ContextConfiguration.class) +@ContextConfiguration(classes = DeviceProvisionServiceTest.TestConfig.class) public class DeviceProvisionServiceTest { - @org.springframework.context.annotation.Configuration - static class ContextConfiguration { - @org.springframework.context.annotation.Bean + @Configuration + static class TestConfig { + @Bean public DeviceProvisionServiceImpl deviceProvisionService(TbQueueProducerProvider producerProvider, DeviceProfileService deviceProfileService, DeviceService deviceService, diff --git a/application/src/test/java/org/thingsboard/server/service/queue/DefaultTbClusterServiceTest.java b/application/src/test/java/org/thingsboard/server/service/queue/DefaultTbClusterServiceTest.java index 79b31acf78..b4f36d9bb5 100644 --- a/application/src/test/java/org/thingsboard/server/service/queue/DefaultTbClusterServiceTest.java +++ b/application/src/test/java/org/thingsboard/server/service/queue/DefaultTbClusterServiceTest.java @@ -17,6 +17,7 @@ package org.thingsboard.server.service.queue; import com.google.common.collect.Sets; import lombok.extern.slf4j.Slf4j; +import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; @@ -115,7 +116,7 @@ public class DefaultTbClusterServiceTest { @MockitoSpyBean protected TbClusterService clusterService; - @org.junit.Before + @Before public void setUp() { lenient().when(topicService.getNotificationsTopic(any(), any())).thenAnswer(invocation -> { ServiceType serviceType = invocation.getArgument(0); diff --git a/application/src/test/java/org/thingsboard/server/service/transport/DefaultTransportApiServiceTest.java b/application/src/test/java/org/thingsboard/server/service/transport/DefaultTransportApiServiceTest.java index 6b667cc811..be3cc2e92b 100644 --- a/application/src/test/java/org/thingsboard/server/service/transport/DefaultTransportApiServiceTest.java +++ b/application/src/test/java/org/thingsboard/server/service/transport/DefaultTransportApiServiceTest.java @@ -20,6 +20,8 @@ import lombok.extern.slf4j.Slf4j; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.springframework.test.context.ContextConfiguration; @@ -69,12 +71,12 @@ import static org.mockito.Mockito.when; @Slf4j @RunWith(SpringRunner.class) -@ContextConfiguration(classes = DefaultTransportApiServiceTest.ContextConfiguration.class) +@ContextConfiguration(classes = DefaultTransportApiServiceTest.TestConfig.class) public class DefaultTransportApiServiceTest { - @org.springframework.context.annotation.Configuration - static class ContextConfiguration { - @org.springframework.context.annotation.Bean + @Configuration + static class TestConfig { + @Bean public DefaultTransportApiService defaultTransportApiService(TbDeviceProfileCache deviceProfileCache, TbTenantProfileCache tenantProfileCache, TbApiUsageStateService apiUsageStateService, From 432262f358f3e844ec942d65d533fa0890ddf9dc Mon Sep 17 00:00:00 2001 From: Oleksandra Matviienko Date: Sun, 5 Jul 2026 22:47:04 +0200 Subject: [PATCH 54/91] Fix AlarmCommentControllerTest delete assertions for callSuper=true The deprecation cleanup set @EqualsAndHashCode(callSuper = true) on AlarmComment, so equals/hashCode now include the BaseData id and createdTime. The delete tests built the expected comment via a fresh builder (no id), which no longer matches the server-generated deletion comment (which reuses the original comment id). Mutate the original alarm comment (already carrying the correct id/createdTime) into the expected SYSTEM deletion comment instead of building a fresh one. --- .../AlarmCommentControllerTest.java | 48 ++++++++----------- 1 file changed, 21 insertions(+), 27 deletions(-) diff --git a/application/src/test/java/org/thingsboard/server/controller/AlarmCommentControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/AlarmCommentControllerTest.java index c778916d02..df6edaaac8 100644 --- a/application/src/test/java/org/thingsboard/server/controller/AlarmCommentControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/AlarmCommentControllerTest.java @@ -226,15 +226,13 @@ public class AlarmCommentControllerTest extends AbstractControllerTest { doDelete("/api/alarm/" + alarm.getId() + "/comment/" + alarmComment.getId()) .andExpect(status().isOk()); - AlarmComment expectedAlarmComment = AlarmComment.builder() - .alarmId(alarm.getId()) - .type(AlarmCommentType.SYSTEM) - .comment(JacksonUtil.newObjectNode() - .put("text", String.format(COMMENT_DELETED.getText(), CUSTOMER_USER_EMAIL)) - .put("subtype", COMMENT_DELETED.name()) - .put("userName", CUSTOMER_USER_EMAIL)) - .build(); - testLogEntityActionEntityEqClass(alarm, alarm.getId(), tenantId, customerId, customerUserId, CUSTOMER_USER_EMAIL, ActionType.DELETED_COMMENT, 1, expectedAlarmComment); + alarmComment.setType(AlarmCommentType.SYSTEM); + alarmComment.setUserId(null); + alarmComment.setComment(JacksonUtil.newObjectNode() + .put("text", String.format(COMMENT_DELETED.getText(), CUSTOMER_USER_EMAIL)) + .put("subtype", COMMENT_DELETED.name()) + .put("userName", CUSTOMER_USER_EMAIL)); + testLogEntityActionEntityEqClass(alarm, alarm.getId(), tenantId, customerId, customerUserId, CUSTOMER_USER_EMAIL, ActionType.DELETED_COMMENT, 1, alarmComment); } @Test @@ -252,15 +250,13 @@ public class AlarmCommentControllerTest extends AbstractControllerTest { loginTenantAdmin(); doDelete("/api/alarm/" + alarm.getId() + "/comment/" + alarmComment.getId()) .andExpect(status().isOk()); - AlarmComment expectedAlarmComment = AlarmComment.builder() - .alarmId(alarm.getId()) - .type(AlarmCommentType.SYSTEM) - .comment(JacksonUtil.newObjectNode() - .put("text", String.format(COMMENT_DELETED.getText(), TENANT_ADMIN_EMAIL)) - .put("subtype", COMMENT_DELETED.name()) - .put("userName", TENANT_ADMIN_EMAIL)) - .build(); - testLogEntityActionEntityEqClass(alarm, alarm.getId(), tenantId, customerId, tenantAdminUserId, TENANT_ADMIN_EMAIL, ActionType.DELETED_COMMENT, 1, expectedAlarmComment); + alarmComment.setType(AlarmCommentType.SYSTEM); + alarmComment.setUserId(null); + alarmComment.setComment(JacksonUtil.newObjectNode() + .put("text", String.format(COMMENT_DELETED.getText(), TENANT_ADMIN_EMAIL)) + .put("subtype", COMMENT_DELETED.name()) + .put("userName", TENANT_ADMIN_EMAIL)); + testLogEntityActionEntityEqClass(alarm, alarm.getId(), tenantId, customerId, tenantAdminUserId, TENANT_ADMIN_EMAIL, ActionType.DELETED_COMMENT, 1, alarmComment); } @Test @@ -285,15 +281,13 @@ public class AlarmCommentControllerTest extends AbstractControllerTest { assertThat(systemComment.getComment().get("text").asText()).isEqualTo(String.format("Comment was deleted by user %s", TENANT_ADMIN_EMAIL)); - AlarmComment expectedAlarmComment = AlarmComment.builder() - .alarmId(alarm.getId()) - .type(AlarmCommentType.SYSTEM) - .comment(JacksonUtil.newObjectNode() - .put("text", String.format(COMMENT_DELETED.getText(), TENANT_ADMIN_EMAIL)) - .put("subtype", COMMENT_DELETED.name()) - .put("userName", TENANT_ADMIN_EMAIL)) - .build(); - testLogEntityActionEntityEqClass(alarm, alarm.getId(), tenantId, customerId, tenantAdminUserId, TENANT_ADMIN_EMAIL, ActionType.DELETED_COMMENT, 1, expectedAlarmComment); + alarmComment.setType(AlarmCommentType.SYSTEM); + alarmComment.setUserId(null); + alarmComment.setComment(JacksonUtil.newObjectNode() + .put("text", String.format(COMMENT_DELETED.getText(), TENANT_ADMIN_EMAIL)) + .put("subtype", COMMENT_DELETED.name()) + .put("userName", TENANT_ADMIN_EMAIL)); + testLogEntityActionEntityEqClass(alarm, alarm.getId(), tenantId, customerId, tenantAdminUserId, TENANT_ADMIN_EMAIL, ActionType.DELETED_COMMENT, 1, alarmComment); } @Test From e2969dd381e154faa31f3532b238d7e0dac6f2be Mon Sep 17 00:00:00 2001 From: Viacheslav Klimov Date: Mon, 6 Jul 2026 11:59:25 +0300 Subject: [PATCH 55/91] Version set to 4.2.2.4-SNAPSHOT --- application/pom.xml | 2 +- common/actor/pom.xml | 2 +- common/cache/pom.xml | 2 +- common/cluster-api/pom.xml | 2 +- common/coap-server/pom.xml | 2 +- common/dao-api/pom.xml | 2 +- common/data/pom.xml | 2 +- common/discovery-api/pom.xml | 2 +- common/edge-api/pom.xml | 2 +- common/edge-api/src/main/proto/edge.proto | 1 + common/edqs/pom.xml | 2 +- common/message/pom.xml | 2 +- common/pom.xml | 2 +- common/proto/pom.xml | 2 +- common/queue/pom.xml | 2 +- common/script/pom.xml | 2 +- common/script/remote-js-client/pom.xml | 2 +- common/script/script-api/pom.xml | 2 +- common/stats/pom.xml | 2 +- common/transport/coap/pom.xml | 2 +- common/transport/http/pom.xml | 2 +- common/transport/lwm2m/pom.xml | 2 +- common/transport/mqtt/pom.xml | 2 +- common/transport/pom.xml | 2 +- common/transport/snmp/pom.xml | 2 +- common/transport/transport-api/pom.xml | 2 +- common/util/pom.xml | 2 +- common/version-control/pom.xml | 2 +- dao/pom.xml | 2 +- edqs/pom.xml | 2 +- monitoring/pom.xml | 2 +- msa/black-box-tests/pom.xml | 2 +- msa/edqs/pom.xml | 2 +- msa/js-executor/package.json | 2 +- msa/js-executor/pom.xml | 2 +- msa/monitoring/pom.xml | 2 +- msa/pom.xml | 2 +- msa/tb-node/pom.xml | 2 +- msa/tb/pom.xml | 2 +- msa/transport/coap/pom.xml | 2 +- msa/transport/http/pom.xml | 2 +- msa/transport/lwm2m/pom.xml | 2 +- msa/transport/mqtt/pom.xml | 2 +- msa/transport/pom.xml | 2 +- msa/transport/snmp/pom.xml | 2 +- msa/vc-executor-docker/pom.xml | 2 +- msa/vc-executor/pom.xml | 2 +- msa/web-ui/package.json | 2 +- msa/web-ui/pom.xml | 2 +- netty-mqtt/pom.xml | 4 ++-- pom.xml | 2 +- rest-client/pom.xml | 2 +- rule-engine/pom.xml | 2 +- rule-engine/rule-engine-api/pom.xml | 2 +- rule-engine/rule-engine-components/pom.xml | 2 +- tools/pom.xml | 2 +- transport/coap/pom.xml | 2 +- transport/http/pom.xml | 2 +- transport/lwm2m/pom.xml | 2 +- transport/mqtt/pom.xml | 2 +- transport/pom.xml | 2 +- transport/snmp/pom.xml | 2 +- ui-ngx/package.json | 2 +- ui-ngx/pom.xml | 2 +- 64 files changed, 65 insertions(+), 64 deletions(-) diff --git a/application/pom.xml b/application/pom.xml index 1ae95e99ed..9a46bbdc3a 100644 --- a/application/pom.xml +++ b/application/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 4.2.2.3-SNAPSHOT + 4.2.2.4-SNAPSHOT thingsboard application diff --git a/common/actor/pom.xml b/common/actor/pom.xml index 61ff41ce80..7d6aba753b 100644 --- a/common/actor/pom.xml +++ b/common/actor/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 4.2.2.3-SNAPSHOT + 4.2.2.4-SNAPSHOT common org.thingsboard.common diff --git a/common/cache/pom.xml b/common/cache/pom.xml index a9d43c9ec1..4db50b2380 100644 --- a/common/cache/pom.xml +++ b/common/cache/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 4.2.2.3-SNAPSHOT + 4.2.2.4-SNAPSHOT common org.thingsboard.common diff --git a/common/cluster-api/pom.xml b/common/cluster-api/pom.xml index 987e6e2ffe..48d931bb53 100644 --- a/common/cluster-api/pom.xml +++ b/common/cluster-api/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 4.2.2.3-SNAPSHOT + 4.2.2.4-SNAPSHOT common org.thingsboard.common diff --git a/common/coap-server/pom.xml b/common/coap-server/pom.xml index c1a83ee870..d6d1d1d69b 100644 --- a/common/coap-server/pom.xml +++ b/common/coap-server/pom.xml @@ -22,7 +22,7 @@ 4.0.0 org.thingsboard - 4.2.2.3-SNAPSHOT + 4.2.2.4-SNAPSHOT common org.thingsboard.common diff --git a/common/dao-api/pom.xml b/common/dao-api/pom.xml index c9cfeae4e7..a0f9a8be78 100644 --- a/common/dao-api/pom.xml +++ b/common/dao-api/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 4.2.2.3-SNAPSHOT + 4.2.2.4-SNAPSHOT common org.thingsboard.common diff --git a/common/data/pom.xml b/common/data/pom.xml index 450a0826b9..a2b9dce687 100644 --- a/common/data/pom.xml +++ b/common/data/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 4.2.2.3-SNAPSHOT + 4.2.2.4-SNAPSHOT common org.thingsboard.common diff --git a/common/discovery-api/pom.xml b/common/discovery-api/pom.xml index 1c3b34f6f4..38774d93f7 100644 --- a/common/discovery-api/pom.xml +++ b/common/discovery-api/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 4.2.2.3-SNAPSHOT + 4.2.2.4-SNAPSHOT common org.thingsboard.common diff --git a/common/edge-api/pom.xml b/common/edge-api/pom.xml index ff630f416c..9141a164d8 100644 --- a/common/edge-api/pom.xml +++ b/common/edge-api/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 4.2.2.3-SNAPSHOT + 4.2.2.4-SNAPSHOT common org.thingsboard.common diff --git a/common/edge-api/src/main/proto/edge.proto b/common/edge-api/src/main/proto/edge.proto index 520b4ac493..376a4d8c5b 100644 --- a/common/edge-api/src/main/proto/edge.proto +++ b/common/edge-api/src/main/proto/edge.proto @@ -49,6 +49,7 @@ enum EdgeVersion { V_4_2_2_1 = 4221; V_4_2_2_2 = 4222; V_4_2_2_3 = 4223; + V_4_2_2_4 = 4224; V_LATEST = 99999; } diff --git a/common/edqs/pom.xml b/common/edqs/pom.xml index f107721524..ae62259f79 100644 --- a/common/edqs/pom.xml +++ b/common/edqs/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 4.2.2.3-SNAPSHOT + 4.2.2.4-SNAPSHOT common org.thingsboard.common diff --git a/common/message/pom.xml b/common/message/pom.xml index d9184ac548..d338f57946 100644 --- a/common/message/pom.xml +++ b/common/message/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 4.2.2.3-SNAPSHOT + 4.2.2.4-SNAPSHOT common org.thingsboard.common diff --git a/common/pom.xml b/common/pom.xml index f63c12d7dc..1eb2dc44b2 100644 --- a/common/pom.xml +++ b/common/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 4.2.2.3-SNAPSHOT + 4.2.2.4-SNAPSHOT thingsboard common diff --git a/common/proto/pom.xml b/common/proto/pom.xml index 5335df00b9..c2f898bb38 100644 --- a/common/proto/pom.xml +++ b/common/proto/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 4.2.2.3-SNAPSHOT + 4.2.2.4-SNAPSHOT common org.thingsboard.common diff --git a/common/queue/pom.xml b/common/queue/pom.xml index 8e684718a0..e714fc749b 100644 --- a/common/queue/pom.xml +++ b/common/queue/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 4.2.2.3-SNAPSHOT + 4.2.2.4-SNAPSHOT common org.thingsboard.common diff --git a/common/script/pom.xml b/common/script/pom.xml index cdfe36cd3c..46a97d2ece 100644 --- a/common/script/pom.xml +++ b/common/script/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 4.2.2.3-SNAPSHOT + 4.2.2.4-SNAPSHOT common org.thingsboard.common diff --git a/common/script/remote-js-client/pom.xml b/common/script/remote-js-client/pom.xml index 9f179e9b1a..0f9191e3cc 100644 --- a/common/script/remote-js-client/pom.xml +++ b/common/script/remote-js-client/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard.common - 4.2.2.3-SNAPSHOT + 4.2.2.4-SNAPSHOT script org.thingsboard.common.script diff --git a/common/script/script-api/pom.xml b/common/script/script-api/pom.xml index 5791fefc6a..6752190015 100644 --- a/common/script/script-api/pom.xml +++ b/common/script/script-api/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard.common - 4.2.2.3-SNAPSHOT + 4.2.2.4-SNAPSHOT script org.thingsboard.common.script diff --git a/common/stats/pom.xml b/common/stats/pom.xml index 0de5ffe6ea..ae013f938c 100644 --- a/common/stats/pom.xml +++ b/common/stats/pom.xml @@ -22,7 +22,7 @@ 4.0.0 org.thingsboard - 4.2.2.3-SNAPSHOT + 4.2.2.4-SNAPSHOT common org.thingsboard.common diff --git a/common/transport/coap/pom.xml b/common/transport/coap/pom.xml index a2681241c6..79c1e4c06b 100644 --- a/common/transport/coap/pom.xml +++ b/common/transport/coap/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard.common - 4.2.2.3-SNAPSHOT + 4.2.2.4-SNAPSHOT transport org.thingsboard.common.transport diff --git a/common/transport/http/pom.xml b/common/transport/http/pom.xml index 4d5b6bce44..801fb49117 100644 --- a/common/transport/http/pom.xml +++ b/common/transport/http/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard.common - 4.2.2.3-SNAPSHOT + 4.2.2.4-SNAPSHOT transport org.thingsboard.common.transport diff --git a/common/transport/lwm2m/pom.xml b/common/transport/lwm2m/pom.xml index 5da25b24d0..a4892f9f80 100644 --- a/common/transport/lwm2m/pom.xml +++ b/common/transport/lwm2m/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard.common - 4.2.2.3-SNAPSHOT + 4.2.2.4-SNAPSHOT transport org.thingsboard.common.transport diff --git a/common/transport/mqtt/pom.xml b/common/transport/mqtt/pom.xml index 9cc958cde9..a6c0686b4b 100644 --- a/common/transport/mqtt/pom.xml +++ b/common/transport/mqtt/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard.common - 4.2.2.3-SNAPSHOT + 4.2.2.4-SNAPSHOT transport org.thingsboard.common.transport diff --git a/common/transport/pom.xml b/common/transport/pom.xml index b069dbe413..dc12d0d7b5 100644 --- a/common/transport/pom.xml +++ b/common/transport/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 4.2.2.3-SNAPSHOT + 4.2.2.4-SNAPSHOT common org.thingsboard.common diff --git a/common/transport/snmp/pom.xml b/common/transport/snmp/pom.xml index 2565016226..b1b2ed7343 100644 --- a/common/transport/snmp/pom.xml +++ b/common/transport/snmp/pom.xml @@ -21,7 +21,7 @@ org.thingsboard.common - 4.2.2.3-SNAPSHOT + 4.2.2.4-SNAPSHOT transport diff --git a/common/transport/transport-api/pom.xml b/common/transport/transport-api/pom.xml index ca992646a9..a11c5b17d1 100644 --- a/common/transport/transport-api/pom.xml +++ b/common/transport/transport-api/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard.common - 4.2.2.3-SNAPSHOT + 4.2.2.4-SNAPSHOT transport org.thingsboard.common.transport diff --git a/common/util/pom.xml b/common/util/pom.xml index 3c60d4f077..db60495e95 100644 --- a/common/util/pom.xml +++ b/common/util/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 4.2.2.3-SNAPSHOT + 4.2.2.4-SNAPSHOT common org.thingsboard.common diff --git a/common/version-control/pom.xml b/common/version-control/pom.xml index 09c4318a20..28a7e6e332 100644 --- a/common/version-control/pom.xml +++ b/common/version-control/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 4.2.2.3-SNAPSHOT + 4.2.2.4-SNAPSHOT common org.thingsboard.common diff --git a/dao/pom.xml b/dao/pom.xml index 4449502857..19c089dee1 100644 --- a/dao/pom.xml +++ b/dao/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 4.2.2.3-SNAPSHOT + 4.2.2.4-SNAPSHOT thingsboard dao diff --git a/edqs/pom.xml b/edqs/pom.xml index 2d811909ec..bdae55999d 100644 --- a/edqs/pom.xml +++ b/edqs/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 4.2.2.3-SNAPSHOT + 4.2.2.4-SNAPSHOT thingsboard edqs diff --git a/monitoring/pom.xml b/monitoring/pom.xml index fa8b83c6f7..2026a40f70 100644 --- a/monitoring/pom.xml +++ b/monitoring/pom.xml @@ -21,7 +21,7 @@ 4.0.0 org.thingsboard - 4.2.2.3-SNAPSHOT + 4.2.2.4-SNAPSHOT thingsboard diff --git a/msa/black-box-tests/pom.xml b/msa/black-box-tests/pom.xml index e433d6bfb2..a78bea8969 100644 --- a/msa/black-box-tests/pom.xml +++ b/msa/black-box-tests/pom.xml @@ -21,7 +21,7 @@ org.thingsboard - 4.2.2.3-SNAPSHOT + 4.2.2.4-SNAPSHOT msa org.thingsboard.msa diff --git a/msa/edqs/pom.xml b/msa/edqs/pom.xml index 54a1cd91c7..74a6e58ad9 100644 --- a/msa/edqs/pom.xml +++ b/msa/edqs/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 4.2.2.3-SNAPSHOT + 4.2.2.4-SNAPSHOT msa org.thingsboard.msa diff --git a/msa/js-executor/package.json b/msa/js-executor/package.json index 070bf829a5..de6339b518 100644 --- a/msa/js-executor/package.json +++ b/msa/js-executor/package.json @@ -1,7 +1,7 @@ { "name": "thingsboard-js-executor", "private": true, - "version": "4.2.2.3", + "version": "4.2.2.4", "description": "ThingsBoard JavaScript Executor Microservice", "main": "server.ts", "bin": "server.js", diff --git a/msa/js-executor/pom.xml b/msa/js-executor/pom.xml index 7174947cbc..f6f7961d0e 100644 --- a/msa/js-executor/pom.xml +++ b/msa/js-executor/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 4.2.2.3-SNAPSHOT + 4.2.2.4-SNAPSHOT msa org.thingsboard.msa diff --git a/msa/monitoring/pom.xml b/msa/monitoring/pom.xml index 519c928b6e..64157d6197 100644 --- a/msa/monitoring/pom.xml +++ b/msa/monitoring/pom.xml @@ -22,7 +22,7 @@ 4.0.0 org.thingsboard - 4.2.2.3-SNAPSHOT + 4.2.2.4-SNAPSHOT msa diff --git a/msa/pom.xml b/msa/pom.xml index 2552bf188c..0847add29e 100644 --- a/msa/pom.xml +++ b/msa/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 4.2.2.3-SNAPSHOT + 4.2.2.4-SNAPSHOT thingsboard msa diff --git a/msa/tb-node/pom.xml b/msa/tb-node/pom.xml index ba83cbb211..9be443d031 100644 --- a/msa/tb-node/pom.xml +++ b/msa/tb-node/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 4.2.2.3-SNAPSHOT + 4.2.2.4-SNAPSHOT msa org.thingsboard.msa diff --git a/msa/tb/pom.xml b/msa/tb/pom.xml index a20505772e..ba18c5279b 100644 --- a/msa/tb/pom.xml +++ b/msa/tb/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 4.2.2.3-SNAPSHOT + 4.2.2.4-SNAPSHOT msa org.thingsboard.msa diff --git a/msa/transport/coap/pom.xml b/msa/transport/coap/pom.xml index 309536b4ef..f78e2f0f13 100644 --- a/msa/transport/coap/pom.xml +++ b/msa/transport/coap/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard.msa - 4.2.2.3-SNAPSHOT + 4.2.2.4-SNAPSHOT transport org.thingsboard.msa.transport diff --git a/msa/transport/http/pom.xml b/msa/transport/http/pom.xml index f7ea4160d1..ac25949c82 100644 --- a/msa/transport/http/pom.xml +++ b/msa/transport/http/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard.msa - 4.2.2.3-SNAPSHOT + 4.2.2.4-SNAPSHOT transport org.thingsboard.msa.transport diff --git a/msa/transport/lwm2m/pom.xml b/msa/transport/lwm2m/pom.xml index d80b63217c..89e99f79e2 100644 --- a/msa/transport/lwm2m/pom.xml +++ b/msa/transport/lwm2m/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard.msa - 4.2.2.3-SNAPSHOT + 4.2.2.4-SNAPSHOT transport org.thingsboard.msa.transport diff --git a/msa/transport/mqtt/pom.xml b/msa/transport/mqtt/pom.xml index 0bf990171b..eb69201745 100644 --- a/msa/transport/mqtt/pom.xml +++ b/msa/transport/mqtt/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard.msa - 4.2.2.3-SNAPSHOT + 4.2.2.4-SNAPSHOT transport org.thingsboard.msa.transport diff --git a/msa/transport/pom.xml b/msa/transport/pom.xml index a711411729..399d84763c 100644 --- a/msa/transport/pom.xml +++ b/msa/transport/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 4.2.2.3-SNAPSHOT + 4.2.2.4-SNAPSHOT msa org.thingsboard.msa diff --git a/msa/transport/snmp/pom.xml b/msa/transport/snmp/pom.xml index f0996dc1bf..330e205394 100644 --- a/msa/transport/snmp/pom.xml +++ b/msa/transport/snmp/pom.xml @@ -21,7 +21,7 @@ org.thingsboard.msa transport - 4.2.2.3-SNAPSHOT + 4.2.2.4-SNAPSHOT org.thingsboard.msa.transport diff --git a/msa/vc-executor-docker/pom.xml b/msa/vc-executor-docker/pom.xml index 9d781e0854..fc8779250a 100644 --- a/msa/vc-executor-docker/pom.xml +++ b/msa/vc-executor-docker/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 4.2.2.3-SNAPSHOT + 4.2.2.4-SNAPSHOT msa org.thingsboard.msa diff --git a/msa/vc-executor/pom.xml b/msa/vc-executor/pom.xml index 47fff0501d..4bb404284a 100644 --- a/msa/vc-executor/pom.xml +++ b/msa/vc-executor/pom.xml @@ -21,7 +21,7 @@ org.thingsboard - 4.2.2.3-SNAPSHOT + 4.2.2.4-SNAPSHOT msa org.thingsboard.msa diff --git a/msa/web-ui/package.json b/msa/web-ui/package.json index 4c58d7a94f..e5acd2a6fa 100644 --- a/msa/web-ui/package.json +++ b/msa/web-ui/package.json @@ -1,7 +1,7 @@ { "name": "thingsboard-web-ui", "private": true, - "version": "4.2.2.3", + "version": "4.2.2.4", "description": "ThingsBoard Web UI Microservice", "main": "server.ts", "bin": "server.js", diff --git a/msa/web-ui/pom.xml b/msa/web-ui/pom.xml index bc40e149ff..738118d4f8 100644 --- a/msa/web-ui/pom.xml +++ b/msa/web-ui/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 4.2.2.3-SNAPSHOT + 4.2.2.4-SNAPSHOT msa org.thingsboard.msa diff --git a/netty-mqtt/pom.xml b/netty-mqtt/pom.xml index 6a2b55cd84..9cc1f94bbe 100644 --- a/netty-mqtt/pom.xml +++ b/netty-mqtt/pom.xml @@ -19,11 +19,11 @@ 4.0.0 org.thingsboard - 4.2.2.3-SNAPSHOT + 4.2.2.4-SNAPSHOT thingsboard netty-mqtt - 4.2.2.3-SNAPSHOT + 4.2.2.4-SNAPSHOT jar Netty MQTT Client diff --git a/pom.xml b/pom.xml index 1a2faa6cb7..7d42f9f1c7 100755 --- a/pom.xml +++ b/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard thingsboard - 4.2.2.3-SNAPSHOT + 4.2.2.4-SNAPSHOT pom Thingsboard diff --git a/rest-client/pom.xml b/rest-client/pom.xml index 9051482016..ceadf1d118 100644 --- a/rest-client/pom.xml +++ b/rest-client/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 4.2.2.3-SNAPSHOT + 4.2.2.4-SNAPSHOT thingsboard rest-client diff --git a/rule-engine/pom.xml b/rule-engine/pom.xml index 2c73670dde..75bd4e06ed 100644 --- a/rule-engine/pom.xml +++ b/rule-engine/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 4.2.2.3-SNAPSHOT + 4.2.2.4-SNAPSHOT thingsboard rule-engine diff --git a/rule-engine/rule-engine-api/pom.xml b/rule-engine/rule-engine-api/pom.xml index 8d9b6e5cbc..f45cd15c34 100644 --- a/rule-engine/rule-engine-api/pom.xml +++ b/rule-engine/rule-engine-api/pom.xml @@ -22,7 +22,7 @@ 4.0.0 org.thingsboard - 4.2.2.3-SNAPSHOT + 4.2.2.4-SNAPSHOT rule-engine org.thingsboard.rule-engine diff --git a/rule-engine/rule-engine-components/pom.xml b/rule-engine/rule-engine-components/pom.xml index dcb0f975f2..c6c2429a4f 100644 --- a/rule-engine/rule-engine-components/pom.xml +++ b/rule-engine/rule-engine-components/pom.xml @@ -22,7 +22,7 @@ 4.0.0 org.thingsboard - 4.2.2.3-SNAPSHOT + 4.2.2.4-SNAPSHOT rule-engine org.thingsboard.rule-engine diff --git a/tools/pom.xml b/tools/pom.xml index 137dbaa1a7..86a17be7a5 100644 --- a/tools/pom.xml +++ b/tools/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 4.2.2.3-SNAPSHOT + 4.2.2.4-SNAPSHOT thingsboard tools diff --git a/transport/coap/pom.xml b/transport/coap/pom.xml index 4fef3b50e7..cf4374ad9e 100644 --- a/transport/coap/pom.xml +++ b/transport/coap/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 4.2.2.3-SNAPSHOT + 4.2.2.4-SNAPSHOT transport org.thingsboard.transport diff --git a/transport/http/pom.xml b/transport/http/pom.xml index 8d24e0d982..d5ff0be961 100644 --- a/transport/http/pom.xml +++ b/transport/http/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 4.2.2.3-SNAPSHOT + 4.2.2.4-SNAPSHOT transport org.thingsboard.transport diff --git a/transport/lwm2m/pom.xml b/transport/lwm2m/pom.xml index 99b98fa7c9..1d0fe86220 100644 --- a/transport/lwm2m/pom.xml +++ b/transport/lwm2m/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 4.2.2.3-SNAPSHOT + 4.2.2.4-SNAPSHOT transport org.thingsboard.transport diff --git a/transport/mqtt/pom.xml b/transport/mqtt/pom.xml index 1d61b07440..e1c9512d05 100644 --- a/transport/mqtt/pom.xml +++ b/transport/mqtt/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 4.2.2.3-SNAPSHOT + 4.2.2.4-SNAPSHOT transport org.thingsboard.transport diff --git a/transport/pom.xml b/transport/pom.xml index 3889d8d334..16052972cd 100644 --- a/transport/pom.xml +++ b/transport/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 4.2.2.3-SNAPSHOT + 4.2.2.4-SNAPSHOT thingsboard transport diff --git a/transport/snmp/pom.xml b/transport/snmp/pom.xml index a1f9d384f1..cc18e3a815 100644 --- a/transport/snmp/pom.xml +++ b/transport/snmp/pom.xml @@ -21,7 +21,7 @@ org.thingsboard - 4.2.2.3-SNAPSHOT + 4.2.2.4-SNAPSHOT transport diff --git a/ui-ngx/package.json b/ui-ngx/package.json index 2ac8b3a6d7..09d354e3a3 100644 --- a/ui-ngx/package.json +++ b/ui-ngx/package.json @@ -1,6 +1,6 @@ { "name": "thingsboard", - "version": "4.2.2.3", + "version": "4.2.2.4", "scripts": { "ng": "ng", "start": "node --max_old_space_size=8048 ./node_modules/@angular/cli/bin/ng serve --configuration development --host 0.0.0.0 --open", diff --git a/ui-ngx/pom.xml b/ui-ngx/pom.xml index 863463e78c..099850fb80 100644 --- a/ui-ngx/pom.xml +++ b/ui-ngx/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 4.2.2.3-SNAPSHOT + 4.2.2.4-SNAPSHOT thingsboard org.thingsboard From 1b9b30e49c9485e2923dae5d94648d435d8599d2 Mon Sep 17 00:00:00 2001 From: Viacheslav Klimov Date: Mon, 13 Jul 2026 16:04:37 +0300 Subject: [PATCH 56/91] Move LTS version range check into LtsVersion --- .../server/service/install/lts/LtsMigrationService.java | 4 +--- .../server/service/install/lts/LtsVersion.java | 8 ++++++++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/service/install/lts/LtsMigrationService.java b/application/src/main/java/org/thingsboard/server/service/install/lts/LtsMigrationService.java index ccafa88234..580db32666 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/lts/LtsMigrationService.java +++ b/application/src/main/java/org/thingsboard/server/service/install/lts/LtsMigrationService.java @@ -126,9 +126,7 @@ public class LtsMigrationService { // so a cross-family upgrade is fully handled by the target-family migrations. // Excluding the dormant older-family beans avoids double-processing. static boolean isInRangeForTargetFamily(LtsVersion version, LtsVersion from, LtsVersion to) { - return version.sameFamily(to) - && version.compareTo(from) > 0 - && version.compareTo(to) <= 0; + return version.sameFamily(to) && version.isInRange(from, to); } private void runSchemaUpdate(String version) { diff --git a/application/src/main/java/org/thingsboard/server/service/install/lts/LtsVersion.java b/application/src/main/java/org/thingsboard/server/service/install/lts/LtsVersion.java index cb55e61b3e..9a0fa5be34 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/lts/LtsVersion.java +++ b/application/src/main/java/org/thingsboard/server/service/install/lts/LtsVersion.java @@ -37,6 +37,14 @@ public record LtsVersion(int major, int minor, int maintenance, int patch) imple return major == other.major && minor == other.minor; } + /** + * Half-open range check: {@code from < this <= to}. The lower bound is exclusive (a source already at + * {@code from} has applied that version) and the upper bound inclusive (the target version's own migration runs). + */ + public boolean isInRange(LtsVersion from, LtsVersion to) { + return compareTo(from) > 0 && compareTo(to) <= 0; + } + @Override public int compareTo(LtsVersion o) { int c = Integer.compare(major, o.major); From 4448c3c646e9597f0fe7f160cc5d90d7c753a645 Mon Sep 17 00:00:00 2001 From: Maksym Tsymbarov Date: Tue, 21 Jul 2026 11:20:07 +0200 Subject: [PATCH 57/91] Updated functionality block at System Administrator level --- ui-ngx/src/assets/dashboard/sys_admin_home_page.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ui-ngx/src/assets/dashboard/sys_admin_home_page.json b/ui-ngx/src/assets/dashboard/sys_admin_home_page.json index 739402e72f..860afa84c8 100644 --- a/ui-ngx/src/assets/dashboard/sys_admin_home_page.json +++ b/ui-ngx/src/assets/dashboard/sys_admin_home_page.json @@ -194,7 +194,8 @@ "padding": "16px", "settings": { "useMarkdownTextFunction": false, - "markdownTextPattern": "
\n
\n
\n
widgets.functions.title
\n
\n {{ 'widgets.functions.switch-to-pe' | translate }}\n
\n
\n
\n
widgets.functions.alarms
\n
widgets.functions.dashboards
\n
widgets.functions.entities-and-relations
\n
widgets.functions.profiles
\n
widgets.functions.advanced-features
\n
\n
\n
widgets.functions.notification-center
\n
widgets.functions.api-usage
\n
widgets.functions.customers
\n
widgets.functions.customers-hierarchy
\n
widgets.functions.roles-and-permissions
\n
\n
\n
widgets.functions.groups
\n
widgets.functions.integrations
\n
widgets.functions.solution-templates
\n
widgets.functions.scheduler
\n
widgets.functions.white-labeling
\n
\n
\n
", + "markdownTextPattern": "
\n
\n
\n
widgets.functions.title
\n
\n {{ 'widgets.functions.switch-to-pe' | translate }}\n
\n
\n
\n
widgets.functions.alarms
\n
widgets.functions.dashboards
\n
widgets.functions.entities-and-relations
\n
widgets.functions.profiles
\n
widgets.functions.advanced-features
\n
widgets.functions.solution-templates
\n
\n
\n
widgets.functions.notification-center
\n
widgets.functions.api-usage
\n
widgets.functions.customers
\n
widgets.functions.customers-hierarchy
\n
widgets.functions.roles-and-permissions
\n
\n
\n
widgets.functions.groups
\n
widgets.functions.integrations
\n
widgets.functions.scheduler
\n
widgets.functions.white-labeling
\n
\n
\n
", + "markdownTextFunction": "return '# Some title\\\\n - Entity name: ' + data[0]['entityName'];", "applyDefaultMarkdownStyle": false, "markdownCss": ".tb-card-header {\n display: flex;\n flex-direction: row;\n justify-content: space-between;\n align-items: center;\n}\n\n.tb-card-content {\n width: 100%;\n height: 100%;\n display: flex;\n flex-direction: row;\n margin-top: 4px;\n overflow: auto;\n}\n\n.tb-card-column {\n min-width: 0px;\n flex: 1;\n display: flex;\n flex-direction: column;\n}\n\n.feature {\n position: relative;\n cursor: default;\n font-weight: 400;\n font-size: 14px;\n line-height: 28px;\n letter-spacing: 0.2px;\n color: rgba(0, 0, 0, 0.76);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.feature:before {\n content: \"check\";\n font-family: 'Material Icons Round';\n display: inline-block;\n font-size: 20px;\n line-height: 20px;\n color: #198038;\n font-weight: 600;\n position: relative;\n background: #F3F6FA;\n border-radius: 4px;\n width: 20px;\n height: 20px;\n padding: 2px;\n vertical-align: sub;\n margin-right: 8px;\n}\n\n.feature.pe:before {\n content: \"close\";\n background: #F4F4F4;\n color: rgba(0, 0, 0, 0.12);\n}\n\n.feature.pe:after {\n position: relative;\n display: inline-block;\n margin-left: 4px;\n vertical-align: baseline;\n top: -0.5em;\n content: \"PE\";\n color: #305680;\n font-weight: 700;\n font-size: 12px;\n line-height: 12px;\n letter-spacing: 0.0015em;\n}\n\n.feature+.feature {\n margin-top: 4px;\n}\n\n@media screen and (min-width: 960px) and (max-width: 1819px) {\n .tb-switch-to-pe {\n height: 24px;\n font-size: 12px;\n padding: 0 4px;\n }\n \n .feature+.feature {\n margin-top: 2px;\n }\n \n .feature {\n font-size: 11px;\n line-height: 18px;\n }\n\n .feature:before {\n font-size: 14px;\n line-height: 14px;\n width: 14px;\n height: 14px;\n margin-right: 4px;\n }\n .feature.pe:after {\n margin-left: 2px;\n top: -0.5em;\n content: \"PE\";\n font-size: 8px;\n line-height: 8px;\n }\n \n}\n\n" }, From 7d3959036ba790fb3556009667108e841016c434 Mon Sep 17 00:00:00 2001 From: nickAS21 Date: Wed, 29 Jul 2026 13:36:34 +0300 Subject: [PATCH 58/91] sparkplug^ fix_bug close session after connect nodde --- .../mqtt/session/AbstractGatewaySessionHandler.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/session/AbstractGatewaySessionHandler.java b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/session/AbstractGatewaySessionHandler.java index 8ea6480142..905814d06d 100644 --- a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/session/AbstractGatewaySessionHandler.java +++ b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/session/AbstractGatewaySessionHandler.java @@ -845,7 +845,14 @@ public abstract class AbstractGatewaySessionHandler Date: Wed, 29 Jul 2026 14:18:20 +0300 Subject: [PATCH 59/91] sparkplug: fix_bug close session after connect nodde - 2 --- .../transport/mqtt/session/AbstractGatewaySessionHandler.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/session/AbstractGatewaySessionHandler.java b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/session/AbstractGatewaySessionHandler.java index 905814d06d..6130d49bfc 100644 --- a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/session/AbstractGatewaySessionHandler.java +++ b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/session/AbstractGatewaySessionHandler.java @@ -846,8 +846,7 @@ public abstract class AbstractGatewaySessionHandler Date: Thu, 30 Jul 2026 16:22:11 +0200 Subject: [PATCH 60/91] Changed sequence --- ui-ngx/src/assets/dashboard/sys_admin_home_page.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui-ngx/src/assets/dashboard/sys_admin_home_page.json b/ui-ngx/src/assets/dashboard/sys_admin_home_page.json index 860afa84c8..97ef4feb2d 100644 --- a/ui-ngx/src/assets/dashboard/sys_admin_home_page.json +++ b/ui-ngx/src/assets/dashboard/sys_admin_home_page.json @@ -194,7 +194,7 @@ "padding": "16px", "settings": { "useMarkdownTextFunction": false, - "markdownTextPattern": "
\n
\n
\n
widgets.functions.title
\n
\n {{ 'widgets.functions.switch-to-pe' | translate }}\n
\n
\n
\n
widgets.functions.alarms
\n
widgets.functions.dashboards
\n
widgets.functions.entities-and-relations
\n
widgets.functions.profiles
\n
widgets.functions.advanced-features
\n
widgets.functions.solution-templates
\n
\n
\n
widgets.functions.notification-center
\n
widgets.functions.api-usage
\n
widgets.functions.customers
\n
widgets.functions.customers-hierarchy
\n
widgets.functions.roles-and-permissions
\n
\n
\n
widgets.functions.groups
\n
widgets.functions.integrations
\n
widgets.functions.scheduler
\n
widgets.functions.white-labeling
\n
\n
\n
", + "markdownTextPattern": "
\n
\n
\n
widgets.functions.title
\n
\n {{ 'widgets.functions.switch-to-pe' | translate }}\n
\n
\n
\n
widgets.functions.alarms
\n
widgets.functions.dashboards
\n
widgets.functions.entities-and-relations
\n
widgets.functions.profiles
\n
widgets.functions.advanced-features
\n
\n
\n
widgets.functions.notification-center
\n
widgets.functions.api-usage
\n
widgets.functions.customers
\n
widgets.functions.solution-templates
\n
widgets.functions.customers-hierarchy
\n
\n
\n
widgets.functions.roles-and-permissions
\n
widgets.functions.groups
\n
widgets.functions.integrations
\n
widgets.functions.scheduler
\n
widgets.functions.white-labeling
\n
\n
\n
", "markdownTextFunction": "return '# Some title\\\\n - Entity name: ' + data[0]['entityName'];", "applyDefaultMarkdownStyle": false, "markdownCss": ".tb-card-header {\n display: flex;\n flex-direction: row;\n justify-content: space-between;\n align-items: center;\n}\n\n.tb-card-content {\n width: 100%;\n height: 100%;\n display: flex;\n flex-direction: row;\n margin-top: 4px;\n overflow: auto;\n}\n\n.tb-card-column {\n min-width: 0px;\n flex: 1;\n display: flex;\n flex-direction: column;\n}\n\n.feature {\n position: relative;\n cursor: default;\n font-weight: 400;\n font-size: 14px;\n line-height: 28px;\n letter-spacing: 0.2px;\n color: rgba(0, 0, 0, 0.76);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.feature:before {\n content: \"check\";\n font-family: 'Material Icons Round';\n display: inline-block;\n font-size: 20px;\n line-height: 20px;\n color: #198038;\n font-weight: 600;\n position: relative;\n background: #F3F6FA;\n border-radius: 4px;\n width: 20px;\n height: 20px;\n padding: 2px;\n vertical-align: sub;\n margin-right: 8px;\n}\n\n.feature.pe:before {\n content: \"close\";\n background: #F4F4F4;\n color: rgba(0, 0, 0, 0.12);\n}\n\n.feature.pe:after {\n position: relative;\n display: inline-block;\n margin-left: 4px;\n vertical-align: baseline;\n top: -0.5em;\n content: \"PE\";\n color: #305680;\n font-weight: 700;\n font-size: 12px;\n line-height: 12px;\n letter-spacing: 0.0015em;\n}\n\n.feature+.feature {\n margin-top: 4px;\n}\n\n@media screen and (min-width: 960px) and (max-width: 1819px) {\n .tb-switch-to-pe {\n height: 24px;\n font-size: 12px;\n padding: 0 4px;\n }\n \n .feature+.feature {\n margin-top: 2px;\n }\n \n .feature {\n font-size: 11px;\n line-height: 18px;\n }\n\n .feature:before {\n font-size: 14px;\n line-height: 14px;\n width: 14px;\n height: 14px;\n margin-right: 4px;\n }\n .feature.pe:after {\n margin-left: 2px;\n top: -0.5em;\n content: \"PE\";\n font-size: 8px;\n line-height: 8px;\n }\n \n}\n\n" From 6de4b30e5ff22848cbab5cb26eb951c5c6b685c5 Mon Sep 17 00:00:00 2001 From: Nikita Mazurenko Date: Tue, 4 Aug 2026 16:01:34 +0300 Subject: [PATCH 61/91] Unblock and interrupt edge event consumer on session destroy --- .../server/service/edge/rpc/EdgeGrpcSession.java | 2 +- .../server/service/edge/rpc/KafkaEdgeGrpcSession.java | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java index fb420d080a..1e9a0ade87 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java @@ -760,7 +760,7 @@ public abstract class EdgeGrpcSession implements Closeable { ctx.getClusterService().onEdgeEventUpdate(new EdgeEventUpdateMsg(edge.getTenantId(), edge.getId())); } - private void stopCurrentSendDownlinkMsgsTask(Boolean isInterrupted) { + protected void stopCurrentSendDownlinkMsgsTask(Boolean isInterrupted) { if (sessionState.getSendDownlinkMsgsFuture() != null && !sessionState.getSendDownlinkMsgsFuture().isDone()) { sessionState.getSendDownlinkMsgsFuture().set(isInterrupted); } diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/KafkaEdgeGrpcSession.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/KafkaEdgeGrpcSession.java index 67c0a19e66..e1acc08ba3 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/KafkaEdgeGrpcSession.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/KafkaEdgeGrpcSession.java @@ -156,6 +156,7 @@ public class KafkaEdgeGrpcSession extends EdgeGrpcSession { @Override public boolean destroy() { + stopCurrentSendDownlinkMsgsTask(true); try { if (consumer != null) { log.info("[{}][{}] Stopping edge event consumer...", tenantId, edge != null ? edge.getId() : null); @@ -180,9 +181,13 @@ public class KafkaEdgeGrpcSession extends EdgeGrpcSession { private void awaitConsumerTermination() { try { - consumerExecutor.awaitTermination(5, java.util.concurrent.TimeUnit.SECONDS); + if (!consumerExecutor.awaitTermination(5, java.util.concurrent.TimeUnit.SECONDS)) { + // without this the thread is leaked for the whole remaining delivery-retry window (or forever, if the future is never completed). + consumerExecutor.shutdownNow(); + } } catch (InterruptedException ie) { log.warn("[{}][{}] Interrupted while awaiting consumer executor termination", tenantId, edge.getId()); + Thread.currentThread().interrupt(); } } From e2617bcd8e15f34e1ed6d1240a2577e5af5f248c Mon Sep 17 00:00:00 2001 From: IrynaMatveieva Date: Wed, 5 Aug 2026 16:06:22 +0300 Subject: [PATCH 62/91] Fix TelemetryObserveStrategy enum values in OpenAPI spec --- .../device/profile/lwm2m/TelemetryObserveStrategy.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/lwm2m/TelemetryObserveStrategy.java b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/lwm2m/TelemetryObserveStrategy.java index 53dafe19b7..615bd4f32e 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/lwm2m/TelemetryObserveStrategy.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/lwm2m/TelemetryObserveStrategy.java @@ -15,8 +15,13 @@ */ package org.thingsboard.server.common.data.device.profile.lwm2m; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Getter; +@Schema(description = "Observation strategy for telemetry. " + + "SINGLE (0): one resource equals one single observe request. " + + "COMPOSITE_ALL (1): all resources in one composite observe request. " + + "COMPOSITE_BY_OBJECT (2): grouped composite observe requests by object.") public enum TelemetryObserveStrategy { SINGLE("One resource equals one single observe request", 0), @@ -52,8 +57,4 @@ public enum TelemetryObserveStrategy { throw new IllegalArgumentException("Unknown TelemetryObserveStrategy id: " + id); } - @Override - public String toString() { - return name() + " (" + id + "): " + description; - } } From 4d6600834cfc4a4f1cdf159b5634f842faad741a Mon Sep 17 00:00:00 2001 From: IrynaMatveieva Date: Thu, 6 Aug 2026 16:29:06 +0300 Subject: [PATCH 63/91] Add OpenAPI discriminator mapping to polymorphic LwM2M and job types --- .../lwm2m/LwM2MBootstrapClientCredential.java | 11 +++++++++++ .../credentials/lwm2m/LwM2MClientCredential.java | 11 +++++++++++ .../bootstrap/LwM2MBootstrapServerCredential.java | 11 +++++++++++ .../thingsboard/server/common/data/job/task/Task.java | 8 ++++++++ .../server/common/data/job/task/TaskResult.java | 8 ++++++++ 5 files changed, 49 insertions(+) diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/device/credentials/lwm2m/LwM2MBootstrapClientCredential.java b/common/data/src/main/java/org/thingsboard/server/common/data/device/credentials/lwm2m/LwM2MBootstrapClientCredential.java index 9041de33f0..008c01e7de 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/device/credentials/lwm2m/LwM2MBootstrapClientCredential.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/device/credentials/lwm2m/LwM2MBootstrapClientCredential.java @@ -19,7 +19,18 @@ 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 io.swagger.v3.oas.annotations.media.DiscriminatorMapping; +import io.swagger.v3.oas.annotations.media.Schema; +@Schema( + discriminatorProperty = "securityMode", + discriminatorMapping = { + @DiscriminatorMapping(value = "NO_SEC", schema = NoSecBootstrapClientCredential.class), + @DiscriminatorMapping(value = "PSK", schema = PSKBootstrapClientCredential.class), + @DiscriminatorMapping(value = "RPK", schema = RPKBootstrapClientCredential.class), + @DiscriminatorMapping(value = "X509", schema = X509BootstrapClientCredential.class) + } +) @JsonTypeInfo( use = JsonTypeInfo.Id.NAME, property = "securityMode") diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/device/credentials/lwm2m/LwM2MClientCredential.java b/common/data/src/main/java/org/thingsboard/server/common/data/device/credentials/lwm2m/LwM2MClientCredential.java index 0ac1911d81..3f939cbd5b 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/device/credentials/lwm2m/LwM2MClientCredential.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/device/credentials/lwm2m/LwM2MClientCredential.java @@ -19,7 +19,18 @@ 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 io.swagger.v3.oas.annotations.media.DiscriminatorMapping; +import io.swagger.v3.oas.annotations.media.Schema; +@Schema( + discriminatorProperty = "securityConfigClientMode", + discriminatorMapping = { + @DiscriminatorMapping(value = "NO_SEC", schema = NoSecClientCredential.class), + @DiscriminatorMapping(value = "PSK", schema = PSKClientCredential.class), + @DiscriminatorMapping(value = "RPK", schema = RPKClientCredential.class), + @DiscriminatorMapping(value = "X509", schema = X509ClientCredential.class) + } +) @JsonTypeInfo( use = JsonTypeInfo.Id.NAME, property = "securityConfigClientMode") diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/lwm2m/bootstrap/LwM2MBootstrapServerCredential.java b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/lwm2m/bootstrap/LwM2MBootstrapServerCredential.java index 71e00cd354..1e6e3d056e 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/lwm2m/bootstrap/LwM2MBootstrapServerCredential.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/lwm2m/bootstrap/LwM2MBootstrapServerCredential.java @@ -19,10 +19,21 @@ 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 io.swagger.v3.oas.annotations.media.DiscriminatorMapping; +import io.swagger.v3.oas.annotations.media.Schema; import org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MSecurityMode; import java.io.Serializable; +@Schema( + discriminatorProperty = "securityMode", + discriminatorMapping = { + @DiscriminatorMapping(value = "NO_SEC", schema = NoSecLwM2MBootstrapServerCredential.class), + @DiscriminatorMapping(value = "PSK", schema = PSKLwM2MBootstrapServerCredential.class), + @DiscriminatorMapping(value = "RPK", schema = RPKLwM2MBootstrapServerCredential.class), + @DiscriminatorMapping(value = "X509", schema = X509LwM2MBootstrapServerCredential.class) + } +) @JsonTypeInfo( use = JsonTypeInfo.Id.NAME, property = "securityMode") diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/job/task/Task.java b/common/data/src/main/java/org/thingsboard/server/common/data/job/task/Task.java index a881780012..bf12d50ece 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/job/task/Task.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/job/task/Task.java @@ -20,6 +20,8 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonSubTypes; import com.fasterxml.jackson.annotation.JsonSubTypes.Type; import com.fasterxml.jackson.annotation.JsonTypeInfo; +import io.swagger.v3.oas.annotations.media.DiscriminatorMapping; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Data; import lombok.experimental.SuperBuilder; @@ -29,6 +31,12 @@ import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.job.JobType; @Data +@Schema( + discriminatorProperty = "jobType", + discriminatorMapping = { + @DiscriminatorMapping(value = "DUMMY", schema = DummyTask.class) + } +) @JsonIgnoreProperties(ignoreUnknown = true) @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "jobType") @JsonSubTypes({ diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/job/task/TaskResult.java b/common/data/src/main/java/org/thingsboard/server/common/data/job/task/TaskResult.java index e882c74eb6..ac55f14b0f 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/job/task/TaskResult.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/job/task/TaskResult.java @@ -20,12 +20,20 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonSubTypes; import com.fasterxml.jackson.annotation.JsonSubTypes.Type; import com.fasterxml.jackson.annotation.JsonTypeInfo; +import io.swagger.v3.oas.annotations.media.DiscriminatorMapping; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.NoArgsConstructor; import org.thingsboard.server.common.data.job.JobType; @Data @NoArgsConstructor +@Schema( + discriminatorProperty = "jobType", + discriminatorMapping = { + @DiscriminatorMapping(value = "DUMMY", schema = DummyTaskResult.class) + } +) @JsonIgnoreProperties(ignoreUnknown = true) @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "jobType") @JsonSubTypes({ From b31845e4beecfbb684b068e265604e8d5f45c152 Mon Sep 17 00:00:00 2001 From: Dmytro Pinkevych <49400214+pinkevmladchy@users.noreply.github.com> Date: Thu, 13 Aug 2026 16:43:01 +0300 Subject: [PATCH 64/91] Merge pull request #16028 from pinkevmladchy/iot-hub-built-in-items Open built-in IoT Hub items locally instead of installing duplicates --- ui-ngx/src/app/core/http/widget.service.ts | 2 +- .../dashboard-widget-select.component.html | 13 +- .../dashboard-widget-select.component.ts | 41 ++++- .../iot-hub/iot-hub-actions.service.ts | 79 +++++++++- .../iot-hub-add-item-dialog.component.ts | 15 ++ .../iot-hub/iot-hub-built-in.service.ts | 146 ++++++++++++++++++ .../iot-hub-install-dialog.component.html | 2 +- .../iot-hub-install-dialog.component.ts | 11 ++ .../iot-hub/iot-hub-item-card.component.html | 32 ++-- .../iot-hub/iot-hub-item-card.component.ts | 13 +- .../iot-hub-item-detail-dialog.component.html | 28 ++-- .../iot-hub-item-detail-dialog.component.ts | 32 ++++ .../home/components/iot-hub/iot-hub-utils.ts | 52 ++++++- .../home-page/iot-hub-widget.component.html | 20 ++- .../lib/home-page/iot-hub-widget.component.ts | 7 +- .../models/iot-hub/iot-hub-version.models.ts | 8 + .../assets/locale/locale.constant-en_US.json | 7 + 17 files changed, 457 insertions(+), 51 deletions(-) create mode 100644 ui-ngx/src/app/modules/home/components/iot-hub/iot-hub-built-in.service.ts diff --git a/ui-ngx/src/app/core/http/widget.service.ts b/ui-ngx/src/app/core/http/widget.service.ts index 06a6c86ddd..e4e50cc830 100644 --- a/ui-ngx/src/app/core/http/widget.service.ts +++ b/ui-ngx/src/app/core/http/widget.service.ts @@ -188,7 +188,7 @@ export class WidgetService { } public getWidgetType(fullFqn: string, config?: RequestConfig): Observable { - return this.http.get(`/api/widgetType?fqn=${fullFqn}`, + return this.http.get(`/api/widgetType?fqn=${encodeURIComponent(fullFqn)}`, defaultHttpOptionsFromConfig(config)); } diff --git a/ui-ngx/src/app/modules/home/components/dashboard-page/dashboard-widget-select.component.html b/ui-ngx/src/app/modules/home/components/dashboard-page/dashboard-widget-select.component.html index 7d2ea9cdb5..6da41a9878 100644 --- a/ui-ngx/src/app/modules/home/components/dashboard-page/dashboard-widget-select.component.html +++ b/ui-ngx/src/app/modules/home/components/dashboard-page/dashboard-widget-select.component.html @@ -370,7 +370,8 @@ - +
{{item.name}} @@ -405,10 +406,12 @@ {{ 'iot-hub.installed' | translate }} } - - file_download - {{ item.totalInstallCount | shortNumber }} - + @if (!isIotHubWidgetBuiltIn(item)) { + + file_download + {{ item.totalInstallCount | shortNumber }} + + }
diff --git a/ui-ngx/src/app/modules/home/components/dashboard-page/dashboard-widget-select.component.ts b/ui-ngx/src/app/modules/home/components/dashboard-page/dashboard-widget-select.component.ts index 3034cee011..46d4e06e91 100644 --- a/ui-ngx/src/app/modules/home/components/dashboard-page/dashboard-widget-select.component.ts +++ b/ui-ngx/src/app/modules/home/components/dashboard-page/dashboard-widget-select.component.ts @@ -39,7 +39,14 @@ import { ItemType, FilterParamInfo, WidgetCategory } from '@shared/models/iot-hu import { IotHubInstalledItem } from '@shared/models/iot-hub/iot-hub-installed-item.models'; import { IotHubApiService } from '@core/http/iot-hub-api.service'; import { IotHubActionsService } from '@home/components/iot-hub/iot-hub-actions.service'; -import { filterIotHubItemsBySearch, groupIotHubFilterItems, IotHubFilterGroup, resolveIotHubItemImageUrl } from '@home/components/iot-hub/iot-hub-utils'; +import { + filterIotHubItemsBySearch, + groupIotHubFilterItems, + IotHubFilterGroup, + isBuiltInItem, + resolveIotHubItemImageUrl +} from '@home/components/iot-hub/iot-hub-utils'; +import { IotHubBuiltInService } from '@home/components/iot-hub/iot-hub-built-in.service'; type selectWidgetMode = 'installed' | 'iotHub'; type installedSubMode = 'default' | 'allWidgets'; @@ -278,6 +285,7 @@ export class DashboardWidgetSelectComponent { constructor(private widgetsService: WidgetService, private iotHubApiService: IotHubApiService, private iotHubActions: IotHubActionsService, + private iotHubBuiltInService: IotHubBuiltInService, private translate: TranslateService, private cd: ChangeDetectorRef) { @@ -494,6 +502,13 @@ export class DashboardWidgetSelectComponent { } return; } + if (isBuiltInItem(item)) { + // Built-in widgets ship with the platform: pick the local widget type matched by fqn + // instead of installing a duplicate, exactly like an already installed item. + this.selectBuiltInWidget(item); + return; + } + // Built-in items never reach the dialog (they return above), so anything added from it installs. this.iotHubActions.openItemDetail(item, undefined, undefined, 'add').subscribe(result => { if (result?.action === 'add') { this.installAndAddWidget(result.item); @@ -505,6 +520,10 @@ export class DashboardWidgetSelectComponent { return this.installedWidgets?.some(i => i.itemId === item.itemId) ?? false; } + isIotHubWidgetBuiltIn(item: MpItemVersionView): boolean { + return isBuiltInItem(item); + } + getIotHubItemImage(item: MpItemVersionView): string | null { return resolveIotHubItemImageUrl(item, this.iotHubApiService); } @@ -737,6 +756,26 @@ export class DashboardWidgetSelectComponent { this.cd.markForCheck(); } + private selectBuiltInWidget(item: MpItemVersionView): void { + this.iotHubBuiltInService.resolveLocalWidgetTypeInfo(item).subscribe(lookup => { + if (lookup.value) { + this.widgetSelected.emit(this.toWidgetInfo(lookup.value)); + return; + } + if (lookup.failed) { + // Existence is unknown — installing now could duplicate a widget that is still there. + this.iotHubActions.showBuiltInLookupFailed(item); + return; + } + // The local copy is gone (e.g. deleted by a sysadmin) — installing is the only way back. + this.iotHubActions.confirmInstallMissingBuiltIn(item).subscribe(confirmed => { + if (confirmed) { + this.installAndAddWidget(item); + } + }); + }); + } + private installAndAddWidget(item: MpItemVersionView): void { const versionId = item.id as string; this.iotHubApiService.installItemVersion(versionId, { ignoreLoading: true }).subscribe({ diff --git a/ui-ngx/src/app/modules/home/components/iot-hub/iot-hub-actions.service.ts b/ui-ngx/src/app/modules/home/components/iot-hub/iot-hub-actions.service.ts index 73e627fbe6..cd3d48d5d5 100644 --- a/ui-ngx/src/app/modules/home/components/iot-hub/iot-hub-actions.service.ts +++ b/ui-ngx/src/app/modules/home/components/iot-hub/iot-hub-actions.service.ts @@ -17,6 +17,7 @@ import { Injectable } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; import { Observable, of, EMPTY } from 'rxjs'; +import { map, switchMap } from 'rxjs/operators'; import { TranslateService } from '@ngx-translate/core'; import { DialogService } from '@core/services/dialog.service'; import { MpItemVersionView } from '@shared/models/iot-hub/iot-hub-version.models'; @@ -30,6 +31,15 @@ import { TbIotHubUpdateDialogComponent, IotHubUpdateDialogData } from './iot-hub import { TbIotHubDeleteDialogComponent, IotHubDeleteDialogData } from './iot-hub-delete-dialog.component'; import { TbDeviceInstallDialogComponent, DeviceInstallDialogData } from './device-install-dialog/device-install-dialog.component'; import { TbIotHubInstalledItemsDialogComponent, IotHubInstalledItemsDialogData } from './iot-hub-installed-items-dialog.component'; +import { IotHubBuiltInService } from './iot-hub-built-in.service'; +import { isBuiltInItem } from './iot-hub-utils'; + +/** + * What `openBuiltInOrConfirmInstall` did with a built-in item: 'handled' means nothing is left to do + * (the local copy was opened, or the user was told why it could not be), while 'install-requested' + * means the component really is absent and the user asked for it to be installed. + */ +export type IotHubBuiltInAction = 'handled' | 'install-requested'; @Injectable() export class IotHubActionsService { @@ -37,7 +47,8 @@ export class IotHubActionsService { constructor( private dialog: MatDialog, private dialogService: DialogService, - private translate: TranslateService + private translate: TranslateService, + private builtInService: IotHubBuiltInService ) {} openItemDetail(item: MpItemVersionView, installedItem?: IotHubInstalledItem, installedItemsCount?: number, @@ -72,7 +83,67 @@ export class IotHubActionsService { }).afterClosed(); } + /** + * Runs the primary action of an item: built-in content is opened locally (never installed), + * device packages are connected, everything else goes through the install dialog. + */ installItem(item: MpItemVersionView): Observable { + if (isBuiltInItem(item)) { + return this.openOrInstallBuiltIn(item); + } + return this.runInstall(item); + } + + /** Opens the local copy of a built-in item, or asks to install it when it really is absent. */ + openBuiltInOrConfirmInstall(item: MpItemVersionView): Observable { + return this.builtInService.openLocalComponent(item).pipe( + switchMap(outcome => { + switch (outcome) { + case 'missing': + return this.confirmInstallMissingBuiltIn(item).pipe( + map((confirmed): IotHubBuiltInAction => confirmed ? 'install-requested' : 'handled') + ); + case 'failed': + this.showBuiltInLookupFailed(item); + return of('handled'); + default: + // 'opened' or 'cancelled' — the component is in place either way, so never install. + return of('handled'); + } + }) + ); + } + + /** + * Asks whether to install a built-in item whose local copy is gone — the component the Hub entry + * mirrors was deleted from this instance, so installing is the only way to get it back. + */ + confirmInstallMissingBuiltIn(item: MpItemVersionView): Observable { + return this.dialogService.confirm( + this.translate.instant('iot-hub.built-in-missing-title'), + this.translate.instant('iot-hub.built-in-missing-text', { name: item?.name }), + this.translate.instant('action.cancel'), + this.translate.instant('iot-hub.install') + ); + } + + /** Reports that the local copy could not be checked — nothing was opened and nothing installed. */ + showBuiltInLookupFailed(item: MpItemVersionView): void { + this.dialogService.alert( + this.translate.instant('iot-hub.built-in-lookup-failed-title'), + this.translate.instant('iot-hub.built-in-lookup-failed-text', { name: item?.name }) + ); + } + + private openOrInstallBuiltIn(item: MpItemVersionView): Observable { + return this.openBuiltInOrConfirmInstall(item).pipe( + // The confirmation inside is the only one the user gets: install starts immediately, + // and opening the component is a separate click once it is back in the library. + switchMap(action => action === 'install-requested' ? this.runInstall(item, true) : EMPTY) + ); + } + + private runInstall(item: MpItemVersionView, skipConfirm = false): Observable { if (item.type === ItemType.ALARM_RULE) { this.dialogService.alert( this.translate.instant('iot-hub.alarm-rule-install-update-required'), @@ -81,13 +152,13 @@ export class IotHubActionsService { return EMPTY; } if (item.type === ItemType.DEVICE) { - return this.installDevice(item); + return this.openDeviceInstallDialog(item); } return this.dialog.open(TbIotHubInstallDialogComponent, { panelClass: ['tb-dialog'], disableClose: true, autoFocus: false, - data: { item } as IotHubInstallDialogData + data: { item, skipConfirm } as IotHubInstallDialogData }).afterClosed(); } @@ -121,6 +192,8 @@ export class IotHubActionsService { }).afterClosed(); } + // Reached only for items whose action mode is 'connect', i.e. never for built-in content: + // that decision is made once, at the public entry points above. installDevice(item: MpItemVersionView): Observable { return this.openDeviceInstallDialog(item); } diff --git a/ui-ngx/src/app/modules/home/components/iot-hub/iot-hub-add-item-dialog.component.ts b/ui-ngx/src/app/modules/home/components/iot-hub/iot-hub-add-item-dialog.component.ts index e83580e271..404ec8ef03 100644 --- a/ui-ngx/src/app/modules/home/components/iot-hub/iot-hub-add-item-dialog.component.ts +++ b/ui-ngx/src/app/modules/home/components/iot-hub/iot-hub-add-item-dialog.component.ts @@ -27,6 +27,7 @@ import { DialogService } from '@core/services/dialog.service'; import { TranslateService } from '@ngx-translate/core'; import { EntityId } from '@shared/models/id/entity-id'; import { IotHubActionsService } from './iot-hub-actions.service'; +import { isBuiltInItem } from './iot-hub-utils'; export interface IotHubAddItemDialogData { itemType: ItemType; @@ -73,6 +74,20 @@ export class TbIotHubAddItemDialogComponent extends DialogComponent { + if (action === 'install-requested') { + this.doAddItem(item); + } + }); + return; + } + this.doAddItem(item); + } + + private doAddItem(item: MpItemVersionView): void { if (this.itemType === ItemType.DEVICE) { this.installDeviceItem(item); return; diff --git a/ui-ngx/src/app/modules/home/components/iot-hub/iot-hub-built-in.service.ts b/ui-ngx/src/app/modules/home/components/iot-hub/iot-hub-built-in.service.ts new file mode 100644 index 0000000000..054bec852f --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/iot-hub/iot-hub-built-in.service.ts @@ -0,0 +1,146 @@ +/// +/// Copyright © 2016-2026 The Thingsboard Authors +/// +/// Licensed under the Apache License, Version 2.0 (the "License"); +/// you may not use this file except in compliance with the License. +/// You may obtain a copy of the License at +/// +/// http://www.apache.org/licenses/LICENSE-2.0 +/// +/// Unless required by applicable law or agreed to in writing, software +/// distributed under the License is distributed on an "AS IS" BASIS, +/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +/// See the License for the specific language governing permissions and +/// limitations under the License. +/// + +import { Injectable } from '@angular/core'; +import { HttpErrorResponse } from '@angular/common/http'; +import { Router } from '@angular/router'; +import { from, Observable, of } from 'rxjs'; +import { catchError, concatMap, first, map, switchMap } from 'rxjs/operators'; +import { WidgetService } from '@core/http/widget.service'; +import { MpItemVersionView } from '@shared/models/iot-hub/iot-hub-version.models'; +import { ItemType } from '@shared/models/iot-hub/iot-hub-item.models'; +import { isValidWidgetFullFqn, WidgetType, WidgetTypeInfo } from '@shared/models/widget.models'; +import { EntityType } from '@shared/models/entity-type.models'; +import { getEntityDetailsPageURL, isNotEmptyStr } from '@core/utils'; + +/** + * Result of looking up the local component a built-in Hub item mirrors. `failed` separates + * "the lookup itself did not answer" (network error, 5xx, no read permission) from "the component + * is not here": only the latter may be offered as an install, otherwise a transient error would + * hand the tenant a duplicate of a component that is still in place. + */ +export interface IotHubLocalLookup { + value: T | null; + failed: boolean; +} + +/** + * Outcome of trying to open the local component of a built-in item. 'cancelled' means the component + * is there but the router did not go — typically a route guard blocked it (unsaved changes) — so + * there is nothing to install and nothing to report. + */ +export type IotHubOpenLocalOutcome = 'opened' | 'cancelled' | 'missing' | 'failed'; + +/** + * Handles IoT Hub items marked `builtIn` — content that already ships inside ThingsBoard. + * Such an item is never installed: its `fqn` is deliberately identical to the fqn of the + * platform's own component, which is used as the match key to reach the local copy. + */ +@Injectable({ + providedIn: 'root' +}) +export class IotHubBuiltInService { + + constructor( + private router: Router, + private widgetService: WidgetService + ) {} + + /** + * Resolves the platform's own widget type mirroring a built-in Hub item, matched by fqn. + * + * There is no API to test a batch of fqns at once — `GET /api/widgetType?fqn=` is per fqn and + * carries the full descriptor, and `/api/widgetTypeFqns` is scoped to a bundle the Hub payload + * does not name — so this must stay a per-item check triggered by a click, never a prefetch + * across a catalogue page. + */ + resolveLocalWidgetType(item: MpItemVersionView): Observable> { + const noMatch: IotHubLocalLookup = { value: null, failed: false }; + const fqn = item?.dataDescriptor?.fqn; + if (!isNotEmptyStr(fqn)) { + // Without a match key nothing was asked of the server, so existence is unknown rather than + // disproven — reporting it as absent would offer an install for a component that is in place. + return of({ value: null, failed: true }); + } + // Hub items carry a bare fqn; platform widget types are addressed by a scoped full fqn. + // Built-in content is system scoped; the tenant scope covers a copy installed into this tenant, + // which matters while the installed-items list a caller filters by is still stale. + const fullFqns = isValidWidgetFullFqn(fqn) ? [fqn] : [`system.${fqn}`, `tenant.${fqn}`]; + return from(fullFqns).pipe( + concatMap(fullFqn => this.widgetService.getWidgetType(fullFqn, { ignoreErrors: true, ignoreLoading: true }).pipe( + map(widgetType => this.lookupResult(widgetType)), + catchError((err: HttpErrorResponse) => of(this.lookupFailure(err))) + )), + // Stop at the first match, and at the first hard failure too: with existence unknown, the + // remaining candidate cannot turn a failure into a trustworthy "not here". + first(lookup => !!lookup.value?.id?.id || lookup.failed, noMatch) + ); + } + + /** Same match, resolved to the info projection widget pickers need (image, description, type). */ + resolveLocalWidgetTypeInfo(item: MpItemVersionView): Observable> { + return this.resolveLocalWidgetType(item).pipe( + switchMap(lookup => lookup.value + ? this.widgetService.getWidgetTypeInfoById(lookup.value.id.id, { ignoreErrors: true, ignoreLoading: true }).pipe( + map(widgetTypeInfo => this.lookupResult(widgetTypeInfo)), + catchError((err: HttpErrorResponse) => of(this.lookupFailure(err))) + ) + : of({ value: null, failed: lookup.failed })) + ); + } + + /** Navigates to the local component a built-in item mirrors, reporting why it could not. */ + openLocalComponent(item: MpItemVersionView): Observable { + return this.resolveLocalComponentUrl(item).pipe( + switchMap(lookup => { + if (!lookup.value) { + return of(lookup.failed ? 'failed' : 'missing'); + } + // The navigation itself can still be refused — a ConfirmOnExitGuard on the page the user is + // leaving, a failing resolver — and reporting it as opened would leave them with the Hub + // dialog closed (it closes on NavigationStart) and nothing opened in its place. + return from(this.router.navigateByUrl(lookup.value)).pipe( + map((navigated): IotHubOpenLocalOutcome => navigated ? 'opened' : 'cancelled'), + catchError(() => of('cancelled')) + ); + }) + ); + } + + private resolveLocalComponentUrl(item: MpItemVersionView): Observable> { + // Only widgets (including SCADA symbol widgets) ship inside the platform today. Other item + // types have no local counterpart to match by fqn, so they count as missing. + if (item?.type !== ItemType.WIDGET) { + return of({ value: null, failed: false }); + } + return this.resolveLocalWidgetType(item).pipe( + map(lookup => ({ + value: lookup.value ? getEntityDetailsPageURL(lookup.value.id.id, EntityType.WIDGET_TYPE) || null : null, + failed: lookup.failed + })) + ); + } + + private lookupResult(value: T | null): IotHubLocalLookup { + return { value: value ?? null, failed: false }; + } + + // A 404 is an answer — the component is not here. Anything else (network error, 5xx, 403) leaves + // existence unknown, and must never be presented to the user as deleted content. + private lookupFailure(err: HttpErrorResponse): IotHubLocalLookup { + return { value: null, failed: err?.status !== 404 }; + } +} diff --git a/ui-ngx/src/app/modules/home/components/iot-hub/iot-hub-install-dialog.component.html b/ui-ngx/src/app/modules/home/components/iot-hub/iot-hub-install-dialog.component.html index ea3774ac11..25c5ca2089 100644 --- a/ui-ngx/src/app/modules/home/components/iot-hub/iot-hub-install-dialog.component.html +++ b/ui-ngx/src/app/modules/home/components/iot-hub/iot-hub-install-dialog.component.html @@ -117,7 +117,7 @@ } @case ('installing') { -

{{ 'iot-hub.install-confirm-title' | translate:{ name: item.name } }}

+

{{ 'iot-hub.installing-title' | translate:{ name: item.name } }}

{{ 'iot-hub.install-desc' | translate }}

} @case ('success') { diff --git a/ui-ngx/src/app/modules/home/components/iot-hub/iot-hub-install-dialog.component.ts b/ui-ngx/src/app/modules/home/components/iot-hub/iot-hub-install-dialog.component.ts index 43ed8d21b4..e4816d19ad 100644 --- a/ui-ngx/src/app/modules/home/components/iot-hub/iot-hub-install-dialog.component.ts +++ b/ui-ngx/src/app/modules/home/components/iot-hub/iot-hub-install-dialog.component.ts @@ -60,6 +60,13 @@ interface PendingOverwrite { export interface IotHubInstallDialogData { item: MpItemVersionView; + /** + * Starts installing right away instead of opening on the confirm step. Set by callers that + * already asked the user — e.g. a built-in item whose local copy was deleted — so the user is + * not asked to confirm the same install twice. Ignored when the item needs input first + * (entity selection, rule chain options). + */ + skipConfirm?: boolean; } export type InstallState = @@ -140,6 +147,10 @@ export class TbIotHubInstallDialogComponent extends DialogComponent{{ item.creatorDisplayName }} - · + @if (showInstallCount) { + · + } + } + @if (showInstallCount) { + download + {{ item.totalInstallCount | shortNumber }} } - download - {{ item.totalInstallCount | shortNumber }}
@if (mode === 'add') { @if (isInstalled()) { check{{ 'iot-hub.installed' | translate }} } @else { - + } } @else if (isInstalled()) { @if (isSameVersion()) { @@ -74,7 +78,7 @@ } } @else { - + } } @else { @@ -105,18 +109,22 @@ [class.clickable]="mode !== 'add'" (click)="mode !== 'add' && onCreatorClick($event)" (keyup.enter)="mode !== 'add' && onCreatorClick($event)">{{ item.creatorDisplayName }} - · + @if (showInstallCount) { + · + } + } + @if (showInstallCount) { + + download + {{ item.totalInstallCount | shortNumber }} + } - - download - {{ item.totalInstallCount | shortNumber }} - @if (mode === 'add') { @if (isInstalled()) { check{{ 'iot-hub.installed' | translate }} } @else { - + } } @else if (isInstalled()) { @if (isSameVersion()) { @@ -143,7 +151,7 @@ } } @else { - + } diff --git a/ui-ngx/src/app/modules/home/components/iot-hub/iot-hub-item-card.component.ts b/ui-ngx/src/app/modules/home/components/iot-hub/iot-hub-item-card.component.ts index 2d9c13d8d7..b2fe9a58f3 100644 --- a/ui-ngx/src/app/modules/home/components/iot-hub/iot-hub-item-card.component.ts +++ b/ui-ngx/src/app/modules/home/components/iot-hub/iot-hub-item-card.component.ts @@ -20,6 +20,7 @@ import { getItemTypeIcon, ItemType } from '@shared/models/iot-hub/iot-hub-item.m import { IotHubInstalledItem } from '@shared/models/iot-hub/iot-hub-installed-item.models'; import { TranslateService } from '@ngx-translate/core'; import { IotHubApiService } from '@core/http/iot-hub-api.service'; +import { iotHubItemActionLabel, isBuiltInItem } from '@home/components/iot-hub/iot-hub-utils'; @Component({ selector: 'tb-iot-hub-item-card', @@ -29,8 +30,6 @@ import { IotHubApiService } from '@core/http/iot-hub-api.service'; }) export class TbIotHubItemCardComponent { - readonly ItemType = ItemType; - @Input() item: MpItemVersionView; @Input() installedItem: IotHubInstalledItem; @Input() installedItemsCount = 0; @@ -51,6 +50,16 @@ export class TbIotHubItemCardComponent { private iotHubApiService: IotHubApiService ) {} + // Install counters mean nothing for content the tenant already has, so the counter and the + // separator that would dangle next to it are both derived from this one boolean. + get showInstallCount(): boolean { + return !isBuiltInItem(this.item); + } + + get actionLabel(): string { + return iotHubItemActionLabel(this.item, this.mode === 'add' ? 'add' : 'card'); + } + isCompactLayout(): boolean { return this.item.type === ItemType.CALCULATED_FIELD || this.item.type === ItemType.ALARM_RULE diff --git a/ui-ngx/src/app/modules/home/components/iot-hub/iot-hub-item-detail-dialog.component.html b/ui-ngx/src/app/modules/home/components/iot-hub/iot-hub-item-detail-dialog.component.html index 30d9322dd9..eba34fb30a 100644 --- a/ui-ngx/src/app/modules/home/components/iot-hub/iot-hub-item-detail-dialog.component.html +++ b/ui-ngx/src/app/modules/home/components/iot-hub/iot-hub-item-detail-dialog.component.html @@ -30,15 +30,17 @@ {{ getTypeIcon() }} {{ typeTranslations.get(item.type) | translate }} - - - download - {{ item.totalInstallCount | shortNumber }} {{ 'iot-hub.installs' | translate }} - + @if (showInstallCount) { + + + download + {{ item.totalInstallCount | shortNumber }} {{ 'iot-hub.installs' | translate }} + + } update - v {{ item.version }} + {{ versionLabel }} @if (preview) { @@ -318,19 +320,13 @@ @if (mode === 'add' && !isInstalled()) { } @if (!isInstalled() && mode !== 'add') { - @if (item.type === ItemType.DEVICE) { - - } @else { - - } + } @if (isInstalled() && mode !== 'add') {