Skip to content

Commit

Permalink
mutations for bulk uninstall/uninstall stream added (#446)
Browse files Browse the repository at this point in the history
  • Loading branch information
soson authored Jul 17, 2024
1 parent 557dcc5 commit 884156a
Show file tree
Hide file tree
Showing 6 changed files with 224 additions and 20 deletions.
12 changes: 5 additions & 7 deletions src/external-api/uniconfig-cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,13 +134,11 @@ export async function uninstallMultipleDevicesCache({
}): Promise<void> {
const uniconfigCache = UniconfigCache.getInstance();
const url = await uniconfigURL;
const response = await uninstallMultipleDevices(url, devicesToUninstall);

response.output['node-results']?.forEach((nodeResult) => {
if (nodeResult.status === 'fail') {
throw new Error(nodeResult['error-message'] ?? 'could not install device');
}
});
try {
await uninstallMultipleDevices(url, devicesToUninstall);
} catch {
throw new Error('some of nodes could not be uninstalled');
}

deviceNames.forEach((deviceName) => uniconfigCache.delete(url, deviceName));
}
12 changes: 2 additions & 10 deletions src/external-api/uniconfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import {
decodeUniconfigDryRunCommitOutput,
decodeUniconfigExternalStorageOutput,
decodeUniconfigInstallOutput,
decodeUniconfigMultipleNodesOutput,
decodeUniconfigSnapshotsOutput,
decodeUniconfigTransactionLogOutput,
InstalledDevicesOutput,
Expand All @@ -28,7 +27,6 @@ import {
UniconfigDryRunCommitInput,
UniconfigDryRunCommitOutput,
UniconfigInstallOutput,
UniconfigMultipleNodesOutput,
UniconfigReplaceInput,
UniconfigSnapshotInput,
UniconfigSnapshotsOutput,
Expand Down Expand Up @@ -133,14 +131,8 @@ export async function installMultipleDevices(baseURL: string, input: unknown): P
await sendPostRequest([baseURL, '/operations/connection-manager:install-multiple-nodes'], input);
}

export async function uninstallMultipleDevices(
baseURL: string,
input: UninstallMultipleDevicesInput,
): Promise<UniconfigMultipleNodesOutput> {
const json = await sendPostRequest([baseURL, '/operations/connection-manager:uninstall-multiple-nodes'], input);
const data = decodeUniconfigMultipleNodesOutput(json);

return data;
export async function uninstallMultipleDevices(baseURL: string, input: UninstallMultipleDevicesInput): Promise<void> {
await sendPostRequest([baseURL, '/operations/connection-manager:uninstall-multiple-nodes'], input);
}

/*
Expand Down
30 changes: 30 additions & 0 deletions src/helpers/stream-helpers.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { JsonValue } from '@prisma/client/runtime/library';
import { Prisma } from '@prisma/client';
import { decodeMountParams } from './converters';
import { Device, Stream } from '../schema/source-types';

export function getUniconfigStreamName(streamName: string, deviceName: string): string {
return `${streamName}>>${deviceName}`;
Expand Down Expand Up @@ -52,6 +54,34 @@ export function getMountParamsForStream(mountParameters: JsonValue, streamParame
};
}

type StreamWithDevice = Stream & {
device: Device;
};

export function makeZonesWithStreamsFromStreams(streams: StreamWithDevice[]) {
const zonesWithStreams = new Map<
string,
{
deviceName: string;
params: Prisma.JsonValue;
}[]
>();

streams.forEach((stream) => {
const { streamName, device, streamParameters } = stream;
const streamsInZone = zonesWithStreams.get(device.uniconfigZoneId) ?? [];

const streamToInstall = {
deviceName: getUniconfigStreamName(streamName, device.name),
params: getMountParamsForStream(device.mountParameters, streamParameters),
};

zonesWithStreams.set(device.uniconfigZoneId, [...streamsInZone, streamToInstall]);
});

return zonesWithStreams;
}

export function getStreamNameQuery(streamName?: string | null): Record<string, unknown> | undefined {
return streamName ? { contains: streamName, mode: 'insensitive' } : undefined;
}
18 changes: 18 additions & 0 deletions src/schema/api.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,14 @@ input BulkInstallDevicesInput {
deviceIds: [String!]!
}

type BulkInstallStreamPayload {
installedStreams: [Stream!]!
}

input BulkInstallStreamsInput {
streamIds: [String!]!
}

type BulkUninstallDevicePayload {
uninstalledDevices: [Device!]!
}
Expand All @@ -125,6 +133,14 @@ input BulkUninstallDevicesInput {
deviceIds: [String!]!
}

type BulkUninstallStreamPayload {
uninstalledStreams: [Stream!]!
}

input BulkUninstallStreamsInput {
streamIds: [String!]!
}

type CSVImport {
isOk: Boolean
}
Expand Down Expand Up @@ -462,7 +478,9 @@ type Mutation {
addZone(input: AddZoneInput!): AddZonePayload!
applySnapshot(input: ApplySnapshotInput!, transactionId: String!): ApplySnapshotPayload!
bulkInstallDevices(input: BulkInstallDevicesInput!): BulkInstallDevicePayload!
bulkInstallStreams(input: BulkInstallStreamsInput!): BulkInstallStreamPayload!
bulkUninstallDevices(input: BulkUninstallDevicesInput!): BulkUninstallDevicePayload!
bulkUninstallStreams(input: BulkUninstallStreamsInput!): BulkUninstallStreamPayload!
closeTransaction(deviceId: String!, transactionId: String!): CloseTransactionPayload!
commitConfig(input: CommitConfigInput!, transactionId: String!): CommitConfigPayload!
createLabel(input: CreateLabelInput!): CreateLabelPayload!
Expand Down
44 changes: 44 additions & 0 deletions src/schema/nexus-typegen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,18 @@ export interface NexusGenInputs {
// input type
deviceIds: string[]; // [String!]!
};
BulkInstallStreamsInput: {
// input type
streamIds: string[]; // [String!]!
};
BulkUninstallDevicesInput: {
// input type
deviceIds: string[]; // [String!]!
};
BulkUninstallStreamsInput: {
// input type
streamIds: string[]; // [String!]!
};
CSVImportInput: {
// input type
file: NexusGenScalars['Upload']; // Upload!
Expand Down Expand Up @@ -256,10 +264,18 @@ export interface NexusGenObjects {
// root type
installedDevices: NexusGenRootTypes['Device'][]; // [Device!]!
};
BulkInstallStreamPayload: {
// root type
installedStreams: NexusGenRootTypes['Stream'][]; // [Stream!]!
};
BulkUninstallDevicePayload: {
// root type
uninstalledDevices: NexusGenRootTypes['Device'][]; // [Device!]!
};
BulkUninstallStreamPayload: {
// root type
uninstalledStreams: NexusGenRootTypes['Stream'][]; // [Stream!]!
};
CSVImport: {
// root type
isOk?: boolean | null; // Boolean
Expand Down Expand Up @@ -792,10 +808,18 @@ export interface NexusGenFieldTypes {
// field return type
installedDevices: NexusGenRootTypes['Device'][]; // [Device!]!
};
BulkInstallStreamPayload: {
// field return type
installedStreams: NexusGenRootTypes['Stream'][]; // [Stream!]!
};
BulkUninstallDevicePayload: {
// field return type
uninstalledDevices: NexusGenRootTypes['Device'][]; // [Device!]!
};
BulkUninstallStreamPayload: {
// field return type
uninstalledStreams: NexusGenRootTypes['Stream'][]; // [Stream!]!
};
CSVImport: {
// field return type
isOk: boolean | null; // Boolean
Expand Down Expand Up @@ -1057,7 +1081,9 @@ export interface NexusGenFieldTypes {
addZone: NexusGenRootTypes['AddZonePayload']; // AddZonePayload!
applySnapshot: NexusGenRootTypes['ApplySnapshotPayload']; // ApplySnapshotPayload!
bulkInstallDevices: NexusGenRootTypes['BulkInstallDevicePayload']; // BulkInstallDevicePayload!
bulkInstallStreams: NexusGenRootTypes['BulkInstallStreamPayload']; // BulkInstallStreamPayload!
bulkUninstallDevices: NexusGenRootTypes['BulkUninstallDevicePayload']; // BulkUninstallDevicePayload!
bulkUninstallStreams: NexusGenRootTypes['BulkUninstallStreamPayload']; // BulkUninstallStreamPayload!
closeTransaction: NexusGenRootTypes['CloseTransactionPayload']; // CloseTransactionPayload!
commitConfig: NexusGenRootTypes['CommitConfigPayload']; // CommitConfigPayload!
createLabel: NexusGenRootTypes['CreateLabelPayload']; // CreateLabelPayload!
Expand Down Expand Up @@ -1453,10 +1479,18 @@ export interface NexusGenFieldTypeNames {
// field return type name
installedDevices: 'Device';
};
BulkInstallStreamPayload: {
// field return type name
installedStreams: 'Stream';
};
BulkUninstallDevicePayload: {
// field return type name
uninstalledDevices: 'Device';
};
BulkUninstallStreamPayload: {
// field return type name
uninstalledStreams: 'Stream';
};
CSVImport: {
// field return type name
isOk: 'Boolean';
Expand Down Expand Up @@ -1718,7 +1752,9 @@ export interface NexusGenFieldTypeNames {
addZone: 'AddZonePayload';
applySnapshot: 'ApplySnapshotPayload';
bulkInstallDevices: 'BulkInstallDevicePayload';
bulkInstallStreams: 'BulkInstallStreamPayload';
bulkUninstallDevices: 'BulkUninstallDevicePayload';
bulkUninstallStreams: 'BulkUninstallStreamPayload';
closeTransaction: 'CloseTransactionPayload';
commitConfig: 'CommitConfigPayload';
createLabel: 'CreateLabelPayload';
Expand Down Expand Up @@ -2107,10 +2143,18 @@ export interface NexusGenArgTypes {
// args
input: NexusGenInputs['BulkInstallDevicesInput']; // BulkInstallDevicesInput!
};
bulkInstallStreams: {
// args
input: NexusGenInputs['BulkInstallStreamsInput']; // BulkInstallStreamsInput!
};
bulkUninstallDevices: {
// args
input: NexusGenInputs['BulkUninstallDevicesInput']; // BulkUninstallDevicesInput!
};
bulkUninstallStreams: {
// args
input: NexusGenInputs['BulkUninstallStreamsInput']; // BulkUninstallStreamsInput!
};
closeTransaction: {
// args
deviceId: string; // String!
Expand Down
128 changes: 125 additions & 3 deletions src/schema/stream.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,28 @@
import { findManyCursorConnection } from '@devoxa/prisma-relay-cursor-connection';
import { arg, enumType, extendType, inputObjectType, nonNull, objectType, stringArg } from 'nexus';
import { getFilterQuery, getOrderingQuery } from '../helpers/device-helpers';
import { getFilterQuery, getOrderingQuery, makeZonesWithDevicesFromDevices } from '../helpers/device-helpers';
import { Node, PageInfo, PaginationConnectionArgs, SortDirection } from './global-types';
import { fromGraphId, toGraphId } from '../helpers/id-helper';
import { decodeMountParams, getConnectionType, prepareInstallParameters } from '../helpers/converters';
import {
decodeMountParams,
getConnectionType,
prepareInstallParameters,
prepareMultipleInstallParameters,
} from '../helpers/converters';
import { getUniconfigURL } from '../helpers/zone.helpers';
import {
getCachedDeviceInstallStatus,
installDeviceCache,
installMultipleDevicesCache,
uninstallDeviceCache,
uninstallMultipleDevicesCache,
} from '../external-api/uniconfig-cache';
import { getMountParamsForStream, getStreamNameQuery, getUniconfigStreamName } from '../helpers/stream-helpers';
import {
getMountParamsForStream,
getUniconfigStreamName,
makeZonesWithStreamsFromStreams,
getStreamNameQuery,
} from '../helpers/stream-helpers';
import config from '../config';
import { Blueprint } from './blueprint';

Expand Down Expand Up @@ -403,3 +415,113 @@ export const UpdateStreamMutation = extendType({
});
},
});

export const BulkInstallStreamPayload = objectType({
name: 'BulkInstallStreamPayload',
definition: (t) => {
t.nonNull.list.nonNull.field('installedStreams', { type: StreamNode });
},
});

export const BulkInstallStreamsInput = inputObjectType({
name: 'BulkInstallStreamsInput',
definition: (t) => {
t.nonNull.list.nonNull.string('streamIds');
},
});

export const BulkInstallStreamsMutation = extendType({
type: 'Mutation',
definition: (t) => {
t.nonNull.field('bulkInstallStreams', {
type: BulkInstallStreamPayload,
args: {
input: nonNull(arg({ type: BulkInstallStreamsInput })),
},
resolve: async (_, args, { prisma, tenantId }) => {
const { streamIds } = args.input;
const nativeIds = streamIds.map((id) => fromGraphId('Stream', id));
const streams = await prisma.stream.findMany({
where: { id: { in: nativeIds }, tenantId },
include: {
device: true,
},
});
const zonesWithStreams = makeZonesWithStreamsFromStreams(streams);

const streamsToInstallWithParams = [...zonesWithStreams.entries()].map(
([uniconfigZoneId, devicesToInstall]) => ({
uniconfigURL: getUniconfigURL(prisma, uniconfigZoneId),
devicesToInstall: prepareMultipleInstallParameters(devicesToInstall),
deviceNames: devicesToInstall.map((device) => device.deviceName),
}),
);

await Promise.all(
streamsToInstallWithParams.map((streamsToInstall) => installMultipleDevicesCache(streamsToInstall)),
);

return { installedStreams: streams };
},
});
},
});

export const BulkUninstallStreamPayload = objectType({
name: 'BulkUninstallStreamPayload',
definition: (t) => {
t.nonNull.list.nonNull.field('uninstalledStreams', { type: StreamNode });
},
});

export const BulkUninstallStreamsInput = inputObjectType({
name: 'BulkUninstallStreamsInput',
definition: (t) => {
t.nonNull.list.nonNull.string('streamIds');
},
});

export const BulkUninstallDevicesMutation = extendType({
type: 'Mutation',
definition: (t) => {
t.nonNull.field('bulkUninstallStreams', {
type: BulkUninstallStreamPayload,
args: {
input: nonNull(arg({ type: BulkUninstallStreamsInput })),
},
resolve: async (_, args, { prisma, tenantId }) => {
const { streamIds } = args.input;
const nativeIds = streamIds.map((id) => fromGraphId('Stream', id));
const streams = await prisma.stream.findMany({
where: { id: { in: nativeIds }, tenantId },
include: { device: true },
});
const deviceStreamMap = new Map(streams.map((s) => [s.deviceName, s]));
const zonesWithDevices = makeZonesWithDevicesFromDevices(streams.map((s) => s.device));

const streamsToUninstallWithParams = [...zonesWithDevices.entries()].map(
([uniconfigZoneId, devicesToUninstall]) => ({
uniconfigURL: getUniconfigURL(prisma, uniconfigZoneId),
devicesToUninstall: {
input: {
nodes: devicesToUninstall.map(({ deviceName, params }) => ({
// eslint-disable-next-line @typescript-eslint/naming-convention
'node-id': getUniconfigStreamName(deviceStreamMap.get(deviceName)?.streamName ?? '', deviceName),
// eslint-disable-next-line @typescript-eslint/naming-convention
'connection-type': getConnectionType(decodeMountParams(params)),
})),
},
},
deviceNames: devicesToUninstall.map((device) => device.deviceName),
}),
);

await Promise.all(
streamsToUninstallWithParams.map((streamsToUninstall) => uninstallMultipleDevicesCache(streamsToUninstall)),
);

return { uninstalledStreams: streams };
},
});
},
});

0 comments on commit 884156a

Please sign in to comment.