Public API and versioning

Goblin follows semantic versioning from 1.0.0 on. This page says which part of the extension the version number speaks for, and what a minor version may still change.

Code that uses this API stays out of production, like Goblin itself (see Does Goblin run in production?). Keep it in src/test/java when only your @QuarkusTest classes use it, or in a module of its own, declared provided like Goblin, when dev mode needs it — a custom Assault or an AssaultObserver for the Dev UI sessions. That module must be indexed for its beans to be discovered: give it an empty src/main/resources/META-INF/beans.xml or the jandex-maven-plugin, otherwise its observers and assaults are silently ignored. Packaged code — the main classes of the application module and of the other modules of the build it depends on, unless they are declared provided — would compile against the provided dependency and then fail in the packaged application, which does not contain Goblin: a dev or test build refuses it and names the class. A Vert.x WebClient needs no Goblin call at all, Goblin arms the application’s clients by itself.

What the version covers

Java API

The stable Java API is the io.quarkiverse.goblin package and the io.quarkiverse.goblin.assault package, the custom assault SPI; nothing else is public API.

Type Role

AssaultEngine

The chaos engine: active flag, auto-off, live configuration, history, counters. Inject it to drive chaos from an application or a @QuarkusTest.

AssaultEngine.AssaultRecord

One recorded assault, as returned by getHistory() and passed to the observers: target, label, AssaultType, source, injected latency, injected value, time.

AssaultConfig

A read-only view of the assault configuration, frozen on one state: AssaultEngine.configSnapshot(), the two sides of an AssaultConfigChange, the configuration a custom assault is applied with.

MutableAssaultConfig

The live configuration, modifiable at runtime, returned by AssaultEngine.getMutableConfig(). Extends AssaultConfig with the setters; its snapshot() returns an AssaultConfig.

AssaultConfig.HeaderRule

One response header rule, as returned by AssaultConfig.getResponseHeaders().

AssaultObserver

SPI notified of every assault, activation change and configuration change. See the observer SPI.

AssaultConfigChange

A configuration change delivered to AssaultObserver.onConfigChange.

GoblinWebClient

Arms a Vert.x WebClient for the client-side assaults.

AssaultType, AssaultSource, AssaultProfile, ChaosLayer, DeactivationReason, ResponseBodyMode, ResponseHeaderAction

The enums used by the types above.

AssaultEngine, AssaultConfig and MutableAssaultConfig are interfaces provided by Goblin: an application uses them, it does not implement them. In this package, AssaultObserver is the only interface meant to be implemented; io.quarkiverse.goblin.assault.Assault is the other one.

Beyond Java

The version also covers what an application, a dashboard or an agent relies on outside the Java API:

  • the quarkus.goblin.* configuration properties (see Configuration reference);

  • the metric names and tags of quarkus-goblin-metrics (see Metrics (Micrometer / Prometheus)), and the span name and attributes of quarkus-goblin-opentelemetry (see Tracing (OpenTelemetry)). In particular the type tag and the goblin.assault.type attribute keep carrying the assault label, e.g. latency or response-body-truncate;

  • the names and parameters of the JSON-RPC methods and Dev MCP tools (see JSON-RPC reference).

Not covered

  • io.quarkiverse.goblin.internal and its sub-packages, and the Java classes of the quarkus-goblin-metrics, quarkus-goblin-opentelemetry and Dev UI modules: implementation, free to change in any version.

  • The constructors of the records — AssaultEngine.AssaultRecord, AssaultConfigChange, AssaultConfig.HeaderRule — and their record patterns (instanceof AssaultRecord(var method, …​), case AssaultRecord(…​)): these records are created by Goblin, and new components can be added. Their accessors are covered.

  • Human-readable text: log messages, AssaultConfig.describeAssaults(), the Markdown report, the Dev UI.

  • The layout of .goblin-state.json and of the .goblin/scenarios/ files.

The custom assault SPI

The io.quarkiverse.goblin.assault package — Assault, AssaultContext, AssaultOutcome, used to add your own assault type — is covered like the rest of the API. Assault is implemented by applications: like AssaultObserver, it only gains default methods in a minor version. AssaultContext and AssaultOutcome are provided by Goblin and may gain methods and constants.

Custom assaults run on the inbound JAX-RS filter only, and AssaultContext carries the JAX-RS request context. Running them on another layer will come as additions to this SPI, never by breaking it before a major version.

What a version may change

Version Changes

Patch (1.0.x)

Bug fixes only.

Minor (1.x.0)

Additions that keep code using the covered surface compiling and running: new types, new methods on AssaultEngine, AssaultConfig and MutableAssaultConfig, new default methods on AssaultObserver and Assault, new methods on AssaultContext, new record components, new enum constants, new configuration properties, JSON-RPC methods and Dev MCP tools, new fields in their results. Deprecations.

Major (x.0.0)

Anything else: removals and incompatible changes of the covered surface.

A covered element is removed only in a major version, after being deprecated in an earlier minor one.

New injection layers — gRPC, GraphQL, reactive clients — arrive in minor versions, and each one adds constants to ChaosLayer and AssaultSource. Keep a default branch when you switch on Goblin enums: an exhaustive switch without one stops compiling, or throws MatchException, once a constant is added.