Class DriftAlertNotifier

java.lang.Object
org.mockserver.mock.drift.DriftAlertNotifier

public class DriftAlertNotifier extends Object
Fires a fire-and-forget HTTP POST webhook whenever a DriftRecord of sufficient severity is stored, carrying the record as JSON. Off by default.

Decoupling: core must not depend on the Netty HTTP client, so the actual request sender is injected via setSender(Function) (mirrors LoadScenarioOrchestrator.setSender / HttpState.setReplayHandler). The Netty runtime wires it from HttpActionHandler.getHttpClient(); unit tests pass a deterministic synchronous fake sender.

Fail-soft: the entire onDriftStored(DriftRecord) body is wrapped in a try/catch that swallows (TRACE-logs) every error, and the outbound send is non-blocking (no .get()) with an exceptionally handler. A webhook misconfiguration, a slow/unreachable endpoint, or a malformed URL can therefore never throw into the drift-analysis pipeline nor affect the served response.

Time is read via a pluggable LongSupplier clock (defaults to System.currentTimeMillis()) so de-dup cooldown behaviour can be driven deterministically in tests without wall-clock sleeps.

  • Method Details

    • getInstance

      public static DriftAlertNotifier getInstance()
    • setSender

      public void setSender(Function<HttpRequest,CompletableFuture<HttpResponse>> sender)
      Install the request sender that issues an outbound HttpRequest and returns the response. Called by the Netty runtime, wiring the existing HTTP client so core never depends on it directly (mirrors LoadScenarioOrchestrator.setSender). This is runtime wiring, not configuration: it is deliberately not cleared by reset().
    • configure

      public void configure(boolean enabled, String webhookUrl, SemanticSeverity threshold, long cooldownMs)
      Apply the drift-alert webhook configuration. Called by the runtime at startup. A blank URL or a disabled flag leaves the notifier inert.
    • onDriftStored

      public void onDriftStored(DriftRecord record)
      Notify that a drift record was just stored. Returns immediately (a no-op) unless the notifier is enabled, a sender is installed, the URL is non-blank, the record's effective severity meets the threshold, and the de-dup cooldown allows it. Otherwise builds an outbound POST and fires it fire-and-forget.

      The whole body is wrapped in a try/catch that swallows every error (TRACE-logged) so it can never throw into the DriftAnalyzer.analyse(org.mockserver.mock.Expectation, org.mockserver.model.HttpResponse) store loop.

    • reset

      public void reset()
      Reset transient runtime state. Clears the de-dup cooldown map ONLY; the installed sender and the configuration are runtime wiring (like HttpState's replay handler) and are deliberately left intact.