diff --git a/src/main/java/io/cryostat/net/AgentClient.java b/src/main/java/io/cryostat/net/AgentClient.java index beed6a8b99..c3eef512cd 100644 --- a/src/main/java/io/cryostat/net/AgentClient.java +++ b/src/main/java/io/cryostat/net/AgentClient.java @@ -101,7 +101,7 @@ Future ping() { Future mbeanMetrics() { Future> f = - invoke(HttpMethod.GET, "/mbean-metrics", BodyCodec.string()); + invoke(HttpMethod.GET, "/mbean-metrics/", BodyCodec.string()); return f.map(HttpResponse::body) // uses Gson rather than Vertx's Jackson because Gson is able to handle MBeanMetrics // with no additional fuss. Jackson complains about private final fields. @@ -112,7 +112,7 @@ Future startRecording(StartRecordingRequest req) { Future> f = invoke( HttpMethod.POST, - "/recordings", + "/recordings/", Buffer.buffer(gson.toJson(req)), BodyCodec.string()); return f.map( @@ -130,8 +130,48 @@ Future startRecording(StartRecordingRequest req) { }); } + Future stopRecording(long id) { + Future> f = + invoke( + HttpMethod.PATCH, + String.format("/recordings/%d", id), + Buffer.buffer(), + BodyCodec.none()); + return f.map( + resp -> { + int statusCode = resp.statusCode(); + if (HttpStatusCodeIdentifier.isSuccessCode(statusCode)) { + return null; + } else if (statusCode == 403) { + throw new UnsupportedOperationException(); + } else { + throw new RuntimeException("Unknown failure"); + } + }); + } + + Future deleteRecording(long id) { + Future> f = + invoke( + HttpMethod.DELETE, + String.format("/recordings/%d", id), + Buffer.buffer(), + BodyCodec.none()); + return f.map( + resp -> { + int statusCode = resp.statusCode(); + if (HttpStatusCodeIdentifier.isSuccessCode(statusCode)) { + return null; + } else if (statusCode == 403) { + throw new UnsupportedOperationException(); + } else { + throw new RuntimeException("Unknown failure"); + } + }); + } + Future> activeRecordings() { - Future> f = invoke(HttpMethod.GET, "/recordings", BodyCodec.string()); + Future> f = invoke(HttpMethod.GET, "/recordings/", BodyCodec.string()); return f.map(HttpResponse::body) .map( s -> @@ -146,14 +186,14 @@ Future> activeRecordings() { Future> eventTypes() { Future> f = - invoke(HttpMethod.GET, "/event-types", BodyCodec.jsonArray()); + invoke(HttpMethod.GET, "/event-types/", BodyCodec.jsonArray()); return f.map(HttpResponse::body) .map(arr -> arr.stream().map(o -> new AgentEventTypeInfo((JsonObject) o)).toList()); } Future> eventSettings() { Future> f = - invoke(HttpMethod.GET, "/event-settings", BodyCodec.jsonArray()); + invoke(HttpMethod.GET, "/event-settings/", BodyCodec.jsonArray()); return f.map(HttpResponse::body) .map( arr -> { @@ -207,7 +247,7 @@ Future> eventSettings() { Future> eventTemplates() { Future> f = - invoke(HttpMethod.GET, "/event-templates", BodyCodec.jsonArray()); + invoke(HttpMethod.GET, "/event-templates/", BodyCodec.jsonArray()); return f.map(HttpResponse::body).map(arr -> arr.stream().map(Object::toString).toList()); } diff --git a/src/main/java/io/cryostat/net/AgentJFRService.java b/src/main/java/io/cryostat/net/AgentJFRService.java index aaa791e5ab..9345f2c719 100644 --- a/src/main/java/io/cryostat/net/AgentJFRService.java +++ b/src/main/java/io/cryostat/net/AgentJFRService.java @@ -82,7 +82,14 @@ public String getVersion() { @Override public void close(IRecordingDescriptor descriptor) throws FlightRecorderException { - throw new UnimplementedException(); + try { + client.deleteRecording(descriptor.getId()) + .toCompletionStage() + .toCompletableFuture() + .get(); + } catch (InterruptedException | ExecutionException e) { + throw new FlightRecorderException("Failed to stop recording", e); + } } @Override @@ -205,8 +212,15 @@ public IRecordingDescriptor start( } @Override - public void stop(IRecordingDescriptor arg0) throws FlightRecorderException { - throw new UnimplementedException(); + public void stop(IRecordingDescriptor descriptor) throws FlightRecorderException { + try { + client.stopRecording(descriptor.getId()) + .toCompletionStage() + .toCompletableFuture() + .get(); + } catch (InterruptedException | ExecutionException e) { + throw new FlightRecorderException("Failed to stop recording", e); + } } @Override