chore(deps): update dependency org.mock-server:mockserver-netty-no-dependencies to v7.2.0#2243
Open
renovate[bot] wants to merge 1 commit into
Open
Conversation
…pendencies to v7.2.0
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR contains the following updates:
7.1.0→7.2.0Release Notes
mock-server/mockserver-monorepo (org.mock-server:mockserver-netty-no-dependencies)
v7.2.0Security
controlPlaneAuthorizationEnabledand a
controlPlaneScopeMapping(e.g.platform-admins=admin,qa-team=mutate,viewers=read), anauthenticated principal's scopes/groups are mapped to one of three hierarchical roles
(
admin⊇mutate⊇read): reads requireread, every mutating operation requiresmutate, and aprincipal lacking the role gets
403 Forbidden(recorded in the audit log). Fail-closed — use togetherwith control-plane OIDC authentication. Covers all
HttpState.handleoperations plus the Netty-serviced/mockserver/configuration,/openapi.yamland/llm/optimisationReportreads/writes. Not yet covered:the lifecycle endpoints (
/bind,/stop,/status) and per-tool MCP authorization. Seedocs/code/tls-and-security.md.JWTValidatorverifies against a public-keyJWK set, so it now accepts only asymmetric algorithms (
RS*/ES*/PS*/EdDSA) and rejects HMAC(
HS256/384/512), closing an algorithm-confusion forgery vector. Switch to an asymmetric key if yourelied on HMAC.
configured, requests are rejected instead of accepting any token, and the comparison is constant-time.
redactSecretsInLog, default off). Maskssensitive header values (
Authorization,Cookie,x-api-key, …) and configured JSON body fields inretrieved/exported logs and the dashboard event view. Matching and verification still see the original
values, so behaviour is unchanged.
dompurifypinned to3.4.11via an npmoverridesentry, clearing all 16 openDependabot DOMPurify advisories (mXSS / DOM-clobbering / prototype-pollution).
Added
AI, LLM & agent protocols (LLM / MCP / A2A)
physics, usage, embeddings, multi-turn conversations, provider failover) and MCP-server-mocking (tools,
resources, prompts over JSON-RPC 2.0) builders are now available in all eight clients (Java, Node, Python,
Ruby, Go, Rust, .NET, PHP), all producing the same wire JSON.
optimisation brief (Markdown) or structured JSON bundle (
LlmOptimisationReport) from captured traffic.Nine deterministic signals detect repeated system prompts, low cache-hit rates, unused tool schema,
model overspend, large resent context, deterministic tool calls, oversized tool results, output-token
bloat and duplicate calls — each with token counts, estimated USD saving, and structured fix guidance
(copy-paste config snippet or example expectation where applicable). An in-product verdict (A–F grade
and "$X recoverable" headline computed via per-call MAX attribution so the total is always ≤ actual spend)
and two new session KPIs (cache-hit rate and one-shot rate) appear in the dashboard and the
Markdown brief. New LLM Optimise dashboard screen (with verdict banner, "Copy verdict" button, and
updated hero cards),
GET /mockserver/llm/optimisationReportendpoint, andexport_optimisation_reportMCP tool. Export-only and deterministic; secrets are redacted. The Anthropic codec now maps the top-level
systemfield so cache and repeated-prompt signals fire on Anthropic traffic.httpLlmResponseembeddings now cover Gemini, Ollama andBedrock (Titan / Cohere-on-Bedrock) in addition to OpenAI/Azure, all deterministic and L2-normalised. A new
rerank action mocks Cohere and Voyage rerank endpoints in the provider-correct envelope.
prompts/list,prompts/getandsampling/createMessageoverHTTP/1.1, HTTP/2 and HTTP/3, configured via a new
McpPromptRegistry.withStreaming()generates an SSE streamof task status/artifact events;
withPushNotifications(webhookUrl)POSTs each completed task to a webhook.enforceOutputSchema, opt-in). A mocked completion whose bodydoesn't conform to its
outputSchemafails loudly (502+ diagnostic header) instead of returning thenon-conforming body — modelling a real provider's strict
json_schemamode. Checked before streaming begins.(Anthropic
overloaded_error, OpenAIserver_error/rate_limit_exceeded, Gemini, Ollama) so SDKretry/backoff can be tested realistically. An optional
errorKind(OVERLOAD/RATE_LIMIT/SERVER_ERROR) emits the provider's distinct body and natural HTTP status without picking the code yourself.image_url,Anthropic
image, Geminiinline_data) and audio parts (OpenAIinput_audio), so a request matcher canassert on image/audio presence;
ParsedMessageexposeshasImage()/hasAudio()etc. A new response-sidetoolChoicefield (auto/none/required/named) drivesfinish_reason. Request recognition only —MockServer does not store the bytes.
Usagegains optionalcachedInputTokens,cacheCreationTokensandreasoningTokens, decoded from each provider's usage shape and emitted on GenAItelemetry spans, so cost dashboards can split cached-input and reasoning spend.
OpenAI (gpt-4.1, o3/o4) and Gemini 2.5 families, with most-specific-prefix matching.
gpt-5*entries areflagged placeholders — confirm against the provider price list.
llmInferUsageEnabled, default off). Amocked completion that omits
usagecan be auto-populated with estimated token counts (documented as anestimate, not a real BPE tokenizer); existing responses are unchanged.
support (configure via
asyncAmqpUri).ai_agent_frameworks.htmlpage with recipes for pointingLlamaIndex and the OpenAI Agents SDK at MockServer to mock LLM provider calls.
Identity provider mocking (OIDC / OAuth2 / SAML / SCIM)
PUT /mockserver/oidc(ormockOpenIdProvider()) stands up acomplete IdP — discovery, JWKS, token, authorize, userinfo, introspection, revocation, logout — with the
full OAuth2 authorization-code flow (PKCE S256/plain), client-credentials, refresh-token, and the device
authorization grant (RFC 8628). Tokens are minted at request time (correct
nonce/at_hash,id_tokensplit from
access_token); signing is configurable (RS/ES 256/384/512). Optional token-endpoint clientauthentication (
enforceClientAuthentication) and opaque access tokens with working/introspect.controlPlaneOidcAuthenticationRequired,off by default). Verifies the
Authorization: Bearertoken against an external IdP's JWK set (direct ordiscovered), asserting issuer, audience,
exp/nbfand required scopes, and records the verifiedsubas the audit principal. Combinable with mTLS and JWT control-plane auth.
PUT /mockserver/samlstands up a mock IdP (metadata + SP-initiated POSTSSO) returning an XML-DSig-signed assertion with configurable subject/attributes. Configurable signing
algorithm (RS/ES 256/384/512), Single Logout, and negative-test flags (
expiredAssertion,wrongAudience,tamperedSignature) to exercise an SP's rejection paths. TypedmockSamlProvider(...)Java API; inboundparsing is XXE-hardened.
PUT /mockserver/scim(ormockScimProvider(...)) generates anin-memory SCIM provider: CRUD over
Users/Groups, discovery documents,application/scim+jsonshapes,single-attribute filtering (
eq/co/sw/pr),PatchOp, pagination, an optional bearer-token gate andconfigurable base path/seed data.
Load injection, chaos & SRE
loadGenerationEnabled, off by default). A named,registry-based control plane (
PUT/GET/DELETE /mockserver/loadScenario,/start,/stop) drives outboundtraffic at a target: load a scenario by name, then trigger one or many to run concurrently, each with
its own
startDelayMillis. A scenario is a list of request steps (template-rendered per iteration with aniterationcontext) with per-step think-time and aprofileof ordered stages — closed-model VUstages, open-model arrival-rate (iterations/sec) stages with
LINEAR/EXPONENTIAL/QUADRATICramp curves,and pauses — composing step/spike/soak/stress shapes. Scenarios can be preloaded at startup
(
loadScenarioInitializationJsonPath). Bounded by hard caps on VUs, rate, stages and concurrent scenarios.Full registry API and runnable examples in all eight clients.
mock_server_load_*family — request duration histogram (withtrace_idexemplars), iterations, bytes,throttles, errors-by-kind, and live
active_vus/inflightgauges — labelled byscenario, run_id, step, route, method, status_class(with auto-templatized low-cardinality routes andopt-in custom labels). Zero-cost when metrics are off;
mock_server_forward_*is unchanged.sloTrackingEnabled, off by default). A windowed sample store records latencyand error per forwarded round-trip;
PUT /mockserver/verifySLOevaluates latency-percentile and error-rateobjectives and returns a structured verdict (
200PASS /406FAIL /400malformed). Pairs with chaos:drive faults, then assert the system stayed within objectives.
mid-response RST, jittered slow-close and HTTP/2 GOAWAY faults. A new
PUT/GET/DELETE /mockserver/preemptionsimulates a Kubernetes rolling-update / spot-reclaim drain — cordoning new exchanges, reporting in-flight
count, and auto-uncordoning after a TTL — without stopping the JVM.
(
/mockserver/chaosExperiment/profiles/{name},/apply/{name}). Profiles persist in theStateBackend,so they survive a reset and replicate across a cluster. The dashboard Chaos panel gains a Saved Profiles list.
startDelayMillis(fixed delay) and/orcronSchedule(5-field cron, JVM time zone, minute granularity); it sits in ascheduledstatus until thescheduled time. No scheduling fields = immediate start (unchanged).
rateLimitexpectation clause, off by default). A protocol-agnosticclause returns a deterministic
429withRetry-AfterandX-RateLimit-*headers once a matchedexpectation exceeds its rate, via
fixed_windowortoken_bucketalgorithms, with an optional named sharedcounter — so a test can exercise client backoff without a chaos profile.
recoverAfteronhttpResponse, opt-in). Returns a failure response(default
503) for the firstfailTimesmatches and then the success response, so a test can deterministicallyexercise client retry/backoff. An optional
idempotencyHeaderscopes the counter per request-header value.httpError().withStreamError(...)resets a matchedrequest stream with a given error code (HTTP/2
RST_STREAM, HTTP/3RESET_STREAM) without affecting othermultiplexed streams; HTTP/1.1 falls back to dropping the connection. Also on the Node, Python and Ruby clients.
skipCount(pause only after N matching hits) and,on the RESPONSE phase,
responseStatusCodeMin/MaxandresponseBodyContainsso a breakpoint can pauseonly on, e.g.,
5xxresponses or a body containing a particular message.Request matching & response generation
SWITCHresponse mode + optionalswitchAfter). With anindex-aligned
httpResponseslist, an expectation serves the first response for its firstNmatches thenadvances — ideal for "succeed, then start failing" on a single endpoint without a full scenario.
WEIGHTEDresponse mode +responseWeights, e.g.[90, 10]).generateFromSchema). Synthesises aschema-valid body at response time, reusing the OpenAPI example engine; fires only when the response has no
explicit body.
request.pathGroups(numbered) andrequest.namedPathGroups, usable from Mustache, Velocity and JavaScript.delaymay carry atemplate+templateTyperenderedagainst the request, so e.g. larger payloads respond slower.
conditionalRequestDefinitionwithif/then/else).accept:<media-type>header-matcher directivematches per RFC 7231 (q-weights, wildcards, specificity).
condition(status code / range / header presence) and/or an ordered
modifierschain where each sees the previous output.FuzzyBody) — matches when the request body is similar enough to anexpected string by Jaro-Winkler ratio at or above a configurable threshold (a non-LLM similarity match).
matchExactCase, default off). When enabled, method, path and regexstring-body matching become case-sensitive; header/cookie/query matching always stays case-insensitive.
defaultResponseHeaders) — stamp organisation-wide headers (Server,trace id, …) onto every response (mock, forwarded, proxied), applied add-if-absent.
withProtocol(...)on anexpectation or
verify(...)matches/asserts on the protocol a request arrived over; the newHTTP_3value(experimental) is server-trusted via the
h3ALPN identifier, and protocol now round-trips throughrecorded requests.
httpResponse().withTrailers(...)emits protocol-appropriate trailing headers(chunked +
Traileron HTTP/1.1, a trailing HEADERS frame on HTTP/2/3). gRPC responses are unaffected.namespacefield plus a configurable match header(
matchNamespaceHeader, defaultX-MockServer-Namespace) lets teams share one instance without colliding;scoped
clear/retrieveand JavaclearByNamespace/retrieveActiveExpectations(...).multipart/form-datarequest-body matching (MultipartBody) — match individual parts by fieldname/value, filename and content-type; OpenAPI multipart bodies build field matchers from the schema.
> 60,>= 60,< 100,<= 30,== 5,!== 5) for header, cookie andquery-string values.
capturerules and scenario-state templates. Acapturerule extracts a value from thematched request (jsonPath/xpath/header/query/cookie/pathParameter) into scenario state; templates can read
and write scenario state via a
scenariohelper — enabling auth→resource→confirm journeys.crypto(md5/sha1/sha256/sha512/hmacSha256),regex(matches/replaceAll/group),
html,csv,xpath(XXE-hardened) andyaml, plusjsonPath/xPathrequest-body extraction now in the Velocity and JavaScript engines (previously Mustache only).
Proxying, forwarding & recording
re-issues idempotent (GET/HEAD/OPTIONS/PUT/DELETE/TRACE) calls on a connection error or 502/503/504 with
linear back-off; the circuit breaker trips open (fail-fast
503) after N consecutive failures to ahost:port, then half-opens. Open upstreams exportmock_server_upstream_circuit_openwhen metrics are on.forwardConnectionPoolEnabled, defaulttrue). Idle HTTP/1.1 keep-aliveupstream connections are pooled and reused, eliminating per-request TCP/TLS handshakes and the ephemeral-port
exhaustion that caused request errors under sustained forward load (a k6 baseline of 21%/68% errors at
750/1500 rps dropped to ~0%). Safe by default: the forward client runs on its own event-loop group (no
self-deadlock in synchronous local callbacks) and a channel is only pooled when its codec is genuinely
quiescent. Only plain HTTP/1.1 keep-alive is pooled — HTTP/2, HTTP/3, binary, streaming, tunnelled and
Connection: closeconnections always use a fresh connection. Set tofalseto restore the old behaviour.GET/PUT /mockserver/retrieve?type=RECORDED_EXPECTATIONS&format=...nowaccepts
forwardUnmatchedTo=<upstream>, arming record-and-forward of unmatched requests and returning therecorded expectations (in any supported language/JSON) in one call — removing the multi-step proxy setup.
The upstream is SSRF-validated before any state is mutated.
jsonPatch(RFC 6902) and/or
jsonMergePatch(RFC 7386) applied to a forwarded/proxied JSON response body, so one fieldof a real upstream response can be changed without replacing the whole body.
jsonPatchruns first; anon-JSON body or failed patch leaves the body unchanged.
redactSecretsInRecordedExpectations(off by default) maskssensitive request headers when recorded expectations are retrieved, generated as code, or persisted; HAR and
Postman imports redact sensitive headers and common secret body fields by default. Redaction preserves
times/timeToLive/priority/idso recordings still replay.only by an id segment (
/users/123,/users/456) into one/users/{id}expectation and drop exactduplicates. With
templatizeRecordedValues(opt-in), volatile query/header/JSON-body values (UUIDs, ids,dates, JWTs, opaque tokens) are also generalized into matchers, while stable values are kept verbatim.
PUT /mockserver/baseline/comparediffs current recordedinteractions against a saved baseline and returns a structured added/removed/changed report (value-insensitive
JSON-shape comparison), usable from CI.
Verification
verify(..., Duration timeout)polls until the verificationpasses or times out (for async / fire-and-forget code), and
verifyNever(..., Duration window)asserts acondition stays unmet for the whole window. Implemented client-side; existing snapshot
verify(...)is unchanged.verifyAll(...)runs every suppliedverification and throws one error listing all mismatches instead of failing on the first.
Verification.withDisposition(FORWARDED | MOCKED)narrows a count to requests that were forwarded vs matcheda mock.
range (
statusCodeRange: "2XX") or operator (">= 400"); verification-only, never written to the wire.detailedVerificationFailuresis enabled (default),a failed sequence verification — and response verification — now appends a per-step "closest match diff"
naming the fields that differ. Response reason-phrase matching honours
matchExactCase, and response cookiesuse the same sub-set/notted semantics as the request side. Diagnostic only; pass/fail is unchanged.
OpenAPI & contract testing
validateRequestsAgainstOpenApiSpec, off bydefault). A request matched by a spec-backed expectation is validated against that spec before the action is
dispatched; a violation is rejected with
400and anOPENAPI_REQUEST_VALIDATION_FAILEDevent. Previouslyvalidation only ran on the proxy/forward path.
PUT /mockserver/contractTest). Runs a spec as contract tests againsta live service: builds a representative request per operation, sends it (with the same SSRF protection as
forwarding), validates the response, and returns a pass/fail-per-operation report. Optional
operationIdrestricts the run.
enforceResponseValidationForMocks, off by default). Whenenabled alongside response validation, a mock response that fails validation is replaced with a
502,matching the proxy-path enforcement; default stays advisory-only.
providerState(s)round-trip on import/verify/exportand map onto a MockServer scenario, so an imported interaction only matches once its state is active.
PUT /mockserver/import?format=pact(or/pact/import) imports Pact v3 consumer contracts as expectations.via a reserved
__generationOptions__entry in the operations map.(bearer / API key / basic from
securitySchemes, else a placeholder JWT bearer) with blank placeholdercredentials, so the collections still work against an unauthenticated MockServer.
gRPC & GraphQL
PUT /mockserver/graphqlimports SDL / introspection and generatesschema-valid expectations per root operation;
PUT /mockserver/asyncapi/httpturns AsyncAPI channels intoGET expectations serving schema-aware payloads.
schema(SDL or introspection JSON);MockServer then synthesises a schema-valid
{"data": {...}}for a matched query with no hand-authoredresponse — honouring types, nullability, lists, enums, aliases,
__typename, and fragments. Backed bygraphql-java(22.x, Java-17-compatible).grpc-status: 0)response and no hand-authored body returns a schema-valid example synthesised from the proto descriptor's
response type (scalars, enums, nested/repeated/map fields,
oneof, well-known types) instead of an emptyframe. Explicit bodies are never overwritten.
grpcBidiResponsemay settemplateType(VELOCITY/MUSTACHE)so its
jsonrenders against the matched inbound message.ConnectResponse.success(json)/ConnectResponse.error(code, message); realapplication/grpctraffic is unaffected.bringing every client to parity with Java.
Dashboard UI
A shared named-scenario registry (lifecycle-state badges, multi-select start, per-row edit/start/stop/delete)
sits above two sub-tabs: Run & Monitor (live "Running now" cards, status, the multi-scenario chart and
post-run summary) and Create / Edit (the stage-builder form with generated register-and-start client
code rendered inline below it). The code uses each client's idiomatic load-scenario builders
(
loadScenario(...).withProfile(LoadProfile.of(LoadStage.constantVus(...))), etc.) rather than raw JSON —matching the Mock and Verification code generators — across Java, Node, Python, Go, C#, Ruby and Rust (plus
raw JSON and curl), and regenerates live as you fill in the form. The view follows the task — editing a
scenario switches to Create / Edit, starting a run switches to Run & Monitor. The chart plots every
concurrently-running scenario at once — a
line per scenario plus an aggregate "all scenarios" total — with independent toggles for which metrics to
show (RPS, VUs, in-flight, p50/p95/p99, error rate) and which scenarios to include (all enabled by default).
Each run shows a determinate progress bar (elapsed / total profile duration), green while driving load and
amber while paused.
pass/fail-per-operation table; Cluster shows state-backend cluster status (node id, coordinator,
members), auto-refreshing.
GraphQL, plaintext) and live JSON / JSON-Schema validation (inline red squiggles before submit). Monaco and
its workers are bundled and served locally (no runtime CDN).
Composer's Review step show a side-by-side JSON diff of what will be created/changed, via a bundled Monaco
JsonDiffViewer.stateDiagram-v2with the current state highlighted, built from what the panel observes.examples, a per-operation dropdown chooses which the generated mock returns (sent as
operationsAndResponses).request's method and path and jumps to the Breakpoints form.
copy; a
P<n>chip and a sortable Priority header show match order.mock; auto-refreshing live panels (Drift, Breakpoints, AsyncAPI, MCP); a Quick/Advanced Composer toggle with
plain-language tooltips; SAML provider mocking; a responsive layout that works on tablet/mobile (collapsing
grid, adaptive "More" navigation, full-screen dialogs); resizable panels; a keyboard-shortcuts help dialog;
baseline-compare; real Mermaid agent-run graphs; and inspect/edit-restart of a running chaos experiment.
filter presets, a side-by-side visual diff in "Why didn't this match?", a matcher test playground, and
authoring of
capturerules in the Composer.IDE extensions (VS Code & JetBrains)
*.mockserver.json(c)files get inline schema validation, autocompletionand hover docs, driven by the same schema MockServer validates against (generated from
mockserver-core).Continue / Modify / Abort on requests and responses, including per-frame stream editing. Breakpoints fire only
on traffic through MockServer.
JSON or DSL — record-to-code), generate expectations from an OpenAPI spec, run scratch-request match analysis,
send ad-hoc test requests, view the request log, and reset.
"update stub to match upstream" quick-fix.
(trace id → open the correlated trace in Jaeger/Tempo/Grafana via a configurable URL template).
both extensions.
own version so it can't drift behind the release.
Client libraries
httpResponseClassCallback/httpForwardClassCallback)are now available in Go, .NET, Rust, PHP, Node, Ruby and Python; object/closure callbacks
(
mockWithCallback(...), response written in your own language over the callback WebSocket) are in Go, .NET,Rust, Node and Python. PHP supports class callbacks only (REST-only).
connect to a secured MockServer — a static or per-request bearer token, a CA certificate to trust the
server's TLS, and a client certificate + key for mutual TLS. Default behaviour is unchanged.
builders, OpenAPI import, and verify-zero-interactions are now in the Go, Rust, .NET, PHP and Node clients,
moving them toward parity with Java/Python.
retrieve?format=<language>nowproduces copy-paste-ready upsert code (and verification code for recorded requests) in Java, JavaScript,
Python, Go, C#, Ruby, Rust and PHP, with correct per-language string escaping; the non-Java clients expose
retrieveExpectationsAsCode(format)/retrieveRecordedExpectationsAsCode(format). The dashboardLibrary → Export tab offers all eight languages plus a verification-code option.
(
MockServerT/t.Cleanup), Node (await usingviaSymbol.asyncDispose), Ruby (RSpec shared context),.NET (
MockServerFixture/IAsyncLifetime), PHP (MockServerTestTrait). A newclient_compatibility.htmlpage documents an 8×8 feature matrix and per-language test-fixture snippets.
release bundle and fail with an actionable message (naming a version that ships bundles, the Docker image, or
the Maven Central jar) instead of a raw 404.
CLI & configuration
--watchlive-reload and amockserver demosubcommand.run --watchlive-reloads expectations whenthe
--init/--openapifile changes (a CLI surface overwatchInitializationJson);mockserver demostarts a server pre-loaded with example expectations and prints getting-started/dashboard URLs and a sample
curl.mockserver import <file>subcommand and clientimportExpectations(...)— load a JSON expectations fileinto an already-running server without restarting it.
--print-configprints every known property asname = value [source](with sensitive values redacted) and exits; the same report is available at runtime from the authenticated
GET /mockserver/config.GET /mockserver/ready) — returns503until initializers and OpenAPI seedingcomplete, then
200, distinct from the always-200liveness/status endpoints; the Helm chart now uses itfor the readiness probe.
failOnInitializationErrorfails startup on a malformed init file insteadof silently continuing with zero expectations, and MockServer now logs a
WARNfor unrecognisedmockserver.*/MOCKSERVER_*keys (e.g. a typo) instead of silently ignoring them.stopDrainMillis(default 15000) for active requests to complete, avoiding cut connections during rolling restarts.
configuration dialog.
WASM custom rules
match_request(ptr, len)now receives the request method, path and headers (as a JSON envelope) in addition to the body, with
fallback to the legacy body-only
match(...). A new dependency-free Rust authoring crate(
mockserver-wasm-sdk) gives typed accessors, andPOST /mockserver/wasm/testruns a module against asample request and returns
{ "matched": … }so a module can be validated without creating a live expectation.Clustering & observability
GET /mockserver/clusterreports cluster membership/health(
clustered,nodeId,coordinator,clusterName, members), degenerate-but-valid on a single node andreal JGroups membership with the Infinispan backend; a
mock_server_cluster_membersgauge exports the count.driftAlertWebhookEnabled, off by default). Fires a fire-and-forgetPOSTcarrying the drift record whenever a stored drift meets the configured severity threshold, with a
per-signature cooldown. Fully fail-soft — a bad endpoint can never affect drift analysis or the served response.
controlPlaneAuditEnabled, off by default). An append-only, bounded,in-memory log of control-plane mutations (who/what/when/where/outcome) recording redacted structural metadata
only — never headers or bodies. Retrieve via
GET /mockserver/audit; cleared on reset.mock_server_forward_request_duration_secondsandmock_server_forward_requestslabelled byupstream_host(andstatus_class), plusserver.address/server.portattributes on the forward span. Host-only labels keep cardinality bounded.exported as
mock_server_dropped_log_events(previously INFO/DEBUG drops vanished silently), with a singleWARN on the first drop.
perExpectationMetricsEnabled, off by default) — amock_server_expectation_matchedcounter labelled by stable expectation id.Changed
npm run demoseeds a crafted seven-call support-agent rundesigned to fire all six optimisation signals, so the LLM Optimise tab is populated out of the box. An
optional documented recipe shows how to capture real agent traffic by proxying a headless OpenCode run.
Sessions tab is renamed Trace and sits after Traffic; the Scenarios state-machine panel moved
from Trace to a tab on the Mocks page. Each tab now shows a one-line description bar, and the Get Started
page leads with the same six features (including LLM Optimise and Performance Testing tiles).
dark-mode-aware log colours), KPI hero cards and a real time axis on Metrics, skeleton loaders, and humanised
server-error messages. Long lists (Log Messages, Active Expectations, Requests) are now viewport-virtualized
so panels with tens of thousands of entries scroll smoothly, and the dashboard is usable on small screens and
the IDE-embedded view (driven by CSS container queries).
and cached (measured ~50–66% less time and allocation on the OpenAPI validation path), and per-request object
churn in the OIDC, SAML and LLM endpoints is reduced. Behaviour and security settings are unchanged.
parameters are converted to matcher form once per request and reused across every candidate expectation,
cutting per-request allocations and CPU. Matching behaviour is unchanged.
HttpRequest.withBody((String) null)now leaves the body unset (matchingHttpResponse), sogetBodyAsString()returnsnulland the request serializes with nobodyfield. Body matching isunchanged — a null string body still matches any body.
withBody("")is unaffected.$refs (http/https/file/jar/ftp) by default — anSSRF hardening. Internal/inline refs are unaffected; set
jsonSchemaAllowRemoteRefs=trueto restore.clients, so none defaults to downloading a stale server binary. Several client connection/error-handling
leaks were also fixed (Python/Ruby now always close the HTTP response; the Node client rejects with the real
error message instead of an empty
{}).Activity Bar side panel and status-bar item, configurable port, and clearer validation warnings before
submitting a file.
Fixed
Correctness & reliability
crossProtocolScenarioswas rejected by the expectation schema — present in the model and honoured atruntime but missing from the validation schema, so any expectation using it was rejected with
400. Added tothe expectation and embedded-OpenAPI schemas.
not(...)expectations now match correctly with fail-fast matching enabled (the default). A negatedmatcher could wrongly report a non-match when a non-method field matched before the first mismatching field
(any expectation with an odd number of NOT flags). The fix only short-circuits when no NOT operator is in play
and evaluates all fields otherwise, so the verdict always equals a full evaluation. Affected path, header and body.
response body used a stripped-down dispatch missing several behaviours (XML/form→JSON conversion, template
bodies, multipart routing, compressed-byte binary matching) and could swallow an internal NullPointer on a
bodyless response into a silent non-match. Request and response body matching now share a single dispatch;
request matching is unchanged.
withPercentagegate(a consume-then-skip bug); the transition now applies only when the response is actually served, atomically
(compare-and-set) so a clustered backend preserves the "exactly one winner" guarantee.
ConfigurationDTOmirrored only about half of theconfiguration, so many settings (SLO tracking, load generation, drift alerting, HTTP/3, gRPC, DNS, WASM,
clustering, OpenTelemetry, audit, forward pool/retry/circuit-breaker, redaction, and more) were silently lost
when configuration was serialized and reloaded; all are now mirrored, guarded by a reflection-driven test.
and evicted real/LLM traffic (emptying the Traffic/Trace/LLM views); load requests are now kept out of the
driver's event log via an in-process-only flag (gated by
loadGenerationSuppressEventLog, defaulttrue).Metrics and SLO samples are unaffected.
DateTimeFormatter),safely-published compiled regexes and lazily-built LLM conversation matchers (
volatile), a thread-safecallback WebSocket registry, exact load-scenario VU accounting, a race-free OIDC device-code poll counter,
atomic SCIM resource updates, gRPC chaos honouring its configured probability, and recycled log entries fully
reset on reuse.
persistence writes atomically (temp-file + rename); path/matrix parameter names with regex metacharacters
match literally; matchers prefixed with only
?/!no longer throw;VerificationTimesrejects negativecounts; a CONNECT/SOCKS tunnel buffer leak is fixed; one client's
reset()/stop()no longer tears downother clients on the same port; a control-plane body filter no longer matches a request with no body via a
literal
"null"(stringification removed); and S3 persistence no longer throws on an empty/missing prefixlisting.
Enginewas never closedand accumulated under per-call construction, exhausting CI forks; it is now a single process-wide shared
engine with a disposing
close()on the thread-local context. Output and theJava.type(...)securityboundary are unchanged.
favicon.svg(and any SVG) now serves a validContent-Type: image/svg+xml— the missingsvgMIME mapping produced anullheader value that crashed Netty's encoder; the mapper now skipsnull-valued headers and falls back to
application/octet-stream(issue #2358).(
[leaf, CA, CA]), which Java 17's PKCS12 keystore rejects; the chain is now de-duplicated to[leaf, CA].times/timeToLiveno longer fail withmissing field 'unlimited', andVerificationTimes::at_least(n)now serializes the unboundedatMost: -1sentinel insteadof an impossible
between(n, 0).Dashboard UI
panel surfaces failures instead of reporting false success; the import dialog no longer reports a misleading
"Imported 0 expectations"; the traffic comparison counter/button no longer disagree; non-HTTP expectations no
longer render their id twice; and a "Capture as mock" body matcher can be added when the captured request had
no body. Plus efficiency fixes (single serialization per row on each WebSocket push, memoized traffic rows,
TTL-only countdown timer) and consistent error humanisation.
IDE extensions (VS Code & JetBrains)
untilBuildremoved, so it stays available incurrent and future IDEs) and no longer risks an
AlreadyDisposedExceptionwhen a project is closed while anHTTP request is in flight; JetBrains JSON-schema completion/validation for
*.mockserver.json(c)now worksin IntelliJ (registered under the correct extension point, with a navigable root and no network schema
fetch). The VS Code extension now activates on
onStartupFinished, so the status-bar item and CodeLensappear immediately on a fresh window.
Request matching & verification
MATCHING_KEYmode now asserts key-absence (!Xmeans "no keyXpresent") instead ofaggregating values from every other key.
collapse the matched-field count under fail-fast (diagnostic-only).
O(n²) (two full reconciliation passes per add); the non-clustered path now does an eviction-only trim,
restoring linear time.
retrieve?format=JAVAnow emits a modifier'scondition,modifiers,jsonPatchandjsonMergePatch, and the NoderesponseModifiertypedef declares them.404s; response-aware sequences with mismatched request/response list lengths are rejected instead of paddingwith always-matching nulls; an entirely-empty sequence is rejected; a recorded pair with a null request is a
non-match instead of an NPE; failing response-sequence messages now show the responses; and a verification
whose request filter fails to build now completes instead of hanging.
OpenAPI & contract testing
allOf: [ $ref to a scalar ]example generation no longer wraps the scalar in a single-element array(
{"baz": ["hello"]}→{"baz": "hello"}), which broke clients typed against the spec (#2357).(
2XX) no longer crash import and validate correctly; distinct specs sharing aninfo.titleno longer deleteeach other's expectations (namespace now keyed by a SHA-256 of the source); expectations→OpenAPI export is
now schema-valid and faithful (path parameters templated, negated/schema matchers preserved, same path+method
responses merged, correct media types);
contextPathPrefixis accepted by its schema; pinning an undefinedstatusCode/exampleNamewarns and falls back instead of silently returning an empty200; a webhooks-only3.1 spec no longer NPEs; and a re-imported URL/file spec now evicts the cache so it picks up current content.
application/xml/text/xml/+xmlresponses,serialised using the schema's
xmlmetadata (name/namespace/prefix/attribute/wrapped) per the OpenAPI XMLObject rules, fixing earlier malformed pluralised/recursive output. OAS 3.1 multi-type
typearrays arepreserved (
["string","null"]→string+nullable). (Behaviour change for XML responses; JSON unchanged.)minItems/maxItems, stringpattern,exclusiveMinimum/Maximum, thetimeformat,minProperties, anddefault/enumon format-lessinteger/number schemas. Unconstrained schemas are unchanged.
Build & dependencies
commons-beanutils(GHSA-wxr5-93ph-8wr9 / CVE-2025-48734) to downstreamconsumers through
velocity-tools-generic— the 1.11.0 pin lived only independencyManagement(nottransitive); it is now excluded from
velocity-tools-genericand declared directly so the fixed versionpropagates (#1981).
Performance under load
/retrieveandclear(issue #2359, afollow-up to #2329). The read paths ran the expensive request matcher on every log entry — including deleted
tombstones and wrong-type entries — before the cheap type/not-deleted filter, so each
/retrievecost grewwith total log size. The filters are now ordered cheap-predicate-first, and
clearskips already-deletedentries. No behaviour change. Tip for high-throughput users: also clear the log (
?type=LOG/ALLor/reset), not just expectations, or lowermaxLogEntries.Configuration
📅 Schedule: (UTC)
🚦 Automerge: Enabled.
♻ Rebasing: Whenever PR is behind base branch, or you tick the rebase/retry checkbox.
🔕 Ignore: Close this PR and you won't be reminded about this update again.
This PR was generated by Mend Renovate. View the repository job log.