The guard around iterating createdEntityIds was checking isEmpty()
instead of !isEmpty(), so entity deletion was skipped whenever there
was actually data to clean up.
SolutionTemplateInstalledItemDescriptor and SolutionInstallResponse now
carry tenantTelemetryKeys and tenantAttributeKeys lists. SolutionService
.deleteSolution takes the full descriptor (instead of just the
created-entity list) so uninstall can also clean up tenant-scoped
telemetry/attributes. Update IotHub install descriptor population and
delete call sites; force-update path logs and continues if delete throws.
PathChildrenCache invoked EnsureContainers internally during start(), so
the parent znode existed when publishCurrentServer ran. CuratorCache does
not, so on a fresh ZK creatingParentsIfNeeded reaches ZKPaths.mkdirs with
the trailing-slash forPath argument and fails with
"Path must not end with / character", aborting Spring startup.
Spring Boot 3.5 deprecated RestTemplateBuilder.setConnectTimeout(Duration) and
setReadTimeout(Duration) for removal; their non-deprecated replacements
connectTimeout(Duration) and readTimeout(Duration) are direct, behavior-equivalent
delegations.
Switches the ZooKeeper-based service discovery from the deprecated
org.apache.curator.framework.recipes.cache.PathChildrenCache to the
modern CuratorCache replacement (Curator 5.x).
- ZkDiscoveryService: field type, construction, listener registration
and child-event handler migrated to the new API. parentPathFilter
and zkNodesDir guard preserve the original direct-children semantics
against the recursive-by-default behaviour of CuratorCache.
- ZkDiscoveryServiceTest: mock type and event construction adapted to
the new listener signature; existing assertions unchanged.
Eliminates 11 [WARNING] lines for PathChildrenCache deprecation on
lts-4.2 (targeted Tier 3 slice of #15481): repo-wide [WARNING] count
843 -> 832, [ERROR] count 0 -> 0.
Install and update dialogs now render error details via tb-markdown
when the failing item is a SOLUTION_TEMPLATE, falling back to the plain
text block for other item types. Supports the rich instruction-style
error messages returned by the solution install flow.
Propagate User through SolutionInstallContext, DefaultSolutionService,
and TbCalculatedFieldService.delete so non-security-context callers can
drive solution installs and calculated-field cleanup. Pass
TenantSolutionTemplateInstructions into the context constructor so the
caller controls instruction state.
Add optional isNew flag on MenuSection; when set, menu-link and
menu-toggle components render a NEW badge next to the label. Marks
the IoT Hub entry as new.
Add CreatedRuleChainInfo extending CreatedEntityInfo that overrides
getEntityPageLink to produce /edgeManagement/ruleChains/<id> for EDGE
rule chains and /ruleChains/<id> otherwise. SolutionInstallContext now
registers rule chains with this type-aware info.
Routes get/set/del/scan/getSet/hGet/hSet/hDel/lRange/zRem/getRange calls
through stringCommands()/keyCommands()/hashCommands()/listCommands()/
zSetCommands() instead of the deprecated shortcut methods on
DefaultedRedisConnection. Behavior-preserving — Spring Data Redis
delegates the deprecated overloads to these same typed commands.
Eliminates 70 deprecation warnings across RedisOtaPackageDataCache, five
Leshan-forked lwm2m stores (TbLwM2mRedisRegistrationStore,
TbLwM2mRedisSecurityStore, TbRedisLwM2MClientStore,
TbRedisLwM2MModelConfigStore, TbLwM2mRedisClientOtaInfoStore,
TbLwM2MDtlsSessionRedisStore) and the TbRedisLwM2MClientStoreTest unit
test, which now uses Answers.RETURNS_DEEP_STUBS to mock the typed
command chain.
Part of #15481 Tier 3 cleanup.
Added @Builder.Default to 5 fields with initializers in
MobileLayoutConfig (pages) and DefaultTenantProfileConfiguration
(maxCalculatedFieldsPerEntity, maxArgumentsPerCF, maxStateSizeInKBytes,
maxSingleValueArgumentSizeInKBytes). Dropped the redundant `= 0` on
Task.attempt (int default is already 0) to clear the same anomaly on
@SuperBuilder.
Eliminates 6 "@Builder/@SuperBuilder will ignore the initializing
expression" warnings from #15481 Tier 2. `[WARNING]` total drops
843 -> 837, `[ERROR]` unchanged at 0.
Uses X500Principal.getName(X500Principal.RFC1779) to keep DN output byte-identical to the old sun.security.x509.X500Name format; expected test strings unchanged. Removes 7 getSubjectDN() and 1 getIssuerDN() deprecation warnings in rule-engine-components.
The IoT Hub backend sends the literal string 'Initial release' as the
changelog payload for every newly-published item. That text tells the
user nothing they don't already see from the v 1.0.0 chip in the meta
bar — just informational noise. Hide the Changelog heading + body when
the trimmed changelog equals 'Initial release'.
Both the inner section guard and the outer container guard use the new
shouldShowChangelog() helper so an item with empty readme + initial
release changelog doesn't leave an empty wrapper.
- Two-column widget showing top-3 solution templates and top-3 devices
fetched by totalInstallCount DESC, with installed-state fetching
(solution templates list + device counts)
- Section titles as .tb-title-link routerLinks to /iot-hub/solution-templates
and /iot-hub/devices
- Item cards open detail dialog via IotHubActionsService; solution template
cards show green check_circle badge in top-right when installed
- HomePageWidgetsModule now imports IotHubComponentsModule to resolve
IotHubActionsService
Device preview styling:
- Switch item card .tb-iot-hub-card-preview to white bg + bottom border
when item.type === DEVICE
- Switch detail dialog .dlg-preview to white bg + full border when DEVICE
Creates missing system images from application/src/main/data/resources/images
during LTS patch startup, mirroring the upgrade-path loadSystemResources logic.
Existing system images in the DB are left untouched.
Reintroduces the canonical item link (/iot-hub/{itemId}) that resolves
to the latest published version. The preview shape (/iot-hub/{itemId}/preview)
stays removed — if a creator wants to preview a specific draft, they
share the /iot-hub/version/{itemVersionId} link with that exact
versionId.
Final URL shapes:
- /iot-hub/{itemId} → latest published version
- /iot-hub/version/{itemVersionId} → specific version, warning if unpublished
Resolver branches on which route param is present — no extra data flag.
Restores getPublishedVersion API method. IoT Hub ask adds back one new
endpoint: GET /api/items/{itemId}/published.
Consolidates to a single deep-link shape: /iot-hub/version/{itemVersionId}.
A specific version snapshot is a more useful sharable link than
"latest of item" — stable, unambiguous, and fits creator review
workflows ("please look at exactly this draft").
Removes /iot-hub/{itemId} and /iot-hub/{itemId}/preview routes, the
getPublishedVersion and getLatestVersion API methods (now unused), the
byVersion and preview route-data flags, and the iot-hub.item-preview
i18n key. Simplifies the resolver to a single getVersionInfo call with
the same warning-if-unpublished gate.
Big win for the IoT Hub backend contract: no new endpoints needed, only
a behavior guarantee on existing /api/versions/{versionId}.
Third URL shape for deep links, pointing at a specific version snapshot
rather than "latest of item". Stable link — useful for creators sharing
"review exactly this draft" references. Routes through the same
resolver component with a new byVersion flag on route data; reuses the
existing getVersionInfo API and the same warning-if-unpublished gate as
the preview flow.
Spec + plan updated to document the new shape and the expanded IoT Hub
backend contract.