fix(adminui): a Sparkplug metric whose name contains / cannot be browse-committed
#509
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?
Browse-commit derives the raw tag Name from the Sparkplug metric name. A tag Name is a RawPath segment
and may not contain
/; a SparkplugmetricNamelegitimately may. So committing a browsed metric such asNode Control/Rebirthis refused whole, withRow N: Name must not contain '/'.This blocks a spec-mandatory metric.
Node Control/Rebirthis required by the Sparkplug B spec on everyedge node, so the one metric an operator is most likely to browse for is the one that cannot be committed.
Current behaviour is safe, not silent — the commit is refused in words and nothing is mis-bound. The
workaround works: author the tag by manual entry with a
/-free Name and type the slashedmetricNameinto the Sparkplug tag editor, which accepts it. So this is a usability defect, not a correctness one.
Fix. The commit mapper should derive a
/-free Name (e.g. replace/with_, or take the last segment)while carrying the original slashed string through as
metricName— the two fields already existseparately and only the derivation conflates them. Sanitising must not collide two distinct metrics onto one
Name; if it would, refuse that pair specifically rather than the whole batch.
Relevant:
src/Server/ZB.MOM.WW.OtOpcUa.AdminUI/Uns/RawBrowseCommitMapper.cs.Acceptance. Browsing the simulator and committing
Node Control/Rebirthproduces a tag whose Name is/-free and whosemetricNameis the exact spec string, and reading it live returns the metric's value.Fixed in master
2a7d1167.Node Control/Rebirthnow commits.The mapper was already correct. It carried
metricNameverbatim; only the derived tag Name —a RawPath segment — tripped
RawPaths.ValidateSegment. NewRawBrowseCommitMapper.ToRawSegmentcoerces the Name (
Node Control/Rebirth→Node Control_Rebirth) and the address is untouched.Two deliberate choices beyond the issue:
produced it: any browser whose leaf name carries a
/hit the same wall, and for all of them thebinding address travels separately and survives.
RawPaths.ValidateSegment, not a charset copied into the test —so a new rule there fails in
RawBrowseCommitMapperTestsrather than letting an illegal Name through.The collision guard the issue asked for is
DescribeNameCollisions, wired into the commit path:A/Band
A_Bboth land onA_B, and silently merging two metrics into one tag bound to whichever addresssurvived would be worse than the refusal this replaced. It is scoped per target group (the same
metric name under two devices is not a collision) and names the specific pair.