Skip to content

Commit

Permalink
Issue warning if PKL does not contain assets of type "text/xml" (#380)
Browse files Browse the repository at this point in the history
CPL/OPL parsing continues to depend on the correct mime type in PKL, but a warning is provided if a PKL does not contain any assets of type text/xml.
  • Loading branch information
fschleich authored Sep 27, 2024
1 parent e1c9cf5 commit 18965f2
Show file tree
Hide file tree
Showing 6 changed files with 385 additions and 12 deletions.
33 changes: 21 additions & 12 deletions src/main/java/com/netflix/imflibrary/app/IMPAnalyzer.java
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,7 @@ public static Map<String, List<ErrorLogger.ErrorObject>> analyzePackage(File roo
}
packingListErrorLogger.addAllErrors(packingList.getErrors());
Map<UUID, PayloadRecord> trackFileIDToHeaderPartitionPayLoadMap = new HashMap<>();
int xmlFileCount = 0;
for (PackingList.Asset asset : packingList.getAssets()) {
if (asset.getType().equals(PackingList.Asset.APPLICATION_MXF_TYPE)) {
URI path = assetMap.getPath(asset.getUUID());
Expand Down Expand Up @@ -302,11 +303,18 @@ public static Map<String, List<ErrorLogger.ErrorObject>> analyzePackage(File roo
finally {
errorMap.put(assetFile.getName(), trackFileErrorLogger.getErrors());
}
} else if (asset.getType().equals(PackingList.Asset.TEXT_XML_TYPE)) {
xmlFileCount++;
}
}

List<ApplicationComposition> applicationCompositionList = analyzeApplicationCompositions( rootFile, assetMap, packingList, headerPartitionPayloadRecords, packingListErrorLogger, errorMap, trackFileIDToHeaderPartitionPayLoadMap);
// issue a warning if the PKL does not contain any assets of type text/xml to help troubleshoot non-compliant mime-types for CPL/OPL
if( xmlFileCount == 0) {
packingListErrorLogger.addError(IMFErrorLogger.IMFErrors.ErrorCodes.IMF_PKL_ERROR,
IMFErrorLogger.IMFErrors.ErrorLevels.WARNING, String.format("Packing List does not contain any assets of type \"%s\" (i.e. PKL does not contain any CPL/OPL files).", PackingList.Asset.TEXT_XML_TYPE));
}

List<ApplicationComposition> applicationCompositionList = analyzeApplicationCompositions( rootFile, assetMap, packingList, headerPartitionPayloadRecords, packingListErrorLogger, errorMap, trackFileIDToHeaderPartitionPayLoadMap);
analyzeOutputProfileLists( rootFile, assetMap, packingList, applicationCompositionList, packingListErrorLogger, errorMap);

} catch (IMFException e) {
Expand Down Expand Up @@ -366,14 +374,14 @@ public static List<OutputProfileList> analyzeOutputProfileLists(File rootFile,
for (PackingList.Asset asset : packingList.getAssets()) {
if (asset.getType().equals(PackingList.Asset.TEXT_XML_TYPE)) {
URI path = assetMap.getPath(asset.getUUID());
if( path == null) {
if (path == null) {
packingListErrorLogger.addError(IMFErrorLogger.IMFErrors.ErrorCodes.IMF_PKL_ERROR,
IMFErrorLogger.IMFErrors.ErrorLevels.FATAL, String.format("Failed to get path for Asset with ID = %s", asset.getUUID().toString()));
continue;
}
File assetFile = new File(rootFile, assetMap.getPath(asset.getUUID()).toString());

if(!assetFile.exists()) {
if (!assetFile.exists()) {
packingListErrorLogger.addError(IMFErrorLogger.IMFErrors.ErrorCodes.IMF_PKL_ERROR,
IMFErrorLogger.IMFErrors.ErrorLevels.FATAL, String.format("Cannot find asset with path %s ID = %s", assetFile.getAbsolutePath(), asset.getUUID().toString()));
continue;
Expand All @@ -384,18 +392,19 @@ public static List<OutputProfileList> analyzeOutputProfileLists(File rootFile,
IMFErrorLogger imfErrorLogger = new IMFErrorLoggerImpl();
try {
OutputProfileList outputProfileListType = OutputProfileList.getOutputProfileListType(resourceByteRangeProvider, imfErrorLogger);
if(outputProfileListType == null) {
if (outputProfileListType == null) {
continue;
}

if(!outputProfileListType.getId().equals(asset.getUUID())) {
if (!outputProfileListType.getId().equals(asset.getUUID())) {
// ST 2067-2:2016 7.3.1: The value of the Id element shall be extracted from the asset as specified in Table 19 for the OPL asset
imfErrorLogger.addError(IMFErrorLogger.IMFErrors.ErrorCodes.IMF_CPL_ERROR,
IMFErrorLogger.IMFErrors.ErrorLevels.NON_FATAL, String.format("UUID %s in the OPL is not same as UUID %s of the OPL in the AssetMap", outputProfileListType.getId().toString(), asset.getUUID().toString()));
} outputProfileListTypeList.add(outputProfileListType);
}
outputProfileListTypeList.add(outputProfileListType);

Optional<ApplicationComposition> optional = applicationCompositionList.stream().filter(e -> e.getUUID().equals(outputProfileListType.getCompositionPlaylistId())).findAny();
if(!optional.isPresent()) {
if (!optional.isPresent()) {
imfErrorLogger.addError(IMFErrorLogger.IMFErrors.ErrorCodes.IMF_OPL_ERROR,
IMFErrorLogger.IMFErrors.ErrorLevels.WARNING, String.format("Failed to get application composition with ID = %s for OutputProfileList with ID %s",
outputProfileListType.getCompositionPlaylistId().toString(), outputProfileListType.getId().toString()));
Expand Down Expand Up @@ -428,14 +437,14 @@ public static List<ApplicationComposition> analyzeApplicationCompositions( File
for (PackingList.Asset asset : packingList.getAssets()) {
if (asset.getType().equals(PackingList.Asset.TEXT_XML_TYPE)) {
URI path = assetMap.getPath(asset.getUUID());
if( path == null) {
if (path == null) {
packingListErrorLogger.addError(IMFErrorLogger.IMFErrors.ErrorCodes.IMF_PKL_ERROR,
IMFErrorLogger.IMFErrors.ErrorLevels.FATAL, String.format("Failed to get path for Asset with ID = %s", asset.getUUID().toString()));
continue;
}
File assetFile = new File(rootFile, assetMap.getPath(asset.getUUID()).toString());

if(!assetFile.exists()) {
if (!assetFile.exists()) {
packingListErrorLogger.addError(IMFErrorLogger.IMFErrors.ErrorCodes.IMF_PKL_ERROR,
IMFErrorLogger.IMFErrors.ErrorLevels.FATAL, String.format("Cannot find asset with path %s ID = %s", assetFile.getAbsolutePath(), asset.getUUID().toString()));
continue;
Expand All @@ -450,10 +459,10 @@ public static List<ApplicationComposition> analyzeApplicationCompositions( File

try {
ApplicationComposition applicationComposition = ApplicationCompositionFactory.getApplicationComposition(resourceByteRangeProvider, compositionErrorLogger);
if(applicationComposition == null) {
if (applicationComposition == null) {
continue;
}
if(!applicationComposition.getUUID().equals(asset.getUUID())) {
if (!applicationComposition.getUUID().equals(asset.getUUID())) {
// ST 2067-2:2016 7.3.1: The value of the Id element shall be extracted from the asset as specified in Table 19 for the CPL asset
compositionErrorLogger.addError(IMFErrorLogger.IMFErrors.ErrorCodes.IMF_CPL_ERROR,
IMFErrorLogger.IMFErrors.ErrorLevels.NON_FATAL, String.format("UUID %s in the CPL is not same as UUID %s of the CPL in the AssetMap", applicationComposition.getUUID().toString(), asset.getUUID().toString()));
Expand Down Expand Up @@ -490,7 +499,7 @@ public static List<ApplicationComposition> analyzeApplicationCompositions( File
.stream()
.map(IMFEssenceComponentVirtualTrack::getTrackResourceIds)
.flatMap(Set::stream)
.map( e -> trackFileIDToHeaderPartitionPayLoadMap.get(e))
.map(e -> trackFileIDToHeaderPartitionPayLoadMap.get(e))
.collect(Collectors.toList());
compositionConformanceErrorLogger.addAllErrors(IMPValidator.areAllVirtualTracksInCPLConformed(cplPayloadRecord, cplHeaderPartitionPayloads));
}
Expand Down
18 changes: 18 additions & 0 deletions src/test/java/com/netflix/imflibrary/app/IMPAnalyzerTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -78,4 +78,22 @@ else if (e.getKey().matches("OPL.*")) {
);

}

@Test
public void IMPAnalyzerTestMimeTypeErrors() throws IOException
{
File inputFile = TestHelper.findResourceByPath("TestIMP/WrongXmlMimeTypes/");
Map<String, List<ErrorLogger.ErrorObject>> errorMap = analyzePackage(inputFile);
Assert.assertEquals(errorMap.size(), 2);
errorMap.entrySet().stream().forEach( e ->
{
if (e.getKey().matches("PKL.*")) {
Assert.assertEquals(e.getValue().size(), 1);
Assert.assertTrue(e.getValue().get(0).getErrorDescription().contains("Packing List does not contain any assets of type"));
} else {
Assert.assertEquals(e.getValue().size(), 0);
}
}
);
}
}
45 changes: 45 additions & 0 deletions src/test/resources/TestIMP/WrongXmlMimeTypes/ASSETMAP.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?xml version="1.0" encoding="UTF-8"?>
<AssetMap xmlns="http://www.smpte-ra.org/schemas/429-9/2007/AM">
<Id>urn:uuid:27d179c3-bf36-4c62-a2a5-d84d5750b188</Id>
<AnnotationText>Untitled Project</AnnotationText>
<Creator>TextEditor</Creator>
<VolumeCount>1</VolumeCount>
<IssueDate>2024-08-22T10:47:34</IssueDate>
<Issuer>TextEditor</Issuer>
<AssetList>
<Asset>
<Id>urn:uuid:cdbc350c-3042-4bb2-849a-43a657455adb</Id>
<ChunkList>
<Chunk>
<Path>CPL_cdbc350c-3042-4bb2-849a-43a657455adb.xml</Path>
<VolumeIndex>1</VolumeIndex>
<Offset>0</Offset>
<Length>12108</Length>
</Chunk>
</ChunkList>
</Asset>
<Asset>
<Id>urn:uuid:d54a68ed-332e-4ddd-b163-c0317abb1e52</Id>
<PackingList>true</PackingList>
<ChunkList>
<Chunk>
<Path>PKL_d54a68ed-332e-4ddd-b163-c0317abb1e52.xml</Path>
<VolumeIndex>1</VolumeIndex>
<Offset>0</Offset>
<Length>1715</Length>
</Chunk>
</ChunkList>
</Asset>
<Asset>
<Id>urn:uuid:778f1aa6-7764-433f-9db7-f1b2c23a5b20</Id>
<ChunkList>
<Chunk>
<Path>OPL_778f1aa6-7764-433f-9db7-f1b2c23a5b20.xml</Path>
<VolumeIndex>1</VolumeIndex>
<Offset>0</Offset>
<Length>706</Length>
</Chunk>
</ChunkList>
</Asset>
</AssetList>
</AssetMap>
Loading

0 comments on commit 18965f2

Please sign in to comment.