Skip to content

Support custom service sets and additional servers in FindServers#1810

Merged
kevinherron merged 1 commit into
mainfrom
feature/find-servers-additional-servers
Jul 16, 2026
Merged

Support custom service sets and additional servers in FindServers#1810
kevinherron merged 1 commit into
mainfrom
feature/find-servers-additional-servers

Conversation

@kevinherron

Copy link
Copy Markdown
Contributor

Summary

Applications embedding OpcUaServer can now substitute any of the service set implementations the server uses, and a server can advertise other servers it knows about through the FindServers service.

  • Introduce a ServiceSets interface with a factory method per service set, each defaulting to the standard implementation, consumed by a new OpcUaServer constructor overload — service set composition was previously hardcoded in the constructor, so replacing an implementation required re-deriving endpoint path registration.
  • Add a DefaultDiscoveryServiceSet constructor accepting a supplier of additional ApplicationDescriptions to include in FindServers results — OPC UA Part 4 §6.6.2.4.5.1 requires each member of a non-transparent RedundantServerSet to return the ApplicationDescriptions of all members, which the default (local-server-only) response can't satisfy.

Key Changes

  • ServiceSets: one factory method per service set (createAttributeServiceSet, createDiscoveryServiceSet, …), all with defaults, so implementations override only what they replace. Each factory is invoked once during construction and the returned instance is registered on every applicable endpoint path (DiscoveryServiceSet on all paths, the others on paths not suffixed /discovery) — the path rules stay inside OpcUaServer.
  • OpcUaServer: the existing 2-arg constructor delegates to the new 3-arg overload with new ServiceSets() {}. Behavior notes for review: the defaults were previously instantiated once per path and are now one instance shared across paths (they are stateless, so this is equivalent, and a single instance is the saner contract for stateful custom sets); factories receive the partially constructed server, exactly as the previous inline new Default*ServiceSet(this) calls did.
  • DefaultDiscoveryServiceSet: the supplier is invoked per FindServers request and may return different results over time; results are appended after the local ApplicationDescription and are subject to the standard serverUris filtering. The 1-arg constructor delegates with an empty supplier, so existing behavior is unchanged.

Testing

  • DefaultDiscoveryServiceSetTest — additional servers included in results; serverUris filtering selecting the additional server, the local server, or nothing; empty-supplier parity with the 1-arg constructor.
  • OpcUaServerServiceSetsTest — a custom DiscoveryServiceSet registered on every endpoint path; a custom non-discovery service set registered on non-discovery paths only; each factory invoked exactly once regardless of path count; default constructor behavior unchanged.
  • Full module suite: mvn -q -pl opc-ua-sdk/sdk-server -am test

References

🤖 Generated with Claude Code

Introduce a ServiceSets interface with a factory method per service set,
each defaulting to the standard implementation, and an OpcUaServer
constructor overload that accepts one. Each factory is invoked once
during construction and the returned instance is registered on every
applicable endpoint path, so applications can substitute any service
set implementation without re-deriving path registration.

Add a DefaultDiscoveryServiceSet constructor that accepts a supplier of
additional ApplicationDescriptions to include in FindServers results,
alongside the local server's own description. The supplier is invoked
per request and its results are subject to the standard serverUris
filtering. This allows a server to advertise the other members of a
non-transparent redundant server set, as required by OPC UA Part 4.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@kevinherron
kevinherron force-pushed the feature/find-servers-additional-servers branch from 4a67920 to 837818a Compare July 16, 2026 13:21
@kevinherron
kevinherron merged commit 48aa94a into main Jul 16, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant