Skip to content

Commit bca429f

Browse files
authored
feat(diagnostics): ThreadDump deletion notification (#1042)
1 parent 103d660 commit bca429f

File tree

2 files changed

+76
-20
lines changed

2 files changed

+76
-20
lines changed

src/main/java/io/cryostat/diagnostic/DiagnosticsHelper.java

Lines changed: 51 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
import io.cryostat.libcryostat.sys.Clock;
2929
import io.cryostat.targets.Target;
3030
import io.cryostat.targets.TargetConnectionManager;
31+
import io.cryostat.ws.MessagingServer;
32+
import io.cryostat.ws.Notification;
3133

3234
import io.quarkus.runtime.StartupEvent;
3335
import io.smallrye.common.annotation.Identifier;
@@ -52,6 +54,12 @@
5254
@ApplicationScoped
5355
public class DiagnosticsHelper {
5456

57+
static final String THREAD_DUMP_DELETED = "ThreadDumpDeleted";
58+
static final String THREAD_DUMP_REQUESTED = "ThreadDumpRequested";
59+
static final String DUMP_THREADS = "threadPrint";
60+
static final String DUMP_THREADS_TO_FIlE = "threadDumpToFile";
61+
private static final String DIAGNOSTIC_BEAN_NAME = "com.sun.management:type=DiagnosticCommand";
62+
5563
@ConfigProperty(name = ConfigProperties.AWS_BUCKET_NAME_THREAD_DUMPS)
5664
String bucket;
5765

@@ -63,12 +71,6 @@ public class DiagnosticsHelper {
6371
@Inject Logger log;
6472
@Inject Clock clock;
6573

66-
static final String DUMP_THREADS = "threadPrint";
67-
static final String DUMP_THREADS_TO_FIlE = "threadDumpToFile";
68-
private static final String DIAGNOSTIC_BEAN_NAME = "com.sun.management:type=DiagnosticCommand";
69-
static final String THREAD_DUMP_REQUESTED = "ThreadDumpRequested";
70-
static final String THREAD_DUMP_DELETED = "ThreadDumpDeleted";
71-
7274
@Inject EventBus bus;
7375
@Inject TargetConnectionManager targetConnectionManager;
7476
@Inject StorageBuckets buckets;
@@ -99,14 +101,21 @@ public ThreadDump dumpThreads(Target target, String format) {
99101
String.class)));
100102
}
101103

102-
public void deleteThreadDump(Target target, String threadDumpID) {
104+
public void deleteThreadDump(Target target, String threadDumpId) {
103105
if (Objects.isNull(target.jvmId)) {
104106
log.errorv("TargetId {0} failed to resolve to a jvmId", target.id);
105107
throw new IllegalArgumentException();
106108
} else {
107-
String key = threadDumpKey(target.jvmId, threadDumpID);
109+
String key = threadDumpKey(target.jvmId, threadDumpId);
108110
storage.headObject(HeadObjectRequest.builder().bucket(bucket).key(key).build());
109111
storage.deleteObject(DeleteObjectRequest.builder().bucket(bucket).key(key).build());
112+
var event =
113+
new ThreadDumpEvent(
114+
EventCategory.DELETED,
115+
ThreadDumpEvent.Payload.of(target, threadDumpId));
116+
bus.publish(
117+
MessagingServer.class.getName(),
118+
new Notification(event.category().category(), event.payload()));
110119
}
111120
}
112121

@@ -204,4 +213,38 @@ public List<S3Object> listThreadDumps(Target target) {
204213
var req = ListObjectsV2Request.builder().bucket(bucket).prefix(jvmId).build();
205214
return storage.listObjectsV2(req).contents();
206215
}
216+
217+
public enum EventCategory {
218+
// ThreadDumpSuccess ("CREATED") events are emitted by LongRunningRequestGenerator
219+
DELETED(THREAD_DUMP_DELETED),
220+
;
221+
222+
private final String category;
223+
224+
private EventCategory(String category) {
225+
this.category = category;
226+
}
227+
228+
public String category() {
229+
return category;
230+
}
231+
}
232+
233+
public record ThreadDumpEvent(EventCategory category, Payload payload) {
234+
public ThreadDumpEvent {
235+
Objects.requireNonNull(category);
236+
Objects.requireNonNull(payload);
237+
}
238+
239+
public record Payload(String jvmId, String threadDumpId) {
240+
public Payload {
241+
Objects.requireNonNull(jvmId);
242+
Objects.requireNonNull(threadDumpId);
243+
}
244+
245+
public static Payload of(Target target, String threadDumpId) {
246+
return new Payload(target.jvmId, threadDumpId);
247+
}
248+
}
249+
}
207250
}

src/test/java/io/cryostat/diagnostics/ThreadDumpsTest.java

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -245,18 +245,31 @@ public void testCreateAndDelete()
245245

246246
var threadDumpId = listResponseJson.getString("[0].threadDumpId");
247247

248-
given().log()
249-
.all()
250-
.when()
251-
.pathParam("targetId", id)
252-
.pathParam("threadDumpId", threadDumpId)
253-
.delete("targets/{targetId}/threaddump/{threadDumpId}")
254-
.then()
255-
.log()
256-
.all()
257-
.and()
258-
.assertThat()
259-
.statusCode(204);
248+
Executors.newSingleThreadScheduledExecutor()
249+
.schedule(
250+
() -> {
251+
given().log()
252+
.all()
253+
.when()
254+
.pathParam("targetId", id)
255+
.pathParam("threadDumpId", threadDumpId)
256+
.delete("targets/{targetId}/threaddump/{threadDumpId}")
257+
.then()
258+
.log()
259+
.all()
260+
.and()
261+
.assertThat()
262+
.statusCode(204);
263+
},
264+
1,
265+
TimeUnit.SECONDS);
266+
267+
expectWebSocketNotification(
268+
"ThreadDumpDeleted",
269+
json ->
270+
Objects.equals(
271+
json.getJsonObject("message").getString("threadDumpId"),
272+
threadDumpId));
260273
}
261274

262275
@Test

0 commit comments

Comments
 (0)