Class BreakpointMatcherRegistry
Thread-safe via a single CopyOnWriteArrayList as the source of truth.
This is ideal for the access pattern here: reads (findMatch(org.mockserver.model.RequestDefinition, org.mockserver.mock.breakpoint.BreakpointPhase)) are frequent
and on the data plane (including the Netty event loop), while writes
(register(org.mockserver.model.RequestDefinition, java.util.Set<org.mockserver.mock.breakpoint.BreakpointPhase>, org.mockserver.configuration.Configuration, org.mockserver.logging.MockServerLogger), remove(java.lang.String), clear()) are rare control-plane
operations. A single structure means register/remove/clear are atomic with respect
to a concurrent findMatch(org.mockserver.model.RequestDefinition, org.mockserver.mock.breakpoint.BreakpointPhase) — there is no window in which two backing
collections can disagree.
Event-loop safety: findMatch(org.mockserver.model.RequestDefinition, org.mockserver.mock.breakpoint.BreakpointPhase) is designed to be called on the
Netty event loop for stream-frame phases. When the registry is empty, it returns
null immediately via a single CopyOnWriteArrayList.isEmpty() check
(zero allocation). When non-empty, it iterates a stable snapshot of the prebuilt
matchers without any blocking or allocation beyond the matcher's own match logic.
-
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionvoidclear()Clears all registered breakpoints.entries()Returns a snapshot of all registered breakpoints in registration order.findMatch(RequestDefinition request, BreakpointPhase phase) Finds the first registered breakpoint whose phases contain the given phase AND whose prebuilt matcher matches the given request AND which should pause for this hit.findResponseMatch(RequestDefinition request, HttpResponse response, BreakpointPhase phase) Response-phase variant offindMatch(org.mockserver.model.RequestDefinition, org.mockserver.mock.breakpoint.BreakpointPhase)that additionally evaluates each matcher's optional response-content conditions (status-code range / body regex) against the actualresponseabout to be written.static BreakpointMatcherRegistryregister(RequestDefinition matcher, Set<BreakpointPhase> phases, String clientId, Integer skipCount, Integer responseStatusCodeMin, Integer responseStatusCodeMax, String responseBodyContains, Configuration configuration, MockServerLogger logger) Registers a new breakpoint matcher with a required owner clientId, an optional skip-count for conditional (Nth-hit) breakpoints, and optional response-content conditions that gate whether a RESPONSE-phase breakpoint pauses.register(RequestDefinition matcher, Set<BreakpointPhase> phases, String clientId, Integer skipCount, Configuration configuration, MockServerLogger logger) Registers a new breakpoint matcher with a required owner clientId and an optional skip-count for conditional (Nth-hit) breakpoints.register(RequestDefinition matcher, Set<BreakpointPhase> phases, String clientId, Configuration configuration, MockServerLogger logger) Registers a new breakpoint matcher with a required owner clientId.register(RequestDefinition matcher, Set<BreakpointPhase> phases, Configuration configuration, MockServerLogger logger) Registers a new breakpoint matcher without an owner client (for tests only).booleanRemoves a breakpoint by id.intremoveByClientId(String clientId) Removes all breakpoints owned by the given callback client.intsize()Number of currently registered breakpoints.
-
Constructor Details
-
BreakpointMatcherRegistry
public BreakpointMatcherRegistry()
-
-
Method Details
-
getInstance
-
register
public String register(RequestDefinition matcher, Set<BreakpointPhase> phases, Configuration configuration, MockServerLogger logger) Registers a new breakpoint matcher without an owner client (for tests only). In production, the REST endpoint requires a clientId; this overload exists for unit tests that exercise the registry directly.- Parameters:
matcher- the request definition to match againstphases- the set of phases at which matching exchanges should breakconfiguration- the active server configuration (passed to MatcherBuilder)logger- the server logger (passed to MatcherBuilder)- Returns:
- the assigned UUID id for the registered breakpoint
-
register
public String register(RequestDefinition matcher, Set<BreakpointPhase> phases, String clientId, Configuration configuration, MockServerLogger logger) Registers a new breakpoint matcher with a required owner clientId. -
register
public String register(RequestDefinition matcher, Set<BreakpointPhase> phases, String clientId, Integer skipCount, Configuration configuration, MockServerLogger logger) Registers a new breakpoint matcher with a required owner clientId and an optional skip-count for conditional (Nth-hit) breakpoints.The
clientIdidentifies the callback WebSocket client that owns this breakpoint. Matched exchanges are dispatched over the callback WebSocket to that client for interactive resolution.The optional
skipCountdelays the first pause: the breakpoint still matches on every hit but only pauses once it has been hit more thanskipCounttimes.null(or a non-positive value) means pause on every hit (legacy behaviour).- Parameters:
matcher- the request definition to match againstphases- the set of phases at which matching exchanges should breakclientId- the callback WS client that owns this breakpoint (required in production)skipCount- the number of matching hits to skip before pausing, ornullto pause every timeconfiguration- the active server configuration (passed to MatcherBuilder)logger- the server logger (passed to MatcherBuilder)- Returns:
- the assigned UUID id for the registered breakpoint
-
register
public String register(RequestDefinition matcher, Set<BreakpointPhase> phases, String clientId, Integer skipCount, Integer responseStatusCodeMin, Integer responseStatusCodeMax, String responseBodyContains, Configuration configuration, MockServerLogger logger) Registers a new breakpoint matcher with a required owner clientId, an optional skip-count for conditional (Nth-hit) breakpoints, and optional response-content conditions that gate whether a RESPONSE-phase breakpoint pauses.The response conditions (
responseStatusCodeMin/responseStatusCodeMaxfor an inclusive status-code range, andresponseBodyContainsfor a regex searched within the response body) are only evaluated at the response phase (the response is not known at the request phase). When set, the breakpoint pauses only when the response satisfies all configured conditions. When all arenull(the default) the breakpoint pauses regardless of response content (legacy behaviour).- Parameters:
matcher- the request definition to match againstphases- the set of phases at which matching exchanges should breakclientId- the callback WS client that owns this breakpoint (required in production)skipCount- the number of matching hits to skip before pausing, ornullto pause every timeresponseStatusCodeMin- inclusive lower bound of the response status-code condition, ornullresponseStatusCodeMax- inclusive upper bound of the response status-code condition, ornullresponseBodyContains- a regex searched (find semantics) within the response body, ornullconfiguration- the active server configuration (passed to MatcherBuilder)logger- the server logger (passed to MatcherBuilder)- Returns:
- the assigned UUID id for the registered breakpoint
-
findMatch
Finds the first registered breakpoint whose phases contain the given phase AND whose prebuilt matcher matches the given request AND which should pause for this hit.Returns
nullif the registry is empty or no matcher matches. This method is allocation-light and safe to call on the Netty event loop.Conditional (skip-count) breakpoints: when a matcher matches, its per-matcher hit counter is incremented (atomically, via
BreakpointMatcher.shouldPause()). If the matcher is configured with askipCountand this hit still falls within the skip window, the hit is recorded but the matcher does NOT pause —findMatchtreats it as the winning match and returnsnull(do not pause) rather than falling through to a later matcher. This preserves first-match semantics: the first matcher to match a request "owns" the decision for that hit. A matcher with noskipCountalways pauses (legacy behaviour).- Parameters:
request- the inbound request to match againstphase- the phase to check- Returns:
- the first matching
BreakpointMatcherthat should pause, ornull
-
findResponseMatch
public BreakpointMatcher findResponseMatch(RequestDefinition request, HttpResponse response, BreakpointPhase phase) Response-phase variant offindMatch(org.mockserver.model.RequestDefinition, org.mockserver.mock.breakpoint.BreakpointPhase)that additionally evaluates each matcher's optional response-content conditions (status-code range / body regex) against the actualresponseabout to be written.Selection semantics:
- A matcher is considered only if its phases contain
phaseand its prebuilt request matcher matchesrequest. - If the matcher has a response condition that the
responsedoes NOT satisfy, it is treated as not applicable and iteration falls through to later matchers (a response condition is part of what the matcher selects, so a non-matching response means this matcher simply does not want this exchange). - The first matcher that matches the request AND satisfies its response
condition (or has none) owns the decision: its per-matcher hit counter is
incremented and it pauses only if it falls outside any configured skip
window — identical to
findMatch(org.mockserver.model.RequestDefinition, org.mockserver.mock.breakpoint.BreakpointPhase).
Matchers with no response condition behave exactly as in
findMatch(org.mockserver.model.RequestDefinition, org.mockserver.mock.breakpoint.BreakpointPhase). This method is safe to call on the data plane (no allocation beyond the matcher's own logic and the condition evaluation).- Parameters:
request- the inbound request to match againstresponse- the response about to be written to the downstream clientphase- the phase to check (typicallyBreakpointPhase.RESPONSE)- Returns:
- the first matching
BreakpointMatcherthat should pause, ornull
- A matcher is considered only if its phases contain
-
remove
Removes a breakpoint by id.- Returns:
- true if the breakpoint was found and removed
-
removeByClientId
Removes all breakpoints owned by the given callback client. Called when a WebSocket client disconnects so its breakpoints are cleaned up.- Parameters:
clientId- the client id whose breakpoints should be removed- Returns:
- the number of breakpoints removed
-
clear
public void clear()Clears all registered breakpoints. -
entries
Returns a snapshot of all registered breakpoints in registration order. -
size
public int size()Number of currently registered breakpoints.
-