use of org.opencastproject.mediapackage.MediaPackageException in project opencast by opencast.
the class TestRestService method newAssetManager.
private static AssetManager newAssetManager() {
Snapshot snapshot = EasyMock.createNiceMock(Snapshot.class);
try {
EasyMock.expect(snapshot.getMediaPackage()).andReturn(new MediaPackageBuilderImpl().createNew()).anyTimes();
} catch (MediaPackageException e) {
throw new RuntimeException(e);
}
ARecord record = EasyMock.createNiceMock(ARecord.class);
EasyMock.expect(record.getSnapshot()).andReturn(Opt.some(snapshot)).anyTimes();
AResult result = EasyMock.createNiceMock(AResult.class);
EasyMock.expect(result.getRecords()).andReturn($(record)).anyTimes();
ASelectQuery select = EasyMock.createNiceMock(ASelectQuery.class);
EasyMock.expect(select.where(EasyMock.anyObject(Predicate.class))).andReturn(select).anyTimes();
EasyMock.expect(select.run()).andReturn(result).anyTimes();
Predicate predicate = EasyMock.createNiceMock(Predicate.class);
EasyMock.expect(predicate.and(EasyMock.anyObject(Predicate.class))).andReturn(predicate).anyTimes();
AQueryBuilder query = EasyMock.createNiceMock(AQueryBuilder.class);
VersionField version = EasyMock.createNiceMock(VersionField.class);
EasyMock.expect(query.version()).andReturn(version).anyTimes();
EasyMock.expect(query.mediaPackageId(EasyMock.anyString())).andReturn(predicate).anyTimes();
EasyMock.expect(query.select(EasyMock.anyObject(Target.class))).andReturn(select).anyTimes();
AssetManager assetManager = EasyMock.createNiceMock(AssetManager.class);
EasyMock.expect(assetManager.createQuery()).andReturn(query).anyTimes();
EasyMock.replay(assetManager, version, query, predicate, select, result, record, snapshot);
return assetManager;
}
use of org.opencastproject.mediapackage.MediaPackageException in project opencast by opencast.
the class CaptionServiceImpl method convert.
/**
* Converts the captions and returns them in a new catalog.
*
* @return the converted catalog
*/
protected MediaPackageElement convert(Job job, MediaPackageElement input, String inputFormat, String outputFormat, String language) throws UnsupportedCaptionFormatException, CaptionConverterException, MediaPackageException {
try {
// check parameters
if (input == null)
throw new IllegalArgumentException("Input element can't be null");
if (StringUtils.isBlank(inputFormat))
throw new IllegalArgumentException("Input format is null");
if (StringUtils.isBlank(outputFormat))
throw new IllegalArgumentException("Output format is null");
// get input file
File captionsFile;
try {
captionsFile = workspace.get(input.getURI());
} catch (NotFoundException e) {
throw new CaptionConverterException("Requested media package element " + input + " could not be found.");
} catch (IOException e) {
throw new CaptionConverterException("Requested media package element " + input + "could not be accessed.");
}
logger.debug("Atempting to convert from {} to {}...", inputFormat, outputFormat);
List<Caption> collection = null;
try {
collection = importCaptions(captionsFile, inputFormat, language);
logger.debug("Parsing to collection succeeded.");
} catch (UnsupportedCaptionFormatException e) {
throw new UnsupportedCaptionFormatException(inputFormat);
} catch (CaptionConverterException e) {
throw e;
}
URI exported;
try {
exported = exportCaptions(collection, job.getId() + "." + FilenameUtils.getExtension(captionsFile.getAbsolutePath()), outputFormat, language);
logger.debug("Exporting captions succeeding.");
} catch (UnsupportedCaptionFormatException e) {
throw new UnsupportedCaptionFormatException(outputFormat);
} catch (IOException e) {
throw new CaptionConverterException("Could not export caption collection.", e);
}
// create catalog and set properties
CaptionConverter converter = getCaptionConverter(outputFormat);
MediaPackageElementBuilder elementBuilder = MediaPackageElementBuilderFactory.newInstance().newElementBuilder();
MediaPackageElement mpe = elementBuilder.elementFromURI(exported, converter.getElementType(), new MediaPackageElementFlavor("captions", outputFormat + (language == null ? "" : "+" + language)));
if (mpe.getMimeType() == null) {
String[] mimetype = FileTypeMap.getDefaultFileTypeMap().getContentType(exported.getPath()).split("/");
mpe.setMimeType(mimeType(mimetype[0], mimetype[1]));
}
if (language != null)
mpe.addTag("lang:" + language);
return mpe;
} catch (Exception e) {
logger.warn("Error converting captions in " + input, e);
if (e instanceof CaptionConverterException) {
throw (CaptionConverterException) e;
} else if (e instanceof UnsupportedCaptionFormatException) {
throw (UnsupportedCaptionFormatException) e;
} else {
throw new CaptionConverterException(e);
}
}
}
use of org.opencastproject.mediapackage.MediaPackageException in project opencast by opencast.
the class IngestRestService method addDCCatalog.
/**
* Adds a dublinCore metadata catalog to the MediaPackage and returns the grown mediaPackage. JQuery Ajax functions
* doesn't support multipart/form-data encoding.
*
* @param mp
* MediaPackage
* @param dc
* DublinCoreCatalog
* @return grown MediaPackage XML
*/
@POST
@Produces(MediaType.TEXT_XML)
@Path("addDCCatalog")
@RestQuery(name = "addDCCatalog", description = "Add a dublincore episode catalog to a given media package using an url", restParameters = { @RestParameter(description = "The media package as XML", isRequired = true, name = "mediaPackage", type = RestParameter.Type.TEXT), @RestParameter(description = "DublinCore catalog as XML", isRequired = true, name = "dublinCore", type = RestParameter.Type.TEXT), @RestParameter(defaultValue = "dublincore/episode", description = "DublinCore Flavor", isRequired = false, name = "flavor", type = RestParameter.Type.STRING) }, reponses = { @RestResponse(description = "Returns augmented media package", responseCode = HttpServletResponse.SC_OK), @RestResponse(description = "Media package not valid", responseCode = HttpServletResponse.SC_BAD_REQUEST), @RestResponse(description = "", responseCode = HttpServletResponse.SC_INTERNAL_SERVER_ERROR) }, returnDescription = "")
public Response addDCCatalog(@FormParam("mediaPackage") String mp, @FormParam("dublinCore") String dc, @FormParam("flavor") String flavor) {
logger.trace("add DC catalog: {} with flavor: {} to media package: {}", dc, flavor, mp);
MediaPackageElementFlavor dcFlavor = MediaPackageElements.EPISODE;
if (flavor != null) {
try {
dcFlavor = MediaPackageElementFlavor.parseFlavor(flavor);
} catch (IllegalArgumentException e) {
logger.warn("Unable to set dublin core flavor to {}, using {} instead", flavor, MediaPackageElements.EPISODE);
}
}
MediaPackage mediaPackage;
/* Check if we got a proper mediapackage and try to parse it */
try {
mediaPackage = MediaPackageBuilderFactory.newInstance().newMediaPackageBuilder().loadFromXml(mp);
} catch (MediaPackageException e) {
return Response.serverError().status(Status.BAD_REQUEST).build();
}
if (MediaPackageSupport.sanityCheck(mediaPackage).isSome()) {
return Response.serverError().status(Status.BAD_REQUEST).build();
}
/* Check if we got a proper catalog */
if (StringUtils.isBlank(dc)) {
return Response.serverError().status(Status.BAD_REQUEST).build();
}
InputStream in = null;
try {
in = IOUtils.toInputStream(dc, "UTF-8");
mediaPackage = ingestService.addCatalog(in, "dublincore.xml", dcFlavor, mediaPackage);
} catch (MediaPackageException e) {
return Response.serverError().status(Status.BAD_REQUEST).build();
} catch (IOException e) {
/* Return an internal server error if we could not write to disk */
logger.error("Could not write catalog to disk: {}", e.getMessage());
return Response.serverError().build();
} catch (Exception e) {
logger.error(e.getMessage());
return Response.serverError().build();
} finally {
IOUtils.closeQuietly(in);
}
return Response.ok(mediaPackage).build();
}
use of org.opencastproject.mediapackage.MediaPackageException in project opencast by opencast.
the class IngestRestService method schedule.
@POST
@Path("schedule/{wdID}")
@RestQuery(name = "schedule", description = "Schedule an event based on the given media package", pathParameters = { @RestParameter(description = "Workflow definition id", isRequired = true, name = "wdID", type = RestParameter.Type.STRING) }, restParameters = { @RestParameter(description = "The media package", isRequired = true, name = "mediaPackage", type = RestParameter.Type.TEXT) }, reponses = { @RestResponse(description = "Event scheduled", responseCode = HttpServletResponse.SC_CREATED), @RestResponse(description = "Media package not valid", responseCode = HttpServletResponse.SC_BAD_REQUEST) }, returnDescription = "")
public Response schedule(@PathParam("wdID") String wdID, MultivaluedMap<String, String> formData) {
if (StringUtils.isBlank(wdID)) {
logger.trace("workflow definition id is not specified");
return Response.status(Response.Status.BAD_REQUEST).build();
}
Map<String, String> wfConfig = getWorkflowConfig(formData);
if (StringUtils.isNotBlank(wdID)) {
wfConfig.put(CaptureParameters.INGEST_WORKFLOW_DEFINITION, wdID);
}
logger.debug("Schedule with workflow definition '{}'", wfConfig.get(WORKFLOW_DEFINITION_ID_PARAM));
String mediaPackageXml = formData.getFirst("mediaPackage");
if (StringUtils.isBlank(mediaPackageXml)) {
logger.debug("Rejected schedule without media package");
return Response.status(Status.BAD_REQUEST).build();
}
MediaPackage mp = null;
try {
mp = factory.newMediaPackageBuilder().loadFromXml(mediaPackageXml);
if (MediaPackageSupport.sanityCheck(mp).isSome()) {
throw new MediaPackageException("Insane media package");
}
} catch (MediaPackageException e) {
logger.debug("Rejected ingest with invalid media package {}", mp);
return Response.status(Status.BAD_REQUEST).build();
}
MediaPackageElement[] mediaPackageElements = mp.getElementsByFlavor(MediaPackageElements.EPISODE);
if (mediaPackageElements.length != 1) {
logger.debug("There can be only one (and exactly one) episode dublin core catalog: https://youtu.be/_J3VeogFUOs");
return Response.status(Status.BAD_REQUEST).build();
}
try {
ingestService.schedule(mp, wdID, wfConfig);
return Response.status(Status.CREATED).build();
} catch (IngestException e) {
return Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build();
} catch (SchedulerConflictException e) {
return Response.status(Status.CONFLICT).entity(e.getMessage()).build();
} catch (NotFoundException | UnauthorizedException | SchedulerException e) {
return Response.serverError().build();
}
}
use of org.opencastproject.mediapackage.MediaPackageException in project opencast by opencast.
the class IngestServiceImpl method addZippedMediaPackage.
/**
* {@inheritDoc}
*
* @see org.opencastproject.ingest.api.IngestService#addZippedMediaPackage(java.io.InputStream, java.lang.String,
* java.util.Map, java.lang.Long)
*/
@Override
public WorkflowInstance addZippedMediaPackage(InputStream zipStream, String workflowDefinitionId, Map<String, String> workflowConfig, Long workflowInstanceId) throws MediaPackageException, IOException, IngestException, NotFoundException, UnauthorizedException {
// Start a job synchronously. We can't keep the open input stream waiting around.
Job job = null;
if (StringUtils.isNotBlank(workflowDefinitionId)) {
try {
workflowService.getWorkflowDefinitionById(workflowDefinitionId);
} catch (WorkflowDatabaseException e) {
throw new IngestException(e);
} catch (NotFoundException nfe) {
logger.warn("Workflow definition {} not found, using default workflow {} instead", workflowDefinitionId, defaultWorkflowDefinionId);
workflowDefinitionId = defaultWorkflowDefinionId;
}
}
if (workflowInstanceId != null) {
logger.warn("Deprecated method! Ingesting zipped mediapackage with workflow {}", workflowInstanceId);
} else {
logger.info("Ingesting zipped mediapackage");
}
ZipArchiveInputStream zis = null;
Set<String> collectionFilenames = new HashSet<>();
try {
// We don't need anybody to do the dispatching for us. Therefore we need to make sure that the job is never in
// QUEUED state but set it to INSTANTIATED in the beginning and then manually switch it to RUNNING.
job = serviceRegistry.createJob(JOB_TYPE, INGEST_ZIP, null, null, false, ingestZipJobLoad);
job.setStatus(Status.RUNNING);
job = serviceRegistry.updateJob(job);
// Create the working file target collection for this ingest operation
String wfrCollectionId = Long.toString(job.getId());
zis = new ZipArchiveInputStream(zipStream);
ZipArchiveEntry entry;
MediaPackage mp = null;
Map<String, URI> uris = new HashMap<>();
// Sequential number to append to file names so that, if two files have the same
// name, one does not overwrite the other (see MH-9688)
int seq = 1;
// Folder name to compare with next one to figure out if there's a root folder
String folderName = null;
// Indicates if zip has a root folder or not, initialized as true
boolean hasRootFolder = true;
// While there are entries write them to a collection
while ((entry = zis.getNextZipEntry()) != null) {
try {
if (entry.isDirectory() || entry.getName().contains("__MACOSX"))
continue;
if (entry.getName().endsWith("manifest.xml") || entry.getName().endsWith("index.xml")) {
// Build the mediapackage
mp = loadMediaPackageFromManifest(new ZipEntryInputStream(zis, entry.getSize()));
} else {
logger.info("Storing zip entry {}/{} in working file repository collection '{}'", job.getId(), entry.getName(), wfrCollectionId);
// Since the directory structure is not being mirrored, makes sure the file
// name is different than the previous one(s) by adding a sequential number
String fileName = FilenameUtils.getBaseName(entry.getName()) + "_" + seq++ + "." + FilenameUtils.getExtension(entry.getName());
URI contentUri = workingFileRepository.putInCollection(wfrCollectionId, fileName, new ZipEntryInputStream(zis, entry.getSize()));
collectionFilenames.add(fileName);
// Key is the zip entry name as it is
String key = entry.getName();
uris.put(key, contentUri);
ingestStatistics.add(entry.getSize());
logger.info("Zip entry {}/{} stored at {}", job.getId(), entry.getName(), contentUri);
// Figures out if there's a root folder. Does entry name starts with a folder?
int pos = entry.getName().indexOf('/');
if (pos == -1) {
// No, we can conclude there's no root folder
hasRootFolder = false;
} else if (hasRootFolder && folderName != null && !folderName.equals(entry.getName().substring(0, pos))) {
// Folder name different from previous so there's no root folder
hasRootFolder = false;
} else if (folderName == null) {
// Just initialize folder name
folderName = entry.getName().substring(0, pos);
}
}
} catch (IOException e) {
logger.warn("Unable to process zip entry {}: {}", entry.getName(), e);
throw e;
}
}
if (mp == null)
throw new MediaPackageException("No manifest found in this zip");
// Determine the mediapackage identifier
if (mp.getIdentifier() == null || isBlank(mp.getIdentifier().toString()))
mp.setIdentifier(new UUIDIdBuilderImpl().createNew());
String mediaPackageId = mp.getIdentifier().toString();
logger.info("Ingesting mediapackage {} is named '{}'", mediaPackageId, mp.getTitle());
// Make sure there are tracks in the mediapackage
if (mp.getTracks().length == 0) {
logger.warn("Mediapackage {} has no media tracks", mediaPackageId);
}
// Update the element uris to point to their working file repository location
for (MediaPackageElement element : mp.elements()) {
// Key has root folder name if there is one
URI uri = uris.get((hasRootFolder ? folderName + "/" : "") + element.getURI().toString());
if (uri == null)
throw new MediaPackageException("Unable to map element name '" + element.getURI() + "' to workspace uri");
logger.info("Ingested mediapackage element {}/{} located at {}", mediaPackageId, element.getIdentifier(), uri);
URI dest = workingFileRepository.moveTo(wfrCollectionId, FilenameUtils.getName(uri.toString()), mediaPackageId, element.getIdentifier(), FilenameUtils.getName(element.getURI().toString()));
element.setURI(dest);
// TODO: This should be triggered somehow instead of being handled here
if (MediaPackageElements.SERIES.equals(element.getFlavor())) {
logger.info("Ingested mediapackage {} contains updated series information", mediaPackageId);
updateSeries(element.getURI());
}
}
// Now that all elements are in place, start with ingest
logger.info("Initiating processing of ingested mediapackage {}", mediaPackageId);
WorkflowInstance workflowInstance = ingest(mp, workflowDefinitionId, workflowConfig, workflowInstanceId);
logger.info("Ingest of mediapackage {} done", mediaPackageId);
job.setStatus(Job.Status.FINISHED);
return workflowInstance;
} catch (ServiceRegistryException e) {
throw new IngestException(e);
} catch (MediaPackageException e) {
job.setStatus(Job.Status.FAILED, Job.FailureReason.DATA);
throw e;
} catch (Exception e) {
if (e instanceof IngestException)
throw (IngestException) e;
throw new IngestException(e);
} finally {
IOUtils.closeQuietly(zis);
finallyUpdateJob(job);
for (String filename : collectionFilenames) {
workingFileRepository.deleteFromCollection(Long.toString(job.getId()), filename, true);
}
}
}
Aggregations