Skip to content

Commit

Permalink
mark labels/annotations required in data model, update accesors for n…
Browse files Browse the repository at this point in the history
…ew format
  • Loading branch information
andrewazores committed Feb 29, 2024
1 parent d748cee commit a37abbb
Show file tree
Hide file tree
Showing 32 changed files with 195 additions and 37 deletions.
10 changes: 10 additions & 0 deletions src/app/Archives/AllTargetsArchivedRecordingsTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,11 @@ export const AllTargetsArchivedRecordingsTable: React.FC<AllTargetsArchivedRecor
const target: Target = {
connectUrl: node.target.serviceUri,
alias: node.target.alias,
labels: [],
annotations: {
cryostat: [],
platform: [],
},
};
return {
target,
Expand Down Expand Up @@ -215,6 +220,11 @@ export const AllTargetsArchivedRecordingsTable: React.FC<AllTargetsArchivedRecor
const target: Target = {
connectUrl: evt.serviceRef.connectUrl,
alias: evt.serviceRef.alias,
labels: [],
annotations: {
cryostat: [],
platform: [],
},
};
if (evt.kind === 'FOUND') {
getCountForNewTarget(target);
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: [],
},
};
};
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/

import { Target } from '@app/Shared/Services/api.types';
import { getAnnotation } from '@app/utils/utils';
import { ClipboardCopyButton, CodeBlock, CodeBlockAction, CodeBlockCode } from '@patternfly/react-core';
import * as React from 'react';

