diff --git a/application/pom.xml b/application/pom.xml index 0f18ba5c50..9a46bbdc3a 100644 --- a/application/pom.xml +++ b/application/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 4.2.2.3 + 4.2.2.4-SNAPSHOT thingsboard application 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/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..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 @@ -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 = 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 e3f1e94bf4..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 @@ -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 = true) @NoArgsConstructor public class SimpleCalculatedFieldState extends BaseCalculatedFieldState { 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(); } } 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/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); 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 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/main/resources/thingsboard.yml b/application/src/main/resources/thingsboard.yml index f678076c57..003cee2eb7 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,23 +115,25 @@ 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 +# 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. @@ -138,6 +141,7 @@ zk: recalculate_delay: "${ZOOKEEPER_RECALCULATE_DELAY_MS:0}" # Cluster parameters +# 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 @@ -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 @@ -597,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 @@ -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: @@ -808,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:}" @@ -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. @@ -1123,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 @@ -1246,16 +1271,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}" @@ -1428,6 +1453,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. @@ -1446,15 +1472,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 @@ -1470,13 +1496,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 @@ -1512,6 +1538,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: @@ -1565,6 +1592,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}" @@ -1628,6 +1656,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}" @@ -1635,6 +1664,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/**}" @@ -1664,6 +1694,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). @@ -2074,12 +2105,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) @@ -2093,6 +2126,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}" @@ -2106,6 +2140,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}" @@ -2116,6 +2151,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}" @@ -2124,6 +2160,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: @@ -2136,6 +2173,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}" @@ -2144,6 +2182,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 parameters +# Configures MQTT client retransmission behavior including max attempts, initial delay, and jitter factor. mqtt: # MQTT client configuration parameters client: 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/AbstractWebTest.java b/application/src/test/java/org/thingsboard/server/controller/AbstractWebTest.java index 2b70e04a85..53fdc5ce07 100644 --- a/application/src/test/java/org/thingsboard/server/controller/AbstractWebTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/AbstractWebTest.java @@ -1244,7 +1244,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/AlarmCommentControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/AlarmCommentControllerTest.java index bebfe832e8..782580002a 100644 --- a/application/src/test/java/org/thingsboard/server/controller/AlarmCommentControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/AlarmCommentControllerTest.java @@ -231,6 +231,10 @@ public class AlarmCommentControllerTest extends AbstractControllerTest { .comment(JacksonUtil.newObjectNode().put("text", String.format("Comment was deleted by user %s", CUSTOMER_USER_EMAIL))) .build(); + // The audit log receives the persisted comment, and AlarmComment equality covers the + // inherited id and createdTime, which the builder cannot populate. + expectedAlarmComment.setId(alarmComment.getId()); + expectedAlarmComment.setCreatedTime(alarmComment.getCreatedTime()); testLogEntityActionEntityEqClass(alarm, alarm.getId(), tenantId, customerId, customerUserId, CUSTOMER_USER_EMAIL, ActionType.DELETED_COMMENT, 1, expectedAlarmComment); } @@ -255,6 +259,10 @@ public class AlarmCommentControllerTest extends AbstractControllerTest { .comment(JacksonUtil.newObjectNode().put("text", String.format("Comment was deleted by user %s", TENANT_ADMIN_EMAIL))) .build(); + // The audit log receives the persisted comment, and AlarmComment equality covers the + // inherited id and createdTime, which the builder cannot populate. + expectedAlarmComment.setId(alarmComment.getId()); + expectedAlarmComment.setCreatedTime(alarmComment.getCreatedTime()); testLogEntityActionEntityEqClass(alarm, alarm.getId(), tenantId, customerId, tenantAdminUserId, TENANT_ADMIN_EMAIL, ActionType.DELETED_COMMENT, 1, expectedAlarmComment); } @@ -286,6 +294,10 @@ public class AlarmCommentControllerTest extends AbstractControllerTest { .comment(JacksonUtil.newObjectNode().put("text", String.format("Comment was deleted by user %s", TENANT_ADMIN_EMAIL))) .build(); + // The audit log receives the persisted comment, and AlarmComment equality covers the + // inherited id and createdTime, which the builder cannot populate. + expectedAlarmComment.setId(alarmComment.getId()); + expectedAlarmComment.setCreatedTime(alarmComment.getCreatedTime()); testLogEntityActionEntityEqClass(alarm, alarm.getId(), tenantId, customerId, tenantAdminUserId, TENANT_ADMIN_EMAIL, ActionType.DELETED_COMMENT, 1, expectedAlarmComment); } 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 d1621b29ec..2f37ed653d 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..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,8 +21,10 @@ 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.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; import org.springframework.test.context.junit4.SpringRunner; import org.thingsboard.server.cluster.TbClusterService; @@ -73,28 +75,43 @@ import static org.mockito.Mockito.when; @Slf4j @RunWith(SpringRunner.class) -@ContextConfiguration(classes = DeviceProvisionServiceImpl.class) +@ContextConfiguration(classes = DeviceProvisionServiceTest.TestConfig.class) public class DeviceProvisionServiceTest { - @MockBean + @Configuration + static class TestConfig { + @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/EdqsEntityServiceTest.java b/application/src/test/java/org/thingsboard/server/service/entitiy/EdqsEntityServiceTest.java index 838695e9a3..bbc62e2d87 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 @@ -21,7 +21,7 @@ import com.google.common.util.concurrent.ListenableFuture; 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.Device; import org.thingsboard.server.common.data.EntityType; @@ -72,7 +72,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/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/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/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/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..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,11 +17,12 @@ 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; -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 +57,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 +69,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 +90,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; + @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 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..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,8 +20,10 @@ 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.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; import org.springframework.test.context.junit4.SpringRunner; import org.thingsboard.server.cache.ota.OtaPackageDataCache; @@ -69,38 +71,60 @@ import static org.mockito.Mockito.when; @Slf4j @RunWith(SpringRunner.class) -@ContextConfiguration(classes = DefaultTransportApiService.class) +@ContextConfiguration(classes = DefaultTransportApiServiceTest.TestConfig.class) public class DefaultTransportApiServiceTest { - @MockBean + @Configuration + static class TestConfig { + @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 8d0f0f2af0..a0590e0523 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; @@ -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; @@ -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..d8fa231124 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; @@ -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; @@ -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 diff --git a/common/actor/pom.xml b/common/actor/pom.xml index 0d14454bc0..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 + 4.2.2.4-SNAPSHOT common org.thingsboard.common diff --git a/common/cache/pom.xml b/common/cache/pom.xml index bde01d1cdc..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 + 4.2.2.4-SNAPSHOT common org.thingsboard.common 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/cluster-api/pom.xml b/common/cluster-api/pom.xml index 8a06b622e1..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 + 4.2.2.4-SNAPSHOT common org.thingsboard.common diff --git a/common/coap-server/pom.xml b/common/coap-server/pom.xml index 069906b800..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 + 4.2.2.4-SNAPSHOT common org.thingsboard.common diff --git a/common/dao-api/pom.xml b/common/dao-api/pom.xml index 85ffa7dc2b..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 + 4.2.2.4-SNAPSHOT common org.thingsboard.common diff --git a/common/data/pom.xml b/common/data/pom.xml index 2382e05778..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 + 4.2.2.4-SNAPSHOT common org.thingsboard.common 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/EventInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/EventInfo.java index 9ca3957050..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 @@ -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 = 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 ce9c8fce78..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 @@ -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 = 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/StringUtils.java b/common/data/src/main/java/org/thingsboard/server/common/data/StringUtils.java index 48b0efe16b..c952e7cf04 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 java.util.regex.Pattern; @@ -162,7 +163,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) { @@ -217,23 +218,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/TenantInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/TenantInfo.java index 4126b1acdd..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 @@ -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 = 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 0a011c287f..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,6 +34,7 @@ import java.io.Serial; @Schema @Data +@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 3f23e4fe14..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 @@ -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 = 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 079ceffada..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 @@ -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 = 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/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; - } } 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..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 @@ -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 = 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 dd751b8b9d..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 @@ -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 = 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 40ad22ed19..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 @@ -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 = 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 ce91aac9d0..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 @@ -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 = 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 e2cdf8f295..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 @@ -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 = 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 4131d58e98..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 @@ -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 = 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 90400ae70d..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 @@ -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 = 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 067c961b9e..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 @@ -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 = 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 1d257b06e1..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 @@ -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 = 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 4e326cf779..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 @@ -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 = 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 13e05daad4..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 @@ -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 = 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 25b7db6aaa..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 @@ -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 = 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 9b538511b2..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 @@ -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 = 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 f6a2889f67..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 @@ -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 = 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 225b85680f..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 @@ -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 = true) @NoArgsConstructor @SuperBuilder public class UserFields extends AbstractEntityFields { 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/kv/BaseDeleteTsKvQuery.java b/common/data/src/main/java/org/thingsboard/server/common/data/kv/BaseDeleteTsKvQuery.java index 233c53849c..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 @@ -16,8 +16,10 @@ package org.thingsboard.server.common.data.kv; import lombok.Data; +import lombok.EqualsAndHashCode; @Data +@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/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/query/AlarmCountQuery.java b/common/data/src/main/java/org/thingsboard/server/common/data/query/AlarmCountQuery.java index f9d2e8d3d8..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 @@ -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 = 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 57e0e6af66..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 @@ -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 = 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 cb861a6726..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 @@ -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 = true) public class RuleNodeState extends BaseData { private RuleNodeId ruleNodeId; 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; 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/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/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..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 @@ -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 = true) public class WidgetTypeInfo extends BaseWidgetType { @Serial diff --git a/common/discovery-api/pom.xml b/common/discovery-api/pom.xml index 4df6033a9b..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 + 4.2.2.4-SNAPSHOT common org.thingsboard.common diff --git a/common/edge-api/pom.xml b/common/edge-api/pom.xml index f30883ba6e..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 + 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 095f90026f..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 + 4.2.2.4-SNAPSHOT common org.thingsboard.common diff --git a/common/message/pom.xml b/common/message/pom.xml index 3b5f1e5e43..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 + 4.2.2.4-SNAPSHOT common org.thingsboard.common diff --git a/common/pom.xml b/common/pom.xml index aaf11784c4..1eb2dc44b2 100644 --- a/common/pom.xml +++ b/common/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 4.2.2.3 + 4.2.2.4-SNAPSHOT thingsboard common diff --git a/common/proto/pom.xml b/common/proto/pom.xml index 770ab9bc92..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 + 4.2.2.4-SNAPSHOT common org.thingsboard.common diff --git a/common/queue/pom.xml b/common/queue/pom.xml index 2732d7915e..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 + 4.2.2.4-SNAPSHOT common org.thingsboard.common 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); } } diff --git a/common/script/pom.xml b/common/script/pom.xml index 52a931e26d..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 + 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 24139b71cf..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 + 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 3f8e8f845b..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 + 4.2.2.4-SNAPSHOT script org.thingsboard.common.script 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 a66a1860cd..eeece8149a 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 @@ -1353,7 +1353,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 dbf56d5140..5e7317a75c 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 @@ -1316,13 +1316,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)); @@ -1336,9 +1336,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/stats/pom.xml b/common/stats/pom.xml index cba027e9ee..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 + 4.2.2.4-SNAPSHOT common org.thingsboard.common diff --git a/common/transport/coap/pom.xml b/common/transport/coap/pom.xml index dc574fff31..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 + 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 2ef5e13f1e..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 + 4.2.2.4-SNAPSHOT transport org.thingsboard.common.transport 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/transport/lwm2m/pom.xml b/common/transport/lwm2m/pom.xml index 60dd5f7c0a..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 + 4.2.2.4-SNAPSHOT transport org.thingsboard.common.transport 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/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(); diff --git a/common/transport/mqtt/pom.xml b/common/transport/mqtt/pom.xml index 5397d4a9ce..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 + 4.2.2.4-SNAPSHOT transport org.thingsboard.common.transport 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..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 @@ -16,8 +16,10 @@ package org.thingsboard.server.transport.mqtt.limits; import lombok.Data; +import lombok.EqualsAndHashCode; @Data +@EqualsAndHashCode(callSuper = true) public class GatewaySessionLimits extends SessionLimits { private SessionRateLimits gatewayRateLimits; 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/common/transport/pom.xml b/common/transport/pom.xml index fe7d59c61a..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 + 4.2.2.4-SNAPSHOT common org.thingsboard.common diff --git a/common/transport/snmp/pom.xml b/common/transport/snmp/pom.xml index 5f0c777211..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 + 4.2.2.4-SNAPSHOT transport diff --git a/common/transport/transport-api/pom.xml b/common/transport/transport-api/pom.xml index f6677d4cfa..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 + 4.2.2.4-SNAPSHOT transport org.thingsboard.common.transport 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/pom.xml b/common/util/pom.xml index 2ff4e2039a..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 + 4.2.2.4-SNAPSHOT common org.thingsboard.common 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/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/common/version-control/pom.xml b/common/version-control/pom.xml index c7a635711a..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 + 4.2.2.4-SNAPSHOT common org.thingsboard.common 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/pom.xml b/dao/pom.xml index d8a1e5b15a..19c089dee1 100644 --- a/dao/pom.xml +++ b/dao/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 4.2.2.3 + 4.2.2.4-SNAPSHOT thingsboard dao 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/model/sqlts/latest/TsKvLatestEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sqlts/latest/TsKvLatestEntity.java index 44a38bf445..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 @@ -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 = true) @Entity @Table(name = "ts_kv_latest") @IdClass(TsKvLatestCompositeKey.class) 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 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(); 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/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/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/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/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/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/pom.xml b/edqs/pom.xml index 182cba53b8..bdae55999d 100644 --- a/edqs/pom.xml +++ b/edqs/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 4.2.2.3 + 4.2.2.4-SNAPSHOT thingsboard edqs 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/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()); diff --git a/monitoring/pom.xml b/monitoring/pom.xml index e0b846159a..2026a40f70 100644 --- a/monitoring/pom.xml +++ b/monitoring/pom.xml @@ -21,7 +21,7 @@ 4.0.0 org.thingsboard - 4.2.2.3 + 4.2.2.4-SNAPSHOT thingsboard diff --git a/monitoring/src/main/java/org/thingsboard/monitoring/client/TbClient.java b/monitoring/src/main/java/org/thingsboard/monitoring/client/TbClient.java index 584b2edc48..64dbde1cdb 100644 --- a/monitoring/src/main/java/org/thingsboard/monitoring/client/TbClient.java +++ b/monitoring/src/main/java/org/thingsboard/monitoring/client/TbClient.java @@ -34,8 +34,8 @@ public class TbClient extends RestClient { public TbClient(@Value("${monitoring.rest.base_url}") String baseUrl, @Value("${monitoring.rest.request_timeout_ms}") int requestTimeoutMs) { super(new RestTemplateBuilder() - .setConnectTimeout(Duration.ofMillis(requestTimeoutMs)) - .setReadTimeout(Duration.ofMillis(requestTimeoutMs)) + .connectTimeout(Duration.ofMillis(requestTimeoutMs)) + .readTimeout(Duration.ofMillis(requestTimeoutMs)) .build(), baseUrl); } 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/notification/channels/impl/SlackNotificationChannel.java b/monitoring/src/main/java/org/thingsboard/monitoring/notification/channels/impl/SlackNotificationChannel.java index c1d25c43c0..5c0df4f6fe 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 @@ -40,8 +40,8 @@ public class SlackNotificationChannel implements NotificationChannel { @PostConstruct private void init() { restTemplate = new RestTemplateBuilder() - .setConnectTimeout(Duration.ofSeconds(5)) - .setReadTimeout(Duration.ofSeconds(2)) + .connectTimeout(Duration.ofSeconds(5)) + .readTimeout(Duration.ofSeconds(2)) .build(); } 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/monitoring/src/main/java/org/thingsboard/monitoring/service/transport/impl/HttpTransportHealthChecker.java b/monitoring/src/main/java/org/thingsboard/monitoring/service/transport/impl/HttpTransportHealthChecker.java index 948ac9fd7e..9a99034d69 100644 --- a/monitoring/src/main/java/org/thingsboard/monitoring/service/transport/impl/HttpTransportHealthChecker.java +++ b/monitoring/src/main/java/org/thingsboard/monitoring/service/transport/impl/HttpTransportHealthChecker.java @@ -43,8 +43,8 @@ public class HttpTransportHealthChecker extends TransportHealthChecker org.thingsboard - 4.2.2.3 + 4.2.2.4-SNAPSHOT msa org.thingsboard.msa diff --git a/msa/edqs/pom.xml b/msa/edqs/pom.xml index bbc8bacd2e..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 + 4.2.2.4-SNAPSHOT msa org.thingsboard.msa diff --git a/msa/js-executor/config/default.yml b/msa/js-executor/config/default.yml index 9a33190069..feae8edc4a 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 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" # 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 @@ -57,9 +67,9 @@ 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" + 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/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 e74f91bb50..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 + 4.2.2.4-SNAPSHOT msa org.thingsboard.msa diff --git a/msa/js-executor/yarn.lock b/msa/js-executor/yarn.lock index 5e3330e0d7..439ab60d05 100644 --- a/msa/js-executor/yarn.lock +++ b/msa/js-executor/yarn.lock @@ -447,9 +447,9 @@ body-parser@^2.2.0: type-is "^2.0.0" brace-expansion@^1.1.7: - version "1.1.13" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.13.tgz#d37875c01dc9eff988dd49d112a57cb67b54efe6" - integrity sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w== + version "1.1.18" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.18.tgz#3ce74d89885136be1535341f8c3d4425c29a5cab" + integrity sha512-Edep/X9fGqVNmzKBVsDYIOtD+z1tuezV70LBjdCst9Tqu76lsnvRiZ6oTic1n+/BIwX6QDGAO94PN4N2SADvtw== dependencies: balanced-match "^1.0.0" concat-map "0.0.1" @@ -1030,9 +1030,9 @@ isarray@~1.0.0: integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== js-yaml@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.1.tgz#854c292467705b699476e1a2decc0c8a3458806b" - integrity sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA== + version "4.3.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.3.1.tgz#01216c001d67f48e2cd560d708c7af21090a3848" + integrity sha512-CY6crGq313MX8GkwvB7tzgp99vjQxY1++5y10/BKN/GUfHqWaOGQMNZkBvqSzsZKWk/ijwHlWzzkLulsGHhjWQ== dependencies: argparse "^2.0.1" @@ -1654,9 +1654,9 @@ tar-stream@^2.1.4: readable-stream "^3.1.1" tar@>=7.5.8, tar@^7.4.3: - version "7.5.11" - resolved "https://registry.yarnpkg.com/tar/-/tar-7.5.11.tgz#1250fae45d98806b36d703b30973fa8e0a6d8868" - integrity sha512-ChjMH33/KetonMTAtpYdgUFr0tbz69Fp2v7zWxQfYZX4g5ZN2nOBXm1R2xyA+lMIKrLKIoKAwFj93jE/avX9cQ== + version "7.5.22" + resolved "https://registry.yarnpkg.com/tar/-/tar-7.5.22.tgz#a696f998136e71487dc3f869a85bba2c67971ba9" + integrity sha512-MFO/QzvtAOmJbkhOaCTvbGcFN9L9b+JunIsDwaKljSOdcLMea3NJ1k9Usz/rjdfSXTq4dfzfeS7W4p4YOAAHeA== dependencies: "@isaacs/fs-minipass" "^4.0.0" chownr "^3.0.0" diff --git a/msa/monitoring/pom.xml b/msa/monitoring/pom.xml index dec1144313..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 + 4.2.2.4-SNAPSHOT msa diff --git a/msa/pom.xml b/msa/pom.xml index e5a733447c..0847add29e 100644 --- a/msa/pom.xml +++ b/msa/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 4.2.2.3 + 4.2.2.4-SNAPSHOT thingsboard msa diff --git a/msa/tb-node/pom.xml b/msa/tb-node/pom.xml index b27b31d95f..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 + 4.2.2.4-SNAPSHOT msa org.thingsboard.msa diff --git a/msa/tb/pom.xml b/msa/tb/pom.xml index db298fc9a7..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 + 4.2.2.4-SNAPSHOT msa org.thingsboard.msa diff --git a/msa/transport/coap/pom.xml b/msa/transport/coap/pom.xml index 5b364b4e73..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 + 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 3d2eee9817..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 + 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 c03c05c735..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 + 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 ec81f5dafe..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 + 4.2.2.4-SNAPSHOT transport org.thingsboard.msa.transport diff --git a/msa/transport/pom.xml b/msa/transport/pom.xml index fcb4872dad..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 + 4.2.2.4-SNAPSHOT msa org.thingsboard.msa diff --git a/msa/transport/snmp/pom.xml b/msa/transport/snmp/pom.xml index 407502854b..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 + 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 c9cc8ee55b..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 + 4.2.2.4-SNAPSHOT msa org.thingsboard.msa diff --git a/msa/vc-executor/pom.xml b/msa/vc-executor/pom.xml index 855b28f12a..4bb404284a 100644 --- a/msa/vc-executor/pom.xml +++ b/msa/vc-executor/pom.xml @@ -21,7 +21,7 @@ org.thingsboard - 4.2.2.3 + 4.2.2.4-SNAPSHOT msa org.thingsboard.msa 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..e540182c06 100644 --- a/msa/vc-executor/src/main/resources/tb-vc-executor.yml +++ b/msa/vc-executor/src/main/resources/tb-vc-executor.yml @@ -15,30 +15,33 @@ # # 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}" # 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. @@ -46,6 +49,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 +200,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 +211,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 +225,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 +234,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 +243,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/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 4f91931ea9..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 + 4.2.2.4-SNAPSHOT msa org.thingsboard.msa diff --git a/msa/web-ui/yarn.lock b/msa/web-ui/yarn.lock index 033aeac686..d876d9df50 100644 --- a/msa/web-ui/yarn.lock +++ b/msa/web-ui/yarn.lock @@ -379,9 +379,9 @@ body-parser@^2.2.0: type-is "^2.0.0" brace-expansion@^1.1.7: - version "1.1.13" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.13.tgz#d37875c01dc9eff988dd49d112a57cb67b54efe6" - integrity sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w== + version "1.1.18" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.18.tgz#3ce74d89885136be1535341f8c3d4425c29a5cab" + integrity sha512-Edep/X9fGqVNmzKBVsDYIOtD+z1tuezV70LBjdCst9Tqu76lsnvRiZ6oTic1n+/BIwX6QDGAO94PN4N2SADvtw== dependencies: balanced-match "^1.0.0" concat-map "0.0.1" @@ -1018,9 +1018,9 @@ isarray@~1.0.0: integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== js-yaml@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.1.tgz#854c292467705b699476e1a2decc0c8a3458806b" - integrity sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA== + version "4.3.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.3.1.tgz#01216c001d67f48e2cd560d708c7af21090a3848" + integrity sha512-CY6crGq313MX8GkwvB7tzgp99vjQxY1++5y10/BKN/GUfHqWaOGQMNZkBvqSzsZKWk/ijwHlWzzkLulsGHhjWQ== dependencies: argparse "^2.0.1" @@ -1631,9 +1631,9 @@ tar-stream@^2.1.4: readable-stream "^3.1.1" tar@>=7.5.8, tar@^7.4.3: - version "7.5.11" - resolved "https://registry.yarnpkg.com/tar/-/tar-7.5.11.tgz#1250fae45d98806b36d703b30973fa8e0a6d8868" - integrity sha512-ChjMH33/KetonMTAtpYdgUFr0tbz69Fp2v7zWxQfYZX4g5ZN2nOBXm1R2xyA+lMIKrLKIoKAwFj93jE/avX9cQ== + version "7.5.22" + resolved "https://registry.yarnpkg.com/tar/-/tar-7.5.22.tgz#a696f998136e71487dc3f869a85bba2c67971ba9" + integrity sha512-MFO/QzvtAOmJbkhOaCTvbGcFN9L9b+JunIsDwaKljSOdcLMea3NJ1k9Usz/rjdfSXTq4dfzfeS7W4p4YOAAHeA== dependencies: "@isaacs/fs-minipass" "^4.0.0" chownr "^3.0.0" diff --git a/netty-mqtt/pom.xml b/netty-mqtt/pom.xml index 9d100a1abe..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 + 4.2.2.4-SNAPSHOT thingsboard netty-mqtt - 4.2.2.3 + 4.2.2.4-SNAPSHOT jar Netty MQTT Client diff --git a/pom.xml b/pom.xml index 196fbdf885..ac36f06375 100755 --- a/pom.xml +++ b/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard thingsboard - 4.2.2.3 + 4.2.2.4-SNAPSHOT pom Thingsboard @@ -70,7 +70,12 @@ entries below once TB migrates its tests off the deprecated @SpyBean/@MockBean to @MockitoSpyBean/@MockitoBean. --> 3.5.13 3.18.0 - 4.1.135.Final + 4.1.136.Final + 10.1.56 + 5.4.3 + 1.5.38 + 2.21.5 + 42.7.12 2.4.0-b180830.0359 0.12.5 0.10 @@ -108,7 +113,7 @@ 2.2.30 0.8 1.19.0 - 1.84 + 1.85 2.0.1 org/thingsboard/server/gen/**/*, org/thingsboard/server/extensions/core/plugin/telemetry/gen/**/* @@ -1015,6 +1020,63 @@ import + + + org.apache.tomcat.embed + tomcat-embed-core + ${tomcat.version} + + + org.apache.tomcat.embed + tomcat-embed-el + ${tomcat.version} + + + org.apache.tomcat.embed + tomcat-embed-websocket + ${tomcat.version} + + + + + org.apache.httpcomponents.core5 + httpcore5 + ${httpcore5.version} + + + org.apache.httpcomponents.core5 + httpcore5-h2 + ${httpcore5.version} + + + + + ch.qos.logback + logback-core + ${logback.version} + + + ch.qos.logback + logback-classic + ${logback.version} + + + + + com.fasterxml.jackson + jackson-bom + ${jackson-bom.version} + pom + import + + + + + org.postgresql + postgresql + ${postgresql.version} + + org.springframework.boot spring-boot-dependencies diff --git a/rest-client/pom.xml b/rest-client/pom.xml index ac1f6b8405..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 + 4.2.2.4-SNAPSHOT thingsboard rest-client diff --git a/rule-engine/pom.xml b/rule-engine/pom.xml index 6102acb3ce..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 + 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 827d30018d..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 + 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 92a6d55015..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 + 4.2.2.4-SNAPSHOT rule-engine org.thingsboard.rule-engine 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..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 @@ -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 = 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 8c791e7634..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 @@ -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 = true) public class TbCreateAlarmNodeConfiguration extends TbAbstractAlarmNodeConfiguration implements NodeConfiguration { @NoXss 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/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/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..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 @@ -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 = 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 fe17c659e1..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 @@ -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 = 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 c786478575..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 @@ -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 = true) public class TbAzureIotHubNodeConfiguration extends TbMqttNodeConfiguration { @Override 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/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/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())); 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/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/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/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/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/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/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/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(); 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; diff --git a/tools/pom.xml b/tools/pom.xml index 1380c94673..86a17be7a5 100644 --- a/tools/pom.xml +++ b/tools/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 4.2.2.3 + 4.2.2.4-SNAPSHOT thingsboard tools 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; 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); diff --git a/transport/coap/pom.xml b/transport/coap/pom.xml index 5b138f1c9b..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 + 4.2.2.4-SNAPSHOT transport org.thingsboard.transport diff --git a/transport/coap/src/main/resources/tb-coap-transport.yml b/transport/coap/src/main/resources/tb-coap-transport.yml index 97d53384ba..f9909e5fdc 100644 --- a/transport/coap/src/main/resources/tb-coap-transport.yml +++ b/transport/coap/src/main/resources/tb-coap-transport.yml @@ -15,30 +15,33 @@ # # 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}" # 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. @@ -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:}" @@ -183,6 +188,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}" @@ -198,15 +204,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 @@ -264,6 +270,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). @@ -417,12 +424,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: @@ -436,11 +445,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: @@ -449,6 +460,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/pom.xml b/transport/http/pom.xml index 5b6ce56df2..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 + 4.2.2.4-SNAPSHOT transport org.thingsboard.transport diff --git a/transport/http/src/main/resources/tb-http-transport.yml b/transport/http/src/main/resources/tb-http-transport.yml index bf8d5e1542..ce0be70eb4 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,23 +55,25 @@ 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 -# 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. @@ -78,6 +81,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 +91,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: @@ -123,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:}" @@ -166,6 +171,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: # Size of the thread pool that executes transport API callbacks (session registration, telemetry/attribute and RPC responses, entity update notifications, and the tenant profile fetch on a cache miss). Bounds how many such callbacks - including those that block on a backend round-trip - can run concurrently. callback_thread_pool_size: "${TB_TRANSPORT_CALLBACK_THREAD_POOL_SIZE:20}" @@ -214,6 +220,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) . @@ -366,12 +373,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: @@ -385,11 +394,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: @@ -398,6 +409,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/pom.xml b/transport/lwm2m/pom.xml index a9c687c2f1..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 + 4.2.2.4-SNAPSHOT transport org.thingsboard.transport diff --git a/transport/lwm2m/src/main/resources/tb-lwm2m-transport.yml b/transport/lwm2m/src/main/resources/tb-lwm2m-transport.yml index 1c14202efd..332463043d 100644 --- a/transport/lwm2m/src/main/resources/tb-lwm2m-transport.yml +++ b/transport/lwm2m/src/main/resources/tb-lwm2m-transport.yml @@ -15,30 +15,33 @@ # # 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}" # 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. @@ -46,6 +49,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 +59,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 @@ -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:}" @@ -133,6 +138,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: # Size of the thread pool that executes transport API callbacks (session registration, telemetry/attribute and RPC responses, entity update notifications, and the tenant profile fetch on a cache miss). Bounds how many such callbacks - including those that block on a backend round-trip - can run concurrently. callback_thread_pool_size: "${TB_TRANSPORT_CALLBACK_THREAD_POOL_SIZE:20}" @@ -168,16 +174,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}" @@ -314,6 +320,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). @@ -467,12 +474,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: @@ -486,11 +495,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: @@ -499,6 +510,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/pom.xml b/transport/mqtt/pom.xml index 3b90a2092d..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 + 4.2.2.4-SNAPSHOT transport org.thingsboard.transport diff --git a/transport/mqtt/src/main/resources/tb-mqtt-transport.yml b/transport/mqtt/src/main/resources/tb-mqtt-transport.yml index 0c011e207e..3e3cffb8bf 100644 --- a/transport/mqtt/src/main/resources/tb-mqtt-transport.yml +++ b/transport/mqtt/src/main/resources/tb-mqtt-transport.yml @@ -15,30 +15,33 @@ # # 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}" # 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 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. @@ -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: @@ -91,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:}" @@ -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: # Size of the thread pool that executes transport API callbacks (session registration, telemetry/attribute and RPC responses, entity update notifications, and the tenant profile fetch on a cache miss). Bounds how many such callbacks - including those that block on a backend round-trip - can run concurrently. callback_thread_pool_size: "${TB_TRANSPORT_CALLBACK_THREAD_POOL_SIZE:20}" @@ -247,6 +253,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). @@ -400,12 +407,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: @@ -419,11 +428,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: @@ -432,6 +443,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/pom.xml b/transport/pom.xml index 024f564f6e..16052972cd 100644 --- a/transport/pom.xml +++ b/transport/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 4.2.2.3 + 4.2.2.4-SNAPSHOT thingsboard transport diff --git a/transport/snmp/pom.xml b/transport/snmp/pom.xml index be2460d367..cc18e3a815 100644 --- a/transport/snmp/pom.xml +++ b/transport/snmp/pom.xml @@ -21,7 +21,7 @@ org.thingsboard - 4.2.2.3 + 4.2.2.4-SNAPSHOT transport diff --git a/transport/snmp/src/main/resources/tb-snmp-transport.yml b/transport/snmp/src/main/resources/tb-snmp-transport.yml index b5ec777af6..2bd673518c 100644 --- a/transport/snmp/src/main/resources/tb-snmp-transport.yml +++ b/transport/snmp/src/main/resources/tb-snmp-transport.yml @@ -15,30 +15,33 @@ # # 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}" # 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. @@ -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 @@ -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:}" @@ -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: # Size of the thread pool that executes transport API callbacks (session registration, telemetry/attribute and RPC responses, entity update notifications, and the tenant profile fetch on a cache miss). Bounds how many such callbacks - including those that block on a backend round-trip - can run concurrently. callback_thread_pool_size: "${TB_TRANSPORT_CALLBACK_THREAD_POOL_SIZE:20}" @@ -186,6 +192,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). @@ -346,12 +353,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: @@ -365,11 +374,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: @@ -378,6 +389,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' diff --git a/ui-ngx/angular.json b/ui-ngx/angular.json index 007af200ba..08ffdd7b9a 100644 --- a/ui-ngx/angular.json +++ b/ui-ngx/angular.json @@ -74,8 +74,8 @@ }, { "glob": "**/*", - "input": "node_modules/tinymce", - "output": "/assets/tinymce/" + "input": "node_modules/hugerte", + "output": "/assets/hugerte/" }, { "glob": "marker-icon-2x.png", diff --git a/ui-ngx/package.json b/ui-ngx/package.json index 2ac8b3a6d7..023ede7bd1 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", @@ -9,24 +9,25 @@ "build:types": "node generate-types.js", "build:icon-metadata": "node generate-icon-metadata.js", "lint": "ng lint", - "prepare": "patch-package" + "prepare": "patch-package --error-on-fail" }, "private": true, "dependencies": { - "@angular/animations": "20.3.25", + "@angular/animations": "20.3.28", "@angular/cdk": "20.2.14", - "@angular/common": "20.3.25", - "@angular/compiler": "20.3.25", - "@angular/core": "20.3.25", - "@angular/forms": "20.3.25", + "@angular/common": "20.3.28", + "@angular/compiler": "20.3.28", + "@angular/core": "20.3.28", + "@angular/forms": "20.3.28", "@angular/material": "20.2.14", - "@angular/platform-browser": "20.3.25", - "@angular/platform-browser-dynamic": "20.3.25", - "@angular/router": "20.3.25", + "@angular/platform-browser": "20.3.28", + "@angular/platform-browser-dynamic": "20.3.28", + "@angular/router": "20.3.28", "@auth0/angular-jwt": "^5.2.0", "@flowjs/flow.js": "^2.14.1", "@flowjs/ngx-flow": "20.0.2", "@geoman-io/leaflet-geoman-free": "2.19.3", + "@hugerte/hugerte-angular": "~1.1.1", "@iplab/ngx-color-picker": "^20.0.0", "@mat-datetimepicker/core": "~16.0.1", "@mdi/svg": "^7.4.47", @@ -38,7 +39,6 @@ "@svgdotjs/svg.filter.js": "^3.0.9", "@svgdotjs/svg.js": "3.2.4", "@svgdotjs/svg.panzoom.js": "^2.1.2", - "@tinymce/tinymce-angular": "^8.0.1", "ace-builds": "1.43.6", "ace-diff": "^3.3.0", "angular-gridster2": "~20.2.4", @@ -51,6 +51,7 @@ "flot.curvedlines": "https://github.com/MichaelZinsmaier/CurvedLines.git#master", "font-awesome": "^4.7.0", "html2canvas": "^1.4.1", + "hugerte": "~1.0.12", "jquery": "^3.7.1", "jquery.terminal": "^2.45.2", "js-beautify": "1.15.4", @@ -87,7 +88,6 @@ "split.js": "^1.6.5", "systemjs": "6.15.1", "tinycolor2": "^1.6.0", - "tinymce": "~6.8.6", "tooltipster": "^4.2.8", "tslib": "^2.8.1", "typeface-roboto": "^1.1.13", @@ -95,13 +95,13 @@ }, "devDependencies": { "@angular-builders/custom-esbuild": "20.0.0", - "@angular-devkit/build-angular": "20.3.25", - "@angular-devkit/core": "20.3.25", - "@angular-devkit/schematics": "20.3.25", - "@angular/build": "20.3.25", - "@angular/cli": "20.3.25", - "@angular/compiler-cli": "20.3.25", - "@angular/language-service": "20.3.25", + "@angular-devkit/build-angular": "20.3.34", + "@angular-devkit/core": "20.3.34", + "@angular-devkit/schematics": "20.3.34", + "@angular/build": "20.3.34", + "@angular/cli": "20.3.34", + "@angular/compiler-cli": "20.3.28", + "@angular/language-service": "20.3.28", "@types/ace-diff": "^2.1.4", "@types/canvas-gauges": "^2.1.8", "@types/flot": "^0.0.36", @@ -137,13 +137,10 @@ "typescript-eslint": "^8.54.0" }, "resolutions": { - "ace-builds": "1.43.6", - "tinymce": "6.8.6", - "@babel/core": "7.28.3", + "@babel/core": "7.29.7", "esbuild": "0.28.1", - "vite": "7.3.5", "rollup": "4.59.0", - "jquery.terminal/**/form-data": ">=4.0.4", + "less": ">=4.9.0", "js-beautify/**/minimatch": "^9.0.7" } } diff --git a/ui-ngx/patches/@angular+build+20.3.25.patch b/ui-ngx/patches/@angular+build+20.3.34.patch similarity index 100% rename from ui-ngx/patches/@angular+build+20.3.25.patch rename to ui-ngx/patches/@angular+build+20.3.34.patch diff --git a/ui-ngx/patches/@angular+core+20.3.25.patch b/ui-ngx/patches/@angular+core+20.3.28.patch similarity index 92% rename from ui-ngx/patches/@angular+core+20.3.25.patch rename to ui-ngx/patches/@angular+core+20.3.28.patch index 5cb9b5e521..cb947112bf 100644 --- a/ui-ngx/patches/@angular+core+20.3.25.patch +++ b/ui-ngx/patches/@angular+core+20.3.28.patch @@ -1,8 +1,8 @@ diff --git a/node_modules/@angular/core/fesm2022/debug_node.mjs b/node_modules/@angular/core/fesm2022/debug_node.mjs -index be43067..079f100 100755 +index be00d4e..8d7ed1a 100755 --- a/node_modules/@angular/core/fesm2022/debug_node.mjs +++ b/node_modules/@angular/core/fesm2022/debug_node.mjs -@@ -9599,13 +9599,13 @@ function findDirectiveDefMatches(tView, tNode) { +@@ -9488,13 +9488,13 @@ function findDirectiveDefMatches(tView, tNode) { if (isNodeMatchingSelectorList(tNode, def.selectors, /* isProjectionMode */ false)) { matches ??= []; if (isComponentDef(def)) { diff --git a/ui-ngx/pom.xml b/ui-ngx/pom.xml index 1bfc897a1a..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 + 4.2.2.4-SNAPSHOT thingsboard org.thingsboard 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') {