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

Conversation

mwangggg
Copy link
Member

@mwangggg mwangggg commented Sep 29, 2023

Welcome to Cryostat! 👋

Before contributing, make sure you have:

  • Read the contributing guidelines
  • Linked a relevant issue which this PR resolves
  • Linked any other relevant issues, PR's, or documentation, if any
  • Resolved all conflicts, if any
  • Rebased your branch PR on top of the latest upstream main branch
  • Attached at least one of the following labels to the PR: [chore, ci, docs, feat, fix, test]
  • Signed all commits using a GPG signature

To recreate commits with GPG signature git fetch upstream && git rebase --force --gpg-sign upstream/main


Fixes: #1452
Related to cryostatio/cryostat-web#1126
Depends on #1743 (for ease of review/verifying event message contents)

@mwangggg mwangggg added the feat New feature or request label Sep 29, 2023
@github-actions
Copy link
Contributor

Hi @mwangggg! Add at least one of the required labels to this PR

Required labels are : chore,ci,cleanup,docs,feat,fix,perf,refactor,style,test

Copy link
Member

@tthvo tthvo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! Tho, I am not sure if this solves #1452. There are other resources to look into:

'activeRecordings', // Done here
'archivedRecordings',
'eventTemplates',
'eventTypes',
'agentProbes',

References: https://github.com/cryostatio/cryostat-web/blob/86a8094c1947004fb1f625da7f517d071e2920d1/src/app/Topology/Entity/types.ts#L43

@mwangggg mwangggg changed the title feat(recordings): include jvmId in issueNotifications for recordings feat(recordings): include jvmId in Notifications to -web Oct 3, 2023
@mwangggg mwangggg requested a review from tthvo October 3, 2023 18:58
@mwangggg
Copy link
Member Author

mwangggg commented Oct 3, 2023

/request_review

@mergify mergify bot requested a review from a team October 3, 2023 20:09
@andrewazores
Copy link
Member

Looks like it makes sense, though I wonder if it's worth doing some refactoring at this point to extract a reusable utility method that looks something like notificationFactory.createOwnedResourceBuilder(targetId), which still returns a notification builder but pre-configured with the JSON content type, a message Map with the target and jvmId pre-populedand can have the owned resource appended, etc.

@mwangggg mwangggg force-pushed the 1452-target-include-jvmID branch 2 times, most recently from e4b8a21 to 6b575e5 Compare October 19, 2023 18:34
@mwangggg
Copy link
Member Author

/build_test

@mwangggg
Copy link
Member Author

@github-actions
Copy link
Contributor

ARCH IMAGE
amd64 ghcr.io/cryostatio/cryostat:pr-1689-6b575e5d17dfe3f8a87b0b16f81d85ef3d8a86bc-linux-amd64
arm64 ghcr.io/cryostatio/cryostat:pr-1689-6b575e5d17dfe3f8a87b0b16f81d85ef3d8a86bc-linux-arm64

To run smoketest:

# amd64          
CRYOSTAT_IMAGE=ghcr.io/cryostatio/cryostat:pr-1689-6b575e5d17dfe3f8a87b0b16f81d85ef3d8a86bc-linux-amd64 sh smoketest.sh

# or arm64
CRYOSTAT_IMAGE=ghcr.io/cryostatio/cryostat:pr-1689-6b575e5d17dfe3f8a87b0b16f81d85ef3d8a86bc-linux-arm64 sh smoketest.sh

@andrewazores
Copy link
Member

Rebase please

@andrewazores
Copy link
Member

/build_test

@mwangggg
Copy link
Member Author

@andrewazores
Copy link
Member

andrewazores commented Oct 19, 2023

Looks like it makes sense, though I wonder if it's worth doing some refactoring at this point to extract a reusable utility method that looks something like notificationFactory.createOwnedResourceBuilder(targetId), which still returns a notification builder but pre-configured with the JSON content type, a message Map with the target and jvmId pre-populedand can have the owned resource appended, etc.

Here's a rough and incomplete patch illustrating a bit more of this half-baked idea I presented before:

diff --git a/src/main/java/io/cryostat/messaging/notifications/Notification.java b/src/main/java/io/cryostat/messaging/notifications/Notification.java
index 44a4f6ea..a1d8981c 100644
--- a/src/main/java/io/cryostat/messaging/notifications/Notification.java
+++ b/src/main/java/io/cryostat/messaging/notifications/Notification.java
@@ -15,6 +15,9 @@
  */
 package io.cryostat.messaging.notifications;
 
+import java.util.HashMap;
+import java.util.Map;
+
 import io.cryostat.net.web.http.HttpMimeType;
 
 public class Notification<T> {
@@ -82,6 +85,27 @@ public class Notification<T> {
         }
     }
 
+    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;
diff --git a/src/main/java/io/cryostat/messaging/notifications/NotificationFactory.java b/src/main/java/io/cryostat/messaging/notifications/NotificationFactory.java
index 1167e17f..c929db2e 100644
--- a/src/main/java/io/cryostat/messaging/notifications/NotificationFactory.java
+++ b/src/main/java/io/cryostat/messaging/notifications/NotificationFactory.java
@@ -15,23 +15,35 @@
  */
 package io.cryostat.messaging.notifications;
 
