Update dependency org.mock-server:mockserver-client-java-no-dependencies to v7#9502
Open
renovate[bot] wants to merge 1 commit into
Open
Update dependency org.mock-server:mockserver-client-java-no-dependencies to v7#9502renovate[bot] wants to merge 1 commit into
renovate[bot] wants to merge 1 commit into
Conversation
4e5147a to
7f61ddb
Compare
7f61ddb to
9b73cd4
Compare
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:
5.15.0→7.4.0Release Notes
mock-server/mockserver-monorepo (org.mock-server:mockserver-client-java-no-dependencies)
v7.4.0Added
Dashboard: every language tab now generates typed client code. The composer's Java, Node.js, Python, Go,
C#, Ruby, and Rust tabs construct each client's typed model — fluent builders and typed constructors matching
the website examples — instead of embedding raw JSON, including full LLM response actions in Java. Every
language's generated output is proven equivalent by executing or compiling it against the real client and
comparing the serialized expectation with the registered JSON, and a CI gate compiles the generated Java
against the built client on every build.
Every client library now round-trips the full expectation model, proven by a shared fidelity harness. The
Go, Rust, C#, Python, Ruby, and Node clients gained typed support for every expectation feature they previously
dropped silently — chaos profiles, rate limits, forward-with-fallback and forward-validate actions, gRPC bidi
responses, before/after actions, steps, capture rules, namespaces, LLM response payloads including moderation,
rerank, and content filters, WebSocket frame matchers, response trailers, DNS matchers, and all body matcher
variants. Forty-four server-validated kitchen-sink fixtures now run as round-trip tests inside each client's own
test suite, with a ratcheting known-gaps ledger that fails CI if a documented gap silently regresses or a fixed
gap is still excused.
Dashboard: JWT and all-of body matchers are now authorable in the composer. The Advanced request form gains a
JWT section (claims, issuer, audience, algorithm) and an all-of body matcher composing multiple sub-matchers,
emitted in the exact server wire format and round-tripping on edit.
Dashboard: the Java code tab is now complete and type-safe. Generated Java uses the real client API for
priority, times, and time-to-live, scenario bindings, namespaces, and capture rules — proven by compiling a
kitchen-sink snippet against the built client — and the Java client gains matching withNamespace and withCapture
fluent methods. Actions the Java builder preview cannot represent show an honest notice instead of fabricated code.
Dashboard: every captured flow is now a launchpad. A "Create From This" menu on traffic detail panes and
log rows fans out into every subsystem pre-filled from that flow — create a mock in the composer, set a
breakpoint, prefill a verification, or add chaos for the host. The traffic inspector also gains structured
Request/Response tabs (headers tables and pretty-printed bodies, with the raw JSON tree kept as a tab),
"Copy as curl" with shell-safe quoting and masked credentials, a Charles-style "Repeat" action (iterations,
bounded concurrency, delay, live progress and cancel), a Proxyman-style diff pool with an editable ignored-headers
list, an unmatched-count chip with why-didn't-this-match and generate-stub actions, and bulk
"Promote to Mocks" over recorded traffic (
PUT /mockserver/recordings/promote).Dashboard: previously server-only capabilities are now reachable from the UI. Validate recorded traffic
against an OpenAPI spec (
/trafficValidate), import GraphQL SDL schemas and mock SCIM providers, import Pactcontracts, generate HTTP expectations from AsyncAPI specs, dry-run WASM modules against a sample request,
reload persisted recording archives (NDJSON or from server disk), a preemption-simulation card and experiment
history in Service Chaos, a control-plane Audit view, a standalone Scenarios view in the navigation, and a
read-only Server Info tab (effective configuration with source tiers, bound ports plus bind-additional-port,
proxy setup with CA download) alongside a server-side decoded-prompt LLM run diff.
Dashboard: quick chaos and honest latency attribution. A one-toggle Quick Chaos strip (percentage slider
over real per-request fault probabilities, per upstream host) makes fault injection approachable, and the
traffic timing waterfall now distinguishes latency MockServer injected (chaos latency, configured response
delays including the global delay, breakpoint holds) from real upstream/processing time — mock-served
responses carry a timing block for the first time when they inject latency (a plain mock's recorded
output is unchanged).
Force a response-sequence variant per request. A request matching an expectation with multiple responses
can force which variant it receives via a 0-based
x-mockserver-response-indexheader. Forced requestsconsume
timesbut never advance the sequential/switch rotation for other callers; the header is retainedin recordings and filtered from every outbound forward, including WebSocket passthrough. Invalid values are
ignored.
Dashboard: faster first load, first-run onboarding, and one-click navigation. All views load lazily
(initial bundle down from 259 kB to about 164 kB gzip), a Try It Now path on the get-started view creates a
first mock, returning users get an open-dashboard shortcut, keyboard shortcuts move off
browser-conflicting bindings with a ? help overlay, and matcher testing is available at the point of need
in the composer and on every expectation row. The scenarios view details each scenario's states, bound
mocks, and transitions with edit-in-composer actions, and the advanced composer models scenario bindings
directly. The audit view explains the opt-in audit trail (and the demo enables it).
Fixed
Dashboard: editing an LLM or otherwise exotic expectation now generates complete typed client code in
every language. Fields the composer form cannot model — LLM responses with their full completion detail,
response sequences, object callbacks, forward-validate, gRPC bidi, rate limits, and cross-protocol
scenarios — were silently dropped from generated Python and Ruby code and embedded as raw JSON in C# and
Rust; all languages now construct the client's typed model, guarded by a universal test asserting no wire
field is ever absent from generated code.
Registering forward-validate, forward-with-fallback, or gRPC bidi expectations no longer fails with a
metrics error. The per-action counter constants for these action types were missing, and a guard test
now asserts every action type has one.
Generated Go code now compiles. All Go code generators — the dashboard expectation, verification, and
load-scenario tabs, the retrieve-as-Go endpoint, and the website examples — emitted the client import without its
/v7 semantic-import-versioning suffix, so generated code never resolved against the published module.
.NET client: reading an object-callback expectation back from the server no longer throws. The
responseCallback field was typed as a string while the server emits a boolean, losing the whole expectation.
Python client: multipart body field matchers no longer vanish on registration. Multipart fields were emitted
in an array form the server misroutes; they now use the server's canonical object form.
Dashboard: editing a mock no longer shows phantom changes. An untouched edit round-trips to a zero diff — the
explicit default forms of priority, times, and timeToLive are preserved instead of appearing as removals, and a
genuine reset shows the explicit unlimited form.
Dashboard: the Promote to Mocks button no longer wraps in a narrow traffic pane.
Dashboard: editing an expectation no longer silently strips fields the form does not model. The composer
now merges its form output onto the original expectation JSON, preserving scenario bindings, namespaces,
response sequences, cross-protocol scenarios, and matcher fields such as
keepAliveandsocketAddressinboth quick and advanced modes, with an alert listing the preserved fields.
Dashboard reliability fixes. Paused breakpoint exchanges survive navigating away from the Breakpoints
view; stream-frame editing is UTF-8 safe and surfaces encode failures; a reconnect re-sends the active
request filter instead of silently streaming unfiltered data; an error-only push no longer blanks the
panels; user-action errors persist until dismissed (and the banner is dismissible); mismatch dialogs report
honest "differs on N field(s)" scores with remediation hints; and a response template rendering invalid
output is now surfaced as a
TEMPLATE_GENERATION_FAILEDevent instead of a silent 404 logged as a success.Dashboard performance, measured. Idle pushes no longer re-render every panel each second, hidden tabs
buffer instead of processing WebSocket updates, and hot parse/search paths are cached — all verified by a
committed benchmark suite (
npm run benchinmockserver-ui) comparing against the pre-optimizationimplementations at small and large payload scales.
Automated release publishing for the Ruby and PHP Testcontainers modules. The
mockserver-testcontainers/rubyand
mockserver-testcontainers/phpmodules now publish automatically as two newsoft_failrelease-pipelinecomponents.
tc-ruby(scripts/release/components/tc-ruby.sh) self-bumps the gemversion.rb, builds inside thepinned Ruby image and
gem pushestestcontainers-mockserverto RubyGems (credential from the existingmockserver-build/rubygemssecret; skips gracefully if absent).tc-php(scripts/release/components/tc-php.sh)subtree-splits the module and pushes
master+ a version tag to themock-server/mockserver-testcontainers-phpPackagist mirror repo, mirroring the PHP-client publish; it skips gracefully until that mirror repo is provisioned
(one-time setup — see
mockserver-testcontainers/php/PUBLISHING.md). Both support--dry-run, are release-typegated (
full/post-maven), and have soft post-release verification checks. Seedocs/operations/release-process.md.Go client:
jwt/allOfmatchers, a/v7module path, and a bundled Testcontainers client. The Goclient (
mockserver-client-go) gains typedjwtrequest-matcher andallOfbody-matcher builders (matchingthe other client libraries). Its module path now carries the required Semantic Import Versioning suffix —
github.com/mock-server/mockserver-monorepo/mockserver-client-go/v7— so it is properlygo get-able as adependency (a future v8 becomes
/v8); update imports to add/v7. With that fixed, the Go Testcontainersmodule now bundles the client and exposes
container.Client(ctx)returning a ready-to-use client pointed atthe container's mapped host and port, instead of only documenting manual construction.
Typed client-library support for the
jwtrequest matcher andallOfbody matcher. The two newmatchers are now first-class in the client libraries as well as the server: the OpenAPI spec, the generated
Node/TypeScript types (
jwt,Jwt, and theALL_OF/bodyAllOfbody variant), and the Java model(
request().withJwt(jwt()...),withBody(allOf(...))) all expose them, and every other client library cansend them over the REST wire format. Consumer docs gain Java and Node examples for both matchers.
Automated package-manager release channels for the CLI (Homebrew, Scoop, winget, Chocolatey, SDKMAN!, asdf/mise).
Six new release-pipeline components (
scripts/release/components/{homebrew,scoop,winget,chocolatey,sdkman,asdf}.sh)publish/update these channels automatically as a
soft_failgroup after the binary-bundle step, distributing the sameself-contained jlink bundles (
mockserver-<version>-<os>-<arch>.tar.gz/.zip, each carrying its own trimmed Javaruntime) that the
binarycomponent uploads to the GitHub Release. A new tap formula (mock-server/homebrew-tap,brew install mock-server/tap/mockserver) is added — complementary to, and separate from, the JAR-based homebrew-coreformula (still bumped by BrewTestBot). Each channel renders its manifest from the real published bundle checksums,
supports
--dry-run, and skips itself gracefully (never breaking the release) when its target repo or API secret isnot yet configured. See
packaging/<channel>/release-component.mdanddocs/operations/release-process.md.WebSocket proxy passthrough + frame recording. MockServer can now proxy WebSocket connections through to a real
upstream server, not just mock them. When a WebSocket upgrade request (
GET+Upgrade: websocket) arrives in proxymode and no WebSocket mock expectation matches — or it matches a plain
FORWARDexpectation — MockServer completesthe upstream connection (honouring
ws/wssscheme and TLS), relays the101 Switching Protocolshandshake, andrelays frames bidirectionally (text, binary, ping, pong, close) until either side closes. This lets a system under
test pointed at MockServer as a proxy reach a real WebSocket backend. The relayed traffic is recorded: the upgrade
exchange is logged as a
FORWARDED_REQUEST(request = the upgrade, response =101carrying a JSON transcript of therelayed frames with direction/opcode/payload), so
retrieveRecordedRequestsand the dashboard show the WebSockettraffic. The transcript is flushed to the log once, on connection close. Frame recording is bounded per connection by
the new
webSocketProxyMaxRecordedFramesconfiguration property (default1000; set to0to disable framerecording — the handshake is still recorded) plus an absolute 8MB transcript cap, following the
maxLogEntriesmemory-management philosophy. The upstream TLS leg uses the forward-proxy trust manager
(
forwardProxyTLSX509CertificatesTrustManagerType, defaultANY) so realwssbackends are reachable, and the sameforwardProxyBlockPrivateNetworksSSRF guard the matched-forward path enforces applies (a WS upgrade to aloopback / RFC1918 / cloud-metadata target is refused with
502). A slow peer cannot exhaust memory — the relayapplies standard writability-based backpressure. An opt-in
webSocketProxyIdleTimeoutSeconds(default0, off)reaps abandoned relays. For a WS upgrade matched by a plain
FORWARDexpectation,Times/verifyapply butresponse-shaping features (
delay,rateLimit,chaos, breakpoints, drift) do not — use theWEBSOCKET_RESPONSEmock action for frame-level control. Scope (v1): HTTP/1.1 upgrade relay (plain and TLS upstream); HTTP/2
extended-CONNECT WebSocket is not yet relayed. See
docs/code/netty-pipeline.md.
Seedable template
fakerfor reproducible fixtures — newtemplateFakerSeedproperty. The templatefakersample-data helper (Velocity$faker, Mustache{{faker.*}}, JavaScriptfaker) can now be seededdeterministically.
templateFakerSeeddefaults to0, which leaves faker unseeded so it produces different,random values on every render (behaviour unchanged); a non-zero value seeds a per-engine
Fakersofaker-driven templates generate reproducible fixtures across runs — the template analogue of the OpenAPI
example generator's fixed-seed model. Determinism is strongest for sequential (single-threaded) generation.
Wired through the config trio (
ConfigurationProperties/Configuration/ConfigurationDTO) and honouredby all three template engines. See docs/code/configuration-reference.md.
Per-host upstream mTLS — new
forwardProxyClientCertificatesByHostproperty. Outbound clientauthentication (mTLS to the upstream) was global-only; it can now vary by upstream host. The property is a
comma-separated list of
host=certificateChainPath;privateKeyPathentries — a matching upstream host(case-insensitive) is sent that host's cert/key pair for client authentication, and any host without an entry
falls back to the global
forwardProxyPrivateKey/forwardProxyCertificateChainpair (default empty, sobehaviour is unchanged). Contexts are cached per mapped host while all unmapped hosts share one context, so a
forward proxy that sees many upstreams cannot grow the cache without bound. See
docs/code/tls-and-security.md.
Testcontainers modules for Ruby and PHP, plus a wired client on every polyglot module. MockServer now
ships official Testcontainers modules for eight languages — Ruby (
testcontainers-mockserver, RubyGems)and PHP (
mock-server/mockserver-testcontainers, Packagist) join the existing Java, .NET, Node.js, Python,Rust and Go modules. Both new modules start the
mockserver/mockserverimage, wait forPUT /mockserver/status→ 200, and expose connection helpers (endpoint/getEndpoint,secure_endpoint,server_port,host).pointed at the mapped host/port, mirroring the Java module's
getClient():get_client(Python, Ruby),getClient()(Node, .NET),getMockServerClient()(PHP — the inherited TestcontainersgetClient()isreserved for the Docker client), and
client()/async_client()(Rust). The language's MockServer clientis now a dependency of its Testcontainers module. (Go instead documents constructing the client from
ctr.Host(ctx)/ctr.ServerPort(ctx)viamockserver.New(host, port):mockserver-client-goispublished at v7.x without a
/v7module-path suffix, so bundling it would make the Go Testcontainers moduleitself unresolvable for downstream
go get.)(
mockserver-<version>) from the MockServer client version — or, for Go, from the module's own version —falling back to the mutable
latesttag when the version cannot be resolved, mirroring the Java module,instead of a hard-coded tag that goes stale.
WASM response shaping (host ABI v3). WASM custom-rule modules can now compute the response, not just
match the request. A module that exports an optional
shape_response(i32 ptr, i32 len) -> i64function isinvoked after a match with a JSON envelope
{version:3, request:{…v2 request…}, response:{statusCode, headers, body}}describing the response the matched expectation would return; it returns a (possiblypartial) response JSON
{statusCode?, headers?, body?}that MockServer applies — replacing the status,merging headers, and replacing the body — enabling WASM-computed dynamic responses. Fully backward
compatible: modules without the export stay pure predicates, and a module can export both
match_requestandshape_responseto match first, then shape. Fail-safe: any trap, invalid JSON, or anover-sized return (capped at 1 MiB) leaves the response unshaped and logs once per module — a broken
shaper never fails the request. The
examples/wasm/sdk-rustauthoring SDK gainsShapeEnvelope,ShapeResponseand aResponseBuilder, plusexport_shape_response!/export_match_and_shape_response!macros, and a newexamples/wasm/rust-shape-responseexample module(matches
POST /shape, setsX-Shaped: true, and rewrites a JSON body field).POST /mockserver/wasm/testaccepts an optional candidate
responseand returns the shaped response so IDEs can preview shaping. Seedocs/code/wasm-rules.mdand the WASM Custom Rules page.SCIM list endpoints now support sorting. The mock SCIM 2.0 provider's
GET {basePath}/Users|Groupslisting accepts the standard
sortByandsortOrderquery parameters (RFC 7644).sortByis anattribute name or nested dotted path (e.g.
name.familyName);sortOrderisascending(default) ordescending. Comparison is case-insensitive and resources with no value for the sort attribute arealways ordered last. Sorting is applied after any
filterand beforestartIndex/countpagination; amalformed
sortBypath or an invalidsortOrderreturns a400error envelope (matching how an invalidfilter is rejected), and the
ServiceProviderConfignow advertisessortas supported.More realistic LLM token estimates and subword streaming by default. The approximate
TokenCounterbehind inferred
usagecounts and token-based quotas now approximates GPT-style subword (BPE)segmentation instead of a plain characters÷4 blend, landing within roughly ±15% of a real tokenizer for
ordinary English prose (validated against GPT-4
cl100k_basereference counts). Streaming LLM responsesnow emit finer, subword-sized deltas by default (via
streamingPhysics.subwordStreaming), so astreamed response streams closer to a real provider's per-token cadence out of the box. Behaviour
change: because a stream now carries more, smaller real-token deltas at the same
tokensPerSecond, itstotal duration is slightly longer than before, and the per-provider streaming wire output is finer-grained.
All streaming-physics timing semantics are preserved (each delta is still one physics event). To restore
the previous whole-word (whitespace-boundary) streaming, set
streamingPhysics.subwordStreamingtofalseexplicitly.Editor extensions can start MockServer without Docker. Both the VS Code extension and the JetBrains/IntelliJ
plugin gain a Start (binary, no Docker) command/action that launches MockServer from the self-contained binary
bundle (a jlink-trimmed Java runtime + the shaded jar + launcher — see
scripts/build-binary-bundle.sh), socorporate machines without a Docker daemon can run a local server straight from the editor. The bundle is taken
from a configured local path (
mockserver.binaryPathin VS Code, Binary bundle path in JetBrains settings) —either the
bin/mockserverlauncher or the unpacked bundle directory — or, when unset, downloaded on demand(after an explicit confirmation) for the current OS/architecture from the GitHub release matching the
extension/plugin version and cached (under the extension's global storage / IDE system cache). Checksum
verification against the published
.sha256sidecar is fail-closed: a digest mismatch always aborts, and asidecar that cannot be fetched (common behind a TLS-inspection proxy, where the small sidecar fetch fails while
the large archive succeeds) aborts too unless the user explicitly confirms installing unverified. The launched
process is tracked for a matching Stop (binary) and terminated on editor/IDE shutdown so it never outlives
the editor holding the port: VS Code streams its output to the MockServer output channel and its download honours
the editor's
http.proxy/ system-proxy settings; JetBrains runs it as a tracked background process registeredfor IDE-shutdown cleanup. Docker-based Start (Docker) is unchanged. See the
IDE Extensions page.
Match requests by the claims inside a JWT (
jwtrequest matcher). An expectation can now route on aJSON Web Token carried in a request header —
withJwt(jwt().withClaim("sub", "user-1").withClaim("scope", ".*admin.*"))matches only requests whose bearer token carries those claims (each claim value is an exactstring or a regex, with
!negation supported). Convenience fieldsissuer(iss),audience(aud,string or array) and
algorithm(JOSE headeralg) are provided, and the header name (defaultauthorization) and scheme prefix (defaultBearer) are configurable. The token'sheader.payloadisdecoded with base64url + JSON and its signature is deliberately not verified — this is request matching
for test routing, not authentication (the control-plane JWT auth stack is unchanged). A request with no such
header, or a malformed token, simply does not match (it never raises an error). Exposed on
HttpRequestandthrough the JSON wire format (
"jwt": { "claims": { ... }, "issuer": "...", "audience": "...", "algorithm": "..." }) and JSON schema. (Java server + JSON wire format; typed client-library wrappers to follow.)Compose several body matchers that must all match (
ALL_OFbody /allOf). A request body can now bematched against several body matchers at once, where every one must match the same body — for example
withBody(allOf(jsonPath("$.name"), jsonSchema(schema), regex(".*value.*"))). This reuses the existing bodymatcher implementations without changing any of their semantics; each component keeps its own
notflag andthe composite honours its own
not(negate the whole conjunction) andoptionalflags. Serialised as{"type":"ALL_OF","bodyAllOf":[ ... ]}and accepted wherever a body matcher is accepted. (Java server + JSONwire format; typed client-library wrappers to follow.)
Fluent
MockServerClient.builder(). The Java client gains a discoverable fluent builder thatcovers every existing construction dimension in one place —
host(defaultlocalhost),port(default
1080),contextPath,Configuration/ClientConfiguration,portFuture, plus TLS(
secure),proxyConfiguration, control plane JWT (controlPlaneJWT) andrequestOverridethatpreviously required post-construction
with...setters.MockServerClient.builder().host("localhost").port(1080).build()is equivalent to the corresponding constructor call. The eight existing constructors remain fully
supported and are not deprecated; the builder simply delegates to them, so it introduces no
behaviour change. Misconfiguration stays loud (an empty
hostthrowsIllegalArgumentException, andportFuture(...)cannot be combined withhost/port/contextPath). Seedocs/code/client-and-integrations.mdand theMockServer Clients page.
Observability quick-win bundle — Grafana dashboard, Helm ServiceMonitor, and a durable audit file sink. Three
independent additions that make MockServer easier to monitor in production:
examples/grafana/mockserver-server.json(with aREADME) is an importable dashboard charting request throughput and match outcomes (via the new
_totalcounters), request-latency percentiles, registered expectations/actions, per-upstream forward/proxy health,
dropped-log-events and chaos counters, and the JVM runtime gauges — every panel references a metric documented in
docs/code/metrics.md. It exposes adatasourcevariable so it imports against any Prometheus data source, andis kept separate from the existing k6 load-injection dashboard.
ServiceMonitorin the Helm chart.serviceMonitor.enabled=true(disabled bydefault) renders a
monitoring.coreos.com/v1ServiceMonitor scraping/mockserver/metrics, withnamespace/interval/scrapeTimeout/path/scheme/honorLabels/labels/namespaceSelector/relabelingsvalues. User-supplied
labelsare merged over the chart labels (user wins) so areleaselabel for thePrometheus
serviceMonitorSelectoroverrides cleanly. Requires the Prometheus Operator CRDs andmockserver.metricsEnabled=true.auditLogFileproperty (empty default = off): when set,each recorded audit entry is also appended as one JSON object per line to the file, giving a restart- and
reset-surviving trail that outlives the bounded in-memory ring. Implemented as a separateAuditFileSinkwriter that only observes the same entries — the in-memory ring is untouched (honouring the "never a sink"
contract). Path resolved once on first write, parent dirs created, append-only (rotation out of scope), and
fail-soft (a single WARN then self-disable on IO error, never crashing request handling).
OpenAPI request validation now checks
style/explode-serialised array and object parameters. When youvalidate traffic against an OpenAPI spec (contract/traffic validation, the
verify_trafficMCP tool, or anOpenAPI-backed expectation returning
400on non-conforming requests),array/objectquery, path and headerparameters were previously skipped unless the value already looked like JSON — so a malformed list or object slipped
through. MockServer now decodes each parameter from its
style/explodeserialisation before schema validation:query
form/spaceDelimited/pipeDelimited/deepObject, pathsimple/label/matrix, and headersimple,for both
explodevalues, with the OpenAPI defaults applied when the spec omits them. Decoding is type-aware(each element/property is coerced to the JSON type its item/property schema declares) so a request that was valid
before stays valid — only values the spec genuinely rejects (e.g. a non-integer element in an
items: integerarray, or a non-integer property in a
deepObject) now fail. It is fail-open: any value that cannot be soundlyreconstructed (a non-primitive item/property, or an unsupported style combination) skips the schema check exactly
as before, while
required-presence is still enforced. Note this is a (spec-conformant) behaviour change fortraffic validation: non-conforming style serialisations that previously slipped through unchecked can now return
400— e.g. a comma-delimited list sent where the spec declares the defaultform/explode: true(which expectsrepeated parameters) is decoded as a single element and validated as such. One known edge: an empty value for a
non-explode
formarray decodes as a single empty-string element rather than an empty array.OpenAPI example generation honours
discriminator,readOnlyandwriteOnly. Generated examples (OpenAPIimport to expectations,
run_contract_test/run_resiliency_test, load scenarios) are now more faithful: for aoneOf/anyOfschema with adiscriminator, a concrete subschema is chosen and the discriminator property is setto the matching mapping key (or the referenced schema name when no explicit
mappingis given), instead of blindlytaking the first subschema; and
readOnlyproperties are omitted from request examples whilewriteOnlyproperties are omitted from response examples, per the OpenAPI spec. Existing callers that do not specify a
direction are unchanged (no
readOnly/writeOnlyfiltering).gRPC forward proxy + record/replay — bring the record-then-mock workflow to gRPC. Until now gRPC
support was mock-only: MockServer could decode inbound gRPC to JSON and serve mocked responses, but could
not forward a gRPC call to a real upstream gRPC server. Now, when a gRPC request (HTTP/2 +
application/grpc) matches aFORWARD-class expectation — or arrives in proxy mode with no matchingexpectation — MockServer re-encodes the decoded request back into gRPC-framed protobuf, relays it to the
upstream gRPC service, decodes the framed protobuf response back to JSON, and re-frames it for the calling
client. The forwarded exchange is recorded in the event log as a
FORWARDED_REQUESTcarrying the decodedgRPC method path, status, and (when a proto descriptor is registered) the decoded message JSON, so
retrieveRecordedExpectations(andpromote_recordings) produce a replayable gRPC mock — the samerecord → snapshot → replay loop already available for HTTP/SSE. A non-OK terminal
grpc-status/grpc-messagedelivered by a real upstream in HTTP/2 (or chunked HTTP/1.1) trailers is preserved through the relay and the
recording, rather than being defaulted to
OK. Unary and client-streaming request bodies(single JSON object / JSON array) and unary or server-streaming responses (one or more frames) are handled.
Decoding of the recorded exchange requires the proto descriptor to be loaded on the proxy (via
grpcDescriptorDirectory/grpcProtoDirectory/PUT /mockserver/grpc/descriptors); without descriptorsthe gRPC bytes are still forwarded verbatim but recorded undecoded. Full bidirectional streaming forward is
out of scope (it is driven by the multiplex bidi pipeline, not the request/response forward path). The
transform is fail-safe — a non-gRPC request, an unknown method, or any conversion error leaves ordinary
HTTP forwarding byte-for-byte unchanged (
GrpcForwardTranslator,org.mockserver.grpc).The dashboard now warns when log events are being silently evicted — the #1 cause of "verification
intermittently fails". When MockServer's log ring buffer fills up, the oldest events are dropped, so
verifications and the dashboard silently miss requests. The Dashboard and Traffic views now show a
dismissible warning banner whenever the server's
mock_server_dropped_log_eventscounter is non-zero("The log ring buffer is full, so the oldest events have been dropped (N so far)…"), pointing at
maxLogEntries/ringBufferSizewith a link to the performance docs. The banner reuses the existingPrometheus metrics endpoint the Metrics view already polls (no new server endpoint) and stays hidden on a
healthy server or when metrics are disabled. It re-appears only if more events are dropped after a
dismissal.
Bulk actions in the dashboard: multi-select expectations and captured requests to clear them in one go.
The Active Expectations list and the Traffic inspector each gained a "Select" mode with per-row checkboxes,
a select-all toggle and a running count. "Delete selected" removes the chosen expectations (batched per-id
clears) and "Clear selected" removes the chosen captured requests from the log, each behind a confirmation
dialog. Compare mode in the Traffic inspector is unchanged (still capped at two rows for a diff) and is
mutually exclusive with the new uncapped select mode.
Migration importers for WireMock, Mountebank and Mockoon. Teams moving off another mock tool can now
convert their existing stubs into MockServer expectations in one shot through the existing
PUT /mockserver/importendpoint, via?format=wiremock,?format=mountebankor?format=mockoon(all three are also auto-detected from the JSON structure when no
formatis supplied). Each importer mapsthe foreign matcher/response model onto MockServer's:
mappingsarray, or bare array) —method/urlPath/urlPathPattern/urlPattern/url,queryParameters/headerspredicates (equalTo/matches/contains),bodyPatterns(
equalToJson/matchesJsonPath/contains/matches/equalTo), responsestatus/headers/body/base64Body/jsonBody/fixedDelayMilliseconds,fault→ connection error,proxyBaseUrl→ forward,WireMock scenarios → MockServer scenarios, and
priority(inverted, since WireMock 1 = highest).http/httpsonly;tcp/smtpskipped with a warning) —equals/deepEquals/contains/matches/exists/startsWith/endsWithpredicates → matchers,is→ response,proxy→forward,
fault→ connection error,_behaviors.wait→ delay,_behaviors.repeat→Times, and multipleisresponses → one cycling multi-response expectation.route→ expectation(s) with:parampath segments converted to regex,response
statusCode/headers/bodyandlatency→ delay, responserules→ matchers (with descendingpriority so array order and the
defaultcatch-all are preserved), andresponseModeSEQUENTIAL/RANDOM→ the matching MockServer response mode.
Every foreign construct with no faithful MockServer equivalent (TCP imposters, XPath/XML predicates, response
templating/transformers, compound
and/or/notpredicates, JavaScriptinject, unsupported ruleoperators, …) produces a structured warning in the response body —
{ "expectations": [...], "warnings": [...] }— rather than being silently dropped. Secret redaction is on by default (as for HAR/Postman/Pactimport). No new runtime dependencies (Jackson only). See
docs/code/request-processing.mdand theImporting Expectations page.
AsyncAPI broker mocking — Kafka Avro/Confluent Schema Registry, AMQP subscribe/verify, and MQTT 5. The
mockserver-asyncmodule gains three enterprise-broker parity features, all driven from the existingPUT /mockserver/asyncapibrokerConfig:kafkaValueFormat: "avro"to publish andconsume Kafka messages framed as
magic byte + schema id + Avro binary, byte-compatible with real ConfluentAvro producers/consumers. Two modes: registry-backed (
kafkaSchemaRegistryUrl— the schema is registeredunder
<topic>-valueon publish and resolved by id on consume) and registry-less (an inlineavroSchemaplus a fixed
avroSchemaId). Consumed Avro is decoded back to JSON so.../asyncapi/verifysubstring andJSON-path checks work unchanged. Implemented with Apache Avro (Apache 2.0) plus a hand-rolled 5-byte
framing and a minimal JDK-
HttpClientSchema Registry REST client — deliberately avoiding theConfluent Community License serde stack. Protobuf is deferred.
consume: true, MockServer nowsubscribes to and records AMQP messages for verification, mirroring Kafka/MQTT. The queue is derived from the
channel's
bindings.amqp(queue-based consumes the named queue; routingKey-based declares the exchange andbinds a private queue on the routing key).
mqttProtocolVersion: 5selects the Paho v5 client for publish and subscribe (default3/3.1.1);v5 additionally delivers message headers (e.g. correlation IDs) as MQTT 5 user properties on publish and
records them as headers on consume — which MQTT 3 cannot carry.
New Docker-gated live-broker tests (Kafka, RabbitMQ, Mosquitto) plus non-Docker serde/wire-format unit tests
cover all three. See docs/code/async-messaging.md.
Mock OpenAI Realtime & Gemini Live voice APIs over WebSocket — new
RealtimeMockBuilder. MockServer cannow mock the two dominant realtime (voice) LLM protocols so agents/apps that use them can be tested offline,
with no real API and no audio hardware. A new pure event codec pair in
mockserver-core(
org.mockserver.llm.realtime.OpenAiRealtimeCodec/GeminiLiveCodec) generates the provider-correctWebSocket event stream for one scripted assistant turn, and the Java client
RealtimeMockBuilder(
org.mockserver.client) wires it into a standardhttpWebSocketResponseexpectation — an initial pushedsession.createdplus per-incoming-frame matchers — so no new action type, DTO, or JSON schema isrequired (exactly as A2A streaming reuses
httpSseResponse). OpenAI Realtime (GA 2025 event protocol,wss://.../v1/realtime): pushessession.createdon connect, acknowledgessession.updateandconversation.item.create, and answers eachresponse.createwith the full lifecycle —response.created→
response.output_item.added→response.content_part.added→ per-tokenresponse.output_audio_transcript.delta+response.output_audio.delta(audio modality) orresponse.output_text.delta(text modality) → the matching*.donemarkers →response.donewith usage.Gemini Live (
BidiGenerateContent): answerssetup→setupCompleteand eachclientContentturn witha streamed
serverContentchunk sequence +generationComplete/turnCompletecarryingusageMetadata.Streaming timing follows a deterministic
tokensPerSecond/ time-to-first-token model; audio bytes are opaquesilence placeholders (the fidelity target is the event protocol, not audio DSP). Deferred protocol corners
(server VAD / input-audio-buffer events, function-call output items, Gemini
toolCall/realtimeInput, etc.)are documented in
docs/code/ai-protocol-mocking.mdrather than half-implemented.Prometheus
_totalcounters for the five monotonic metrics (correctrate()/increase()). The fivegenuinely-monotonic counts —
requests_received_count,expectations_not_matched_count,response_expectations_matched_count,forward_expectations_matched_count, andllm_chaos_injected_count—now additionally publish a proper Prometheus
Counteralongside their legacy gauge:mock_server_requests_received_total,mock_server_expectations_not_matched_total,mock_server_response_expectations_matched_total,mock_server_forward_expectations_matched_total, andmock_server_llm_chaos_injected_total. This is non-breaking and additive — the legacy_countgauges areretained unchanged so the dashboard UI and existing Grafana dashboards keep working, while PromQL
rate()/increase()queries can now use the true monotonic_totalseries (e.g.rate(mock_server_requests_received_total[5m])). The new counters are incremented in lock-step with thelegacy gauges from the same call sites and are mirrored to the OTLP export as observable monotonic counters.
WASM matcher envelope v2 — query parameters and cookies in
match_request. The richer WASM ABI nowexposes the request's query-string parameters and cookies to a module, so a rule can route on
?tenant=acmeor asessioncookie, not just method/path/headers/body. The JSON envelope passed tomatch_requestgained a top-levelversionfield (currently2) plusqueryStringParameters(name toarray of values) and
cookies(name to single value). The change is additive and backward compatible:every envelope version is a strict superset of the previous one, so existing version-1 modules (which read
only method/path/headers/body and ignore unknown fields) keep working unchanged — guarded by a
WasmRuntimeRequestV2AbiTestthat runs the version-1 example module against a version-2 envelope. Themockserver-wasm-sdkRust authoring crate gainsreq.query_param(...),req.cookie(...)andreq.version()accessors (returningNoneagainst an older envelope), and a newexamples/wasm/rust-request-v2/sample module (with prebuilt.wasm) demonstrates query-parameter andcookie routing. The
POST /mockserver/wasm/testendpoint acceptsqueryStringParametersandcookiesinthe sample request. See
docs/code/wasm-rules.md.Test a WASM rule from the editor extensions. The VS Code and JetBrains MockServer extensions can now
call
POST /mockserver/wasm/testto check what a WASM module does against a sample request withoutuploading it or creating an expectation, complementing the existing WASM module upload/list wiring.
Deterministic embeddings are now semantically plausible, so offline RAG-retrieval tests can rank. A mocked
embeddings response with
deterministicFromInput: truepreviously produced a hash-seeded uniform-random unitvector, so cosine similarity between related texts was meaningless — you could not test vector-search / RAG
ranking against a mock. MockServer now builds the deterministic vector by n-gram feature hashing: the input
is tokenised (Unicode-aware, lowercased) into word unigrams, word bigrams, and character 3-grams; each feature
is hashed (seeded FNV-1a) into a bucket with a signed, sublinear-TF-weighted contribution; the result is
L2-normalised. Texts that share vocabulary now have a higher cosine similarity (paraphrases ~0.3–0.6) while
unrelated texts stay near-orthogonal (~0.0–0.1) — e.g.
"the cat sat on the mat"ranks far above"quarterly financial report"against"a cat sits on a mat"— so retrieval code can rank related documentsoffline with no real embedding model. The vector stays deterministic for the same input, seed, and
dimensions and unit-length (feature-less input falls back to a seeded non-zero vector); the
dimensions/seedparameters, provider JSON envelopes, and the non-deterministic (default) random path areunchanged.
Authenticated cross-node cluster verify/retrieve fan-in. The opt-in cluster fan-in
(
clusterVerifyFanIn) now works on a cluster with control-plane authentication enabled. A newclusterFanInPeerAuthTokenproperty (envMOCKSERVER_CLUSTER_FAN_IN_PEER_AUTH_TOKEN, default empty)gives the peer accessor (
HttpClusterPeerAccessor) a credential to present on every cross-node query:when set, it is sent verbatim as the control-plane
Authorizationheader (include the scheme, e.g.Bearer <jwt>), so peers accept the fan-in query instead of rejecting it with 401/403. All nodes mustshare the same token. With no token (the default) no credential is sent — unchanged, non-breaking
behaviour; fan-in remains off by default. The property is wired through the config trio
(
ConfigurationProperties/Configuration/ConfigurationDTO) and is covered by the reflective DTOround-trip drift guard. The programmatic
retrieve(REQUESTS/REQUEST_RESPONSES)path that backsdashboard export / one-shot traffic queries already fans in when enabled (verified with a test). Still
node-local by design (documented, no shared clock across nodes):
verifySequencecross-node ordering,the live dashboard WebSocket log-view stream, rate-limit / chaos-quota counters, and mTLS
client-certificate peer authentication. See
docs/code/clustered-state.md.Startup warm-up removes first-request latency — new
startupWarmupproperty (default on). The veryfirst request handled by a freshly started MockServer was a few hundred milliseconds slower than every
request after it because the request-handling path (Netty HTTP codec, JSON serialisation, response writers)
only loads and initialises on first use — a cost paid by every readiness poll, including Testcontainers wait
strategies. MockServer now sends itself a single background
PUT /mockserver/statusloopback requestimmediately after the ports bind, so that one-off cost is paid off the start-up thread and the first real
request is fast. The warm-up never delays port binding, is fail-soft (any failure is ignored and logged only
at TRACE), and uses a control-plane endpoint that creates no recorded requests or log events, so it never
pollutes
verify/retrieve. Disable with-Dmockserver.startupWarmup=false/MOCKSERVER_STARTUP_WARMUP=false(e.g. in a locked-down environment where MockServer must not connect toitself).
MCP spec 2025-06-18 negotiation with structured tool output and resource links. MockServer's MCP
server (
McpRequestProcessor) now advertises and negotiates the 2025-06-18 MCP revision while stayingbackward compatible: a client that requests
2025-06-18gets it, clients still on2025-03-26/2024-11-05keep getting their requested revision (echoed back), and an unknown/omitted version falls back to the latest
2025-06-18(negotiateProtocolVersion, stored per-McpSession). For sessions that negotiated 2025-06-18+,tools/callresults additionally carrystructuredContent(the machine-readable tool-result object)alongside the existing text block; older sessions are unchanged. The Java
McpMockBuildergainswithOutputSchema(...)(advertised intools/list),respondingWithStructured(text, structuredJson)(emits
structuredContent), andrespondingWithResourceLink(uri, name, description, mimeType)(emits aresource_linkcontent item), and now defaultsprotocolVersionto2025-06-18. TheMcpContractTestconformance tester defaults to
2025-06-18, records the server's negotiated version, and validates the newstructuredContent/resource_linkshapes when present (optional — older servers still pass).Mcp-Session-Idemission/handling was already in place. Elicitation (
elicitation/create) and the GET SSE server-push streamare not mocked (they require a server→client channel MockServer's request/response model does not have); JSON-RPC
batching remains accepted for back-compat. No MCP tools were added or reclassified.
Expectation-authoring and record/replay control tools on the MCP server. An AI coding agent
(Claude Code, Cursor, etc.) can now stand up and drive mocks entirely through the MCP server at
/mockserver/mcp, closing the "AI agents can only read, not author" gap. Three new tools are added,each delegating to the existing
HttpStatecontrol-plane operation (no logic fork):list_expectations(READ — active expectations, optionally filtered by method/path;PUT /retrieve?type=ACTIVE_EXPECTATIONS),set_operating_mode(MUTATE — switch SIMULATE/SPY/CAPTURE;PUT /mockserver/mode), andpromote_recordings(MUTATE — turn recorded traffic into active mocks withredaction/consolidation/parameterization;
PUT /mockserver/recordings/promote). Each tool is classifiedread-vs-mutate so the control-plane authorization gate applies — a MUTATE tool requires the MUTATE role
when
controlPlaneAuthorizationEnabledis on. The pre-existing authoring/read tools (create_expectation,raw_expectation,clear_expectations,verify_request,retrieve_recorded_requests,retrieve_request_responses) are unchanged; the/mockserver/modeand/mockserver/recordings/promoteREST handlers were refactored onto new shared
HttpState.setMode(...)/HttpState.promoteRecordings(...)methods so REST and MCP share one code path.
OpenAI Responses API server-side state —
previous_response_idchaining,store, andGET /v1/responses/{id}. MockServer's Responses API mock (OPENAI_RESPONSES) is no longer stateless:each issued
POST /v1/responsesresponse is recorded (by default; honours the request'sstoreflag) in anew process-wide
OpenAiResponsesStore, so agents that chain turns viaprevious_response_id— sending onlythe new turn plus the prior response id — now run against the mock.
OpenAiResponsesCodec.decodeprepends thestored prior conversation when a request carries a
previous_response_id, so conversation matchers and usageinference see the full dialogue, and
GET /v1/responses/{id}returns the stored response body. The store isbounded (LRU), cleared on server reset, and fully back-compatible — a request with no
previous_response_idand the default
store:truebehaves exactly as before (it only additionally records the response).OpenAI-compatible provider aliases: Mistral, xAI (Grok), DeepSeek, Groq, and OpenRouter. Five new
Providervalues whose codecs and runtime clients delegate to the OpenAI Chat Completions implementations(exactly as
AZURE_OPENAIdoes), distinguished by host (api.mistral.ai,api.x.ai,api.deepseek.com,api.groq.com,openrouter.ai) in bothLlmProviderSnifferandProviderDetector. Proxy observability nowclassifies traffic to these gateways as LLM (with provider-correct GenAI spans and cost metrics) instead of
dropping it as non-LLM. Approximate, clearly-flagged pricing rows were added for each in
LlmPricing(OpenRouter routes vendor-prefixed model ids such as
openai/gpt-4oto the underlying vendor's table).Chaos experiment composition: recurring runs, staged TCP/lifecycle faults, steady-state pre-check, and
history. The
ChaosExperimentOrchestratornow composes fault primitives beyond a single one-shot HTTP run,all as new optional fields that default to the previous behaviour:
(1) Recurring cron experiments — set
"recurring": truealongside acronScheduleand, after each cleancompletion, the experiment records the run and re-arms itself for the next cron occurrence (e.g. a
"nightly-error-storm"on"0 2 * * *") instead of going terminal after one run; a stop, auto-halt, or SLObreach still ends it for good.
(2) Staged TCP / connection-lifecycle faults — a stage may carry a
tcpProfilesmap (host →TcpChaosProfile) applied/reset with the same discipline as HTTPprofiles, so transport-level faults(RST, GOAWAY, latency, bandwidth, preemption) get the same auto-halt and stage progression; a stage is valid
with HTTP profiles, TCP profiles, or both.
(3) Steady-state baseline pre-check — with an
sloCriteria, an optionalbaselineWindowMillisevaluatesthe SLO over the pre-experiment lookback window before applying stage 0 and refuses to start
(
aborted_baseline_unhealthy, verdict attached) if the steady state does not already hold, instead of runningand blaming the experiment.
(4) Bounded experiment history — every terminal transition (including each recurring run and a
baseline-refused start) is appended to a bounded ring (last 50, newest first) exposed at
GET /mockserver/chaosExperiment/historyfor recurring-run trails and CI trend dashboards. The newrecurring,tcpProfiles, andbaselineWindowMillisfields round-trip through the experiment definition JSON.Typed mock-drift client methods across all 8 client libraries. Each client now exposes a typed wrapper
for the drift-detection control plane —
retrieveDrift()(GET /mockserver/drift, returns the parsed{ count, drifts }report) andclearDrift()(PUT /mockserver/drift/clear) — so programmatic users nolonger have to hand-roll raw HTTP. Added to the Java (
retrieveDrift/clearDrift), Node(
retrieveDrift/clearDrift), Python (retrieve_drift/clear_drift), Ruby (retrieve_drift/clear_drift),Go (
RetrieveDrift/ClearDrift), .NET (RetrieveDrift/ClearDrift+ async variants), Rust(
retrieve_drift/clear_drift) and PHP (retrieveDrift/clearDrift) clients, each following that client'sexisting control-plane conventions, with mocked-transport unit tests. The drift-detection documentation now
shows client-library tabs alongside the REST examples.
Experimental JDK 25 AOT-cache Docker image variant (Project Leyden) for ~2x faster container startup.
New
docker/aot/Dockerfilebuilds a MockServer image on a jlink-trimmed Temurin 25 runtime with anahead-of-time cache (JEP 483/514) baked in via a training run at image build time. Measured time-to-ready
roughly halves versus the standard image (~0.35 s vs ~0.7–0.8 s from
docker runto a 200 fromPUT /mockserver/status) with identical behaviour — it is the real HotSpot JVM, so 100% feature parity.Published from this release as opt-in
X.Y.Z-aot/latest-aottags (Docker Hub + ECR Public),error-isolated in the release pipeline like the clustered image, and selectable from the MockServer
Testcontainers module via
new MockServerContainer(MockServerContainer.aotImage()). The Testcontainersdocumentation now explains the fast-test hierarchy (suite-scoped container +
reset(), in-processMockServer for Java tests) and the runtime-level options evaluated (AppCDS, AOT cache, GraalVM native
image) with measured figures and the reasons native-image is not supported. (relates to #2385)
Mock-drift detection master switch and sampling. New
driftDetectionEnabled(boolean, defaulttrue) turnsmock-drift analysis of forwarded responses on or off, and
driftSampleRate(double0.0–1.0, default1.0)analyses only a sampled fraction of forwarded responses. Both defaults preserve the previous always-on behaviour;
set
driftDetectionEnabled=false(or lowerdriftSampleRate) to cut the per-forward overhead when proxying athigh volume.
**Runnable Kubernetes example:
Configuration
📅 Schedule: (UTC)
🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.
♻ Rebasing: Whenever PR becomes conflicted, 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.