- Extract RuleChainDetailsDao from RuleChainDao to reuse JpaAbstractDao
save logic (proper @Version increment, flush, detach)
- Reduce notes column size from 10MB to 1MB in schema and migration
- Catch "value too long" DB error with user-friendly message
- Pass tenantId consistently through the details DAO API
- Exclude content/markdownCss from RuleChainNote toString
- Add tests: save/load notes, update notes, preserve notes on
RuleChain save, remove notes, exceeded size limit
Rename `openConnections`/`connectionsCounter` to `statsName`/`number`
to match DefaultTransportService and avoid misleading future readers.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Refactor update/delete endpoints to use installed item's own ID instead of marketplace itemId
- Add SHA-256 checksum comparison to detect local entity modifications before update
- Support force update to skip checksum check when user confirms overwrite
- Add per-type update methods (widget, dashboard, calculated field, rule chain)
- Add entityId field to CalculatedFieldInstalledItemDescriptor
- Replace checkForUpdates with getItemsPublishedVersions API
- Replace getInstalledItemInfos with getInstalledItemIds returning List<UUID>
- Remove unused IotHubInstalledItemInfo class and resolver
- Set metadata version from saved rule chain in install/update flows
- Add entity-modified confirmation dialog in update UI
- Full entity stack: IotHubInstalledItem with ID, descriptors, JPA entity, DAO (extends JpaAbstractDao), service
- Controller endpoints: install, list (paginated), list infos, get by itemId, delete
- Install flow saves descriptor with entity IDs, delete cascades to installed entities
- Frontend installed items page with search, pagination, type chips, action buttons
- Browse page shows "Installed" label on cards, detail dialog shows "Open details" for installed items
- Installed item infos fetched on browse page init to track installation state
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>