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

fix(graphql): adjust GraphQL queries and models for updated server schema #1222

Merged
merged 68 commits into from
Apr 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
68 commits
Select commit Hold shift + click to select a range
a2a8815
chore(mbeans): adjust MBeanMetrics GraphQL query for updated schema (…
andrewazores Mar 1, 2024
c6eacbe
correct tests
andrewazores Mar 1, 2024
c29d250
fixup! correct tests
andrewazores Mar 1, 2024
817e32d
fix(graphql): adjustments for Dashboard Automated Analysis with new A…
andrewazores Mar 4, 2024
885487b
fix(archives): adjust queries and response handling for updated data …
andrewazores Mar 4, 2024
811bd99
fix(topology): update for new GraphQL schema
andrewazores Mar 4, 2024
cae8d54
adjust queries to avoid 'recordings' struct field and use new direct …
andrewazores Mar 7, 2024
95e18cb
use new filter input type name
andrewazores Mar 7, 2024
08aca67
indentation
andrewazores Mar 11, 2024
4de7511
update fake graphql query response format
andrewazores Mar 11, 2024
4bbda01
use dynamic mock timestamp
andrewazores Mar 11, 2024
387edd6
apply formatting
andrewazores Mar 11, 2024
daa01bc
schema adjustments for Mirage preview
andrewazores Mar 11, 2024
3849ab4
fixup
andrewazores Mar 11, 2024
f122a6e
indentation
andrewazores Mar 11, 2024
1f5f62d
test fixup
andrewazores Mar 11, 2024
87d8e3b
chore(mbeans): adjust MBeanMetrics GraphQL query for updated schema (…
andrewazores Mar 1, 2024
59a1b93
correct tests
andrewazores Mar 1, 2024
387b39e
fixup! correct tests
andrewazores Mar 1, 2024
7507dc1
fix(graphql): adjustments for Dashboard Automated Analysis with new A…
andrewazores Mar 4, 2024
b9977b9
fix(archives): adjust queries and response handling for updated data …
andrewazores Mar 4, 2024
dcc22a5
fix(topology): update for new GraphQL schema (#1224)
andrewazores Mar 15, 2024
f672769
cleanup
aali309 Mar 15, 2024
2b24efd
update for archive
aali309 Mar 26, 2024
e98cd4b
update ArchivedRecordingsTable
aali309 Mar 27, 2024
cf85cd5
squash
aali309 Mar 27, 2024
bd19700
logs to see filtered recordings and labels
aali309 Apr 1, 2024
4b3ff57
filter by label completed && cleanup
aali309 Apr 3, 2024
7b33d12
fixup delete archive recordings
aali309 Apr 3, 2024
402cca3
proper path
aali309 Apr 3, 2024
ebe5a84
cleanup
aali309 Apr 3, 2024
3d5ddd8
resolve issues
aali309 Apr 3, 2024
85d6499
get labels displayed on query
aali309 Apr 4, 2024
9ec94ef
log event
aali309 Apr 4, 2024
23e7bd3
Merge branch 'cryostat3-graphql' into grapql-updateMetadata2
aali309 Apr 5, 2024
aa5547c
optional chaining to access archiveCount
aali309 Apr 8, 2024
0c0c76e
reset
aali309 Apr 8, 2024
751bd73
access target recording name to update count
aali309 Apr 8, 2024
260a465
reset2
aali309 Apr 8, 2024
5a02d19
add metadata update to AllTargetArchivedRecordingsTable
aali309 Apr 8, 2024
efc25ca
add right path
aali309 Apr 8, 2024
1c522bd
add [] if recordings empty
aali309 Apr 8, 2024
c87f35a
log all archives
aali309 Apr 8, 2024
dd05fdd
annd [] on setArchivedForTargets
aali309 Apr 8, 2024
552ed31
define archiveRecording
aali309 Apr 8, 2024
2931736
diff logic
aali309 Apr 8, 2024
8966e92
diff logic2
aali309 Apr 8, 2024
f820fba
reset from scratch
aali309 Apr 8, 2024
e0c32ba
reset from scratch2
aali309 Apr 9, 2024
5510ed1
reset from scratch3
aali309 Apr 9, 2024
0a0a65b
reset from scratch4
aali309 Apr 9, 2024
c72e968
reset from scratch5
aali309 Apr 9, 2024
ce2456d
fix table update bug
andrewazores Apr 9, 2024
9abb0e2
use jvmId to handle nonunique connection URL collisions
andrewazores Apr 9, 2024
ab3aabc
object identity react bugfix
andrewazores Apr 9, 2024
aea7485
uploaded table updated && cleanup
aali309 Apr 13, 2024
2dd37b3
yarn format
aali309 Apr 13, 2024
6472704
lint fixes
andrewazores Apr 13, 2024
9613133
chore(mbeans): adjust MBeanMetrics GraphQL query for updated schema (…
andrewazores Mar 1, 2024
6f4bdd1
correct tests
andrewazores Mar 1, 2024
cd4bf5a
fixup! correct tests
andrewazores Mar 1, 2024
4acf4a3
fix(graphql): adjustments for Dashboard Automated Analysis with new A…
andrewazores Mar 4, 2024
9c1a626
fix(archives): adjust queries and response handling for updated data …
andrewazores Mar 4, 2024
8aec3ac
fix(topology): update for new GraphQL schema (#1224)
andrewazores Mar 15, 2024
2ed2ce8
Merge branch 'grapql-updateMetadata2' into cryostat3-graphql
andrewazores Apr 13, 2024
704861e
Merge remote-tracking branch 'atali/grapql-updateMetadata2' into cryo…
andrewazores Apr 13, 2024
156dfd6
fix(test): fix broken test related to GraphQL (#1242)
aali309 Apr 18, 2024
66848cb
Merge branch 'main' into cryostat3-graphql
andrewazores Apr 18, 2024
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
29 changes: 19 additions & 10 deletions src/app/Archives/AllArchivedRecordingsTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -169,19 +169,28 @@ export const AllArchivedRecordingsTable: React.FC<AllArchivedRecordingsTableProp

React.useEffect(() => {
addSubscription(
context.notificationChannel.messages(NotificationCategory.RecordingMetadataUpdated).subscribe(() => {
refreshDirectoriesAndCounts();
}),
);
}, [addSubscription, context.notificationChannel, refreshDirectoriesAndCounts]);
context.notificationChannel.messages(NotificationCategory.RecordingMetadataUpdated).subscribe((event) => {
const updatedRecordingInfo = event.message;

React.useEffect(() => {
addSubscription(
context.notificationChannel.messages(NotificationCategory.ActiveRecordingSaved).subscribe(() => {
refreshDirectoriesAndCounts();
setDirectories((currentDirectories) => {
const newDirectories = currentDirectories.map((directory) => ({
...directory,
recordings: directory.recordings.map((recording) => {
if (recording.name === updatedRecordingInfo.recording.name) {
return {
...recording,
metadata: { ...recording.metadata, labels: updatedRecordingInfo?.recording?.metadata?.labels },
};
}
return recording;
}),
}));

return newDirectories;
});
}),
);
}, [addSubscription, context.notificationChannel, refreshDirectoriesAndCounts]);
}, [addSubscription, context.notificationChannel, setDirectories]);

React.useEffect(() => {
addSubscription(
Expand Down
176 changes: 117 additions & 59 deletions src/app/Archives/AllTargetsArchivedRecordingsTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import { ErrorView } from '@app/ErrorView/ErrorView';
import { authFailMessage, isAuthFail } from '@app/ErrorView/types';
import { ArchivedRecordingsTable } from '@app/Recordings/ArchivedRecordingsTable';
import { LoadingView } from '@app/Shared/Components/LoadingView';
import { Target, TargetDiscoveryEvent, NotificationCategory } from '@app/Shared/Services/api.types';
import { Target, TargetDiscoveryEvent, NotificationCategory, Metadata } from '@app/Shared/Services/api.types';
import { isEqualTarget, indexOfTarget, includesTarget } from '@app/Shared/Services/api.utils';
import { ServiceContext } from '@app/Shared/Services/Services';
import { useSort } from '@app/utils/hooks/useSort';
Expand Down Expand Up @@ -70,10 +70,21 @@ const tableColumns: TableColumn[] = [
},
];

interface ArchivedRecording {
jvmId?: string;
name: string;
downloadUrl: string;
reportUrl: string;
metadata: Metadata;
size: number;
archivedTime: number;
}

type ArchivesForTarget = {
target: Target;
targetAsObs: Observable<Target>;
archiveCount: number;
recordings: ArchivedRecording[];
};

export interface AllTargetsArchivedRecordingsTableProps {}
Expand All @@ -89,16 +100,26 @@ export const AllTargetsArchivedRecordingsTable: React.FC<AllTargetsArchivedRecor
const addSubscription = useSubscriptions();
const [sortBy, getSortParams] = useSort();

const updateCount = React.useCallback(
(connectUrl: string, delta: number) => {
const handleNotification = React.useCallback(
(_: string, recording: ArchivedRecording, delta: number) => {
setArchivesForTargets((old) => {
const idx = old.findIndex(({ target }) => target.connectUrl === connectUrl);
if (idx >= 0) {
const matched = old[idx];
old.splice(idx, 1, { ...matched, archiveCount: matched.archiveCount + delta });
return [...old];
const matchingTargets = old.filter(({ target }) => {
return target.jvmId === recording.jvmId;
});
for (const matchedTarget of matchingTargets) {
const targetIdx = old.findIndex(({ target }) => target.connectUrl === matchedTarget.target.connectUrl);
const recordings = [...matchedTarget.recordings];
if (delta === 1) {
recordings.push(recording);
} else {
const recordingIdx = recordings.findIndex((r) => r.name === recording.name);
recordings.splice(recordingIdx, 1);
}

old.splice(targetIdx, 1, { ...matchedTarget, archiveCount: matchedTarget.archiveCount + delta, recordings });
}
return old;

return [...old];
});
},
[setArchivesForTargets],
Expand All @@ -112,13 +133,20 @@ export const AllTargetsArchivedRecordingsTable: React.FC<AllTargetsArchivedRecor
setArchivesForTargets(
targetNodes.map((node) => {
const target: Target = {
connectUrl: node.target.serviceUri,
jvmId: node.target.jvmId,
connectUrl: node.target.connectUrl,
alias: node.target.alias,
labels: [],
annotations: {
cryostat: [],
platform: [],
},
};
return {
target,
targetAsObs: of(target),
archiveCount: node.recordings.archived.aggregate.count,
archiveCount: node?.archiveCount ?? 0,
recordings: node?.recordings ?? [],
};
}),
);
Expand All @@ -134,29 +162,54 @@ export const AllTargetsArchivedRecordingsTable: React.FC<AllTargetsArchivedRecor
[setIsLoading, setErrorMessage],
);

/* eslint-disable @typescript-eslint/no-explicit-any */
const refreshArchivesForTargets = React.useCallback(() => {
setIsLoading(true);
addSubscription(
context.api
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
.graphql<any>(
`query AllTargetsArchives {
targetNodes {
target {
serviceUri
alias
}
recordings {
archived {
aggregate {
count
}
}
}
}
}`,
targetNodes {
target {
connectUrl
alias
jvmId
archivedRecordings {
data {
jvmId
name
downloadUrl
reportUrl
metadata {
labels {
key
value
}
}
size
archivedTime
}
aggregate {
count
}
}
}
}
}`,
)
.pipe(
map((v) => {
return v.data.targetNodes.map((node) => {
const target: Target = node.target;
return {
target,
targetAsObs: of(target),
archiveCount: node.target.archivedRecordings.aggregate.count,
recordings: node.target.archivedRecordings.data as ArchivedRecording[],
};
});
}),
)
.pipe(map((v) => v.data.targetNodes))
.subscribe({
next: handleArchivesForTargets,
error: handleError,
Expand All @@ -170,18 +223,31 @@ export const AllTargetsArchivedRecordingsTable: React.FC<AllTargetsArchivedRecor
addSubscription(
context.api
.graphql<any>(
`
query ArchiveCountForTarget($connectUrl: String) {
targetNodes(filter: { name: $connectUrl }) {
recordings {
archived {
aggregate {
count
`query ArchiveCountForTarget($connectUrl: String) {
targetNodes(filter: { name: $connectUrl }) {
target {
archivedRecordings {
data {
jvmId
name
downloadUrl
reportUrl
metadata {
labels {
key
value
}
}
size
archivedTime
}
aggregate {
count
}
}
}
}
}
}
}`,
}`,
{ connectUrl: target.connectUrl },
)
.subscribe((v) => {
Expand All @@ -191,7 +257,8 @@ export const AllTargetsArchivedRecordingsTable: React.FC<AllTargetsArchivedRecor
{
target: target,
targetAsObs: of(target),
archiveCount: v.data.targetNodes[0].recordings.archived.aggregate.count,
archiveCount: v.data.targetNodes[0]?.target?.archivedRecordings?.aggregate?.count ?? 0,
recordings: v.data.targetNodes[0]?.target?.archivedRecordings,
},
];
});
Expand All @@ -212,27 +279,26 @@ export const AllTargetsArchivedRecordingsTable: React.FC<AllTargetsArchivedRecor

const handleTargetNotification = React.useCallback(
(evt: TargetDiscoveryEvent) => {
const target: Target = {
connectUrl: evt.serviceRef.connectUrl,
alias: evt.serviceRef.alias,
};
if (evt.kind === 'FOUND') {
getCountForNewTarget(target);
getCountForNewTarget(evt.serviceRef);
} else if (evt.kind === 'MODIFIED') {
setArchivesForTargets((old) => {
const idx = old.findIndex(({ target: t }) => isEqualTarget(t, target));
const idx = old.findIndex(({ target: t }) => isEqualTarget(t, evt.serviceRef));
if (idx >= 0) {
const matched = old[idx];
if (target.connectUrl === matched.target.connectUrl && target.alias === matched.target.alias) {
if (
evt.serviceRef.connectUrl === matched.target.connectUrl &&
evt.serviceRef.alias === matched.target.alias
) {
// If alias and connectUrl are not updated, ignore changes.
return old;
}
return old.splice(idx, 1, { ...matched, target: target, targetAsObs: of(target) });
return old.splice(idx, 1, { ...matched, target: evt.serviceRef, targetAsObs: of(evt.serviceRef) });
}
return old;
});
} else if (evt.kind === 'LOST') {
handleLostTarget(target);
handleLostTarget(evt.serviceRef);
}
},
[setArchivesForTargets, getCountForNewTarget, handleLostTarget],
Expand Down Expand Up @@ -302,29 +368,21 @@ export const AllTargetsArchivedRecordingsTable: React.FC<AllTargetsArchivedRecor
);
}, [addSubscription, context.notificationChannel, handleTargetNotification]);

React.useEffect(() => {
addSubscription(
context.notificationChannel.messages(NotificationCategory.ActiveRecordingSaved).subscribe((v) => {
updateCount(v.message.target, 1);
}),
);
}, [addSubscription, context.notificationChannel, updateCount]);

React.useEffect(() => {
addSubscription(
context.notificationChannel.messages(NotificationCategory.ArchivedRecordingCreated).subscribe((v) => {
updateCount(v.message.target, 1);
handleNotification(v.message.target, v.message.recording, 1);
}),
);
}, [addSubscription, context.notificationChannel, updateCount]);
}, [addSubscription, context.notificationChannel, handleNotification]);

React.useEffect(() => {
addSubscription(
context.notificationChannel.messages(NotificationCategory.ArchivedRecordingDeleted).subscribe((v) => {
updateCount(v.message.target, -1);
handleNotification(v.message.target, v.message.recording, -1);
}),
);
}, [addSubscription, context.notificationChannel, updateCount]);
}, [addSubscription, context.notificationChannel, handleNotification]);

const toggleExpanded = React.useCallback(
(target) => {
Expand Down
6 changes: 3 additions & 3 deletions src/app/Archives/ArchiveUploadModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@
* limitations under the License.
*/
import { RecordingLabelFields } from '@app/RecordingMetadata/RecordingLabelFields';
import { RecordingLabel } from '@app/RecordingMetadata/types';
import { FUpload, MultiFileUpload, UploadCallbacks } from '@app/Shared/Components/FileUploads';
import { LoadingProps } from '@app/Shared/Components/types';
import { KeyValue } from '@app/Shared/Services/api.types';
import { ServiceContext } from '@app/Shared/Services/Services';
import { useSubscriptions } from '@app/utils/hooks/useSubscriptions';
import { portalRoot } from '@app/utils/utils';
Expand Down Expand Up @@ -51,7 +51,7 @@ export const ArchiveUploadModal: React.FC<ArchiveUploadModalProps> = ({ onClose,
const [uploading, setUploading] = React.useState(false);
const [numOfFiles, setNumOfFiles] = React.useState(0);
const [allOks, setAllOks] = React.useState(false);
const [labels, setLabels] = React.useState([] as RecordingLabel[]);
const [labels, setLabels] = React.useState([] as KeyValue[]);
const [valid, setValid] = React.useState(ValidatedOptions.success);

const getFormattedLabels = React.useCallback(() => {
Expand All @@ -66,7 +66,7 @@ export const ArchiveUploadModal: React.FC<ArchiveUploadModalProps> = ({ onClose,

const reset = React.useCallback(() => {
setUploading(false);
setLabels([] as RecordingLabel[]);
setLabels([] as KeyValue[]);
setValid(ValidatedOptions.success);
setNumOfFiles(0);
}, [setUploading, setLabels, setValid, setNumOfFiles]);
Expand Down
5 changes: 5 additions & 0 deletions src/app/Archives/Archives.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ import { AllTargetsArchivedRecordingsTable } from './AllTargetsArchivedRecording
export const uploadAsTarget: Target = {
connectUrl: UPLOADS_SUBDIRECTORY,
alias: '',
labels: [],
annotations: {
cryostat: [],
platform: [],
},
};

enum ArchiveTab {
Expand Down
5 changes: 5 additions & 0 deletions src/app/Archives/utils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,5 +34,10 @@ export const getTargetFromDirectory = (dir: RecordingDirectory): Target => {
return {
connectUrl: dir.connectUrl,
alias: dir.jvmId,
labels: [],
annotations: {
cryostat: [],
platform: [],
},
};
};
Loading
Loading