Skip to content
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
package com.dotcms.rest.api.v1.maintenance;

import com.dotcms.annotations.Nullable;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import io.swagger.v3.oas.annotations.media.Schema;
import java.util.List;
import org.immutables.value.Value;

/**
* Immutable view describing a single JVM thread in a thread dump.
*
* @author hassandotcms
*/
@Value.Style(typeImmutable = "*", typeAbstract = "Abstract*")
@Value.Immutable
@JsonSerialize(as = ThreadDescriptorView.class)
@JsonDeserialize(as = ThreadDescriptorView.class)
@Schema(description = "Single thread entry in a JVM thread dump")
public interface AbstractThreadDescriptorView {

@Schema(
description = "Thread name",
example = "http-nio-8080-exec-1",
requiredMode = Schema.RequiredMode.REQUIRED
)
String name();

@Schema(
description = "JVM-assigned thread id",
example = "142",
requiredMode = Schema.RequiredMode.REQUIRED
)
long id();

@Schema(
description = "Whether this is a daemon thread",
example = "true",
requiredMode = Schema.RequiredMode.REQUIRED
)
boolean daemon();

@Schema(
description = "Thread priority (1-10)",
example = "5",
requiredMode = Schema.RequiredMode.REQUIRED
)
int priority();

@Schema(
description = "Thread state name (e.g. RUNNABLE, WAITING, TIMED_WAITING, BLOCKED)",
example = "RUNNABLE",
requiredMode = Schema.RequiredMode.REQUIRED
)
String state();

@Schema(
description = "Whether this thread is part of a detected deadlock cycle",
example = "false",
requiredMode = Schema.RequiredMode.REQUIRED
)
boolean deadlocked();

@Schema(
description = "Stack trace as a list of formatted frames",
requiredMode = Schema.RequiredMode.REQUIRED
)
List<String> stackTrace();

@Schema(
description = "Locked monitors held by this thread, formatted as 'ClassName at depth N'",
requiredMode = Schema.RequiredMode.REQUIRED
)
List<String> lockedMonitors();

@Schema(
description = "Locked ownable synchronizers held by this thread (LockInfo.toString())",
requiredMode = Schema.RequiredMode.REQUIRED
)
List<String> lockedSynchronizers();

@Schema(
description = "String form of the lock the thread is currently waiting on; null if none",
example = "java.util.concurrent.locks.ReentrantLock$NonfairSync@1a2b3c"
)
@Nullable
String lockInfo();

@Schema(
description = "Name of the thread that owns the lock this thread is waiting on; null if none",
example = "http-nio-8080-exec-7"
)
@Nullable
String lockOwnerName();

@Schema(
description = "Id of the thread that owns the lock this thread is waiting on; null if none",
example = "187"
)
@Nullable
Long lockOwnerId();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package com.dotcms.rest.api.v1.maintenance;

import com.dotcms.annotations.Nullable;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import io.swagger.v3.oas.annotations.media.Schema;
import java.util.List;
import org.immutables.value.Value;

/**
* Immutable view representing a full JVM thread dump.
*
* @author hassandotcms
*/
@Value.Style(typeImmutable = "*", typeAbstract = "Abstract*")
@Value.Immutable
@JsonSerialize(as = ThreadDumpView.class)
@JsonDeserialize(as = ThreadDumpView.class)
@Schema(description = "Full JVM thread dump with deadlock detection")
public interface AbstractThreadDumpView {

@Schema(
description = "Identifier of the cluster node that produced this dump",
example = "01HXX2J3K4M5N6P7Q8R9S0T1U2",
requiredMode = Schema.RequiredMode.REQUIRED
)
String serverId();

@Schema(
description = "Human-readable name of the cluster node, when configured",
example = "node-1"
)
@Nullable
String serverName();

@Schema(
description = "Wall-clock timestamp when the dump was captured",
example = "Thu Apr 03 10:30:00 UTC 2026",
requiredMode = Schema.RequiredMode.REQUIRED
)
String timestamp();

@Schema(
description = "JVM identification: vm name and runtime version",
example = "OpenJDK 64-Bit Server VM 21.0.2+13-58",
requiredMode = Schema.RequiredMode.REQUIRED
)
String vmInfo();

@Schema(
description = "Number of threads included in the response (after filtering)",
example = "42",
requiredMode = Schema.RequiredMode.REQUIRED
)
int threadCount();

@Schema(
description = "Total number of deadlocked threads detected JVM-wide",
example = "0",
requiredMode = Schema.RequiredMode.REQUIRED
)
int deadlockedCount();

@Schema(
description = "Per-thread descriptors",
requiredMode = Schema.RequiredMode.REQUIRED
)
List<ThreadDescriptorView> threads();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package com.dotcms.rest.api.v1.maintenance;

import com.dotcms.annotations.Nullable;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import io.swagger.v3.oas.annotations.media.Schema;
import org.immutables.value.Value;

/**
* Immutable view with lightweight JVM startup and thread-count information.
*
* @author hassandotcms
*/
@Value.Style(typeImmutable = "*", typeAbstract = "Abstract*")
@Value.Immutable
@JsonSerialize(as = ThreadSystemInfoView.class)
@JsonDeserialize(as = ThreadSystemInfoView.class)
@Schema(description = "JVM startup time and thread-count summary")
public interface AbstractThreadSystemInfoView {

@Schema(
description = "Identifier of the cluster node serving this request",
example = "01HXX2J3K4M5N6P7Q8R9S0T1U2",
requiredMode = Schema.RequiredMode.REQUIRED
)
String serverId();

@Schema(
description = "Human-readable name of the cluster node, when configured",
example = "node-1"
)
@Nullable
String serverName();

@Schema(
description = "JVM startup time formatted as 'dd MMM yyyy HH:mm:ss' (server local time)",
example = "03 Apr 2026 08:15:30",
requiredMode = Schema.RequiredMode.REQUIRED
)
String systemStartupTime();

@Schema(
description = "JVM startup time as epoch milliseconds",
example = "1775376930000",
requiredMode = Schema.RequiredMode.REQUIRED
)
long startTimeMillis();

@Schema(
description = "JVM uptime in milliseconds",
example = "7830000",
requiredMode = Schema.RequiredMode.REQUIRED
)
long uptimeMillis();

@Schema(
description = "Current live thread count (daemon and non-daemon)",
example = "187",
requiredMode = Schema.RequiredMode.REQUIRED
)
int currentThreadCount();

@Schema(
description = "Peak live thread count since the JVM started",
example = "245",
requiredMode = Schema.RequiredMode.REQUIRED
)
int peakThreadCount();
}
Loading
Loading