Rename `openConnections`/`connectionsCounter` to `statsName`/`number`
to match DefaultTransportService and avoid misleading future readers.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
In Jackson 2.18.x, EXISTING_PROPERTY type info combined with the no-arg
@JsonIgnoreProperties causes the triggerType discriminator field to be
silently excluded from the serialized JSON. When the server then tries to
deserialize the POST body for /api/notification/rule, Jackson cannot find
triggerType and throws "missing type id property 'triggerType'", resulting
in a 500 for NotificationEdgeTest.testNotificationRule.
Fix by:
1. Adding @JsonProperty("triggerType") to force the field into normal bean
serialization, overriding any suppression by the type info machinery.
2. Replacing the no-arg @JsonIgnoreProperties with @JsonIgnoreProperties(
ignoreUnknown = true) so unknown properties are ignored rather than
causing errors (e.g. for forward compatibility).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Methods stubbed via Mockito spy in same-package tests must remain
package-private. Revert isSSL() to package-private; getClientAddr()
follows the same convention as getAddress().
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Rename TagsKey → tagsKey and make it private (Java naming convention)
- Make isSSL() private in MqttTransportHandler (internal use only)
- Fix double space in if (isSSL) in MqttTransportContext
- Extract getClientAddr() helper and move clientAddr computation inside
logging guards so address resolution is skipped when logging is disabled
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Document each action type with: what it represents, which TbMsgType
it pushes to the rule engine (if any), key metadata fields, and
audit log payload description.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Fix "device" copy-paste errors in Tenant, Customer, and EntityView @Schema descriptions.
Add documented keys and JSON examples to all additionalInfo annotations.
Add missing getAdditionalInfo() override with @Schema to Edge.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Using the same connection for both SCAN cursor iteration and GET value
fetches causes Jedis 5.x response-ordering corruption: the SCAN response
parser receives a GET response (byte[]) where it expects a List, and vice
versa, resulting in ClassCastException on startup.
Fix: open two connections per getAll() call — one dedicated to the scan
cursor and one for value fetches — eliminating any interleaving.
Affected: TbRedisLwM2MClientStore, TbRedisLwM2MModelConfigStore,
TbLwM2mRedisRegistrationStore.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Tests that read shared static state (e.g. testAllowedUrls with 8.8.8.8)
could run concurrently with tests that mutate it (e.g. testAdditionalBlockedSingleIp),
causing intermittent failures. Class-level @ResourceLock serializes all tests.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Move TestDbCallbackExecutor from rule-engine test sources to
common/util main sources as DirectListeningExecutor, making it
available to all modules. Convert to an enum singleton since the
executor is stateless. Widen JpaAbstractDaoListeningExecutorService
service field type from JpaExecutorService to ListeningExecutor to
allow injecting DirectListeningExecutor in tests. Fix
AbstractChunkedAggregationTimeseriesDaoTest NPE by injecting the
direct executor into the spy.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When a TbRuleChainInputNode has `forwardMsgToDefaultRuleChain=true` and the originator's
default rule chain is the same as the rule chain containing this node, the message enters
an infinite loop: the node forwards to the default rule chain, which routes back to the
same node, which forwards again, causing unbounded recursion and 100% CPU on rule-engine.
Fix: detect the loop in DefaultTbContext.input() by checking whether the calling rule node
is already present in the message's return stack (TbMsgProcessingCtx). On the second+
iteration the stack already contains the (ruleChainId, ruleNodeId) pair of the node,
so the call is a cycle. In that case tellFailure() is called with a descriptive message
and a WARN log is emitted instead of re-enqueuing the message.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Delay and deduplication rule nodes were creating brand new TbMsg objects
instead of copying the original, which reset the ruleNodeExecCounter to 0.
This allowed bypassing the maxRuleNodeExecutionsPerMessage limit.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>