Skip to content

fix(json-cppagent): emit cppagent v2 header fields on every envelope#147

Draft
ottobolyos wants to merge 28 commits intoTrakHound:masterfrom
ottobolyos:fix/issue-130-131
Draft

fix(json-cppagent): emit cppagent v2 header fields on every envelope#147
ottobolyos wants to merge 28 commits intoTrakHound:masterfrom
ottobolyos:fix/issue-130-131

Conversation

@ottobolyos
Copy link
Copy Markdown

@ottobolyos ottobolyos commented Apr 25, 2026

Summary

Fixes #130 — the Header element of MTConnectStreams, MTConnectDevices, and MTConnectAssets envelopes emitted by the JSON-cppagent formatters now carries schemaVersion, matching the cppagent v2 wire shape. Issue #131 (testIndicator) is locked in by regression tests; production code already emits the field.

  • Add SchemaVersion to IMTConnectStreamsHeader, IMTConnectDevicesHeader, and IMTConnectAssetsHeader plus their MTConnect*Header implementations.
  • Map SchemaVersion through JsonStreamsHeader, JsonDevicesHeader, and JsonAssetsHeader constructors and reverse mappers.
  • Emit Validation on every cppagent header DTO so the field reaches the wire alongside schemaVersion and testIndicator.
  • Cache the DataItems list and DataItem type set during MTConnectAgent.NormalizeDevice backfill so AddDevice's required-DataItem fan-out is linear in DataItem count rather than quadratic.
  • Refresh the SchemaVersion xmldoc example to v2.7 and document the property on the cppagent header DTOs so the public xmldoc surface tracks the wire emission.
  • Add NUnit pins for schemaVersion, testIndicator, and Validation regression coverage on every JSON-cppagent header DTO; reflection guard keeps future header classes from regressing on any of the three fields.
  • Pin the AddDevice required-DataItem backfill contract and the schema-version wire shape across v2.0 / v2.3 / v2.5.
  • Extract a shared (envelopeKind, version) wire-shape matrix so future header / envelope additions reuse the compliance grid instead of forking it.
  • No public-API breaks (additive interface members on producer-only IMTConnect*Header surfaces).

@ottobolyos ottobolyos force-pushed the fix/issue-130-131 branch 2 times, most recently from 681bdf4 to 47c69aa Compare April 28, 2026 10:55
The docs/testing/issue-130-131/ subtree carried phase-by-phase campaign writeups that
referenced internal tooling (CONVENTIONS rule-book, internal section
numbers, extra-files.user/ paths, internal tracker terminology). Those
writeups belong in the campaign's gitignored planning area, not in
the maintainer-facing public docs tree.
Adds three RED regression fixtures (Assets/Streams/Devices) that pin the
cppagent v2.7.0.7 Header.validation wire shape: ctor copy, serialized
property, and round-trip through To*Header(). Tests fail until the
Validation property is added to the JSON-cppagent header DTOs.

Source authority: cppagent v2.7.0.7 emits Header.validation on every
envelope. Public defect tracker:
TrakHound#130
TrakHound#131
Adds the `validation` JSON property to JsonAssetsHeader, JsonStreamsHeader,
and JsonDevicesHeader, mapped from `IMTConnect{Assets,Streams,Devices}Header.Validation`
in the constructor and copied back through `To{Assets,Streams,Devices}Header()`.
Mirrors the cppagent v2.7.0.7 wire shape that emits `Header.validation` on
every envelope. Greens the F-C17 regression tests.

Source authority: cppagent v2.7.0.7 emits Header.validation on every
envelope. Public defect tracker:
TrakHound#130
TrakHound#131
Adds RED fixture asserting that an internal static
JsonHeaderWireShapeMatrix in TestHelpers exposes a TestCaseSource-shaped
compliance matrix for the (Assets|Streams|Devices) x (2.0|2.3|2.5)
combinations consumed by per-envelope and cross-envelope E2E tests.
Tagged [Category("ComplianceMatrix")].
Centralizes the (Assets|Streams|Devices) x (2.0|2.3|2.5) matrix into
TestHelpers/JsonHeaderWireShapeMatrix as an internal static class with
TestCaseSource-shaped Cases (cross-envelope) and SchemaVersionCases
(per-envelope) generators. Per-envelope SchemaVersion fixtures and the
cross-envelope E2E fixture now pull from this single source so adding a
new schema version automatically extends both layers. Tests are tagged
[Category("ComplianceMatrix")].

