use of org.opencastproject.workflow.api.WorkflowOperationInstance in project opencast by opencast.
the class JobEndpoint method getOperationsAsJSON.
/**
* Returns the list of operations for a given workflow instance
*
* @param jobId
* the workflow instance id
* @return the list of workflow operations as JSON object
* @throws JobEndpointException
* @throws NotFoundException
*/
public JValue getOperationsAsJSON(long jobId) throws JobEndpointException, NotFoundException {
WorkflowInstance instance = getWorkflowById(jobId);
List<WorkflowOperationInstance> operations = instance.getOperations();
List<JValue> operationsJSON = new ArrayList<>();
for (WorkflowOperationInstance wflOp : operations) {
List<Field> fields = new ArrayList<>();
for (String key : wflOp.getConfigurationKeys()) {
fields.add(f(key, v(wflOp.getConfiguration(key), Jsons.BLANK)));
}
operationsJSON.add(obj(f("status", v(wflOp.getState(), Jsons.BLANK)), f("title", v(wflOp.getTemplate(), Jsons.BLANK)), f("description", v(wflOp.getDescription(), Jsons.BLANK)), f("id", v(wflOp.getId(), Jsons.BLANK)), f("configuration", obj(fields))));
}
return arr(operationsJSON);
}
use of org.opencastproject.workflow.api.WorkflowOperationInstance in project opencast by opencast.
the class JobEndpoint method getOperationAsJSON.
/**
* Returns the operation with the given id from the given workflow instance
*
* @param jobId
* the workflow instance id
* @param operationPosition
* the operation position
* @return the operation as JSON object
* @throws JobEndpointException
* @throws NotFoundException
*/
public JObject getOperationAsJSON(long jobId, int operationPosition) throws JobEndpointException, NotFoundException {
WorkflowInstance instance = getWorkflowById(jobId);
List<WorkflowOperationInstance> operations = instance.getOperations();
if (operations.size() > operationPosition) {
WorkflowOperationInstance wflOp = operations.get(operationPosition);
return obj(f("retry_strategy", v(wflOp.getRetryStrategy(), Jsons.BLANK)), f("execution_host", v(wflOp.getExecutionHost(), Jsons.BLANK)), f("failed_attempts", v(wflOp.getFailedAttempts())), f("max_attempts", v(wflOp.getMaxAttempts())), f("exception_handler_workflow", v(wflOp.getExceptionHandlingWorkflow(), Jsons.BLANK)), f("fail_on_error", v(wflOp.isFailWorkflowOnException())), f("description", v(wflOp.getDescription(), Jsons.BLANK)), f("state", v(wflOp.getState(), Jsons.BLANK)), f("job", v(wflOp.getId(), Jsons.BLANK)), f("name", v(wflOp.getTemplate(), Jsons.BLANK)), f("time_in_queue", v(wflOp.getTimeInQueue(), v(0))), f("started", wflOp.getDateStarted() != null ? v(toUTC(wflOp.getDateStarted().getTime())) : Jsons.BLANK), f("completed", wflOp.getDateCompleted() != null ? v(toUTC(wflOp.getDateCompleted().getTime())) : Jsons.BLANK));
}
return null;
}
use of org.opencastproject.workflow.api.WorkflowOperationInstance in project opencast by opencast.
the class AnimateWorkflowOperationHandler method start.
/**
* {@inheritDoc}
*
* @see
* org.opencastproject.workflow.api.WorkflowOperationHandler#start(org.opencastproject.workflow.api.WorkflowInstance,
* org.opencastproject.job.api.JobContext)
*/
@Override
public WorkflowOperationResult start(WorkflowInstance workflowInstance, JobContext context) throws WorkflowOperationException {
MediaPackage mediaPackage = workflowInstance.getMediaPackage();
logger.info("Start animate workflow operation for media package {}", mediaPackage);
WorkflowOperationInstance operation = workflowInstance.getCurrentOperation();
List<String> arguments;
// Check required options
final File animationFile = new File(StringUtils.trimToEmpty(operation.getConfiguration(ANIMATION_FILE_PROPERTY)));
if (!animationFile.isFile()) {
throw new WorkflowOperationException(String.format("Animation file `%s` does not exist", animationFile));
}
URI animation = animationFile.toURI();
final MediaPackageElementFlavor targetFlavor;
try {
targetFlavor = MediaPackageElementFlavor.parseFlavor(StringUtils.trimToNull(operation.getConfiguration(TARGET_FLAVOR_PROPERTY)));
} catch (IllegalArgumentException e) {
throw new WorkflowOperationException("Invalid target flavor", e);
}
// Get optional options
String targetTagsProperty = StringUtils.trimToNull(operation.getConfiguration(TARGET_TAGS_PROPERTY));
// Check if we have custom command line options
String cmd = operation.getConfiguration(COMMANDLINE_ARGUMENTS_PROPERTY);
if (StringUtils.isNotEmpty(cmd)) {
arguments = Arrays.asList(StringUtils.split(cmd));
} else {
// set default encoding
arguments = new ArrayList<>();
arguments.add("-t");
arguments.add("ffmpeg");
arguments.add("--video-codec");
arguments.add("libx264-lossless");
arguments.add("--video-bitrate");
arguments.add("10000");
addArgumentIfExists(operation, arguments, WIDTH_PROPERTY, "-w");
addArgumentIfExists(operation, arguments, HEIGHT_PROPERTY, "-h");
addArgumentIfExists(operation, arguments, FPS_PROPERTY, "--fps");
}
final Map<String, String> metadata = getMetadata(mediaPackage);
Job job;
try {
job = animateService.animate(animation, metadata, arguments);
} catch (AnimateServiceException e) {
throw new WorkflowOperationException(String.format("Rendering animation from '%s' in media package '%s' failed", animation, mediaPackage), e);
}
if (!waitForStatus(job).isSuccess()) {
throw new WorkflowOperationException(String.format("Animate job for media package '%s' failed", mediaPackage));
}
// put animated clip into media package
try {
URI output = new URI(job.getPayload());
String id = UUID.randomUUID().toString();
InputStream in = workspace.read(output);
URI uri = workspace.put(mediaPackage.getIdentifier().toString(), id, FilenameUtils.getName(output.getPath()), in);
TrackImpl track = new TrackImpl();
track.setIdentifier(id);
track.setFlavor(targetFlavor);
track.setURI(uri);
Job inspection = mediaInspectionService.enrich(track, true);
if (!waitForStatus(inspection).isSuccess()) {
throw new AnimateServiceException(String.format("Animating %s failed", animation));
}
track = (TrackImpl) MediaPackageElementParser.getFromXml(inspection.getPayload());
// add track to media package
for (String tag : asList(targetTagsProperty)) {
track.addTag(tag);
}
mediaPackage.add(track);
workspace.delete(output);
} catch (Exception e) {
throw new WorkflowOperationException("Error handling animation service output", e);
}
try {
workspace.cleanup(mediaPackage.getIdentifier());
} catch (IOException e) {
throw new WorkflowOperationException(e);
}
logger.info("Animate workflow operation for media package {} completed", mediaPackage);
return createResult(mediaPackage, WorkflowOperationResult.Action.CONTINUE);
}
use of org.opencastproject.workflow.api.WorkflowOperationInstance in project opencast by opencast.
the class StartTranscriptionOperationHandlerTest method setUp.
@Before
public void setUp() throws Exception {
MediaPackageBuilder builder = MediaPackageBuilderFactory.newInstance().newMediaPackageBuilder();
// Media package set up
URI mediaPackageURI = StartTranscriptionOperationHandlerTest.class.getResource("/mp.xml").toURI();
mediaPackage = builder.loadFromXml(mediaPackageURI.toURL().openStream());
// Service registry set up
Job job1 = EasyMock.createNiceMock(Job.class);
EasyMock.expect(job1.getId()).andReturn(1L);
EasyMock.expect(job1.getPayload()).andReturn(null).anyTimes();
EasyMock.expect(job1.getStatus()).andReturn(Job.Status.FINISHED);
EasyMock.expect(job1.getDateCreated()).andReturn(new Date());
EasyMock.expect(job1.getDateStarted()).andReturn(new Date());
EasyMock.expect(job1.getQueueTime()).andReturn(new Long(0));
EasyMock.replay(job1);
ServiceRegistry serviceRegistry = EasyMock.createNiceMock(ServiceRegistry.class);
EasyMock.expect(serviceRegistry.getJob(1L)).andReturn(job1);
EasyMock.replay(serviceRegistry);
// Transcription service set up
service = EasyMock.createStrictMock(TranscriptionService.class);
capturedTrack = Capture.newInstance();
EasyMock.expect(service.startTranscription(EasyMock.anyObject(String.class), EasyMock.capture(capturedTrack))).andReturn(null);
EasyMock.replay(service);
// Workflow set up
WorkflowDefinitionImpl def = new WorkflowDefinitionImpl();
def.setId("DCE-start-transcription");
def.setPublished(true);
workflowInstance = new WorkflowInstanceImpl(def, mediaPackage, null, null, null, null);
workflowInstance.setId(1);
operation = new WorkflowOperationInstanceImpl("start-transcript", OperationState.RUNNING);
List<WorkflowOperationInstance> operationList = new ArrayList<WorkflowOperationInstance>();
operationList.add(operation);
workflowInstance.setOperations(operationList);
// Operation handler set up
operationHandler = new StartTranscriptionOperationHandler();
operationHandler.setTranscriptionService(service);
operationHandler.setServiceRegistry(serviceRegistry);
}
use of org.opencastproject.workflow.api.WorkflowOperationInstance in project opencast by opencast.
the class AttachTranscriptionOperationHandler method start.
/**
* {@inheritDoc}
*
* @see org.opencastproject.workflow.api.WorkflowOperationHandler#start(org.opencastproject.workflow.api.WorkflowInstance,
* JobContext)
*/
@Override
public WorkflowOperationResult start(final WorkflowInstance workflowInstance, JobContext context) throws WorkflowOperationException {
MediaPackage mediaPackage = workflowInstance.getMediaPackage();
WorkflowOperationInstance operation = workflowInstance.getCurrentOperation();
logger.debug("Attach transcription for mediapackage {} started", mediaPackage);
// Get job id.
String jobId = StringUtils.trimToNull(operation.getConfiguration(TRANSCRIPTION_JOB_ID));
if (jobId == null)
throw new WorkflowOperationException(TRANSCRIPTION_JOB_ID + " missing");
// Check which tags/flavors have been configured
String targetTagOption = StringUtils.trimToNull(operation.getConfiguration(TARGET_TAG));
String targetFlavorOption = StringUtils.trimToNull(operation.getConfiguration(TARGET_FLAVOR));
String captionFormatOption = StringUtils.trimToNull(operation.getConfiguration(TARGET_CAPTION_FORMAT));
// Target flavor is mandatory if target-caption-format was NOT informed and no conversion is done
if (targetFlavorOption == null && captionFormatOption == null)
throw new WorkflowOperationException(TARGET_FLAVOR + " missing");
// Target flavor is optional if target-caption-format was informed because the default flavor
// will be "captions/<format>". If informed, will override the default.
MediaPackageElementFlavor flavor = null;
if (targetFlavorOption != null)
flavor = MediaPackageElementFlavor.parseFlavor(targetFlavorOption);
try {
// Get transcription file from the service
MediaPackageElement original = service.getGeneratedTranscription(mediaPackage.getIdentifier().compact(), jobId);
MediaPackageElement transcription = original;
// If caption format passed, convert to desired format
if (captionFormatOption != null) {
Job job = captionService.convert(transcription, "ibm-watson", captionFormatOption, service.getLanguage());
if (!waitForStatus(job).isSuccess()) {
throw new WorkflowOperationException("Transcription format conversion job did not complete successfully");
}
transcription = MediaPackageElementParser.getFromXml(job.getPayload());
}
// Set the target flavor if informed
if (flavor != null)
transcription.setFlavor(flavor);
// Add tags
if (targetTagOption != null) {
for (String tag : asList(targetTagOption)) {
if (StringUtils.trimToNull(tag) != null)
transcription.addTag(tag);
}
}
// Add to media package
mediaPackage.add(transcription);
String uri = transcription.getURI().toString();
String ext = uri.substring(uri.lastIndexOf("."));
transcription.setURI(workspace.moveTo(transcription.getURI(), mediaPackage.getIdentifier().toString(), transcription.getIdentifier(), "captions." + ext));
} catch (Exception e) {
throw new WorkflowOperationException(e);
}
return createResult(mediaPackage, Action.CONTINUE);
}
Aggregations