DiscoverHierarchy: subtree root + server-side filters #102
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?
Motivation
galaxy_repository.v1.DiscoverHierarchytoday returns the entire deployed Galaxy as one paged stream. Every consumer that only cares about a slice (a single Area, only$WinPlatformruntime hosts, only alarm-bearing or historized attributes, a tag-name pattern for an Admin UI search box) has to pull the whole hierarchy and filter client-side.For a 50k-object Galaxy this is wasteful for first-load and for any UI that does narrow lookups, and it makes future per-key scoped permissions (#follow-up) harder to implement because the server has no concept of "this caller's view of the hierarchy."
The gateway already materializes the full object list inside
GalaxyHierarchyCacheonce per deploy, so server-side slicing is cheap —Where/Skip/Takeover an in-memory list.Proposed proto change
Field numbers 3-12 are additive; existing clients keep working unchanged.
Server behavior
root_*resolves to agobject_id; missing root returnsNotFound.max_depthis computed against the resolved root, not the Galaxy root.tag_name_globuses standard*/?glob, anchored, case-insensitive.include_attributes=falsereturnsGalaxyObjectskeletons with emptyattributes— useful for Admin UI tree lazy-load.total_object_countreflects post-filter count.Acceptance
total_object_countis post-filter.gobject_id, subtree bytag_name, subtree bycontained_path,max_depthcap, each filter individually, all filters combined, paging across a filtered result..NETclientGalaxyRepositoryClientexposes a typedDiscoverHierarchyAsync(DiscoverHierarchyOptions)overload covering the new fields. The current zero-argDiscoverHierarchyAsync()keeps current behavior.docs/GalaxyRepository.mddocuments subtree + filter semantics.Out of scope
Per-API-key constraint scoping (e.g. "this key may only see
Area1/*") is a separate feature — see the per-key scoping issue. This issue ships the mechanism; that issue plugs key-bound constraints into the same code path.Source
Surfaced during
lmxopcuaGalaxy → MxGateway migration planning (seelmx_mxgw_impl.mdaudit). OtOpcUa itself doesn't need this for the v1 migration since it pulls the whole hierarchy at startup, but it unblocks Admin UI use cases and is a structural prerequisite for per-key scoping.Companion: #103 (per-key scoped permissions). The
browse_subtreesconstraint there reuses the filtering pipeline added by this issue.Implemented in
b995c17(codex/fix-runtime-review-findings).Verification passed:
dotnet build src\MxGateway.Contracts\MxGateway.Contracts.csprojscripts\publish-client-proto-inputs.ps1clients\go\generate-proto.ps1clients\python\generate-proto.ps1gradle :mxgateway-client:generateProtodotnet test src\MxGateway.sln --no-restoredotnet test clients\dotnet\MxGateway.Client.sln --no-restorego test ./...python -m pytestcargo fmt --all --checkcargo test --workspacegradle testgit diff --check