Skip to content

Commit c303cdc

Browse files
chore(deps): update dependency org.mock-server:mockserver-netty-no-dependencies to v7.6.0 (#2386)
This PR contains the following updates: | Package | Change | [Age](https://docs.renovatebot.com/merge-confidence/) | [Confidence](https://docs.renovatebot.com/merge-confidence/) | |---|---|---|---| | [org.mock-server:mockserver-netty-no-dependencies](https://www.mock-server.com) ([source](https://redirect.github.com/mock-server/mockserver-monorepo)) | `7.5.0` → `7.6.0` | ![age](https://developer.mend.io/api/mc/badges/age/maven/org.mock-server:mockserver-netty-no-dependencies/7.6.0?slim=true) | ![confidence](https://developer.mend.io/api/mc/badges/confidence/maven/org.mock-server:mockserver-netty-no-dependencies/7.5.0/7.6.0?slim=true) | --- ### Release Notes <details> <summary>mock-server/mockserver-monorepo (org.mock-server:mockserver-netty-no-dependencies)</summary> ### [`v7.6.0`](https://redirect.github.com/mock-server/mockserver-monorepo/blob/HEAD/changelog.md#760---2026-08-17) ##### Changed - The three Kubernetes container-integration cases that need Java-built images — `helm_sidecar_injection` (admission-webhook sidecar injection), `helm_clustered_convergence`, and `helm_jgroups_dns_ping` (both the `-clustered` Infinispan image) — now run **blocking in CI** instead of recording a skip. Previously the CI helm step ran with no JDK and never built those images, so all three recorded an honest but permanent SKIP — coverage that looked green while proving nothing. A new `:maven: build container-test images (jars)` step in the `mockserver-container-tests` pipeline builds the `mockserver-netty`, `mockserver-k8s-webhook`, and `mockserver-state-infinispan` jars **from the tree** (once, via the Maven-in-Docker reactor) and hands them to the helm step as Buildkite artifacts; the helm step downloads them and does cheap `docker build`s (a COPY into distroless) to produce the `-clustered` and `mockserver-webhook` images, then runs the suite. The jars travel as artifacts (\~200 MB total) rather than `docker save`d images (\~1.3 GB), mirroring the node-launcher / WAR hand-off. Both layers **fail closed**: the helm step exits non-zero if any jar artifact is absent, and the harness runs with `REQUIRE_CLUSTERED_IMAGE=true`/`REQUIRE_WEBHOOK_IMAGE=true` so an image that is expected-but-absent is recorded as a **FAILURE**, never a skip — a skip in CI is now impossible. Local `container_integration_tests/integration_tests.sh` is unchanged for a developer without the images: it still records a comprehensible SKIP (no fail-closed flag set), and the harness now also builds the `mockserver-webhook` image locally (`build_webhook_docker`) so the sidecar case runs blocking in local dev too — it was never built by the harness before, so that case had always skipped. ##### Added - Two new rules in the always-on `check-false-green-guards.sh` CI gate. **Rule 4** fails the build if a CI step runs the container-integration harness with the helm/k3d cases active but does not export both `REQUIRE_CLUSTERED_IMAGE=true` and `REQUIRE_WEBHOOK_IMAGE=true` — the exact way the three image-dependent Kubernetes cases could silently revert to a green SKIP. It is keyed on the step's *behaviour* (invokes `integration_tests.sh` without `SKIP_HELM_TESTS=true`), not on a filename, so a rename or a second helm-running step is covered automatically. **Rule 5** fails the build if a `mockserver-core` test that performs a JVM-global logging side effect (reaching `LogManager.readConfiguration`'s handler `reset()` via the static `ConfigurationProperties` logging setters or a forced fresh `<clinit>`) is not in the `sequential-tests` include list — the shape behind a release-blocking flake that `ParallelStaticStateGuardTest` structurally cannot catch. Both rules fail closed on an empty corpus and carry a rotating allow-list. See [docs/operations/false-green-guards.md](docs/operations/false-green-guards.md). - A `jarPath` launcher option and matching `MOCKSERVER_JAR_PATH` environment variable for `mockserver-node`, pointing `start_mockserver` at a pre-provisioned `mockserver-netty` jar-with-dependencies instead of downloading one from Maven Central. When set, that exact jar is launched and no download is attempted; a configured-but-missing path is a **hard error** (`... refusing to fall back to downloading a release`) rather than a silent fall-back to a released jar, so a missing artifact fails loudly. Mirrors the existing `MOCKSERVER_BINARY_BASE_URL` bring-your-own-artifact path for the standalone binary, and serves air-gapped/corporate installs as well as testing a locally-built jar (`jarPath` takes precedence over `mockServerVersion`/`artifactory*`; the option beats the env var). The Node launcher integration tests now use it in CI: a new `:maven: build node launcher jar` step builds the jar **from the tree** and the launcher-test step downloads it as an artifact and launches it via `MOCKSERVER_JAR_PATH` — so the suite finally tests the repo's own code instead of the last release. Previously it ran a downloaded release chosen by `package.json`'s version, so a `mockserver-core` fix could not green it and a regression could not red it; that released jar also carried the shipped dynamic-CA generation race (fixed on master in `4cff56e61`) and flaked \~8% of runs. The launcher step **fails closed** if the tree-built jar is absent rather than reverting to a download, and local `npm test` outside CI is unchanged (with neither the option nor the env var set it still downloads as before). - A structural wire-contract test for the LLM provider codecs (`LlmCodecStructuralContractTest`), breaking the self-derivation weakness in the golden-file drift test. `LlmCodecGoldenFileTest` regenerates its golden **bodies** from the codec itself (`-Dmockserver.updateLlmGoldens=true`), so a structural codec defect — a renamed field, a wrong SSE event name, a dropped `finish_reason` — bakes straight into its own golden and the byte-for-byte drift test then passes forever, confirming only that the codec is consistent with itself (token *counts* were already pinned separately by `shouldEncodeCanonicalTokenUsageCounts`; the bodies were not). The new test asserts the live codec output against **hand-authored expectations taken from each provider's published API schema** — required fields, JSON types, the enum discriminators each provider uses (`object`/`type`/`finish_reason`/`stop_reason`/ `finishReason`/`status`/`done`), the tool-call envelope shape (arguments as a JSON *string* for OpenAI/Responses vs a structured *object* for Anthropic/Gemini/Ollama), and the exact SSE event-name sequence for the event-typed providers — across all seven chat/completion providers (Azure and Bedrock via their delegate codecs). Crucially it **never reads the golden files and is unaffected by `-Dmockserver.updateLlmGoldens=true`**, so regenerating goldens cannot silence it. Each named defect class was injected into a codec and confirmed to turn the test red without regenerating goldens (OpenAI renamed `finish_reason`; Anthropic SSE `content_block_delta`→`content_delta`; Gemini dropped `finishReason`; Responses renamed `status`; Ollama renamed terminal `done`), then reverted. Residual streaming-over-the-wire behaviour remains covered by `LlmAgentLoopE2eTest`. - Endpoint-level test (`HttpStateCassetteEndpointTest`) and an authoritative `CassetteRegistry` javadoc note pinning the settled decision that **loading and recording register a cassette automatically**. The `record_llm_fixtures` and `load_expectations_from_file` MCP tools already auto-register the fixture in the process-wide `CassetteRegistry` (keyed by file path, origin `recorded`/`loaded`, upserting on re-load/re-record) so it surfaces under `GET /mockserver/cassettes` and in the dashboard's Cassettes tab without a manual `PUT /mockserver/cassettes` — but nothing pinned that a so-registered cassette is actually retrievable *through the GET endpoint*, and the registration policy lived only in the two MCP callers, inviting the question to be re-opened. The new test drives `GET /mockserver/cassettes` (and the bare `/cassettes` alias) against a registry populated the way the load/record handlers populate it and asserts the documented body shape (path, derived filename, expectation count, origin, lastUsed), that record-then-load on one path yields a single upserted entry, and that a server reset clears it. The MCP tools and consumer docs (`ai_mcp_tools.html`) already stated this behaviour; both are now clarified to say the fixture is registered automatically. This closes the "CassetteRegistry auto-population" product-decision item by recording the decision in code, docs, and a test rather than leaving it to resurface. - Compile gates for the dashboard composer's generated client code in Python, Ruby, Go and Rust (`.buildkite/scripts/steps/ui-client-codegen-compile.sh`, wired into `pipeline-ui.yml`), closing the gap where five of the composer's seven languages had no compile check — only Java (`ui-java-codegen-compile.sh`) and C# (`ComposerCodegenEquivalenceTests.cs`) were gated, so an emitter bug or a client-API rename would ship broken generated code to users caught by nothing (the existing per-language tests only string/byte-compare the emitter output, never feed it to a compiler). Each gate drives the shared representative composer matrix (`extractParityCases.ts` — the exact `combos` the byte-identity parity tests use) through that language's emitter and runs the lightest credible toolchain check: `python -m py_compile` and `ruby -c` catch any emitter bug that produces malformed source (the strongest static check for a dynamically-typed client with no shipped type stubs), while **Go** (`go build`/`go vet ./...`) and **Rust** (`cargo check`) compile the generated code against the real in-repo `mockserver-client-go` / `mockserver-client-rust`, so a renamed client method fails the build — the direct analog of the Java `javac` gate. Node was already covered: the `tsc` type-proof in `node.test.ts` (`typecheck-node-codegen.mjs`) runs under `npm test`, so the orphaned-script concern was already resolved by that test. All four new gates are proven to go red (emitter drift → non-zero exit) and green. Each phase runs in its toolchain's Docker image via `run-in-docker.sh`; set `CODEGEN_COMPILE_USE_DOCKER=false` for host validation. - Config-to-client wiring tests for the GCS and Azure blob-store backends (`GcsBlobStoreRegistrarConfigWiringTest`, `AzureBlobStoreRegistrarConfigWiringTest`), closing the gap where only S3 (`S3BlobStoreRegistrarConfigWiringTest`) proved that `blobStoreType` configuration is turned into a working client. The GCS and Azure contract tests hand-build their clients (`new GcsBlobStore(storage, …)`, `new AzureBlobStore(containerClient, …)`), so the registrar that reads the bucket/container name, endpoint, credentials and project from configuration and constructs the client was never exercised — a wiring bug there would ship silently because the contract tests bypass it. The new tests drive each registrar from configuration only (as production does) against the same Docker emulator the contract tests use (fake-gcs-server for GCS, Azurite `3.36.0 --skipApiVersionCheck` for Azure) and assert the wiring that can actually be got wrong: endpoint override, credentials, project id, and that a round-tripped object lands in the *configured* bucket/container under the *configured* key prefix — verified through an independent admin client so a mis-wired name cannot pass. Docker-gated via the canonical `DockerAvailability.isAvailable(...)` probe. - The Node and Python Testcontainers modules (`mockserver-testcontainers/node`, `mockserver-testcontainers/python`) now start a real MockServer container in CI and assert against it, closing a false-green gap where both published client libraries had jobs that passed having exercised nothing (`npm run test:unit` and `pytest -m "not docker"` both skipped the container). Their CI steps now mount the Docker socket, run the existing integration tests that start a `mockserver/mockserver` container and drive it over HTTP, and — mirroring the Go/.NET/Rust steps — fail closed by grepping for an evidence marker the test prints only after a real container answered `PUT /mockserver/status` with `200`. A skip (test filtered out, renamed, or Docker unusable) therefore fails the CI build loudly instead of reading as green, while the tests still degrade gracefully to a skip off-CI. - A GitHub Actions workflow (`.github/workflows/dependency-submission.yml`) now submits the resolved Maven dependency graph so Dependabot vulnerability **alerts** stay accurate for the monorepo layout. GitHub's managed Maven auto-submission only discovers a project at the repository root, so it silently stopped when the Java project moved into `mockserver/` — freezing the alerting graph at a pre-move snapshot that produced phantom Spring advisories and hid already-landed `log4j-api`/`jsoup` fixes. The workflow resolves and submits the `mockserver/` reactor (which includes `examples/java`) and the separate `mockserver-maven-plugin` build under distinct correlators, path-gated to `mockserver/**/pom.xml`. Dependabot's security-update pull requests were unaffected — they read manifests directly; it was only the alerting graph that had gone stale. - A CI guard (`.buildkite/scripts/steps/check-certificate-expiry.sh`, wired into the Java pipeline) now sweeps every committed certificate PEM and fails the build when any certificate is already expired or expires within 30 days, warning between 30 and 180 days. It checks every certificate in a chain file, allow-lists the one intentional expired test fixture while asserting it stays expired, and enforces two structural invariants that previously had no automation: every `leaf-cert.pem` must expire on or before its sibling `ca.pem`, and the shipped default CA files must stay in lockstep (the [PKCS#1](https://redirect.github.com/PKCS/mockserver-monorepo/issues/1) and [PKCS#8](https://redirect.github.com/PKCS/mockserver-monorepo/issues/8) CA private keys are the same key, that key matches the CA certificate, and the two committed copies of the CA certificate remain byte-identical). Certificate expiry had previously only ever been discovered by the build going red. - A standing CI guard (`check-false-green-guards.sh`) that fails closed when a new "false-green" test shape is introduced — a test or CI step that reports success while verifying nothing. The 2026-07-21 coverage audit named these shapes but they lived only in plan documents, and the repository then produced \~a dozen fresh instances in a single day. The guard enforces the three that can be pinned down precisely and each caused a real shipped false green: (1) every JUnit suite gated by `Assume.assumeTrue(DockerAvailability.isAvailable(...))` must be paired with `assert-suite-ran.sh` over its reports, or a broken Docker socket skips it while the build stays green; (2) no CI step may mount the Docker socket and then deselect the Docker-marked tests (e.g. `pytest -m "not docker"`), starting no container yet passing; (3) no container-integration `logTestSkip` may park deferred work ("CI wiring is a follow-up") as a green skip. It runs always-on (a new false green can enter from any of several pipelines) and carries a justified, self-verifying allow-list that fails if an entry no longer names what it claims. Wiring this up also closed a live gap it found — the `Gcs`/`Azure` `RegistrarConfigWiringTest` cloud suites ran under a Docker socket in CI but were not fail-closed-asserted. See `docs/operations/false-green-guards.md`. - A local-only, opt-in `K3D_LOCAL_CA_BUNDLE` hook in `container_integration_tests/helm-deploy.sh` so the Helm integration suite's k3d cluster can be stood up on a developer machine behind a corporate TLS-inspection proxy. When set, `start-up-k8s` overmounts the given **combined** CA bundle (system/public roots + corporate root) as the k3s node's containerd trust store at cluster-create time; when unset the `k3d cluster create` command is byte-identical to before, so CI (which never sets it) is unchanged. Warns rather than fails if the variable is set but the file is missing, mirroring `LOCAL_DOCKER_CA_BUNDLE` in `.buildkite/scripts/run-in-docker.sh`. This unblocks the three Kubernetes test-coverage gaps that were previously (and incorrectly) deferred as impossible behind the proxy: the host Docker daemon already trusts the corporate root so the node image pulls, but the *in-node* containerd has its own public-roots-only trust store and otherwise cannot pull even the `rancher/mirrored-pause` sandbox image (every pod fails sandbox creation with `x509: certificate signed by unknown authority`). See `docs/operations/build-system.md` → *Local Development Behind a Corporate TLS-Inspection Proxy*. - Two live Kubernetes container-integration tests that exercise admission-webhook and JGroups discovery paths which previously shipped unproven. `helm_sidecar_injection` deploys the chart with `webhook.enabled=true` (self-signed TLS bootstrap Jobs + webhook handler Deployment + `MutatingWebhookConfiguration`), drives a real labelled pod `CREATE` through the admission path, and asserts the resulting pod **spec** carries the injected `mockserver-sidecar` container, `mockserver-iptables-init` init container, and `mockserver.org/injected` annotation — with a negative-control pod (no opt-in annotation) that must **not** be injected, so a webhook that injects unconditionally fails the test. `helm_jgroups_dns_ping` deploys two clustered replicas and asserts the headless Service is truly headless (`clusterIP: None`), that `JGROUPS_DNS_QUERY` is wired to its FQDN, that it resolves to ≥2 pod IPs (Endpoints plus an in-cluster `nslookup`), that a ≥2-node JGroups/Infinispan view forms (the anti "two clusters of one" guard), and that state converges across the pods — exercising the Kubernetes DNS discovery path that `JGroupsKubernetesStackTest` (XML-parse only) and `ClusteredTwoNodeTest` (loopback MPING) never run. Both were proven red by degrading the exact behaviour they name (deleting the `MutatingWebhookConfiguration`; deleting the headless Service and rolling the pods). Both depend on Java-built images (the `-clustered` variant and the `mockserver-webhook` handler); when those images are absent — e.g. the CI helm step runs with `SKIP_JAVA_BUILD=true` and no JDK — the cases record an honest **SKIP** rather than a misleading pass, and run **blocking** only where the images exist. ##### Changed - `helm_clustered_convergence` is now a **blocking** container-integration test rather than `non_blocking || true`. The swallowed `k3d image import ... 2>/dev/null || true` is replaced by a deterministic import that verifies the image is present in the k3d node's containerd (via `crictl`) before deploying, and a pre-deploy `ensure_namespace_absent` guard removes the real back-to-back flake (`helm install` into a still-`Terminating` namespace left by a prior run/retry). When the `-clustered` image is absent (CI helm step, no JDK) the case records an honest **SKIP**; when present it runs blocking so a genuine clustering regression reds the suite. - The `docker_compose_war_tomcat` container integration test (MockServer deployed as a WAR into Tomcat 10.1) now actually runs in CI, closing a false-green gap where it silently skipped with *"WAR artifact not present … CI wiring is a follow-up"* — a working behavioural test that never ran, in a demonstrated weak spot (the ROOT-context percent-decode regression `66b5d51d2` shipped and broke builds, and this is the suite that would have caught it). Buildkite steps share no filesystem, so the WAR (already built by the reactor in the `:maven: build` step but never published) is now uploaded via that step's `artifact_paths` and downloaded by `container-tests-run.sh` into the path the test globs. A missing WAR now fails the step **closed** (both an explicit presence check in `container-tests-run.sh` and, defensively, `prepare_war` in `integration_test.sh` red the case) instead of skipping — a skip that reads as green is the exact defect being closed. The case runs in the Java pipeline's master-only `:docker: container integration tests` step (triggered by `mockserver/`, `mockserver-ui/`, `test-fixtures/` changes); it was already declared required in `expected_tests.manifest`, so no manifest change was needed. - Upgraded Netty from `4.2.16.Final` to `4.2.17.Final` and, in lockstep, `netty-tcnative-boringssl-static` from `2.0.78.Final` to `2.0.81.Final` (the tcnative version the Netty 4.2.17 BOM aligns to). The two must move together: the Netty BOM pins the transitively-resolved native-classifier tcnative jars to `2.0.81.Final`, so a mismatched main-artifact pin fails the enforcer `DependencyConvergence` rule in `mockserver-core`. The `NETTY_TCNATIVE` build args in every `docker/*/Dockerfile` were updated to match. This unblocks Dependabot PRs [#&#8203;2523](https://redirect.github.com/mock-server/mockserver-monorepo/issues/2523) and [#&#8203;2532](https://redirect.github.com/mock-server/mockserver-monorepo/issues/2532). - Removed the manual `netty-tcnative` version-synchronisation step that made every Netty upgrade a convergence trap. `netty-tcnative-boringssl-static` no longer has its own version property or `dependencyManagement` override — the imported `netty-bom` now governs the base artifact and every OS/arch native classifier together, so the two can no longer diverge and break the enforcer `DependencyConvergence` rule. The server jars (which ship tcnative classes but, per [#&#8203;1778](https://redirect.github.com/mock-server/mockserver-monorepo/issues/1778), no natives) are stamped at build time with their resolved tcnative version at `META-INF/mockserver-tcnative.version`, and every `docker/*/Dockerfile` now derives the native `.so` download from that stamp instead of a hardcoded `NETTY_TCNATIVE=` build arg (SHA256 verification of the download is unchanged). Both jars a Dockerfile can consume carry the stamp: the shaded `mockserver-netty-no-dependencies` jar used by the `source=copy` path (release/snapshot/CI) and the `mockserver-netty` assembly `-jar-with-dependencies.jar` used by the default `source=download` path (the public reference build), stamped via the same script so they cannot drift. A Netty bump therefore needs no tcnative pin update and no Docker edit, and the native `.so` can never be a different version than the tcnative classes it pairs with. - **BREAKING BEHAVIOUR: the default enabled TLS protocols are now `TLSv1.2,TLSv1.3` (previously `TLSv1,TLSv1.1,TLSv1.2`), and `tlsAllowInsecureProtocols` now defaults to `false` (previously `true`).** TLSv1 and TLSv1.1 are deprecated by RFC 8996 and vulnerable to BEAST/POODLE, and TLSv1.3 was previously never negotiated unless explicitly configured. This is a breaking change for a client that can only speak TLSv1 or TLSv1.1: its handshake to MockServer will now fail. To restore the legacy protocols set `mockserver.tlsProtocols=TLSv1,TLSv1.1,TLSv1.2` AND `mockserver.tlsAllowInsecureProtocols=true` (both are required — the insecure-protocol filter strips TLSv1/TLSv1.1 unless it is explicitly allowed). The inbound server always applies the strong `Http2SecurityUtil` cipher suites, so no weak-cipher combination becomes reachable as a result of this change. - Renewed the TLS/mTLS test-certificate fixtures. The two mutual-TLS authentication CAs (which were 151 days from expiry) and the three Netty TLS integration CAs were re-issued with a 10-year validity, and every leaf they sign was re-issued with a shorter 5-year validity so that a leaf can no longer outlive its issuing CA. The existing CA and leaf private keys were preserved (so key encodings, Subject/Authority Key Identifiers and existing signatures are unchanged); only the certificates were re-minted. ##### Security - Pinned `org.apache.logging.log4j:log4j-api` to `2.25.5` to resolve GHSA-qv9r-c865-cp47. It is pulled in transitively at compile scope (via `spring-boot-starter-logging` -> `log4j-to-slf4j`) and lands in a shaded artifact, so it is shipped; the pin manages `log4j-api` only (`log4j-core` is not on the dependency tree). - Pinned `org.jsoup:jsoup` to `1.23.1` to resolve GHSA-pmhh-3w7g-xqp8. jsoup is used only at test scope (never shipped); the pin guards against a future transitive downgrade below the fixed version. - Upgraded `com.azure:azure-storage-blob` from `12.29.1` to `12.35.0` in the optional `mockserver-blob-azure` module to resolve the `io.projectreactor.netty:reactor-netty-http` chained-redirect credential-leak advisory (fixed in reactor-netty `1.2.8`). The old stack pulled `azure-core-http-netty:1.15.10`, which pins the vulnerable reactor-netty `1.0.48` pair transitively; `12.35.0` pulls `azure-core-http-netty:1.16.5`, which advances both `reactor-netty-http` and `reactor-netty-core` to `1.2.18` as a matched pair. This exposure surfaced only when GitHub's Maven dependency-graph submission was restored (submission had silently frozen at a pre-move snapshot, so the alert had been invisible to Dependabot). The whole Azure stack (azure-core `1.58.1`, reactor-netty `1.2.18`, reactor-core `3.7.19`) remains Java-8 bytecode, so the Java 17 floor is preserved. A module-scoped `dependencyManagement` pin of `io.projectreactor:reactor-core` to `3.7.19` reconciles the one internal off-by-one in the 12.35.0 stack (azure-core declares `3.7.18`, reactor-netty declares `3.7.19`) so the enforcer `DependencyConvergence` rule stays satisfied. The Docker-gated Azurite contract test moves to Azurite `3.36.0` with `--skipApiVersionCheck`, since the newer SDK negotiates a Storage REST API version that runs ahead of every released Azurite build. - Pinned three transitive dependencies to close vulnerability alerts that surfaced only when GitHub's Maven dependency-graph submission was restored (submission had silently frozen at a pre-move snapshot on 5 May, so these real exposures had been invisible to Dependabot). None required moving the direct dependency that introduces them: - Jackson 3 (`tools.jackson.core:jackson-databind`, `:jackson-core`, `tools.jackson.dataformat:jackson-dataformat-yaml`) pinned to `3.1.5` to resolve GHSA-5gvw-p9qm-jgwh (vulnerable `>=3.0.0, <=3.1.4`). It arrives at compile scope via `com.networknt:json-schema-validator:3.0.6` and is shade-relocated into `shaded_package.tools.jackson`, so it ships in every distributed jar — the one broad, shipped, runtime exposure of the three. All three artifacts resolve in lockstep and are pinned together so the enforcer `DependencyConvergence` rule stays satisfied. The pin is inherited by the separate `mockserver-maven-plugin` build (same parent pom), closing its alert too. - `at.yawk.lz4:lz4-java` pinned to `1.11.1` to resolve GHSA-6qcp-4vqm-vf35 (native XXHash JVM crash; vulnerable `<=1.11.0`). Arrives via `org.apache.kafka:kafka-clients:3.9.2` — optional in `mockserver-netty`, runtime in `mockserver-async`. Note this is the `at.yawk.lz4` fork coordinate, not `org.lz4`. - `org.apache.commons:commons-compress` pinned to `1.27.1` to resolve the `>=1.21, <1.26.0` advisories. Arrives at test scope via `org.testcontainers:testcontainers:1.21.4`, which resolves it at `1.24.0`. The direct pin overrides that transitive version without bumping Testcontainers, which is deliberately held at `1.21.4` for Docker Desktop 4.67+ compatibility. - Made outbound TLS host name verification consistent and controllable for the forward/proxy client (Wave 3). When `forwardProxyTLSX509CertificatesTrustManagerType` is `JVM` or `CUSTOM` — the modes that actually validate the upstream certificate chain — MockServer now verifies the upstream host name against the certificate (RFC 2818 / HTTPS endpoint identification) on every outbound path. Netty already enabled this for client connections opened with a known host/port, but NOT for the no-host relay paths, so verification was silently skipped on some paths and there was no way to turn it off; without the host-name binding a certificate signed by a trusted CA for any host name would be accepted, leaving a user who had opted into real upstream validation open to a man-in-the-middle. It is now forced uniformly at the single point every outbound path shares (HTTP/1.1, HTTP/2, CONNECT-tunnelled relay, websocket relay, the reverse-proxy relay — which verifies against the CONNECT target host/port, not the connected socket address — and the LLM forward paths). It has no effect on the default `ANY` trust manager, which deliberately trusts everything and performs no host-name verification. A new `forwardProxyTLSHostnameVerificationEnabled` property (default `true`) turns off just the host-name check while keeping chain validation, for the legitimate testing case of an upstream whose certificate host name does not match the address connected to (it actively clears the algorithm Netty would otherwise default on); it is carried by `ConfigurationDTO` and folded into the client SSL-context cache key so a runtime change takes effect. The trust-manager javadoc, which previously implied only `ANY` skipped host-name verification, has been corrected. - Added a single startup WARN when the publicly-published bundled Certificate Authority (whose private key ships in the MockServer jar) is the trust anchor signing served traffic, naming the two supported fixes (`dynamicallyCreateCertificateAuthorityCertificate=true`, or `--proxy-setup`). Shipping the CA key is intentional and documented and the default is unchanged; the warning just makes the trade-off visible so an operator does not mistake the bundled CA for real interception security. Logged once per JVM, never per handshake. - A user-supplied FIXED server certificate is now re-checked on a cheap, time-bounded schedule (at most once a minute, stat only — never a per-handshake re-parse) so a long-running server surfaces a problem instead of silently serving it: a certificate rotated in place on disk forces a rebuild (which re-runs validation and picks up the replacement, failing loudly if it too is expired), and an unchanged-but-expired certificate is surfaced with a single WARN. Wave 1 had deliberately left this gap (self-generated leaves already self-renew; fixed certificates were validated only at startup). - Added a control-plane audit WARN when a `PUT /mockserver/configuration` lowers or alters TLS security posture — downgrading the forward-proxy trust manager to `ANY`, turning off `tlsMutualAuthenticationRequired`, turning off `forwardProxyTLSHostnameVerificationEnabled`, or repointing the TLS key/certificate/CA paths. Control-plane authentication is off by default, so such a runtime downgrade would otherwise be silent. The change is audited, not blocked (blocking would be an init-only breaking change). - Hardened the dynamic TLS certificate cache so it can no longer serve stale, torn or over-broad material (Wave 1, resilience only — certificate validity periods and extensions are unchanged). The cached server SSL context now regenerates a fresh leaf once the current one passes a renewal threshold (80% of its validity elapsed) instead of serving an expired certificate for the JVM lifetime; the cache-reuse decision is driven by a content signature over the Subject-Alternative-Name set, certificate-authority identity, key/cert paths, mTLS and protocol inputs (replacing a single consumable boolean that could return a certificate missing a just-added SAN under concurrency); client SSL contexts and the memoised certificate authority now self-invalidate when their inputs are rotated at runtime. Certificate generation now publishes the new private key and certificate atomically (a mid-flight failure keeps the previous working pair instead of leaving a new key paired with the old certificate), and SNI-driven provisioning runs off the Netty event loop with per-host coalescing. Only the leaf drives that renewal trigger: a dynamically-generated certificate authority nearing its own expiry is warned about once (it is never rotated automatically, which would invalidate every client trust store that imported it) rather than demanding a leaf regeneration the certificate-authority guard can never satisfy — which would otherwise re-mint the leaf on every handshake indefinitely. - Bounded the dynamically-grown Subject-Alternative-Name list with a new `maxSubjectAlternativeNames` property (default 100; when the cap is reached the genuinely oldest dynamically-discovered entry is evicted first, in FIFO order, with a warning, while configured and default SANs such as localhost are never evicted) and now normalise/validate each SNI hostname and `Host` header (lowercase, length and label-charset checked) before it is added, closing a denial-of-service vector where any client could force the leaf certificate to be re-minted with an unbounded SAN list. Both `maxSubjectAlternativeNames` and `sslCertificateLeafValidityInDays` are now carried by `ConfigurationDTO`, so they round-trip through `GET`/`PUT /mockserver/configuration` and can be set per-instance rather than only via the static store (a runtime change to `maxSubjectAlternativeNames` takes effect on the next SAN added). - Dynamically-generated private key material (leaf key, certificate-authority key, and the JKS key store) is now written owner-readable-only (`0600`) and atomically, and public certificates `0644`; a corrupt or unreadable certificate-authority PEM now fails loudly instead of being silently treated as absent and overwritten (which would invalidate every pinned client trust store), with cross-process locking around certificate-authority generation. - Deferred BouncyCastle registration in `PEMToFile` off the class-load path, restoring the lazy-BouncyCastle startup optimisation. - Shortened the auto-generated TLS **leaf** (server) certificate to a 397-day validity by default (Wave 2), so it stays inside Apple's 825-day maximum for TLS server certificates (iOS 13 / macOS 10.15) — the previous 10-year leaf exceeded that cap and is the likely cause of TLS handshake failures on Apple platforms ([#&#8203;2531](https://redirect.github.com/mock-server/mockserver-monorepo/issues/2531)). The generated Certificate Authority keeps its long (10-year) life, and the Wave 1 proactive renewal (regenerating the leaf once 80% of its validity has elapsed) means a long-running server never serves an expired leaf; the previous long-lived behaviour can be restored with the new `sslCertificateLeafValidityInDays` property (e.g. `3650`). That override is clamped to a usable range of 30–3650 days (a WARN is logged when a value is clamped): a value below 30 would mint a leaf that — because the `notBefore` is back-dated 5 days — is either already expired at issuance or already past its renewal threshold (so it would be re-minted on every handshake), and a value above 3650 could push the expiry past the X.509 date ceiling; a non-positive value still falls back to the 397-day default. The generated leaf now also carries a `serverAuth`+`clientAuth` extended-key-usage (Apple requires `serverAuth` on the leaf independently of validity), a critical `digitalSignature`+`keyEncipherment` key-usage, and an authority-key-identifier derived from the CA; the root CA no longer carries a (non-idiomatic) extended-key-usage. Certificate serial numbers are now forced positive as required by RFC 5280, and the HTTP/3 legacy echo-mode self-signed fallback gained a back-dated `notBefore`, subject-alternative-names, `serverAuth` extended-key-usage and a key-usage (it keeps the long validity because it is both trust anchor and server certificate with no renewal loop). ##### Removed - Removed the unused `PKCS1CertificateAuthorityPrivateKey.pem` resource from the published `mockserver-core` jar. It was the explicit [PKCS#1](https://redirect.github.com/PKCS/mockserver-monorepo/issues/1) half of an encoding pair added in 2020 for the since-removed JDK key/certificate builder, whose deletion in 2022 left it with no references for around four years. It was byte-identical to the original `CertificateAuthorityPrivateKey.pem`, which is retained (it backs a published raw-URL link and remains the stable [PKCS#1](https://redirect.github.com/PKCS/mockserver-monorepo/issues/1) form); the code continues to load `PKCS8CertificateAuthorityPrivateKey.pem`. ##### Fixed - Fixed a rare `mockserver-core` unit-test flake (`ConfigurationValueRedactionTest` / `ConfigurationDTOCredentialMaskingTest` failing with `Expected: is <1> but: was <0>` when asserting an exact count of captured log records). These tests attach a `java.util.logging` handler and assert what is emitted. Two other tests — `ClassInitializationDeadlockTest` and `ConfigurationPropertiesInitializationTest` — force a fresh `<clinit>` of MockServer classes in an isolated child-first classloader; that initialisation reaches `MockServerLogger.installDefaultJavaLoggingFormat()` → `LogManager.getLogManager().readConfiguration(...)`, and `java.util.logging.LogManager` is a **JVM-global singleton the child-first classloader does not isolate**, so its `readConfiguration` performs a `reset()` that removes every handler from every logger in the JVM. When one of those classes ran in the parallel Surefire phase alongside a handler-capturing test, the reset detached the capturing handler mid-test and a subsequent emit went uncounted. Both fresh-`<clinit>` classes are now pinned to the sequential (`parallel=none`) Surefire phase in `mockserver-core/pom.xml`, so they can never run concurrently with a handler-capturing test. No production behaviour changes. - Fixed the Helm chart's sidecar-injection webhook being broken out of the box. The default TLS-bootstrap image `webhook.tls.setupImage: bitnami/kubectl:1.31` no longer exists — Bitnami withdrew the tag from Docker Hub — so both bootstrap Jobs failed, the `MutatingWebhookConfiguration`'s `caBundle` was never patched, and because `failurePolicy: Fail` the webhook then **rejected every matched pod CREATE**. Anyone enabling `webhook.enabled=true` from the shipped defaults got an admission path that blocked pod creation rather than injecting a sidecar. The bootstrap now uses `registry.k8s.io/ingress-nginx/kube-webhook-certgen`, the purpose-built tool for exactly this job, published on the most stable-publication registry available and self-contained (no shell, no `openssl` CLI, no install-at-runtime step that would fail on an airgapped or proxied cluster). Phase 2's ClusterRole also gains the `update` verb, which the patch step genuinely needs. `helm_sidecar_injection` now renders and asserts the **chart default** is pullable rather than overriding it, so this cannot silently rot again. - Fixed the Kubernetes sidecar-injection webhook rejecting valid TLS private keys. `WebhookServer` parsed [PKCS#8](https://redirect.github.com/PKCS/mockserver-monorepo/issues/8) only and explicitly rejected anything else, which broke the **cert-manager** path as well: the chart's `Certificate` requests `algorithm: RSA` without `encoding: PKCS8`, i.e. [PKCS#1](https://redirect.github.com/PKCS/mockserver-monorepo/issues/1), so a cert-manager-issued key could not be loaded. It now accepts any standard unencrypted PEM private key — [PKCS#8](https://redirect.github.com/PKCS/mockserver-monorepo/issues/8), [PKCS#1](https://redirect.github.com/PKCS/mockserver-monorepo/issues/1), and SEC1 EC. This coupling is why the broken bootstrap image above could not simply be swapped: the handler only tolerated the one format that one withdrawn image happened to emit. - Fixed a thread race in dynamic Certificate Authority generation that could leave a standalone / CLI / Docker MockServer serving broken TLS for the rest of the process's lifetime. When `dynamicallyCreateCertificateAuthorityCertificate` is enabled, two startup paths could generate the CA concurrently — the proxy-setup log (`proxySetupLogging`, on by default in the CLI) writing the CA to disk, and the first HTTPS handshake building the server certificate. Generation was serialised only by a cross-process file lock; a second lock attempt **within the same JVM** threw `OverlappingFileLockException`, which was caught and treated as "proceed without serialisation", so both threads minted different CA key pairs and interleaved their writes. The result was a torn CA key/certificate pair on disk: every leaf certificate was then signed with one generation's CA key but verified against the other's CA public key, failing with `SignatureException: certificate does not verify with supplied key` — and because the mismatched CA was memoised, **every subsequent TLS handshake failed for the life of the process**. CA generation (and the paired load of the CA key + certificate) is now serialised within the JVM on a per-directory monitor in addition to the cross-process file lock, so the key and certificate are always published from the same generation. Embedded `ClientAndServer` users were unaffected (they default `proxySetupLogging` off); standalone, CLI and Docker users generating a dynamic CA could hit it intermittently. - Unblocked the daily Dependabot updater, which had been failing and raising no PRs. The Maven wrappers under `mockserver/` and `mockserver/mockserver-maven-plugin/` were modernised from the legacy Takari format to the Apache `only-script` wrapper (`wrapperVersion` 3.3.4, Maven pinned at 3.9.16), so the `maven-wrapper-updater` can parse them; `mockserver-vscode` was split into its own npm job (a lockfile `EOVERRIDE` there no longer aborts the other npm directories) and pinned `js-yaml` to `^4.1.1` via `overrides`; and `/.opencode` (which had only an orphan lockfile and no tracked manifest) was removed from the npm directories and its lockfile untracked. - Cloning an `X509Certificate` model that contains certificate metadata without an underlying Java certificate no longer throws a `NullPointerException`; metadata-only and certificate-backed models now both preserve their state when cloned ([#&#8203;2527](https://redirect.github.com/mock-server/mockserver-monorepo/issues/2527)). - JSON body matching no longer depends on which JSON provider [json-unit](https://redirect.github.com/lukas-krecan/JsonUnit) resolves to. MockServer parses both documents with Jackson and hands json-unit the resulting nodes to avoid re-parsing on every match, but json-unit picks its provider by asking each in turn whether it claims the value and falling back to the last one registered — and only its Jackson provider claims a Jackson node. Where another provider won (for example `org.json`, whether because Jackson was not visible to json-unit or because `json-unit.libraries` pinned it) every JSON match threw `Unsupported type class com.fasterxml.jackson.databind.node.ObjectNode` and **no JSON body ever matched**. MockServer now falls back to giving json-unit the raw JSON text, which it parses with whichever provider it resolved to ([#&#8203;2496](https://redirect.github.com/mock-server/mockserver-monorepo/issues/2496)). - Match failures from the JSON body matcher now report why the match failed. When JSON matching threw, the log said only `exception while perform json match failed` and the exception was recorded solely at `TRACE`, so at the default log level there was no way to tell a malformed body from a missing class from a runtime error. The cause is now included in the reported difference, as it already was for the XML schema, JSON path and JSON-RPC matchers. - Resolved the outstanding npm security advisories in the shipped and published Node packages: `dompurify` `3.4.12` → `3.4.13` in the bundled dashboard (`mockserver-ui`), `brace-expansion` `5.0.8` → `5.0.9` (ReDoS) in `mockserver-testcontainers/node`, and `js-yaml` `4.3.0` → `4.3.1` in `mockserver-client-node`, `mockserver-node` and `mockserver-testcontainers/node`. The `brace-expansion` fix bumps only the parent so the `minimatch`/`archiver` glob split is preserved (a blanket override previously broke `archiver`); no `brace-expansion` override was added. - Documented and mitigated a clustered-deployment TLS trust defect: with the default dynamic Certificate Authority generation, every MockServer node in a cluster mints its own distinct CA, so a client that trusts one node's `mockserver-ca.pem` gets an intermittent TLS validation failure when a load balancer routes it to another node. `StateBackendFactory.create()` now logs a WARN when it detects `clusterEnabled=true` together with `dynamicallyCreateCertificateAuthorityCertificate=true`, and the limitation and its fix are now documented in `docs/code/clustered-state.md`, `docs/code/tls-and-security.md`, the Helm chart README, and the Centralized Deployment consumer page. - Added first-class Helm chart support for supplying **one shared TLS Certificate Authority to every replica** via a Kubernetes Secret — the supported fix for the clustered CA defect above. New opt-in values `app.tls.*` create (or reference an existing) Secret, mount it read-only, and set `certificateAuthorityCertificate` / `certificateAuthorityPrivateKey` with `dynamicallyCreateCertificateAuthorityCertificate=false` on every pod. A CA private key now lands in a Secret rather than a ConfigMap. Also added `app.dynamicCertificateDir.*` (a writable `emptyDir` for the single-replica dynamic-CA case, so certificate writes no longer depend on a non-writable working directory) and `app.extraEnv` (arbitrary container environment variables, enabling any `MOCKSERVER_*` property the chart does not expose directly). All new values are opt-in and default to today's behaviour. - Fixed a latent dead condition in the Helm chart Deployment template: the `MOCKSERVER_PROPERTY_FILE` env var was gated on an undeclared `app.mountConfigMap` value (always false). `app.mountConfigMap` is now a declared value (default `false`, preserving prior behaviour) so external-ConfigMap users can opt into having MockServer pointed at the mounted `mockserver.properties`. </details> --- ### Configuration 📅 **Schedule**: (UTC) - Branch creation - At any time (no schedule defined) - Automerge - At any time (no schedule defined) 🚦 **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. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/prometheus/client_java). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0NC4yOS41IiwidXBkYXRlZEluVmVyIjoiNDQuMjkuNSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiZGVwZW5kZW5jaWVzIl19--> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
1 parent 1bcb903 commit c303cdc

1 file changed

Lines changed: 1 addition & 1 deletion

File tree

  • prometheus-metrics-exporter-pushgateway

prometheus-metrics-exporter-pushgateway/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
<dependency>
3636
<groupId>org.mock-server</groupId>
3737
<artifactId>mockserver-netty-no-dependencies</artifactId>
38-
<version>7.5.0</version>
38+
<version>7.6.0</version>
3939
<scope>test</scope>
4040
</dependency>
4141
<dependency>

0 commit comments

Comments
 (0)