Greens the F-Si-M5 RED matrix fixture; full suite passes (60/60).
Adds regression fixture asserting NormalizeDevice/AddDevice backfills the
four required Device-level DataItems (Availability, AssetChanged,
AssetRemoved, AssetCount) exactly once each across four starting states
(null, empty, with one required, with all required) and preserves
user-provided DataItems. Lets the F-P-H5 perf optimization
(cast DataItems once + HashSet for type checks) refactor the inner loop
without regressing behavior.
Hoists the per-required-type LINQ scan out of the four required-DataItem
backfill blocks in MTConnectAgent.NormalizeDevice. The DataItems
enumerable is now materialized once into a List<IDataItem> and the
existing types are projected into a HashSet<string>, dropping per-block
work from O(n) lookups + four ToList() allocations to O(1) lookups + one
materialization. Behavior preserved per NormalizeDeviceRequiredDataItemsTests.
Adds a RED file-content fixture asserting the SchemaVersion XML-doc
example on the six MTConnect.NET-Common Header types does not pin to the
stale "2.5" string. Drives the F-D15 doc fix that updates the example to
"2.7" or a neutral phrasing.
Updates the SchemaVersion XML-doc example on the six MTConnect.NET-Common
Header interfaces and classes from the stale "2.5" snapshot to "2.7" so
IntelliSense matches the current MTConnect Standard release the agent
targets. Greens the F-D15 regression pin.
Adds RED file-content fixture asserting the SchemaVersion property in the
three JSON-cppagent header DTOs (Assets/Streams/Devices) is preceded by
an XML-doc <summary> block. Drives the F-D16 doc fix that documents the
new property as the cppagent v2 wire-shape mirror.
Adds an XML-doc <summary> block above the SchemaVersion property in the
JsonAssetsHeader and JsonStreamsHeader DTOs describing the property as the
cppagent v2 wire-shape mirror. JsonDevicesHeader's SchemaVersion summary is
contributed by fix/issue-128 (envelope-vs-Header semantics) which lands
ahead of this branch per the documented merge order; the F-D16 test only
requires that a <summary> block precede [JsonPropertyName("schemaVersion")]
on each of the three DTOs and is greened by either author. Greens the
F-D16 doc pin.
The F-P-H5 refactor (cast DataItems to List<IDataItem> once + HashSet
for type checks) inadvertently dropped the spec-required line that
overrides the auto-injected AssetCount's Representation from VALUE to
DATA_SET. Restore the override + the explanatory comment citing the
MTConnect Part 2 UML id.

Cross-PR interaction: per the campaign convention, the consuming PR
fixes the test that depends on the refactored default — here the
consuming surface is the fix/issue-132 regression suite, but the fix
must land on this branch since that's where F-P-H5 dropped the line.
`new HashSet<T>(int capacity)` was added in .NET Framework 4.7.2 +
netstandard 2.1 + .NET Core 2.0; net461 / net47 / net471 / netstandard2.0
only know `(IEqualityComparer<T>)` and reject the int with CS1503. The
NormalizeDevice DataItem-type cache landed in 355b74e used the capacity
ctor unconditionally, which broke `dotnet pack -c Release` on those TFMs.

Wrap the capacity-aware allocation in a conditional so:
- net472 + / netstandard2.1 + / netcoreapp2.0 + → keep the capacity hint
  (the perf optimization the F-P-H5 commit was after).
- net461 / net471 / net47 / netstandard2.0 → fall back to the
  parameterless ctor; behaviour identical apart from one extra rehash on
  the first hot-path call.

Surfaced via `dotnet pack -c Release` from the integration branch.
The class-level summary on NormalizeDeviceRequiredDataItemsTests cited an
internal audit-finding code when describing the inner-loop perf
optimisation it leaves room for; rewrite the summary so the same point
is made inline.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

JSON-cppagent-mqtt: Header.schemaVersion absent on MQTT Streams Header

1 participant