HistoryServerCapabilities: every boolean capability is false even though data and event history are served #881
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
With the HistorianGateway backend (vd03, real AVEVA), every Boolean under
Server/ServerCapabilities/HistoryServerCapabilitiesreadsfalse, includingAccessHistoryDataCapabilityandAccessHistoryEventsCapability, even though raw, processed and at-time reads and event history all work.AggregateFunctionscorrectly lists the 10 supported aggregates.Impact: a spec-following client that checks these flags before calling HistoryRead skips history entirely.
Expected: populate the flags from the active backend's real capabilities: AccessHistoryData/Events true, insert/replace/update/delete false for the Gateway backend (it has no HistoryUpdate path), and the per-backend values for SqlServer/QuestDb, which do support HistoryUpdate. Add a test per backend.
Evidence: lmxopcua#801 AVEVA history gate (comment 11735), OtOpcUa master
008f0b36docs/plans/evidence/2026-11-10-opcua2/aveva-history-801.md; harnessAvevaGatewayHistoryLiveGateTests(f607ee75). Reproduces identically on SDK 1.5.378.182 (efb9197a) and SDK 2.0.1, so it is not an SDK2 regression.Fixed on master
b27b5b9c(not deployed).Cause: nothing ever wrote the Boolean
HistoryServerCapabilitiesproperties, so the SDK default (all false) was what clients saw. OnlyAggregateFunctions(#682) andMaxReturnDataValues(#736) were synced.Fix: each backend declares its own capabilities, and the server advertises and enforces those declarations.
IHistorianDataSource.ReadCapabilities(Data/Events/ServerTimestamps). Every production source declares it itself, and a reflection guard checks this. The Null source declaresNone.IHistorianDataUpdater.Capabilitiesis a required member (InsertData/ReplaceData/UpdateData/DeleteRaw/DeleteAtTime).AdvertisedHistoryCapabilities). The same declarations also drive dispatch:BadHistoryOperationUnsupportedand never reaches the updater.HistoryWriteAccessLevel bit follows a non-empty declaration.Eventsflag.AggregateFunctionsis unchanged.MaxReturnEventValuesstays 0 (no limit).ServerTimeUtcstored)The event and annotation flags are false on every backend because the node manager dispatches no
UpdateEventDetailsor annotation update to any backend.IsDeleteModifiedandRemoveare still refused.Caveat: a SqlServer schema at v1 (
AutoCreateSchema=falsewith no modification trail; a Warning is logged at boot) still advertises the update flags. Each update on that schema still returnsBadHistoryOperationUnsupportedat run time, as before.Tests:
HistoryServerCapabilitiesWireTestsboots a real server and reads every flag over a client session, with the backends built throughHistorianBackendRegistrythe way the Host builds them. It covers Gateway, SqlServer and QuestDb, no historian (all false), and a SqlServer→Gateway rewire on the same session (Insert/DeleteRaw/ServerTimestamp go from true to false).DeleteRawfrom the SqlServer updater's declaration makes 2 tests fail; restored.HistoryUpdateTests.AvevaGatewayHistoryLiveGateTestsnow asserts the Gateway flags. Not run here (it needs vd03).Runs: