Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BXC-4510 add StreamingMetadataService #89

Merged
merged 4 commits into from
Apr 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
package edu.unc.lib.boxc.migration.cdm.services;

import edu.unc.lib.boxc.migration.cdm.exceptions.MigrationException;
import edu.unc.lib.boxc.migration.cdm.model.CdmFieldInfo;
import edu.unc.lib.boxc.migration.cdm.model.MigrationProject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.List;

import static edu.unc.lib.boxc.migration.cdm.util.CLIConstants.outputLogger;

/**
* Service for retrieving streaming metadata
* @author krwong
*/
public class StreamingMetadataService {
private static final Logger log = LoggerFactory.getLogger(StreamingMetadataService.class);

private MigrationProject project;
private CdmFieldService fieldService;
private CdmIndexService indexService;

public static final String STREAMING_FILE_FIELD = "stream";
public static final String DURACLOUD_SPACE_FIELD = "duracl";
public static final String PLAYLIST_FILE_EXTENSION = "-playlist.m3u8";
public static final String DURACLOUD_OPEN = "open-hls";
public static final String DURACLOUD_CAMPUS = "campus-hls";
public static final String DURACLOUD_CLOSED = "closed-hls";
public static final String STREAMING_HOST = "duracloud";

private Boolean projectHasStreamingMetadata = null;

/**
* Verify if a record has streaming metadata
* @param cdmId
* @return true/false
*/
public boolean verifyRecordHasStreamingMetadata(String cdmId) {
if (!hasProjectStreamingMetadataField()) {
return false;
}

var streamingFields = getStreamingFieldValues(cdmId);
return streamingFields[0] != null && streamingFields[1] != null;
}

private boolean hasProjectStreamingMetadataField() {
if (projectHasStreamingMetadata == null) {
// check if project has streamingFile field and duracloudSpace field
fieldService.validateFieldsFile(project);
CdmFieldInfo fieldInfo = fieldService.loadFieldsFromProject(project);
List<String> exportFields = fieldInfo.listAllExportFields();
projectHasStreamingMetadata = exportFields.contains(STREAMING_FILE_FIELD) && exportFields.contains(DURACLOUD_SPACE_FIELD);
}
return projectHasStreamingMetadata;
}

/**
* Retrieve streaming metadata and remap to correct values
* @param cdmId
* @return object with streamingFile, duracloudSpace, and streamingHost fields
*/
public String[] getStreamingMetadata(String cdmId) {
var streamingValues = getStreamingFieldValues(cdmId);
String duracloudSpace = streamingValues[1];
String streamingFile = streamingValues[0];

if (duracloudSpace == null || streamingFile == null) {
throw new MigrationException("Streaming metadata not found for " + cdmId);
}
// transform to playlist file extensions
streamingFile = streamingFile.split("\\.")[0] + PLAYLIST_FILE_EXTENSION;

// transform to current duracloud space IDs
if (duracloudSpace.contains("open")) {
duracloudSpace = DURACLOUD_OPEN;
} else if (duracloudSpace.contains("campus")) {
duracloudSpace = DURACLOUD_CAMPUS;
} else if (duracloudSpace.contains("closed")) {
duracloudSpace = DURACLOUD_CLOSED;
}

return new String[] {streamingFile, duracloudSpace, STREAMING_HOST};
}

private String[] getStreamingFieldValues(String cdmId) {
String duracloudSpace = null;
String streamingFile = null;

// retrieve streaming metadata
Connection conn = null;
try {
conn = indexService.openDbConnection();
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("select " + STREAMING_FILE_FIELD + ", " + DURACLOUD_SPACE_FIELD
+ " from " + CdmIndexService.TB_NAME
+ " where " + CdmFieldInfo.CDM_ID + " = " + cdmId);
while (rs.next()) {
if (!rs.getString(1).isEmpty()) {
streamingFile = rs.getString(1);
}
if (!rs.getString(2).isEmpty()) {
duracloudSpace = rs.getString(2);
}
}
} catch (SQLException e) {
throw new MigrationException("Error interacting with export index", e);
} finally {
CdmIndexService.closeDbConnection(conn);
}
return new String[] {streamingFile, duracloudSpace};
}

public void setProject(MigrationProject project) {
this.project = project;
}

public void setFieldService(CdmFieldService fieldService) {
this.fieldService = fieldService;
}

public void setIndexService(CdmIndexService indexService) {
this.indexService = indexService;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public void reportInitialized() throws Exception {

assertOutputContains("CDM Collection Fields");
assertOutputMatches(".*Mapping File Valid: +Yes.*");
assertOutputMatches(".*Fields: +61\n.*");
assertOutputMatches(".*Fields: +63\n.*");
assertOutputMatches(".*Skipped: +1\n.*");

assertOutputContains("CDM Collection Exports");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
import static org.mockito.Matchers.any;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;
import static org.mockito.MockitoAnnotations.openMocks;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public void allExpectedCellsPopulatedTest() throws Exception {
XSSFWorkbook workbook = new XSSFWorkbook(inputStream);
Sheet sheet = workbook.getSheetAt(0);

assertEquals(60, sheet.getLastRowNum());
assertEquals(62, sheet.getLastRowNum());
assertEquals(16, sheet.getRow(0).getPhysicalNumberOfCells());
assertEquals(12, sheet.getRow(1).getPhysicalNumberOfCells());
assertEquals(12, sheet.getRow(60).getPhysicalNumberOfCells());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package edu.unc.lib.boxc.migration.cdm.services;

import edu.unc.lib.boxc.migration.cdm.exceptions.MigrationException;
import edu.unc.lib.boxc.migration.cdm.model.MigrationProject;
import edu.unc.lib.boxc.migration.cdm.test.BxcEnvironmentHelper;
import edu.unc.lib.boxc.migration.cdm.test.CdmEnvironmentHelper;
import edu.unc.lib.boxc.migration.cdm.test.SipServiceHelper;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;

import java.nio.file.Path;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.MockitoAnnotations.openMocks;

public class StreamingMetadataServiceTest {
private static final String PROJECT_NAME = "proj";

@TempDir
public Path tmpFolder;

private SipServiceHelper testHelper;
private MigrationProject project;
private StreamingMetadataService service;
private AutoCloseable closeable;

@BeforeEach
public void setup() throws Exception {
closeable = openMocks(this);
project = MigrationProjectFactory.createMigrationProject(
tmpFolder, PROJECT_NAME, null, "user",
CdmEnvironmentHelper.DEFAULT_ENV_ID, BxcEnvironmentHelper.DEFAULT_ENV_ID);
testHelper = new SipServiceHelper(project, tmpFolder);
service = new StreamingMetadataService();
service.setProject(project);
service.setFieldService(testHelper.getFieldService());
service.setIndexService(testHelper.getIndexService());
}

@AfterEach
void closeService() throws Exception {
closeable.close();
}

@Test
public void verifyNoStreamingMetadata() throws Exception {
testHelper.indexExportData("mini_gilmer");

var result = service.verifyRecordHasStreamingMetadata("25");
assertFalse(result);
}

@Test
public void verifyHasStreamingMetadata() throws Exception {
testHelper.indexExportData("mini_gilmer");

var result = service.verifyRecordHasStreamingMetadata("27");
assertTrue(result);
}

@Test
public void getStreamingMetadataSuccess() throws Exception {
testHelper.indexExportData("mini_gilmer");

var result = service.getStreamingMetadata("27");
assertEquals("gilmer_recording-playlist.m3u8", result[0]);
assertEquals("open-hls", result[1]);
assertEquals("duracloud", result[2]);
}

@Test
public void getStreamingMetadataFail() throws Exception {
testHelper.indexExportData("mini_gilmer");

Exception exception = assertThrows(MigrationException.class, () -> {
service.getStreamingMetadata("25");
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,8 @@
<fila>TIFF</fila>
<filb>TIFF</filb>
<groupa>group2</groupa>
<stream>gilmer_recording.mp3</stream>
<duracl>sfc20009-open</duracl>
<full>/shc/gilmer_maps/</full>
<fullrs>276_203_E.tif</fullrs>
<find>50.jp2</find>
Expand Down
2 changes: 2 additions & 0 deletions src/test/resources/gilmer_fields.csv
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ color,color,Color Space Raw Scan,false,n,n,y,n,BLANK
coloa,coloa,Color Space filename,false,n,n,y,n,BLANK
fila,fila,File Format Raw Scan,false,n,n,y,y,BLANK
filb,filb,File Format filename,false,n,n,y,y,BLANK
stream,stream,StreamingFile,false,n,n,n,y,BLANK
duracl,duracl,duracloudSpace,false,n,n,n,y,identi
full,full,path,false,n,n,n,n,BLANK
fullrs,fullrs,Full resolution,false,n,n,y,n,
dmoclcno,dmoclcno,OCLC number,false,n,n,y,n,
Expand Down
Loading