Caching Strategy (Hazelcast)

Role of Hazelcast in the platform

Hazelcast is a required, shared cluster used by multiple backend services. ft-configs-service publishes derived, read-optimized configuration snapshots into Hazelcast so other services can read them at runtime without reading files or querying the configs database.

  • Database is the source of truth.

  • Hazelcast contains snapshots/read models.

  • Consumers include ACS, northbound-api, provisionportal, serviceapi, and an “angular backend” that read Hazelcast directly.

Hazelcast Client Configuration

Hazelcast wiring is provided by dependency com.friendly:ft-cache:0.0.8:

  • Default client YAML resource: hazelcast-client.yaml on the application classpath (packaged inside ft-cache).

  • Config file location property: cache-config.path (default classpath:). Effective resource is ${cache-config.path}hazelcast-client.yaml.

  • Member override env var: HZ_MEMBERS (comma/space separated); when set, it overrides hazelcast-client.network.cluster-members.

  • Embedded member mode (not used for this service in production): cache.is-server=true makes it load ${cache-config.path}hazelcast.yaml and start a Hazelcast member.

Known production setting (confirmed): hazelcast-client.cluster-name=dev.

Defaults shipped by ft-cache

The default hazelcast-client.yaml packaged in com.friendly:ft-cache:0.0.8 includes:

  • members: 127.0.0.1:5701 (overridden by HZ_MEMBERS in non-local environments)

  • near-cache defaults:

    • time-to-live-seconds: 90

    • max-idle-seconds: 100

    • invalidate-on-change: true

Cache Catalog (maps/lists)

Cache Type Key → Value (publisher)

northbound-config

IMap

StringNorthboundConfigurationDto\n`NorthboundConfigCacheService`

tab-view

IMap

ClientTypeList<TabViewCacheDto>\n`TabViewCacheService`

tabs

IMap

ClientTypeList<TabItemCacheDto>\n`TabCacheService`

simplified-view

IMap

ClientTypeSimplifiedViewsCacheDto\n`SimplifiedViewCacheService`

custom-params

IMap

ClientTypeCustomParamsCacheDto\n`CustomParamCacheService`

rpc-methods

IMap

ClientTypeList<RpcMethodCacheDto>\n`RpcMethodsCacheService`

frame-groups

IMap

ClientTypeList<FrameCacheDto>\n`FrameCacheService`

replace-services

IMap

ClientTypeReplaceServiceCacheDto\n`ReplaceServiceCacheService`

network-map

IMap

ClientTypeNetworkMapCacheDto\n`NetworkMapCacheService`

mesh

IMap

ClientTypeNetworkMapCacheDto\n`MeshCacheService`

snmp-configuration

IMap

ClientTypeSnmpConfigurationCacheDto\n`SnmpConfigurationCacheService`

device-monitoring

IMap

ClientTypeList<String>\n`DeviceMonitoringCacheService`

device-activity

IMap

ClientTypeList<DeviceActivityCacheDto>\n`DeviceActivityCacheService`

network-device-param-mapping

IMap

ClientTypeList<NetworkDeviceParamMappingCacheDto>\n`NetworkDeviceParamMappingCacheService`

neighboring-wifi-diagnostic-paths

IMap

ClientTypeList<String>\n`NeighboringWiFiDiagnosticPathCacheService`

user-info

IMap

ClientTypeMap<String, Boolean>\n`UserInfoCacheService`

cube-dsl-parameters

IMap

ClientType.scCubeDslCacheDto\n`CubeDslCacheService`

column-definitions

IMap

LongColumnDefinitionCacheDto\n`ColumnDefinitionCacheService`

interface-items

IList

index → InterfaceItemDto\n`InterfaceItemCacheService`

The table uses short publisher class names to keep the rendered layout stable. See the service packages in code for fully qualified names.

Data Flow for Critical Caches

ft-configs-cache-dataflow

Consistency and Refresh Semantics

What is implemented

  • Most cache services warm up on startup (@PostConstruct), by reading DB and writing to Hazelcast.

  • Many domain services call cache refresh methods after writes to keep Hazelcast close to DB state (for example NetworkMapService calls NetworkMapCacheService.refreshClientType).

Known correctness requirements and gaps

The intended contract (confirmed) is:

  • Hazelcast snapshots must be updated only after the database transaction commits.

Current code has gaps:

  • Many refresh calls execute inside the same @Transactional method and may publish before commit.

  • tabs cache is warmed on startup (TabCacheService.init()), but is not refreshed by /tabs/** write/import flows today (this is a known bug: TabService and TabImportService do not invoke TabCacheService).

Sequence: Cache Refresh (example)

This is the current request flow for one domain (NetworkMap), which refreshes Hazelcast inside the write transaction:

ft-configs-seq-cache-refresh