-import io.cryostat.net.web.http.HttpMimeType;
+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 <T> Notification.Builder<T> createOwnedResourceBuilder(String notificationCategory) {
-        return new Notification.Builder<T>(source)
-                .metaType(HttpMimeType.JSON)
-                .metaCategory(notificationCategory);
+    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)
+                // FIXME the websocket notification system should only emit the targetId under one
+                // named key or the other, not both - are we already consistent with this?
+                .messageEntry("target", targetId)
+                .messageEntry("connectUrl", targetId)
+                .messageEntry("jvmId", jvmIdHelper.getJvmId(targetId));
     }
 }
diff --git a/src/main/java/io/cryostat/messaging/notifications/NotificationsModule.java b/src/main/java/io/cryostat/messaging/notifications/NotificationsModule.java
index 9777bfff..120f72c3 100644
--- a/src/main/java/io/cryostat/messaging/notifications/NotificationsModule.java
+++ b/src/main/java/io/cryostat/messaging/notifications/NotificationsModule.java
@@ -19,6 +19,8 @@ import java.util.Set;
 
 import javax.inject.Singleton;
 
+import io.cryostat.recordings.JvmIdHelper;
+
 import dagger.Lazy;
 import dagger.Module;
 import dagger.Provides;
@@ -34,7 +36,8 @@ public abstract class NotificationsModule {
 
     @Provides
     @Singleton
-    static NotificationFactory provideNotificationFactory(NotificationSource source) {
-        return new NotificationFactory(source);
+    static NotificationFactory provideNotificationFactory(
+            NotificationSource source, JvmIdHelper idHelper) {
+        return new NotificationFactory(source, idHelper);
     }
 }
diff --git a/src/main/java/io/cryostat/net/web/http/api/beta/RecordingsFromIdPostHandler.java b/src/main/java/io/cryostat/net/web/http/api/beta/RecordingsFromIdPostHandler.java
index 6bd995d3..87dd745a 100644
--- a/src/main/java/io/cryostat/net/web/http/api/beta/RecordingsFromIdPostHandler.java
+++ b/src/main/java/io/cryostat/net/web/http/api/beta/RecordingsFromIdPostHandler.java
@@ -47,6 +47,7 @@ import io.cryostat.net.web.http.api.ApiVersion;
 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;
@@ -274,35 +275,30 @@ public class RecordingsFromIdPostHandler extends AbstractAuthenticatedRequestHan
                                     try {
 
                                         notificationFactory
-                                                .createOwnedResourceBuilder(NOTIFICATION_CATEGORY)
-                                                .message(
-                                                        Map.of(
-                                                                "recording",
-                                                                new ArchivedRecordingInfo(
-                                                                        connectUrl,
-                                                                        fsName,
-                                                                        webServer
-                                                                                .get()
-                                                                                .getArchivedDownloadURL(
-                                                                                        connectUrl,
-                                                                                        fsName),
-                                                                        webServer
-                                                                                .get()
-                                                                                .getArchivedReportURL(
-                                                                                        connectUrl,
-                                                                                        fsName),
-                                                                        metadata,
-                                                                        size,
-                                                                        archivedTime),
-                                                                "target",
+                                                .createOwnedResourceBuilder(
+                                                        connectUrl, NOTIFICATION_CATEGORY)
+                                                .messageEntry(
+                                                        "recording",
+                                                        new ArchivedRecordingInfo(
                                                                 connectUrl,
-                                                                "jvmId",
-                                                                jvmId))
+                                                                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);
                                     }

WDYT? This is just meant to make it a little easier to pass the right data in and get the expected notification emitted, or rather to make it a little harder to forget to include things.

@mwangggg
Copy link
Member Author

looks good! I'll try it out

@mwangggg
Copy link
Member Author

/build_test

@mwangggg
Copy link
Member Author

@mwangggg
Copy link
Member Author

/build_test

@mwangggg
Copy link
Member Author

@github-actions
Copy link
Contributor

ARCH IMAGE
amd64 ghcr.io/cryostatio/cryostat:pr-1689-3c391a4490ae5b30041b3bf88fb62fb4b4fad1db-linux-amd64
arm64 ghcr.io/cryostatio/cryostat:pr-1689-3c391a4490ae5b30041b3bf88fb62fb4b4fad1db-linux-arm64

To run smoketest:

# amd64          
CRYOSTAT_IMAGE=ghcr.io/cryostatio/cryostat:pr-1689-3c391a4490ae5b30041b3bf88fb62fb4b4fad1db-linux-amd64 sh smoketest.sh

# or arm64
CRYOSTAT_IMAGE=ghcr.io/cryostatio/cryostat:pr-1689-3c391a4490ae5b30041b3bf88fb62fb4b4fad1db-linux-arm64 sh smoketest.sh

@github-actions
Copy link
Contributor

This PR/issue depends on:

@andrewazores
Copy link
Member

Rebase please

@mwangggg mwangggg force-pushed the 1452-target-include-jvmID branch 3 times, most recently from 8768645 to 58e9fa4 Compare October 30, 2023 15:26
@andrewazores andrewazores merged commit 3202849 into cryostatio:main Oct 30, 2023
10 checks passed
mergify bot pushed a commit that referenced this pull request Oct 30, 2023
andrewazores pushed a commit that referenced this pull request Oct 30, 2023
(cherry picked from commit 3202849)

Co-authored-by: Ming Yu Wang <90855268+mwangggg@users.noreply.github.com>
@mwangggg mwangggg deleted the 1452-target-include-jvmID branch March 12, 2024 15:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backport feat New feature or request safe-to-test
Projects
No open projects
Status: Done
Development

Successfully merging this pull request may close these issues.

[Request] Target owned resource update event should include JvmID
3 participants