use of org.opencastproject.workflow.api.WorkflowOperationException in project opencast by opencast.
the class ImportWorkflowPropertiesWOH method loadPropertiesElementFromMediaPackage.
static Opt<Attachment> loadPropertiesElementFromMediaPackage(MediaPackageElementFlavor sourceFlavor, WorkflowInstance wi) throws WorkflowOperationException {
final MediaPackage mp = wi.getMediaPackage();
final Attachment[] elements = mp.getAttachments(sourceFlavor);
if (elements.length < 1) {
logger.info("Cannot import workflow properties - no element with flavor '{}' found in media package '{}'", sourceFlavor, mp.getIdentifier());
return Opt.none();
} else if (elements.length > 1) {
throw new WorkflowOperationException(format("Found more than one element with flavor '%s' in media package '%s'", sourceFlavor, mp.getIdentifier()));
}
return Opt.some(elements[0]);
}
use of org.opencastproject.workflow.api.WorkflowOperationException in project opencast by opencast.
the class CopyWorkflowOperationHandlerTest method testCopyWithTwoElementsMatchingFlavorsTags.
@Test
public void testCopyWithTwoElementsMatchingFlavorsTags() throws Exception {
// operation configuration
Map<String, String> configurations = new HashMap<String, String>();
configurations.put(CopyWorkflowOperationHandler.OPT_SOURCE_FLAVORS, "*/source");
configurations.put(CopyWorkflowOperationHandler.OPT_TARGET_DIRECTORY, videoFile.getParent());
configurations.put(CopyWorkflowOperationHandler.OPT_TARGET_FILENAME, "testCopy");
// run the operation handler
try {
WorkflowOperationResult result = getWorkflowOperationResult(mp, configurations);
Assert.assertEquals(Action.CONTINUE, result.getAction());
} catch (WorkflowOperationException e) {
Assert.fail("The workflow should ");
}
}
use of org.opencastproject.workflow.api.WorkflowOperationException in project opencast by opencast.
the class ZipWorkflowOperationHandler method zip.
/**
* Creates a zip archive of all elements in a mediapackage.
*
* @param mediaPackage
* the mediapackage to zip
*
* @return the zip file
*
* @throws IOException
* If an IO exception occurs
* @throws NotFoundException
* If a file referenced in the mediapackage can not be found
* @throws MediaPackageException
* If the mediapackage can not be serialized to xml
* @throws WorkflowOperationException
* If the mediapackage is invalid
*/
protected File zip(MediaPackage mediaPackage, List<MediaPackageElementFlavor> flavorsToZip, boolean compress) throws IOException, NotFoundException, MediaPackageException, WorkflowOperationException {
if (mediaPackage == null) {
throw new WorkflowOperationException("Invalid mediapackage");
}
// Create the temp directory
File mediaPackageDir = new File(tempStorageDir, mediaPackage.getIdentifier().compact());
FileUtils.forceMkdir(mediaPackageDir);
// Link or copy each matching element's file from the workspace to the temp directory
MediaPackageSerializer serializer = new DefaultMediaPackageSerializerImpl(mediaPackageDir);
MediaPackage clone = (MediaPackage) mediaPackage.clone();
for (MediaPackageElement element : clone.getElements()) {
// remove the element if it doesn't match the flavors to zip
boolean remove = true;
for (MediaPackageElementFlavor flavor : flavorsToZip) {
if (flavor.matches(element.getFlavor())) {
remove = false;
break;
}
}
if (remove) {
clone.remove(element);
continue;
}
File elementDir = new File(mediaPackageDir, element.getIdentifier());
FileUtils.forceMkdir(elementDir);
File workspaceFile = workspace.get(element.getURI());
File linkedFile = FileSupport.link(workspaceFile, new File(elementDir, workspaceFile.getName()), true);
try {
element.setURI(serializer.encodeURI(linkedFile.toURI()));
} catch (URISyntaxException e) {
throw new MediaPackageException("unable to serialize a mediapackage element", e);
}
}
// Add the manifest
FileUtils.writeStringToFile(new File(mediaPackageDir, "manifest.xml"), MediaPackageParser.getAsXml(clone), "UTF-8");
// Zip the directory
File zip = new File(tempStorageDir, clone.getIdentifier().compact() + ".zip");
int compressValue = compress ? ZipUtil.DEFAULT_COMPRESSION : ZipUtil.NO_COMPRESSION;
long startTime = System.currentTimeMillis();
ZipUtil.zip(new File[] { mediaPackageDir }, zip, true, compressValue);
long stopTime = System.currentTimeMillis();
logger.debug("Zip file creation took {} seconds", (stopTime - startTime) / 1000);
// Remove the directory
FileUtils.forceDelete(mediaPackageDir);
// Return the zip
return zip;
}
use of org.opencastproject.workflow.api.WorkflowOperationException in project opencast by opencast.
the class SilenceDetectionWorkflowOperationHandler method start.
@Override
public WorkflowOperationResult start(WorkflowInstance workflowInstance, JobContext context) throws WorkflowOperationException {
MediaPackage mp = workflowInstance.getMediaPackage();
logger.debug("Start silence detection workflow operation for mediapackage {}", mp.getIdentifier().compact());
String sourceFlavors = StringUtils.trimToNull(workflowInstance.getCurrentOperation().getConfiguration(SOURCE_FLAVORS_PROPERTY));
String sourceFlavor = StringUtils.trimToNull(workflowInstance.getCurrentOperation().getConfiguration(SOURCE_FLAVOR_PROPERTY));
String smilFlavorSubType = StringUtils.trimToNull(workflowInstance.getCurrentOperation().getConfiguration(SMIL_FLAVOR_SUBTYPE_PROPERTY));
String smilTargetFlavorString = StringUtils.trimToNull(workflowInstance.getCurrentOperation().getConfiguration(SMIL_TARGET_FLAVOR_PROPERTY));
MediaPackageElementFlavor smilTargetFlavor = null;
if (smilTargetFlavorString != null)
smilTargetFlavor = MediaPackageElementFlavor.parseFlavor(smilTargetFlavorString);
if (sourceFlavor == null && sourceFlavors == null) {
throw new WorkflowOperationException(String.format("No %s or %s have been specified", SOURCE_FLAVOR_PROPERTY, SOURCE_FLAVORS_PROPERTY));
}
if (smilFlavorSubType == null && smilTargetFlavor == null) {
throw new WorkflowOperationException(String.format("No %s or %s have been specified", SMIL_FLAVOR_SUBTYPE_PROPERTY, SMIL_TARGET_FLAVOR_PROPERTY));
}
if (sourceFlavors != null && smilTargetFlavor != null) {
throw new WorkflowOperationException(String.format("Can't use %s and %s together", SOURCE_FLAVORS_PROPERTY, SMIL_TARGET_FLAVOR_PROPERTY));
}
final String finalSourceFlavors;
if (smilTargetFlavor != null) {
finalSourceFlavors = sourceFlavor;
} else {
finalSourceFlavors = sourceFlavors;
}
String referenceTracksFlavor = StringUtils.trimToNull(workflowInstance.getCurrentOperation().getConfiguration(REFERENCE_TRACKS_FLAVOR_PROPERTY));
if (referenceTracksFlavor == null)
referenceTracksFlavor = finalSourceFlavors;
TrackSelector trackSelector = new TrackSelector();
for (String flavor : asList(finalSourceFlavors)) {
trackSelector.addFlavor(flavor);
}
Collection<Track> sourceTracks = trackSelector.select(mp, false);
if (sourceTracks.isEmpty()) {
logger.info("No source tracks found, skip silence detection");
return createResult(mp, Action.SKIP);
}
trackSelector = new TrackSelector();
for (String flavor : asList(referenceTracksFlavor)) {
trackSelector.addFlavor(flavor);
}
Collection<Track> referenceTracks = trackSelector.select(mp, false);
if (referenceTracks.isEmpty()) {
// REFERENCE_TRACKS_FLAVOR_PROPERTY was set to wrong value
throw new WorkflowOperationException(String.format("No tracks found filtered by flavor(s) '%s'", referenceTracksFlavor));
}
MediaPackageElementBuilder mpeBuilder = MediaPackageElementBuilderFactory.newInstance().newElementBuilder();
for (Track sourceTrack : sourceTracks) {
// Skip over track with no audio stream
if (!sourceTrack.hasAudio()) {
logger.info("Skipping silence detection of track {} since it has no audio", sourceTrack);
continue;
}
logger.info("Executing silence detection on track {}", sourceTrack.getIdentifier());
try {
Job detectionJob = detetionService.detect(sourceTrack, referenceTracks.toArray(new Track[referenceTracks.size()]));
if (!waitForStatus(detectionJob).isSuccess()) {
throw new WorkflowOperationException("Silence Detection failed");
}
Smil smil = smilService.fromXml(detectionJob.getPayload()).getSmil();
InputStream is = null;
try {
is = IOUtils.toInputStream(smil.toXML(), "UTF-8");
URI smilURI = workspace.put(mp.getIdentifier().compact(), smil.getId(), TARGET_FILE_NAME, is);
MediaPackageElementFlavor smilFlavor = smilTargetFlavor;
if (smilFlavor == null)
smilFlavor = new MediaPackageElementFlavor(sourceTrack.getFlavor().getType(), smilFlavorSubType);
Catalog catalog = (Catalog) mpeBuilder.elementFromURI(smilURI, MediaPackageElement.Type.Catalog, smilFlavor);
catalog.setIdentifier(smil.getId());
mp.add(catalog);
} catch (Exception ex) {
throw new WorkflowOperationException(String.format("Failed to put smil into workspace. Silence detection for track %s failed", sourceTrack.getIdentifier()), ex);
} finally {
IOUtils.closeQuietly(is);
}
logger.info("Finished silence detection on track {}", sourceTrack.getIdentifier());
} catch (SilenceDetectionFailedException ex) {
throw new WorkflowOperationException(String.format("Failed to create silence detection job for track %s", sourceTrack.getIdentifier()));
} catch (SmilException ex) {
throw new WorkflowOperationException(String.format("Failed to get smil from silence detection job for track %s", sourceTrack.getIdentifier()));
}
}
logger.debug("Finished silence detection workflow operation for mediapackage {}", mp.getIdentifier().compact());
return createResult(mp, Action.CONTINUE);
}
use of org.opencastproject.workflow.api.WorkflowOperationException in project opencast by opencast.
the class WorkflowServiceImpl method handleOperationResult.
/**
* Callback for workflow operation handlers that executed and finished without exception. This implementation assumes
* that the operation worker has already adjusted the current operation's state appropriately.
*
* @param workflow
* the workflow instance
* @param result
* the workflow operation result
* @return the workflow instance
* @throws WorkflowDatabaseException
* if updating the workflow fails
*/
protected WorkflowInstance handleOperationResult(WorkflowInstance workflow, WorkflowOperationResult result) throws WorkflowDatabaseException {
// Get the operation and its handler
WorkflowOperationInstanceImpl currentOperation = (WorkflowOperationInstanceImpl) workflow.getCurrentOperation();
WorkflowOperationHandler handler = getWorkflowOperationHandler(currentOperation.getTemplate());
// Create an operation result for the lazy or else update the workflow's media package
if (result == null) {
logger.warn("Handling a null operation result for workflow %s in operation %s", workflow.getId(), currentOperation.getTemplate());
result = new WorkflowOperationResultImpl(workflow.getMediaPackage(), null, Action.CONTINUE, 0);
} else {
MediaPackage mp = result.getMediaPackage();
if (mp != null) {
workflow.setMediaPackage(mp);
}
}
// The action to take
Action action = result.getAction();
// Update the workflow configuration. Update the reference to the current operation as well, since the workflow has
// been serialized and deserialized in the meantime.
int currentOperationPosition = currentOperation.getPosition();
workflow = updateConfiguration(workflow, result.getProperties());
currentOperation = (WorkflowOperationInstanceImpl) workflow.getOperations().get(currentOperationPosition);
// Adjust workflow statistics
currentOperation.setTimeInQueue(result.getTimeInQueue());
// Adjust the operation state
switch(action) {
case CONTINUE:
currentOperation.setState(OperationState.SUCCEEDED);
break;
case PAUSE:
if (!(handler instanceof ResumableWorkflowOperationHandler)) {
throw new IllegalStateException("Operation " + currentOperation.getTemplate() + " is not resumable");
}
// Set abortable and continuable to default values
currentOperation.setContinuable(result.allowsContinue());
currentOperation.setAbortable(result.allowsAbort());
ResumableWorkflowOperationHandler resumableHandler = (ResumableWorkflowOperationHandler) handler;
try {
String url = resumableHandler.getHoldStateUserInterfaceURL(workflow);
if (url != null) {
String holdActionTitle = resumableHandler.getHoldActionTitle();
currentOperation.setHoldActionTitle(holdActionTitle);
currentOperation.setHoldStateUserInterfaceUrl(url);
}
} catch (WorkflowOperationException e) {
logger.warn(e, "unable to replace workflow ID in the hold state URL");
}
workflow.setState(PAUSED);
currentOperation.setState(OperationState.PAUSED);
break;
case SKIP:
currentOperation.setState(OperationState.SKIPPED);
break;
default:
throw new IllegalStateException("Unknown action '" + action + "' returned");
}
if (ERROR_RESOLUTION_HANDLER_ID.equals(currentOperation.getTemplate()) && result.getAction() == Action.CONTINUE) {
Map<String, String> resultProperties = result.getProperties();
if (resultProperties == null || StringUtils.isBlank(resultProperties.get(RETRY_STRATEGY)))
throw new WorkflowDatabaseException("Retry strategy not present in properties!");
RetryStrategy retryStrategy = RetryStrategy.valueOf(resultProperties.get(RETRY_STRATEGY));
switch(retryStrategy) {
case NONE:
handleFailedOperation(workflow, workflow.getCurrentOperation());
break;
case RETRY:
currentOperation = (WorkflowOperationInstanceImpl) workflow.getCurrentOperation();
break;
default:
throw new WorkflowDatabaseException("Retry strategy not implemented yet!");
}
}
return workflow;
}
Aggregations