Class AdminMixin

java.lang.Object
org.apache.juneau.rest.server.ops.AdminMixin

public class AdminMixin extends Object
Mixin that serves operational-introspection endpoints under /admin/*: thread dump, heap statistics, configurable cache-flush hooks, and rate-limit-bucket inspection.

Sibling of EchoMixin (/echo/*) and RouteIndexMixin (/options). All three classes live in the org.apache.juneau.rest.server.ops ops/introspection mixin pack.

Default-deny security posture:

The mixin is annotated with @Rest(guards=DenyAllGuard.class), so every admin path returns 403 Forbidden until the importer registers a @Bean RestGuardList factory on the host. The framework's bean-store override seam replaces the entire annotation-derived guard list (including this deny-all) with the user-supplied chain — pair the mixin with whatever authentication / authorization story your service uses (bearer-token guard, API-key guard, Spring Security adapter, etc.).

Why deny-all rather than a non-existent role-name placeholder? The role-guard approach (declaring a role that no real principal has) has clean semantics but harder ergonomics: the importer overrides by setting the principal's roles to include the placeholder, which couples the host's auth strategy to a framework-internal role name. Replacing a RestGuardList via @Bean keeps the override surface narrow — one factory method on the host — and matches the way every other Juneau op-context bean is wired.

Configurable mount prefix:

The default mount prefix /admin can be overridden via the SVL variable ${juneau.admin.path:admin} — a single override relocates all four endpoints (/threads, /heap, /cache/flush, /ratelimit) under the new prefix. Set via system property (-Djuneau.admin.path=ops), environment variable (JUNEAU_ADMIN_PATH=ops), or Config key (juneau.admin.path = ops) to change the runtime mount without subclassing. Resolution happens once at RestContext construction time (SVL resolution in @RestOp(path)).

Override accepts bare token (admin), leading slash (/admin), trailing slash (admin/), or wildcard suffix (/admin/*) — all resolve to the same mount.

Mixin-only deployment:

This resource is designed for composition via @Rest(mixins=...). The four mount paths (/admin/threads, /admin/heap, /admin/cache/flush, /admin/ratelimit) are pinned at the op level by @RestGet/@RestPost(path=...) on the handler methods; a class-level @Rest(paths=...) declaration would be silently ignored under the mixin pattern (see @Rest(paths) Javadoc).

Composition example:

@Rest(path="/api", mixins=AdminMixin.class) public class ApiResource extends RestServlet { // Required: register an auth guard chain to unlock the admin paths. @Bean(name="guards") public RestGuardList guards(BeanStore bs) { return RestGuardList.create(bs) .append(new MyBearerTokenGuard()) .build(); } @Bean AdminMixin admin() { return AdminMixin.create() .cacheFlush("primary", () -> primaryCache.invalidateAll()) .build(); } }

Endpoints:
  • GET /admin/threads — emits a JSON list of currently-live threads. The default thread filter excludes framework noise (JVM internals, servlet container, Spring Boot infrastructure); override via AdminMixin.Builder.threadNamePrefixExclude(String...).
  • GET /admin/heap — emits a JSON map with Runtime heap stats (total, free, max, used) plus non-heap memory usage. No heap-dump file generation in v1 (security risk).
  • POST /admin/cache/flush — runs all registered cache-flush hooks, or just a comma-separated names subset when supplied as a query parameter. Returns a JSON map of the hooks that were invoked. Hooks are registered name-keyed via AdminMixin.Builder.cacheFlush(String,Runnable); users that want async semantics own the threading model.
  • GET /admin/ratelimit — emits a JSON map keyed by bean name listing the registered RateLimitGuard configuration and live per-bucket state. Each entry has two sub-fields: config (the guard's static configuration — class, limit, permitsPerSecond, xForwardedForAware, exemptPaths) and snapshot (a sorted array of RateLimitGuard.BucketState entries describing every per-key bucket the storage backend currently tracks). Returns 404 Not Found when no RateLimitGuard bean is registered on the importer's bean store. Storage backends that don't override RateLimitGuard.Storage#snapshot() (e.g. Redis-backed impls that can't cheaply enumerate buckets) emit an empty snapshot array.

All four endpoints carry @OpSwagger(ignore=true) so the admin surface stays out of any generated Swagger / OpenAPI spec.

See Also:
Since:
10.0.0
  • Field Details

    • DEFAULT_THREAD_NAME_PREFIX_EXCLUDE

      Default thread-name-prefix exclude list: filter out JVM internals, servlet container, and Spring Boot infrastructure threads.
  • Constructor Details

    • AdminMixin

      public AdminMixin()
      No-arg constructor — delegates to a default AdminProvider worker (default thread filter and no cache-flush hooks).
    • AdminMixin

      protected AdminMixin(AdminProvider worker)
      Worker constructor.
      Parameters:
      worker - The shared AdminProvider worker this flavor delegates to. Must not be null.
  • Method Details

    • create

      public static AdminMixin.Builder create()
      Creates a new builder.
      Returns:
      A new builder.
    • getThreads

      public void getThreads(RestResponse res) throws IOException
      [GET /admin/threads] — emit a JSON list of currently-live threads.
      Parameters:
      res - The current REST response.
      Throws:
      IOException - If an I/O error occurs while writing the response.
    • getHeap

      public void getHeap(RestResponse res) throws IOException
      [GET /admin/heap] — emit JVM heap and non-heap memory statistics.
      Parameters:
      res - The current REST response.
      Throws:
      IOException - If an I/O error occurs while writing the response.
    • postCacheFlush

      public void postCacheFlush(RestRequest req, RestResponse res) throws IOException
      [POST /admin/cache/flush] — run all registered cache-flush hooks (or a subset).
      Parameters:
      req - The current REST request — names query parameter is read off it.
      res - The current REST response.
      Throws:
      IOException - If an I/O error occurs while writing the response.
    • getRateLimit

      public void getRateLimit(RestRequest req, RestResponse res) throws IOException
      [GET /admin/ratelimit] — emit registered RateLimitGuard bean configuration.

      Returns 404 Not Found when no RateLimitGuard bean is registered.

      Parameters:
      req - The current REST request — supplies the bean store for guard lookup.
      res - The current REST response.
      Throws:
      IOException - If an I/O error occurs while writing the response.
    • getCacheFlushHooks

      Returns the registered cache-flush hooks (test/inspection helper).
      Returns:
      The hooks, keyed by registration name. Never null.
    • getThreadNamePrefixExclude

      Returns the configured thread-name-prefix exclude list (test/inspection helper).
      Returns:
      The exclude list. Never null.