Skip to content

Commit 5987326

Browse files
committed
Merge pull request Sofie-Automation#1263 from bbc/upstream/config-package-manager-from-blueprints
# Conflicts: # packages/corelib/src/dataModel/Studio.ts
2 parents 1ccd814 + e8e1a28 commit 5987326

File tree

25 files changed

+1256
-895
lines changed

25 files changed

+1256
-895
lines changed

meteor/__mocks__/defaultCollectionObjects.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ export function defaultStudio(_id: StudioId): DBStudio {
114114
_rundownVersionHash: '',
115115
routeSetsWithOverrides: wrapDefaultObject({}),
116116
routeSetExclusivityGroupsWithOverrides: wrapDefaultObject({}),
117-
packageContainers: {},
117+
packageContainersWithOverrides: wrapDefaultObject({}),
118118
previewContainerIds: [],
119119
thumbnailContainerIds: [],
120120
peripheralDeviceSettings: {

meteor/server/api/rest/v1/typeConversion.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,7 @@ export async function studioFrom(apiStudio: APIStudio, existingId?: StudioId): P
279279
routeSetsWithOverrides: wrapDefaultObject({}),
280280
_rundownVersionHash: '',
281281
routeSetExclusivityGroupsWithOverrides: wrapDefaultObject({}),
282-
packageContainers: {},
282+
packageContainersWithOverrides: wrapDefaultObject({}),
283283
previewContainerIds: [],
284284
thumbnailContainerIds: [],
285285
peripheralDeviceSettings: {

meteor/server/api/studio/api.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ export async function insertStudioInner(organizationId: OrganizationId | null, n
5252
_rundownVersionHash: '',
5353
routeSetsWithOverrides: wrapDefaultObject({}),
5454
routeSetExclusivityGroupsWithOverrides: wrapDefaultObject({}),
55-
packageContainers: {},
55+
packageContainersWithOverrides: wrapDefaultObject({}),
5656
thumbnailContainerIds: [],
5757
previewContainerIds: [],
5858
peripheralDeviceSettings: {

meteor/server/migration/0_1_0.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -447,7 +447,7 @@ export const addSteps = addMigrationSteps('0.1.0', [
447447
_rundownVersionHash: '',
448448
routeSetsWithOverrides: wrapDefaultObject({}),
449449
routeSetExclusivityGroupsWithOverrides: wrapDefaultObject({}),
450-
packageContainers: {},
450+
packageContainersWithOverrides: wrapDefaultObject({}),
451451
thumbnailContainerIds: [],
452452
previewContainerIds: [],
453453
peripheralDeviceSettings: {

meteor/server/migration/X_X_X.ts

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,11 @@ import { addMigrationSteps } from './databaseMigration'
22
import { CURRENT_SYSTEM_VERSION } from './currentSystemVersion'
33
import { Studios } from '../collections'
44
import { convertObjectIntoOverrides } from '@sofie-automation/corelib/dist/settings/objectWithOverrides'
5-
import { StudioRouteSet, StudioRouteSetExclusivityGroup } from '@sofie-automation/corelib/dist/dataModel/Studio'
5+
import {
6+
StudioRouteSet,
7+
StudioRouteSetExclusivityGroup,
8+
StudioPackageContainer,
9+
} from '@sofie-automation/corelib/dist/dataModel/Studio'
610

711
/*
812
* **************************************************************************************
@@ -140,4 +144,47 @@ export const addSteps = addMigrationSteps(CURRENT_SYSTEM_VERSION, [
140144
}
141145
},
142146
},
147+
{
148+
id: `convert packageContainers to ObjectWithOverrides`,
149+
canBeRunAutomatically: true,
150+
validate: async () => {
151+
const studios = await Studios.findFetchAsync({
152+
packageContainers: { $exists: true },
153+
packageContainersWithOverrides: { $exists: false },
154+
})
155+
156+
for (const studio of studios) {
157+
// @ts-expect-error packageContainers is typed as Record<string, StudioPackageContainer>
158+
if (studio.packageContainers) {
159+
return 'packageContainers must be converted to an ObjectWithOverrides'
160+
}
161+
}
162+
163+
return false
164+
},
165+
migrate: async () => {
166+
const studios = await Studios.findFetchAsync({
167+
packageContainers: { $exists: true },
168+
packageContainersWithOverrides: { $exists: false },
169+
})
170+
171+
for (const studio of studios) {
172+
// @ts-expect-error packageContainers is typed as Record<string, StudioPackageContainer>
173+
const oldPackageContainers = studio.packageContainers
174+
175+
const newPackageContainers = convertObjectIntoOverrides<StudioPackageContainer>(
176+
oldPackageContainers || {}
177+
)
178+
179+
await Studios.updateAsync(studio._id, {
180+
$set: {
181+
packageContainersWithOverrides: newPackageContainers,
182+
},
183+
$unset: {
184+
packageContainers: 1,
185+
},
186+
})
187+
}
188+
},
189+
},
143190
])

meteor/server/migration/__tests__/migrations.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ describe('Migrations', () => {
132132
_rundownVersionHash: '',
133133
routeSetsWithOverrides: wrapDefaultObject({}),
134134
routeSetExclusivityGroupsWithOverrides: wrapDefaultObject({}),
135-
packageContainers: {},
135+
packageContainersWithOverrides: wrapDefaultObject({}),
136136
previewContainerIds: [],
137137
thumbnailContainerIds: [],
138138
peripheralDeviceSettings: {
@@ -170,7 +170,7 @@ describe('Migrations', () => {
170170
_rundownVersionHash: '',
171171
routeSetsWithOverrides: wrapDefaultObject({}),
172172
routeSetExclusivityGroupsWithOverrides: wrapDefaultObject({}),
173-
packageContainers: {},
173+
packageContainersWithOverrides: wrapDefaultObject({}),
174174
previewContainerIds: [],
175175
thumbnailContainerIds: [],
176176
peripheralDeviceSettings: {
@@ -208,7 +208,7 @@ describe('Migrations', () => {
208208
_rundownVersionHash: '',
209209
routeSetsWithOverrides: wrapDefaultObject({}),
210210
routeSetExclusivityGroupsWithOverrides: wrapDefaultObject({}),
211-
packageContainers: {},
211+
packageContainersWithOverrides: wrapDefaultObject({}),
212212
previewContainerIds: [],
213213
thumbnailContainerIds: [],
214214
peripheralDeviceSettings: {

meteor/server/publications/packageManager/expectedPackages/generate.ts

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ export async function updateCollectionForExpectedPackageIds(
3131
contentCache: ReadonlyDeep<ExpectedPackagesContentCache>,
3232
studio: Pick<DBStudio, StudioFields>,
3333
layerNameToDeviceIds: Map<string, PeripheralDeviceId[]>,
34+
packageContainers: Record<string, StudioPackageContainer>,
3435
collection: CustomPublishCollection<PackageManagerExpectedPackage>,
3536
filterPlayoutDeviceIds: ReadonlyDeep<PeripheralDeviceId[]> | undefined,
3637
regenerateIds: Set<ExpectedPackageId>
@@ -66,7 +67,8 @@ export async function updateCollectionForExpectedPackageIds(
6667
},
6768
deviceId,
6869
null,
69-
Priorities.OTHER // low priority
70+
Priorities.OTHER, // low priority
71+
packageContainers
7072
)
7173

7274
updatedDocIds.add(routedPackage._id)
@@ -99,6 +101,7 @@ export async function updateCollectionForPieceInstanceIds(
99101
contentCache: ReadonlyDeep<ExpectedPackagesContentCache>,
100102
studio: Pick<DBStudio, StudioFields>,
101103
layerNameToDeviceIds: Map<string, PeripheralDeviceId[]>,
104+
packageContainers: Record<string, StudioPackageContainer>,
102105
collection: CustomPublishCollection<PackageManagerExpectedPackage>,
103106
filterPlayoutDeviceIds: ReadonlyDeep<PeripheralDeviceId[]> | undefined,
104107
regenerateIds: Set<PieceInstanceId>
@@ -140,7 +143,8 @@ export async function updateCollectionForPieceInstanceIds(
140143
},
141144
deviceId,
142145
pieceInstanceId,
143-
Priorities.OTHER // low priority
146+
Priorities.OTHER, // low priority
147+
packageContainers
144148
)
145149

146150
updatedDocIds.add(routedPackage._id)
@@ -172,17 +176,21 @@ enum Priorities {
172176
}
173177

174178
function generateExpectedPackageForDevice(
175-
studio: Pick<StudioLight, '_id' | 'packageContainers' | 'previewContainerIds' | 'thumbnailContainerIds'>,
179+
studio: Pick<
180+
StudioLight,
181+
'_id' | 'packageContainersWithOverrides' | 'previewContainerIds' | 'thumbnailContainerIds'
182+
>,
176183
expectedPackage: PackageManagerExpectedPackageBase,
177184
deviceId: PeripheralDeviceId,
178185
pieceInstanceId: PieceInstanceId | null,
179-
priority: Priorities
186+
priority: Priorities,
187+
packageContainers: Record<string, StudioPackageContainer>
180188
): PackageManagerExpectedPackage {
181189
// Lookup Package sources:
182190
const combinedSources: PackageContainerOnPackage[] = []
183191

184192
for (const packageSource of expectedPackage.sources) {
185-
const lookedUpSource = studio.packageContainers[packageSource.containerId]
193+
const lookedUpSource = packageContainers[packageSource.containerId]
186194
if (lookedUpSource) {
187195
combinedSources.push(calculateCombinedSource(packageSource, lookedUpSource))
188196
} else {
@@ -199,7 +207,7 @@ function generateExpectedPackageForDevice(
199207
}
200208

201209
// Lookup Package targets:
202-
const combinedTargets = calculateCombinedTargets(studio, expectedPackage, deviceId)
210+
const combinedTargets = calculateCombinedTargets(expectedPackage, deviceId, packageContainers)
203211

204212
if (!combinedSources.length && expectedPackage.sources.length !== 0) {
205213
logger.warn(`Pub.expectedPackagesForDevice: No sources found for "${expectedPackage._id}"`)
@@ -253,14 +261,14 @@ function calculateCombinedSource(
253261
return combinedSource
254262
}
255263
function calculateCombinedTargets(
256-
studio: Pick<StudioLight, '_id' | 'packageContainers'>,
257264
expectedPackage: PackageManagerExpectedPackageBase,
258-
deviceId: PeripheralDeviceId
265+
deviceId: PeripheralDeviceId,
266+
packageContainers: Record<string, StudioPackageContainer>
259267
): PackageContainerOnPackage[] {
260268
const mappingDeviceId = unprotectString(deviceId)
261269

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

271279
const combinedTargets: PackageContainerOnPackage[] = []
272280
if (packageContainerId) {
273-
const lookedUpTarget = studio.packageContainers[packageContainerId]
281+
const lookedUpTarget = packageContainers[packageContainerId]
274282
if (lookedUpTarget) {
275283
// Todo: should the be any combination of properties here?
276284
combinedTargets.push({

meteor/server/publications/packageManager/expectedPackages/publication.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { Meteor } from 'meteor/meteor'
22
import { PeripheralDeviceReadAccess } from '../../../security/peripheralDevice'
3-
import { DBStudio } from '@sofie-automation/corelib/dist/dataModel/Studio'
3+
import { DBStudio, StudioPackageContainer } from '@sofie-automation/corelib/dist/dataModel/Studio'
44
import {
55
TriggerUpdate,
66
meteorCustomPublish,
@@ -48,6 +48,7 @@ interface ExpectedPackagesPublicationUpdateProps {
4848
interface ExpectedPackagesPublicationState {
4949
studio: Pick<DBStudio, StudioFields> | undefined
5050
layerNameToDeviceIds: Map<string, PeripheralDeviceId[]>
51+
packageContainers: Record<string, StudioPackageContainer>
5152

5253
contentCache: ReadonlyDeep<ExpectedPackagesContentCache>
5354
}
@@ -56,14 +57,14 @@ export type StudioFields =
5657
| '_id'
5758
| 'routeSetsWithOverrides'
5859
| 'mappingsWithOverrides'
59-
| 'packageContainers'
60+
| 'packageContainersWithOverrides'
6061
| 'previewContainerIds'
6162
| 'thumbnailContainerIds'
6263
const studioFieldSpecifier = literal<MongoFieldSpecifierOnesStrict<Pick<DBStudio, StudioFields>>>({
6364
_id: 1,
6465
routeSetsWithOverrides: 1,
6566
mappingsWithOverrides: 1,
66-
packageContainers: 1,
67+
packageContainersWithOverrides: 1,
6768
previewContainerIds: 1,
6869
thumbnailContainerIds: 1,
6970
})
@@ -122,6 +123,7 @@ async function manipulateExpectedPackagesPublicationData(
122123
const invalidateAllItems = !updateProps || updateProps.newCache || updateProps.invalidateStudio
123124

124125
if (!state.layerNameToDeviceIds) state.layerNameToDeviceIds = new Map()
126+
if (!state.packageContainers) state.packageContainers = {}
125127

126128
if (invalidateAllItems) {
127129
// Everything is invalid, reset everything
@@ -141,12 +143,14 @@ async function manipulateExpectedPackagesPublicationData(
141143
if (!state.studio) {
142144
logger.warn(`Pub.expectedPackagesForDevice: studio "${args.studioId}" not found!`)
143145
state.layerNameToDeviceIds = new Map()
146+
state.packageContainers = {}
144147
} else {
145148
const studioMappings = applyAndValidateOverrides(state.studio.mappingsWithOverrides).obj
146149
state.layerNameToDeviceIds = buildMappingsToDeviceIdMap(
147150
applyAndValidateOverrides(state.studio.routeSetsWithOverrides).obj,
148151
studioMappings
149152
)
153+
state.packageContainers = applyAndValidateOverrides(state.studio.packageContainersWithOverrides).obj
150154
}
151155
}
152156

@@ -173,6 +177,7 @@ async function manipulateExpectedPackagesPublicationData(
173177
state.contentCache,
174178
state.studio,
175179
state.layerNameToDeviceIds,
180+
state.packageContainers,
176181
collection,
177182
args.filterPlayoutDeviceIds,
178183
regenerateExpectedPackageIds
@@ -181,6 +186,7 @@ async function manipulateExpectedPackagesPublicationData(
181186
state.contentCache,
182187
state.studio,
183188
state.layerNameToDeviceIds,
189+
state.packageContainers,
184190
collection,
185191
args.filterPlayoutDeviceIds,
186192
regeneratePieceInstanceIds

meteor/server/publications/packageManager/packageContainers.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,12 @@ import {
1515
PeripheralDevicePubSub,
1616
PeripheralDevicePubSubCollectionsNames,
1717
} from '@sofie-automation/shared-lib/dist/pubsub/peripheralDevice'
18+
import { applyAndValidateOverrides } from '@sofie-automation/corelib/dist/settings/objectWithOverrides'
1819

19-
type StudioFields = '_id' | 'packageContainers'
20+
type StudioFields = '_id' | 'packageContainersWithOverrides'
2021
const studioFieldSpecifier = literal<MongoFieldSpecifierOnesStrict<Pick<DBStudio, StudioFields>>>({
2122
_id: 1,
22-
packageContainers: 1,
23+
packageContainersWithOverrides: 1,
2324
})
2425

2526
interface PackageManagerPackageContainersArgs {
@@ -68,8 +69,9 @@ async function manipulateExpectedPackagesPublicationData(
6869

6970
const packageContainers: { [containerId: string]: PackageContainer } = {}
7071
if (studio) {
72+
const studioPackageContainers = applyAndValidateOverrides(studio.packageContainersWithOverrides).obj
7173
for (const [containerId, studioPackageContainer] of Object.entries<StudioPackageContainer>(
72-
studio.packageContainers
74+
studioPackageContainers
7375
)) {
7476
packageContainers[containerId] = studioPackageContainer.container
7577
}

meteor/server/publications/pieceContentStatusUI/__tests__/checkPieceContentStatus.test.ts

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
getMediaObjectMediaId,
66
PieceContentStreamInfo,
77
checkPieceContentStatusAndDependencies,
8+
PieceContentStatusStudio,
89
} from '../checkPieceContentStatus'
910
import {
1011
PackageInfo,
@@ -31,12 +32,10 @@ import {
3132
MediaStream,
3233
MediaStreamType,
3334
} from '@sofie-automation/shared-lib/dist/core/model/MediaObjects'
34-
import { UIStudio } from '@sofie-automation/meteor-lib/dist/api/studios'
3535
import { defaultStudio } from '../../../../__mocks__/defaultCollectionObjects'
3636
import { testInFiber } from '../../../../__mocks__/helpers/jest'
3737
import { MediaObjects } from '../../../collections'
3838
import { PieceDependencies } from '../common'
39-
import { DBStudio } from '@sofie-automation/corelib/dist/dataModel/Studio'
4039
import { DEFAULT_MINIMUM_TAKE_SPAN } from '@sofie-automation/shared-lib/dist/core/constants'
4140

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

176175
const mockDefaultStudio = defaultStudio(protectString('studio0'))
177-
const mockStudio: Complete<
178-
Pick<DBStudio, '_id' | 'settings' | 'packageContainers' | 'previewContainerIds' | 'thumbnailContainerIds'> &
179-
Pick<UIStudio, 'mappings' | 'routeSets'>
180-
> = {
176+
const mockStudio: Complete<PieceContentStatusStudio> = {
181177
_id: mockDefaultStudio._id,
182178
settings: mockStudioSettings,
183-
packageContainers: mockDefaultStudio.packageContainers,
184179
previewContainerIds: ['previews0'],
185180
thumbnailContainerIds: ['thumbnails0'],
186181
routeSets: applyAndValidateOverrides(mockDefaultStudio.routeSetsWithOverrides).obj,
187182
mappings: applyAndValidateOverrides(mockDefaultStudio.mappingsWithOverrides).obj,
183+
packageContainers: applyAndValidateOverrides(mockDefaultStudio.packageContainersWithOverrides).obj,
188184
}
189185

190186
mockMediaObjectsCollection.insert(

0 commit comments

Comments
 (0)