Expand All @@ -30,7 +31,10 @@ export const MatchExpressionHint: React.FC<MatchExpressionHintProps> = ({ target
if (!target || !target.alias || !target.connectUrl) {
body = 'true';
} else {
body = `target.alias == '${target.alias}' || target.annotations.cryostat['PORT'] == ${target.annotations?.cryostat['PORT']}`;
body = `target.alias == '${target.alias}' || target.annotations.cryostat['PORT'] == ${getAnnotation(
target.annotations.cryostat,
'PORT',
)}`;
}
body = JSON.stringify(body, null, 2);
body = body.substring(1, body.length - 1);
Expand Down
3 changes: 2 additions & 1 deletion src/app/Shared/Services/Api.service.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ import {
XMLHttpRequestConfig,
XMLHttpResponse,
KeyValue,
CustomTargetStub,
} from './api.types';
import { isHttpError, includesTarget, isHttpOk, isXMLHttpError } from './api.utils';
import { LoginService } from './Login.service';
Expand Down Expand Up @@ -170,7 +171,7 @@ export class ApiService {
}

createTarget(
target: Target,
target: CustomTargetStub,
credentials?: { username?: string; password?: string },
storeCredentials = false,
dryrun = false,
Expand Down
6 changes: 4 additions & 2 deletions src/app/Shared/Services/api.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@ export class XMLHttpError extends Error {
}
}

export type CustomTargetStub = Omit<Target, 'jvmId' | 'labels' | 'annotations'>;

// ======================================
// Health Resources
// ======================================
Expand Down Expand Up @@ -447,8 +449,8 @@ export interface Target {
jvmId?: string; // present in responses, but we do not need to provide it in requests
connectUrl: string;
alias: string;
labels?: KeyValue[];
annotations?: {
labels: KeyValue[];
annotations: {
cryostat: KeyValue[];
platform: KeyValue[];
};
Expand Down
5 changes: 3 additions & 2 deletions src/app/TargetView/TargetContextSelector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { isEqualTarget, getTargetRepresentation } from '@app/Shared/Services/api
import { ServiceContext } from '@app/Shared/Services/Services';
import { useSubscriptions } from '@app/utils/hooks/useSubscriptions';
import { getFromLocalStorage, removeFromLocalStorage, saveToLocalStorage } from '@app/utils/LocalStorage';
import { getAnnotation } from '@app/utils/utils';
import { Button, Divider, Select, SelectGroup, SelectOption, SelectVariant } from '@patternfly/react-core';
import * as React from 'react';
import { Link } from 'react-router-dom';
Expand Down Expand Up @@ -113,13 +114,13 @@ export const TargetContextSelector: React.FC<TargetContextSelectorProps> = ({ cl
const favSet = new Set(favorites);

const groupNames = new Set<string>();
targets.forEach((t) => groupNames.add(t.annotations?.cryostat['REALM'] || 'Others'));
targets.forEach((t) => groupNames.add(getAnnotation(t.annotations.cryostat, 'REALM') || 'Others'));

const options = Array.from(groupNames)
.map((name) => (
<SelectGroup key={name} label={name}>
{targets
.filter((t) => (t.annotations?.cryostat['REALM'] || 'Others') === name)
.filter((t) => getAnnotation(t.annotations.cryostat, 'REALM') === name)
.map((t: Target) => (
<SelectOption
isFavorite={favSet.has(t.connectUrl)}
Expand Down
5 changes: 3 additions & 2 deletions src/app/TargetView/TargetSelect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { NoTargetSelected } from '@app/TargetView/NoTargetSelected';
import { SerializedTarget } from '@app/TargetView/SerializedTarget';
import { useSubscriptions } from '@app/utils/hooks/useSubscriptions';
import { getFromLocalStorage } from '@app/utils/LocalStorage';
import { getAnnotation } from '@app/utils/utils';
import {
Card,
CardBody,
Expand Down Expand Up @@ -108,14 +109,14 @@ export const TargetSelect: React.FC<TargetSelectProps> = ({ onSelect, simple, ..
let options = [] as JSX.Element[];

const groupNames = new Set<string>();
targets.forEach((t) => groupNames.add(t.annotations?.cryostat['REALM'] || 'Others'));
targets.forEach((t) => groupNames.add(getAnnotation(t.annotations.cryostat, 'REALM') || 'Others'));

options = options.concat(
Array.from(groupNames)
.map((name) => (
<SelectGroup key={name} label={name}>
{targets
.filter((t) => (t.annotations?.cryostat['REALM'] || 'Others') === name)
.filter((t) => (getAnnotation(t.annotations.cryostat, 'REALM') || 'Others') === name)
.map((t: Target) => (
<SelectOption key={t.connectUrl} value={t} isPlaceholder={false}>
{!t.alias || t.alias === t.connectUrl ? `${t.connectUrl}` : `${t.alias} (${t.connectUrl})`}
Expand Down
11 changes: 8 additions & 3 deletions src/app/Topology/Actions/CreateTarget.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import { ServiceContext } from '@app/Shared/Services/Services';
import '@app/Topology/styles/base.css';
import { useSubscriptions } from '@app/utils/hooks/useSubscriptions';
import { getFromLocalStorage } from '@app/utils/LocalStorage';
import { portalRoot } from '@app/utils/utils';
import { getAnnotation, portalRoot } from '@app/utils/utils';
import {
Accordion,
AccordionContent,
Expand Down Expand Up @@ -241,7 +241,7 @@ export const CreateTarget: React.FC<CreateTargetProps> = ({ prefilled }) => {
React.useEffect(() => {
addSubscription(
context.targets.targets().subscribe((ts) => {
const discoveredTargets = ts.filter((t) => t.annotations?.cryostat['REALM'] !== 'Custom Targets');
const discoveredTargets = ts.filter((t) => getAnnotation(t.annotations.cryostat, 'REALM') !== 'Custom Targets');
if (discoveredTargets.length) {
setExample(discoveredTargets[0].connectUrl);
}
Expand Down Expand Up @@ -400,7 +400,12 @@ export const CreateTarget: React.FC<CreateTargetProps> = ({ prefilled }) => {
</FormGroup>
</GridItem>
<GridItem {...responsiveSpans[1]} order={{ default: '1', lg: '1', xl: '1', md: '1' }}>
<SampleNodeDonut target={target} validation={validation} testing={testing} onClick={testTarget} />
<SampleNodeDonut
target={{ ...target, labels: [], annotations: { cryostat: [], platform: [] } }}
validation={validation}
testing={testing}
onClick={testTarget}
/>
</GridItem>
</Grid>
<ActionGroup>
Expand Down
5 changes: 3 additions & 2 deletions src/app/Topology/Entity/EntityAnnotations.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@
import { Label, LabelGroup } from '@patternfly/react-core';
import * as React from 'react';
import { EmptyText } from '../../Shared/Components/EmptyText';
import { Annotations } from './types';

export const EntityAnnotations: React.FC<{ annotations?: object; maxDisplay?: number }> = ({
export const EntityAnnotations: React.FC<{ annotations?: Annotations; maxDisplay?: number }> = ({
annotations,
maxDisplay,
...props
Expand All @@ -26,7 +27,7 @@ export const EntityAnnotations: React.FC<{ annotations?: object; maxDisplay?: nu
return annotations
? Object.keys(annotations).map((groupK) => ({
groupLabel: groupK,
annotations: Object.keys(annotations[groupK]).map((k) => `${k}=${annotations[groupK][k]}`),
annotations: annotations[groupK].map((kv) => `${kv.key}=${kv.value}`),
}))
: [];
}, [annotations]);
Expand Down
6 changes: 6 additions & 0 deletions src/app/Topology/Entity/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import type {
EventProbe,
EventTemplate,
EventType,
KeyValue,
NotificationMessage,
Recording,
Rule,
Expand Down Expand Up @@ -48,6 +49,11 @@ export const TargetOwnedResourceTypeAsArray = [
'agentProbes',
] as const;

export type Annotations = {
cryostat: KeyValue[];
platform: KeyValue[];
};

export const TargetRelatedResourceTypeAsArray = ['automatedRules', 'credentials'] as const;

export type TargetOwnedResourceType = (typeof TargetOwnedResourceTypeAsArray)[number];
Expand Down
13 changes: 13 additions & 0 deletions src/app/utils/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
* limitations under the License.
*/

import { KeyValue } from '@app/Shared/Services/api.types';
import { ISortBy, SortByDirection } from '@patternfly/react-table';
import _ from 'lodash';
import { NavigateFunction } from 'react-router-dom';
Expand Down Expand Up @@ -181,6 +182,18 @@ export interface TableColumn {
width?: number;
}

export const getAnnotation = (kv: KeyValue[], key: string, def?: string): string | undefined => {
if (!kv) {
return def;
}
for (const k of kv) {
if (k.key === key) {
return k.value;
}
}
return def;
};

const mapper = (tableColumns: TableColumn[], index?: number) => {
if (index === undefined) {
return undefined;
Expand Down
8 changes: 7 additions & 1 deletion src/test/Agent/AgentLiveProbes.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,13 @@ import { render, renderSnapshot } from '../utils';

const mockConnectUrl = 'service:jmx:rmi://someUrl';
const mockJvmId = 'id';
const mockTarget = { connectUrl: mockConnectUrl, alias: 'fooTarget', jvmId: mockJvmId };
const mockTarget = {
connectUrl: mockConnectUrl,
alias: 'fooTarget',
jvmId: mockJvmId,
labels: [],
annotations: { cryostat: [], platform: [] },
};

const mockMessageType = { type: 'application', subtype: 'json' } as MessageType;

Expand Down
6 changes: 6 additions & 0 deletions src/test/Archives/AllTargetsArchivedRecordingsTable.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ const mockAlias1 = 'fooTarget1';
const mockTarget1: Target = {
connectUrl: mockConnectUrl1,
alias: mockAlias1,
jvmId: 'foo',
labels: [],
annotations: { cryostat: [], platform: [] },
};
const mockConnectUrl2 = 'service:jmx:rmi://someUrl2';
const mockAlias2 = 'fooTarget2';
Expand All @@ -36,6 +39,9 @@ const mockNewAlias = 'newTarget';
const mockNewTarget: Target = {
connectUrl: mockNewConnectUrl,
alias: mockNewAlias,
jvmId: 'foo',
labels: [],
annotations: { cryostat: [], platform: [] },
};
const mockCount1 = 1;
const mockCount2 = 3;
Expand Down
12 changes: 9 additions & 3 deletions src/test/CreateRecording/CustomRecordingForm.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
*/
import { CustomRecordingForm } from '@app/CreateRecording/CustomRecordingForm';
import { authFailMessage } from '@app/ErrorView/types';
import { EventTemplate, AdvancedRecordingOptions, RecordingAttributes } from '@app/Shared/Services/api.types';
import { EventTemplate, AdvancedRecordingOptions, RecordingAttributes, Target } from '@app/Shared/Services/api.types';
import { ServiceContext, Services, defaultServices } from '@app/Shared/Services/Services';
import { TargetService } from '@app/Shared/Services/Target.service';
import { screen, cleanup, act as doAct } from '@testing-library/react';
Expand All @@ -36,7 +36,13 @@ jest.mock('react-router-dom', () => ({
}));

const mockConnectUrl = 'service:jmx:rmi://someUrl';
const mockTarget = { connectUrl: mockConnectUrl, alias: 'fooTarget' };
const mockTarget = {
connectUrl: mockConnectUrl,
alias: 'fooTarget',
jvmId: 'foo',
labels: [],
annotations: { cryostat: [], platform: [] },
};

const mockCustomEventTemplate: EventTemplate = {
name: 'someEventTemplate',
Expand Down Expand Up @@ -150,7 +156,7 @@ describe('<CustomRecordingForm />', () => {
it('should show error view if failing to retrieve templates or recording options', async () => {
const subj = new Subject<void>();
const mockTargetSvc = {
target: () => of(mockTarget),
target: () => of(mockTarget as Target),
authFailure: () => subj.asObservable(),
} as TargetService;
const services: Services = {
Expand Down
8 changes: 7 additions & 1 deletion src/test/CreateRecording/SnapshotRecordingForm.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,13 @@ import { of, Subject } from 'rxjs';
import { render, renderSnapshot } from '../utils';

const mockConnectUrl = 'service:jmx:rmi://someUrl';
const mockTarget = { connectUrl: mockConnectUrl, alias: 'fooTarget' };
const mockTarget = {
connectUrl: mockConnectUrl,
alias: 'fooTarget',
jvmId: 'foo',
labels: [],
annotations: { cryostat: [], platform: [] },
};

jest.spyOn(defaultServices.target, 'authFailure').mockReturnValue(of());
jest.spyOn(defaultServices.target, 'target').mockReturnValue(of(mockTarget));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,13 @@ jest.mock('@app/Dashboard/AutomatedAnalysis/AutomatedAnalysisCardList', () => {
};
});

const mockTarget = { connectUrl: 'service:jmx:rmi://someUrl', alias: 'fooTarget' };
const mockTarget = {
connectUrl: 'service:jmx:rmi://someUrl',
alias: 'fooTarget',
jvmId: 'foo',
labels: [],
annotations: { cryostat: [], platform: [] },
};

const mockEmptyCachedReport: CachedReportValue = {
report: [],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,13 @@ import { cleanup, screen } from '@testing-library/react';
import { of } from 'rxjs';
import { render, testT } from '../../utils';

const mockTarget = { connectUrl: 'service:jmx:rmi://someUrl', alias: 'fooTarget' };
const mockTarget = {
connectUrl: 'service:jmx:rmi://someUrl',
alias: 'fooTarget',
jvmId: 'foo',
labels: [],
annotations: { cryostat: [], platform: [] },
};

const mockTemplate1: EventTemplate = {
name: 'template1',
Expand Down
8 changes: 7 additions & 1 deletion src/test/Dashboard/Charts/jfr/JFRMetricsChartCard.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,13 @@ import { mockMediaQueryList, render, renderSnapshot } from '../../../utils';
const mockDashboardUrl = 'http://localhost:3000';
jest.spyOn(defaultServices.api, 'grafanaDashboardUrl').mockReturnValue(of(mockDashboardUrl));

const mockTarget = { connectUrl: 'service:jmx:rmi://someUrl', alias: 'fooTarget' };
const mockTarget = {
connectUrl: 'service:jmx:rmi://someUrl',
alias: 'fooTarget',
jvmId: 'foo',
labels: [],
annotations: { cryostat: [], platform: [] },
};
jest.spyOn(defaultServices.target, 'target').mockReturnValue(of(mockTarget));

jest.spyOn(defaultServices.settings, 'themeSetting').mockReturnValue(of(ThemeSetting.LIGHT));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,13 @@ jest.spyOn(defaultServices.settings, 'datetimeFormat').mockReturnValue(of(defaul
jest.spyOn(defaultServices.settings, 'themeSetting').mockReturnValue(of(ThemeSetting.DARK));
jest.spyOn(defaultServices.settings, 'media').mockReturnValue(of(mockMediaQueryList));

const mockTarget = { connectUrl: 'service:jmx:rmi://someUrl', alias: 'fooTarget' };
const mockTarget = {
connectUrl: 'service:jmx:rmi://someUrl',
alias: 'fooTarget',
jvmId: 'foo',
labels: [],
annotations: { cryostat: [], platform: [] },
};
jest.spyOn(defaultServices.target, 'target').mockReturnValue(of(mockTarget));

const mockJfrController = new JFRMetricsChartController(
Expand Down
Loading

0 comments on commit a37abbb

Please sign in to comment.