Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(recordings): include jvmId in Notifications to -web #1689

Merged
merged 8 commits into from
Oct 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
*/
package io.cryostat.messaging.notifications;

import java.time.Instant;
import java.util.HashMap;
import java.util.Map;

import io.cryostat.net.web.http.HttpMimeType;

Expand Down Expand Up @@ -84,10 +85,30 @@ public Notification<T> build() {
}
}

public static class OwnedResourceBuilder extends Builder<Map<String, Object>> {

private final Map<String, Object> map = new HashMap<>();

OwnedResourceBuilder(NotificationSource source, String category) {
super(source);
metaType(HttpMimeType.JSON);
metaCategory(category);
message(map);
}

public OwnedResourceBuilder messageEntry(String key, Object value) {
if (value == null) {
this.map.remove(key);
} else {
this.map.put(key, value);
}
return this;
}
}

public static class Meta {
private final String category;
private final MetaType type;
private final long serverTime = Instant.now().getEpochSecond();
andrewazores marked this conversation as resolved.
Show resolved Hide resolved

public Meta(String category, MetaType type) {
this.category = category;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,32 @@
*/
package io.cryostat.messaging.notifications;

import io.cryostat.recordings.JvmIdHelper;
import io.cryostat.recordings.JvmIdHelper.JvmIdGetException;

public class NotificationFactory {

private final NotificationSource source;
private final JvmIdHelper jvmIdHelper;

NotificationFactory(NotificationSource source) {
NotificationFactory(NotificationSource source, JvmIdHelper jvmIdHelper) {
this.source = source;
this.jvmIdHelper = jvmIdHelper;
}

public <T> Notification.Builder<T> createBuilder() {
return new Notification.Builder<T>(source);
}

public Notification.OwnedResourceBuilder createOwnedResourceBuilder(
String notificationCategory) {
return new Notification.OwnedResourceBuilder(source, notificationCategory);
}

public Notification.OwnedResourceBuilder createOwnedResourceBuilder(
String targetId, String notificationCategory) throws JvmIdGetException {
return new Notification.OwnedResourceBuilder(source, notificationCategory)
.messageEntry("target", targetId)
.messageEntry("jvmId", jvmIdHelper.getJvmId(targetId));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@

import javax.inject.Singleton;

import io.cryostat.recordings.JvmIdHelper;

import dagger.Lazy;
import dagger.Module;
import dagger.Provides;
Expand All @@ -34,7 +36,8 @@ static NotificationSource provideNotificationSource(Lazy<Set<NotificationListene

@Provides
@Singleton
static NotificationFactory provideNotificationFactory(NotificationSource source) {
return new NotificationFactory(source);
static NotificationFactory provideNotificationFactory(
NotificationSource source, JvmIdHelper idHelper) {
return new NotificationFactory(source, idHelper);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -84,22 +84,22 @@ Path copyRecordingToFile(
if (!Objects.equals(rec.getName(), recordingName)) {
continue;
}
try (OutputStream out = new BufferedOutputStream(new FileOutputStream(path.toFile()))) {
try (conn;
InputStream in = conn.getService().openStream(rec, false)) {
byte[] buff = new byte[READ_BUFFER_SIZE];
int n = 0;
while ((n = in.read(buff)) != -1) {
out.write(buff, 0, n);
if (!targetConnectionManager.markConnectionInUse(cd)) {
throw new IOException(
"Target connection unexpectedly closed while streaming"
+ " recording");
}
try (conn;
OutputStream out =
new BufferedOutputStream(new FileOutputStream(path.toFile()));
InputStream in = conn.getService().openStream(rec, false)) {
byte[] buff = new byte[READ_BUFFER_SIZE];
int n = 0;
while ((n = in.read(buff)) != -1) {
out.write(buff, 0, n);
if (!targetConnectionManager.markConnectionInUse(cd)) {
throw new IOException(
"Target connection unexpectedly closed while streaming"
+ " recording");
}
out.flush();
return path;
}
out.flush();
return path;
}
}
throw new RecordingNotFoundException(cd.getTargetId(), recordingName);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
import io.cryostat.net.web.http.api.v2.ApiException;
import io.cryostat.recordings.JvmIdHelper;
import io.cryostat.recordings.JvmIdHelper.JvmIdDoesNotExistException;
import io.cryostat.recordings.JvmIdHelper.JvmIdGetException;
import io.cryostat.recordings.RecordingArchiveHelper;
import io.cryostat.recordings.RecordingMetadataManager;
import io.cryostat.recordings.RecordingMetadataManager.Metadata;
Expand Down Expand Up @@ -274,35 +275,30 @@ public void handleAuthenticated(RoutingContext ctx) throws Exception {
try {

notificationFactory
.createBuilder()
.metaCategory(NOTIFICATION_CATEGORY)
.metaType(HttpMimeType.JSON)
.message(
Map.of(
"recording",
new ArchivedRecordingInfo(
connectUrl,
fsName,
webServer
.get()
.getArchivedDownloadURL(
connectUrl,
fsName),
webServer
.get()
.getArchivedReportURL(
connectUrl,
fsName),
metadata,
size,
archivedTime),
"target",
connectUrl))
.createOwnedResourceBuilder(
connectUrl, NOTIFICATION_CATEGORY)
.messageEntry(
"recording",
new ArchivedRecordingInfo(
connectUrl,
fsName,
webServer
.get()
.getArchivedDownloadURL(
connectUrl, fsName),
webServer
.get()
.getArchivedReportURL(
connectUrl, fsName),
metadata,
size,
archivedTime))
.build()
.send();
} catch (URISyntaxException
| UnknownHostException
| SocketException e) {
| SocketException
| JvmIdGetException e) {
logger.error(e);
throw new ApiException(500, e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@
import io.cryostat.net.security.ResourceAction;
import io.cryostat.net.web.http.HttpMimeType;
import io.cryostat.net.web.http.api.ApiVersion;
import io.cryostat.recordings.JvmIdHelper;
import io.cryostat.recordings.JvmIdHelper.JvmIdGetException;

import com.google.gson.Gson;
import io.vertx.core.http.HttpMethod;
Expand Down Expand Up @@ -76,6 +78,7 @@ class TargetProbePostHandler extends AbstractV2RequestHandler<Void> {
private final NotificationFactory notificationFactory;
private final LocalProbeTemplateService probeTemplateService;
private final FileSystem fs;
private final JvmIdHelper jvmIdHelper;
private final TargetConnectionManager connectionManager;
private final Environment env;
private static final String NOTIFICATION_CATEGORY = "ProbeTemplateApplied";
Expand All @@ -88,13 +91,15 @@ class TargetProbePostHandler extends AbstractV2RequestHandler<Void> {
FileSystem fs,
AuthManager auth,
CredentialsManager credentialsManager,
JvmIdHelper jvmIdHelper,
TargetConnectionManager connectionManager,
Environment env,
Gson gson) {
super(auth, credentialsManager, gson);
this.logger = logger;
this.notificationFactory = notificationFactory;
this.probeTemplateService = service;
this.jvmIdHelper = jvmIdHelper;
this.connectionManager = connectionManager;
this.env = env;
this.fs = fs;
Expand Down Expand Up @@ -151,20 +156,17 @@ public IntermediateResponse<Void> handle(RequestParameters requestParams) throws
new ByteArrayInputStream(
templateContent.getBytes(StandardCharsets.UTF_8)));
List<Event> events = Arrays.asList(template.getEvents());
notificationFactory
.createBuilder()
.metaCategory(NOTIFICATION_CATEGORY)
.metaType(HttpMimeType.JSON)
.message(
Map.of(
"targetId",
targetId,
"probeTemplate",
probeTemplate,
"events",
events))
.build()
.send();
try {
notificationFactory
.createOwnedResourceBuilder(targetId, NOTIFICATION_CATEGORY)
.messageEntry("probeTemplate", probeTemplate)
.messageEntry("events", events)
.build()
.send();
} catch (JvmIdGetException e) {
logger.info("Retain null jvmId for target [{}]", targetId);
logger.info(e);
}
return new IntermediateResponse<Void>().body(null);
});
}
Expand Down
38 changes: 10 additions & 28 deletions src/main/java/io/cryostat/recordings/RecordingArchiveHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CancellationException;
Expand Down Expand Up @@ -66,7 +65,6 @@
import io.cryostat.net.TargetConnectionManager;
import io.cryostat.net.web.WebModule;
import io.cryostat.net.web.WebServer;
import io.cryostat.net.web.http.HttpMimeType;
import io.cryostat.net.web.http.api.v2.ApiException;
import io.cryostat.platform.PlatformClient;
import io.cryostat.recordings.JvmIdHelper.JvmIdGetException;
Expand Down Expand Up @@ -385,36 +383,24 @@ public Future<ArchivedRecordingInfo> saveRecording(
validateSavePath(recordingName, savePath);
Path filenamePath = savePath.getFileName();
String filename = filenamePath.toString();
String targetId = connectionDescriptor.getTargetId();
Metadata metadata =
recordingMetadataManager
.copyMetadataToArchives(connectionDescriptor, recordingName, filename)
.get();
ArchivedRecordingInfo archivedRecordingInfo =
new ArchivedRecordingInfo(
connectionDescriptor.getTargetId(),
targetId,
filename,
webServerProvider
.get()
.getArchivedDownloadURL(
connectionDescriptor.getTargetId(), filename),
webServerProvider
.get()
.getArchivedReportURL(
connectionDescriptor.getTargetId(), filename),
webServerProvider.get().getArchivedDownloadURL(targetId, filename),
webServerProvider.get().getArchivedReportURL(targetId, filename),
metadata,
getFileSize(filename),
getArchivedTime(filename));
future.complete(archivedRecordingInfo);
notificationFactory
.createBuilder()
.metaCategory(SAVE_NOTIFICATION_CATEGORY)
.metaType(HttpMimeType.JSON)
.message(
Map.of(
"recording",
archivedRecordingInfo,
"target",
connectionDescriptor.getTargetId()))
.createOwnedResourceBuilder(targetId, SAVE_NOTIFICATION_CATEGORY)
.messageEntry("recording", archivedRecordingInfo)
.build()
.send();
} catch (Exception e) {
Expand Down Expand Up @@ -451,10 +437,8 @@ public Future<ArchivedRecordingInfo> deleteRecordingFromPath(
getFileSize(filename),
getArchivedTime(filename));
notificationFactory
.createBuilder()
.metaCategory(DELETE_NOTIFICATION_CATEGORY)
.metaType(HttpMimeType.JSON)
.message(Map.of("recording", archivedRecordingInfo, "target", targetId))
.createOwnedResourceBuilder(targetId, DELETE_NOTIFICATION_CATEGORY)
.messageEntry("recording", archivedRecordingInfo)
.build()
.send();
fs.deleteIfExists(recordingPath);
Expand Down Expand Up @@ -515,10 +499,8 @@ private CompletableFuture<ArchivedRecordingInfo> handleDeleteRecordingRequest(
getFileSize(filename),
getArchivedTime(filename));
notificationFactory
.createBuilder()
.metaCategory(DELETE_NOTIFICATION_CATEGORY)
.metaType(HttpMimeType.JSON)
.message(Map.of("recording", archivedRecordingInfo, "target", targetId))
.createOwnedResourceBuilder(targetId, DELETE_NOTIFICATION_CATEGORY)
.messageEntry("recording", archivedRecordingInfo)
.build()
.send();
checkEmptySubdirectory(parentPath);
Expand Down
30 changes: 7 additions & 23 deletions src/main/java/io/cryostat/recordings/RecordingMetadataManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@
import io.cryostat.messaging.notifications.NotificationFactory;
import io.cryostat.net.ConnectionDescriptor;
import io.cryostat.net.TargetConnectionManager;
import io.cryostat.net.web.http.HttpMimeType;
import io.cryostat.platform.PlatformClient;
import io.cryostat.platform.ServiceRef;
import io.cryostat.platform.TargetDiscoveryEvent;
Expand Down Expand Up @@ -514,17 +513,9 @@ public Future<Metadata> setRecordingMetadataFromPath(
StandardOpenOption.TRUNCATE_EXISTING);

notificationFactory
.createBuilder()
.metaCategory(RecordingMetadataManager.NOTIFICATION_CATEGORY)
.metaType(HttpMimeType.JSON)
.message(
Map.of(
"recordingName",
recordingName,
"target",
connectUrl,
"metadata",
metadata))
.createOwnedResourceBuilder(connectUrl, NOTIFICATION_CATEGORY)
.messageEntry("recordingName", recordingName)
.messageEntry("metadata", metadata)
.build()
.send();

Expand Down Expand Up @@ -557,17 +548,10 @@ public Future<Metadata> setRecordingMetadata(

if (issueNotification) {
notificationFactory
.createBuilder()
.metaCategory(RecordingMetadataManager.NOTIFICATION_CATEGORY)
.metaType(HttpMimeType.JSON)
.message(
Map.of(
"recordingName",
recordingName,
"target",
connectionDescriptor.getTargetId(),
"metadata",
metadata))
.createOwnedResourceBuilder(
connectionDescriptor.getTargetId(), NOTIFICATION_CATEGORY)
.messageEntry("recordingName", recordingName)
.messageEntry("metadata", metadata)
.build()
.send();
}
Expand Down
Loading
Loading