Skip to content

Commit

Permalink
feat: config package manager from blueprints
Browse files Browse the repository at this point in the history
  • Loading branch information
olzzon authored and Julusian committed Sep 27, 2024
1 parent e839b97 commit bcb9edf
Show file tree
Hide file tree
Showing 25 changed files with 1,244 additions and 894 deletions.
2 changes: 1 addition & 1 deletion meteor/__mocks__/defaultCollectionObjects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ export function defaultStudio(_id: StudioId): DBStudio {
_rundownVersionHash: '',
routeSetsWithOverrides: wrapDefaultObject({}),
routeSetExclusivityGroupsWithOverrides: wrapDefaultObject({}),
packageContainers: {},
packageContainersWithOverrides: wrapDefaultObject({}),
previewContainerIds: [],
thumbnailContainerIds: [],
peripheralDeviceSettings: {
Expand Down
2 changes: 1 addition & 1 deletion meteor/server/api/rest/v1/typeConversion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ export async function studioFrom(apiStudio: APIStudio, existingId?: StudioId): P
routeSetsWithOverrides: wrapDefaultObject({}),
_rundownVersionHash: '',
routeSetExclusivityGroupsWithOverrides: wrapDefaultObject({}),
packageContainers: {},
packageContainersWithOverrides: wrapDefaultObject({}),
previewContainerIds: [],
thumbnailContainerIds: [],
peripheralDeviceSettings: {
Expand Down
2 changes: 1 addition & 1 deletion meteor/server/api/studio/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ export async function insertStudioInner(organizationId: OrganizationId | null, n
_rundownVersionHash: '',
routeSetsWithOverrides: wrapDefaultObject({}),
routeSetExclusivityGroupsWithOverrides: wrapDefaultObject({}),
packageContainers: {},
packageContainersWithOverrides: wrapDefaultObject({}),
thumbnailContainerIds: [],
previewContainerIds: [],
peripheralDeviceSettings: {
Expand Down
2 changes: 1 addition & 1 deletion meteor/server/migration/0_1_0.ts
Original file line number Diff line number Diff line change
Expand Up @@ -447,7 +447,7 @@ export const addSteps = addMigrationSteps('0.1.0', [
_rundownVersionHash: '',
routeSetsWithOverrides: wrapDefaultObject({}),
routeSetExclusivityGroupsWithOverrides: wrapDefaultObject({}),
packageContainers: {},
packageContainersWithOverrides: wrapDefaultObject({}),
thumbnailContainerIds: [],
previewContainerIds: [],
peripheralDeviceSettings: {
Expand Down
43 changes: 42 additions & 1 deletion meteor/server/migration/X_X_X.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@ import { addMigrationSteps } from './databaseMigration'
import { CURRENT_SYSTEM_VERSION } from './currentSystemVersion'
import { Studios } from '../collections'
import { convertObjectIntoOverrides } from '@sofie-automation/corelib/dist/settings/objectWithOverrides'
import { StudioRouteSet, StudioRouteSetExclusivityGroup } from '@sofie-automation/corelib/dist/dataModel/Studio'
import {
StudioRouteSet,
StudioRouteSetExclusivityGroup,
StudioPackageContainer,
} from '@sofie-automation/corelib/dist/dataModel/Studio'

/*
* **************************************************************************************
Expand Down Expand Up @@ -92,4 +96,41 @@ export const addSteps = addMigrationSteps(CURRENT_SYSTEM_VERSION, [
}
},
},
{
id: `convert packageContainers to ObjectWithOverrides`,
canBeRunAutomatically: true,
validate: async () => {
const studios = await Studios.findFetchAsync({ packageContainers: { $exists: true } })

for (const studio of studios) {
//@ts-expect-error packageContainers is not typed as ObjectWithOverrides
if (studio.packageContainers) {
return 'packageContainers must be converted to an ObjectWithOverrides'
}
}

return false
},
migrate: async () => {
const studios = await Studios.findFetchAsync({ packageContainers: { $exists: true } })

for (const studio of studios) {
//@ts-expect-error packageContainers is not typed as ObjectWithOverrides
if (!studio.packageContainers) continue
//@ts-expect-error packageContainers is not typed as ObjectWithOverrides
const oldPackageContainers = studio.packageContainers as any as Record<string, StudioPackageContainer>

const newPackageContainers = convertObjectIntoOverrides(oldPackageContainers)

await Studios.updateAsync(studio._id, {
$set: {
packageContainersWithOverrides: newPackageContainers,
},
$unset: {
packageContainers: 1,
},
})
}
},
},
])
6 changes: 3 additions & 3 deletions meteor/server/migration/__tests__/migrations.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ describe('Migrations', () => {
_rundownVersionHash: '',
routeSetsWithOverrides: wrapDefaultObject({}),
routeSetExclusivityGroupsWithOverrides: wrapDefaultObject({}),
packageContainers: {},
packageContainersWithOverrides: wrapDefaultObject({}),
previewContainerIds: [],
thumbnailContainerIds: [],
peripheralDeviceSettings: {
Expand Down Expand Up @@ -170,7 +170,7 @@ describe('Migrations', () => {
_rundownVersionHash: '',
routeSetsWithOverrides: wrapDefaultObject({}),
routeSetExclusivityGroupsWithOverrides: wrapDefaultObject({}),
packageContainers: {},
packageContainersWithOverrides: wrapDefaultObject({}),
previewContainerIds: [],
thumbnailContainerIds: [],
peripheralDeviceSettings: {
Expand Down Expand Up @@ -208,7 +208,7 @@ describe('Migrations', () => {
_rundownVersionHash: '',
routeSetsWithOverrides: wrapDefaultObject({}),
routeSetExclusivityGroupsWithOverrides: wrapDefaultObject({}),
packageContainers: {},
packageContainersWithOverrides: wrapDefaultObject({}),
previewContainerIds: [],
thumbnailContainerIds: [],
peripheralDeviceSettings: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { CustomPublishCollection } from '../../../lib/customPublication'
import { logger } from '../../../logging'
import { ExpectedPackagesContentCache } from './contentCache'
import type { StudioFields } from './publication'
import { applyAndValidateOverrides } from '@sofie-automation/corelib/dist/settings/objectWithOverrides'

/**
* Regenerate the output for the provided ExpectedPackage `regenerateIds`, updating the data in `collection` as needed
Expand All @@ -37,6 +38,7 @@ export async function updateCollectionForExpectedPackageIds(
): Promise<void> {
const updatedDocIds = new Set<PackageManagerExpectedPackageId>()
const missingExpectedPackageIds = new Set<ExpectedPackageId>()
const packageContainers = applyAndValidateOverrides(studio.packageContainersWithOverrides).obj

for (const packageId of regenerateIds) {
const packageDoc = contentCache.ExpectedPackages.findOne(packageId)
Expand Down Expand Up @@ -66,7 +68,8 @@ export async function updateCollectionForExpectedPackageIds(
},
deviceId,
null,
Priorities.OTHER // low priority
Priorities.OTHER, // low priority
packageContainers
)

updatedDocIds.add(routedPackage._id)
Expand Down Expand Up @@ -105,6 +108,7 @@ export async function updateCollectionForPieceInstanceIds(
): Promise<void> {
const updatedDocIds = new Set<PackageManagerExpectedPackageId>()
const missingPieceInstanceIds = new Set<PieceInstanceId>()
const packageContainers = applyAndValidateOverrides(studio.packageContainersWithOverrides).obj

for (const pieceInstanceId of regenerateIds) {
const pieceInstanceDoc = contentCache.PieceInstances.findOne(pieceInstanceId)
Expand Down Expand Up @@ -140,7 +144,8 @@ export async function updateCollectionForPieceInstanceIds(
},
deviceId,
pieceInstanceId,
Priorities.OTHER // low priority
Priorities.OTHER, // low priority
packageContainers
)

updatedDocIds.add(routedPackage._id)
Expand Down Expand Up @@ -172,17 +177,21 @@ enum Priorities {
}

function generateExpectedPackageForDevice(
studio: Pick<StudioLight, '_id' | 'packageContainers' | 'previewContainerIds' | 'thumbnailContainerIds'>,
studio: Pick<
StudioLight,
'_id' | 'packageContainersWithOverrides' | 'previewContainerIds' | 'thumbnailContainerIds'
>,
expectedPackage: PackageManagerExpectedPackageBase,
deviceId: PeripheralDeviceId,
pieceInstanceId: PieceInstanceId | null,
priority: Priorities
priority: Priorities,
packageContainers: Record<string, StudioPackageContainer>
): PackageManagerExpectedPackage {
// Lookup Package sources:
const combinedSources: PackageContainerOnPackage[] = []

for (const packageSource of expectedPackage.sources) {
const lookedUpSource = studio.packageContainers[packageSource.containerId]
const lookedUpSource = packageContainers[packageSource.containerId]
if (lookedUpSource) {
combinedSources.push(calculateCombinedSource(packageSource, lookedUpSource))
} else {
Expand All @@ -199,7 +208,7 @@ function generateExpectedPackageForDevice(
}

// Lookup Package targets:
const combinedTargets = calculateCombinedTargets(studio, expectedPackage, deviceId)
const combinedTargets = calculateCombinedTargets(expectedPackage, deviceId, packageContainers)

if (!combinedSources.length && expectedPackage.sources.length !== 0) {
logger.warn(`Pub.expectedPackagesForDevice: No sources found for "${expectedPackage._id}"`)
Expand Down Expand Up @@ -253,14 +262,14 @@ function calculateCombinedSource(
return combinedSource
}
function calculateCombinedTargets(
studio: Pick<StudioLight, '_id' | 'packageContainers'>,
expectedPackage: PackageManagerExpectedPackageBase,
deviceId: PeripheralDeviceId
deviceId: PeripheralDeviceId,
packageContainers: Record<string, StudioPackageContainer>
): PackageContainerOnPackage[] {
const mappingDeviceId = unprotectString(deviceId)

let packageContainerId: string | undefined
for (const [containerId, packageContainer] of Object.entries<StudioPackageContainer>(studio.packageContainers)) {
for (const [containerId, packageContainer] of Object.entries<StudioPackageContainer>(packageContainers)) {
if (packageContainer.deviceIds.includes(mappingDeviceId)) {
// TODO: how to handle if a device has multiple containers?
packageContainerId = containerId
Expand All @@ -270,7 +279,7 @@ function calculateCombinedTargets(

const combinedTargets: PackageContainerOnPackage[] = []
if (packageContainerId) {
const lookedUpTarget = studio.packageContainers[packageContainerId]
const lookedUpTarget = packageContainers[packageContainerId]
if (lookedUpTarget) {
// Todo: should the be any combination of properties here?
combinedTargets.push({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,14 +56,14 @@ export type StudioFields =
| '_id'
| 'routeSetsWithOverrides'
| 'mappingsWithOverrides'
| 'packageContainers'
| 'packageContainersWithOverrides'
| 'previewContainerIds'
| 'thumbnailContainerIds'
const studioFieldSpecifier = literal<MongoFieldSpecifierOnesStrict<Pick<DBStudio, StudioFields>>>({
_id: 1,
routeSetsWithOverrides: 1,
mappingsWithOverrides: 1,
packageContainers: 1,
packageContainersWithOverrides: 1,
previewContainerIds: 1,
thumbnailContainerIds: 1,
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,12 @@ import {
PeripheralDevicePubSub,
PeripheralDevicePubSubCollectionsNames,
} from '@sofie-automation/shared-lib/dist/pubsub/peripheralDevice'
import { applyAndValidateOverrides } from '@sofie-automation/corelib/dist/settings/objectWithOverrides'

type StudioFields = '_id' | 'packageContainers'
type StudioFields = '_id' | 'packageContainersWithOverrides'
const studioFieldSpecifier = literal<MongoFieldSpecifierOnesStrict<Pick<DBStudio, StudioFields>>>({
_id: 1,
packageContainers: 1,
packageContainersWithOverrides: 1,
})

interface PackageManagerPackageContainersArgs {
Expand Down Expand Up @@ -68,8 +69,9 @@ async function manipulateExpectedPackagesPublicationData(

const packageContainers: { [containerId: string]: PackageContainer } = {}
if (studio) {
const studioPackageContainers = applyAndValidateOverrides(studio.packageContainersWithOverrides).obj
for (const [containerId, studioPackageContainer] of Object.entries<StudioPackageContainer>(
studio.packageContainers
studioPackageContainers
)) {
packageContainers[containerId] = studioPackageContainer.container
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
getMediaObjectMediaId,
PieceContentStreamInfo,
checkPieceContentStatusAndDependencies,
PieceContentStatusStudio,
} from '../checkPieceContentStatus'
import {
PackageInfo,
Expand All @@ -31,12 +32,10 @@ import {
MediaStream,
MediaStreamType,
} from '@sofie-automation/shared-lib/dist/core/model/MediaObjects'
import { UIStudio } from '@sofie-automation/meteor-lib/dist/api/studios'
import { defaultStudio } from '../../../../__mocks__/defaultCollectionObjects'
import { testInFiber } from '../../../../__mocks__/helpers/jest'
import { MediaObjects } from '../../../collections'
import { PieceDependencies } from '../common'
import { DBStudio } from '@sofie-automation/corelib/dist/dataModel/Studio'
import { DEFAULT_MINIMUM_TAKE_SPAN } from '@sofie-automation/shared-lib/dist/core/constants'

const mockMediaObjectsCollection = MongoMock.getInnerMockCollection<MediaObject>(MediaObjects)
Expand Down Expand Up @@ -174,17 +173,14 @@ describe('lib/mediaObjects', () => {
}

const mockDefaultStudio = defaultStudio(protectString('studio0'))
const mockStudio: Complete<
Pick<DBStudio, '_id' | 'settings' | 'packageContainers' | 'previewContainerIds' | 'thumbnailContainerIds'> &
Pick<UIStudio, 'mappings' | 'routeSets'>
> = {
const mockStudio: Complete<PieceContentStatusStudio> = {
_id: mockDefaultStudio._id,
settings: mockStudioSettings,
packageContainers: mockDefaultStudio.packageContainers,
previewContainerIds: ['previews0'],
thumbnailContainerIds: ['thumbnails0'],
routeSets: applyAndValidateOverrides(mockDefaultStudio.routeSetsWithOverrides).obj,
mappings: applyAndValidateOverrides(mockDefaultStudio.mappingsWithOverrides).obj,
packageContainers: applyAndValidateOverrides(mockDefaultStudio.packageContainersWithOverrides).obj,
}

mockMediaObjectsCollection.insert(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -173,11 +173,15 @@ export type PieceContentStatusPiece = Pick<PieceGeneric, '_id' | 'content' | 'ex
pieceInstanceId?: PieceInstanceId
}
export interface PieceContentStatusStudio
extends Pick<DBStudio, '_id' | 'settings' | 'packageContainers' | 'previewContainerIds' | 'thumbnailContainerIds'> {
extends Pick<DBStudio, '_id' | 'settings' | 'previewContainerIds' | 'thumbnailContainerIds'> {
/** Mappings between the physical devices / outputs and logical ones */
mappings: MappingsExt
/** Route sets with overrides */
routeSets: Record<string, StudioRouteSet>
/** Contains settings for which Package Containers are present in the studio.
* (These are used by the Package Manager and the Expected Packages)
*/
packageContainers: Record<string, StudioPackageContainer>
}

export async function checkPieceContentStatusAndDependencies(
Expand Down Expand Up @@ -557,7 +561,7 @@ async function checkPieceContentExpectedPackageStatus(
const sideEffect = getSideEffect(expectedPackage, studio)

thumbnailUrl = await getAssetUrlFromPackageContainerStatus(
studio,
studio.packageContainers,
getPackageContainerPackageStatus,
expectedPackageId,
sideEffect.thumbnailContainerId,
Expand All @@ -569,7 +573,7 @@ async function checkPieceContentExpectedPackageStatus(
const sideEffect = getSideEffect(expectedPackage, studio)

previewUrl = await getAssetUrlFromPackageContainerStatus(
studio,
studio.packageContainers,
getPackageContainerPackageStatus,
expectedPackageId,
sideEffect.previewContainerId,
Expand Down Expand Up @@ -716,7 +720,7 @@ async function checkPieceContentExpectedPackageStatus(
}

async function getAssetUrlFromPackageContainerStatus(
studio: PieceContentStatusStudio,
packageContainers: Record<string, StudioPackageContainer>,
getPackageContainerPackageStatus: (
packageContainerId: string,
expectedPackageId: ExpectedPackageId
Expand All @@ -727,7 +731,7 @@ async function getAssetUrlFromPackageContainerStatus(
): Promise<string | undefined> {
if (!assetContainerId || !packageAssetPath) return

const assetPackageContainer = studio.packageContainers[assetContainerId]
const assetPackageContainer = packageContainers[assetContainerId]
if (!assetPackageContainer) return

const previewPackageOnPackageContainer = await getPackageContainerPackageStatus(assetContainerId, expectedPackageId)
Expand Down
6 changes: 3 additions & 3 deletions meteor/server/publications/pieceContentStatusUI/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,15 @@ import { PieceContentStatusStudio } from './checkPieceContentStatus'
export type StudioFields =
| '_id'
| 'settings'
| 'packageContainers'
| 'packageContainersWithOverrides'
| 'previewContainerIds'
| 'thumbnailContainerIds'
| 'mappingsWithOverrides'
| 'routeSetsWithOverrides'
export const studioFieldSpecifier = literal<MongoFieldSpecifierOnesStrict<Pick<DBStudio, StudioFields>>>({
_id: 1,
settings: 1,
packageContainers: 1,
packageContainersWithOverrides: 1,
previewContainerIds: 1,
thumbnailContainerIds: 1,
mappingsWithOverrides: 1,
Expand Down Expand Up @@ -113,10 +113,10 @@ export async function fetchStudio(studioId: StudioId): Promise<PieceContentStatu
return {
_id: studio._id,
settings: studio.settings,
packageContainers: studio.packageContainers,
previewContainerIds: studio.previewContainerIds,
thumbnailContainerIds: studio.thumbnailContainerIds,
mappings: applyAndValidateOverrides(studio.mappingsWithOverrides).obj,
routeSets: applyAndValidateOverrides(studio.routeSetsWithOverrides).obj,
packageContainers: applyAndValidateOverrides(studio.packageContainersWithOverrides).obj,
}
}
Loading

0 comments on commit bcb9edf

Please sign in to comment.