use of org.opencastproject.workflow.api.WorkflowOperationInstance in project opencast by opencast.
the class VideoEditorWorkflowOperationHandlerTest method testEditorResume.
@Test
public void testEditorResume() throws WorkflowOperationException, URISyntaxException, NotFoundException, IOException, ProcessFailedException, ServiceRegistryException, MediaPackageException {
// filled smil file
URI episodeSmilURI = VideoEditorWorkflowOperationHandlerTest.class.getResource("/editor_smil_filled.smil").toURI();
File episodeSmilFile = new File(episodeSmilURI);
// setup mock services
EasyMock.expect(workspaceMock.get((URI) EasyMock.anyObject())).andReturn(episodeSmilFile);
EasyMock.expect(workspaceMock.put((String) EasyMock.anyObject(), (String) EasyMock.anyObject(), (String) EasyMock.anyObject(), (InputStream) EasyMock.anyObject())).andReturn(episodeSmilURI);
EasyMock.expect(workspaceMock.moveTo((URI) EasyMock.anyObject(), (String) EasyMock.anyObject(), (String) EasyMock.anyObject(), (String) EasyMock.anyObject())).andReturn(URI.create("http://localhost:8080/foo/trimmed.mp4"));
Job job = EasyMock.createNiceMock(Job.class);
EasyMock.expect(job.getPayload()).andReturn(MediaPackageElementParser.getAsXml(mpSmil.getTracks()[0])).anyTimes();
EasyMock.expect(job.getStatus()).andReturn(Job.Status.FINISHED);
ServiceRegistry serviceRegistry = EasyMock.createNiceMock(ServiceRegistry.class);
videoEditorWorkflowOperationHandler.setServiceRegistry(serviceRegistry);
EasyMock.expect(serviceRegistry.getJob(EasyMock.anyLong())).andReturn(job);
EasyMock.expect(videoEditorServiceMock.processSmil((Smil) EasyMock.anyObject())).andReturn(Arrays.asList(job));
EasyMock.replay(workspaceMock, job, serviceRegistry, videoEditorServiceMock);
WorkflowInstanceImpl workflowInstance = getWorkflowInstance(mpSmil, getDefaultConfiguration(true));
// run test
WorkflowOperationResult result = videoEditorWorkflowOperationHandler.resume(workflowInstance, null, null);
Assert.assertNotNull("VideoEditor workflow operation returns null but should be an instantiated WorkflowOperationResult", result);
EasyMock.verify(workspaceMock, job, serviceRegistry, videoEditorServiceMock);
// verify trimmed track derived from source track
WorkflowOperationInstance worflowOperationInstance = workflowInstance.getCurrentOperation();
String targetFlavorSubtypeProperty = worflowOperationInstance.getConfiguration("target-flavor-subtype");
String sourceFlavorsProperty = worflowOperationInstance.getConfiguration("source-flavors");
TrackSelector trackSelector = new TrackSelector();
trackSelector.addFlavor(sourceFlavorsProperty);
Collection<Track> sourceTracks = trackSelector.select(result.getMediaPackage(), false);
Assert.assertTrue("Mediapackage does not contain any tracks matching flavor " + sourceFlavorsProperty, sourceTracks != null && !sourceTracks.isEmpty());
for (Track sourceTrack : sourceTracks) {
MediaPackageElementFlavor targetFlavor = MediaPackageElementFlavor.flavor(sourceTrack.getFlavor().getType(), targetFlavorSubtypeProperty);
Track[] targetTracks = result.getMediaPackage().getTracks(targetFlavor);
Assert.assertTrue("Media package doesn't contain track with flavor " + targetFlavor.toString(), targetTracks != null && targetTracks.length > 0);
}
}
use of org.opencastproject.workflow.api.WorkflowOperationInstance in project opencast by opencast.
the class VideoSegmenterWorkflowOperationHandler method start.
/**
* {@inheritDoc}
*
* @see org.opencastproject.workflow.api.WorkflowOperationHandler#start(org.opencastproject.workflow.api.WorkflowInstance,
* JobContext)
*/
public WorkflowOperationResult start(final WorkflowInstance workflowInstance, JobContext context) throws WorkflowOperationException {
logger.debug("Running video segmentation on workflow {}", workflowInstance.getId());
WorkflowOperationInstance operation = workflowInstance.getCurrentOperation();
MediaPackage mediaPackage = workflowInstance.getMediaPackage();
// Find movie track to analyze
String trackFlavor = StringUtils.trimToNull(operation.getConfiguration(PROP_ANALYSIS_TRACK_FLAVOR));
List<String> targetTags = asList(operation.getConfiguration(PROP_TARGET_TAGS));
List<Track> candidates = new ArrayList<Track>();
if (trackFlavor != null)
candidates.addAll(Arrays.asList(mediaPackage.getTracks(MediaPackageElementFlavor.parseFlavor(trackFlavor))));
else
candidates.addAll(Arrays.asList(mediaPackage.getTracks(MediaPackageElements.PRESENTATION_SOURCE)));
// Remove unsupported tracks (only those containing video can be segmented)
Iterator<Track> ti = candidates.iterator();
while (ti.hasNext()) {
Track t = ti.next();
if (!t.hasVideo())
ti.remove();
}
// Found one?
if (candidates.size() == 0) {
logger.info("No matching tracks available for video segmentation in workflow {}", workflowInstance);
return createResult(Action.CONTINUE);
}
// More than one left? Let's be pragmatic...
if (candidates.size() > 1) {
logger.info("Found more than one track to segment, choosing the first one ({})", candidates.get(0));
}
Track track = candidates.get(0);
// Segment the media package
Catalog mpeg7Catalog = null;
Job job = null;
try {
job = videosegmenter.segment(track);
if (!waitForStatus(job).isSuccess()) {
throw new WorkflowOperationException("Video segmentation of " + track + " failed");
}
mpeg7Catalog = (Catalog) MediaPackageElementParser.getFromXml(job.getPayload());
mediaPackage.add(mpeg7Catalog);
mpeg7Catalog.setURI(workspace.moveTo(mpeg7Catalog.getURI(), mediaPackage.getIdentifier().toString(), mpeg7Catalog.getIdentifier(), "segments.xml"));
mpeg7Catalog.setReference(new MediaPackageReferenceImpl(track));
// Add target tags
for (String tag : targetTags) {
mpeg7Catalog.addTag(tag);
}
} catch (Exception e) {
throw new WorkflowOperationException(e);
}
logger.debug("Video segmentation completed");
return createResult(mediaPackage, Action.CONTINUE, job.getQueueTime());
}
use of org.opencastproject.workflow.api.WorkflowOperationInstance in project opencast by opencast.
the class ConfigurablePublishWorkflowOperationHandler method start.
@Override
public WorkflowOperationResult start(WorkflowInstance workflowInstance, JobContext context) throws WorkflowOperationException {
RequireUtil.notNull(workflowInstance, "workflowInstance");
final MediaPackage mp = workflowInstance.getMediaPackage();
final WorkflowOperationInstance op = workflowInstance.getCurrentOperation();
final String channelId = StringUtils.trimToEmpty(op.getConfiguration(CHANNEL_ID_KEY));
if ("".equals(channelId)) {
throw new WorkflowOperationException("Unable to publish this mediapackage as the configuration key " + CHANNEL_ID_KEY + " is missing. Unable to determine where to publish these elements.");
}
final String urlPattern = StringUtils.trimToEmpty(op.getConfiguration(URL_PATTERN));
MimeType mimetype = null;
String mimetypeString = StringUtils.trimToEmpty(op.getConfiguration(MIME_TYPE));
if (!"".equals(mimetypeString)) {
try {
mimetype = MimeTypes.parseMimeType(mimetypeString);
} catch (IllegalArgumentException e) {
throw new WorkflowOperationException("Unable to parse the provided configuration for " + MIME_TYPE, e);
}
}
final boolean withPublishedElements = BooleanUtils.toBoolean(StringUtils.trimToEmpty(op.getConfiguration(WITH_PUBLISHED_ELEMENTS)));
boolean checkAvailability = BooleanUtils.toBoolean(StringUtils.trimToEmpty(op.getConfiguration(CHECK_AVAILABILITY)));
if (getPublications(mp, channelId).size() > 0) {
final String rePublishStrategy = StringUtils.trimToEmpty(op.getConfiguration(STRATEGY));
switch(rePublishStrategy) {
case ("fail"):
// fail is a dummy function for further distribution strategies
fail(mp);
break;
case ("merge"):
// nothing to do here. other publication strategies can be added to this list later on
break;
default:
retract(mp, channelId);
}
}
String mode = StringUtils.trimToEmpty(op.getConfiguration(MODE));
if ("".equals(mode)) {
mode = DEFAULT_MODE;
} else if (!ArrayUtils.contains(KNOWN_MODES, mode)) {
logger.error("Unknown value for configuration key mode: '{}'", mode);
throw new IllegalArgumentException("Unknown value for configuration key mode");
}
final String[] sourceFlavors = StringUtils.split(StringUtils.trimToEmpty(op.getConfiguration(SOURCE_FLAVORS)), ",");
final String[] sourceTags = StringUtils.split(StringUtils.trimToEmpty(op.getConfiguration(SOURCE_TAGS)), ",");
String publicationUUID = UUID.randomUUID().toString();
Publication publication = PublicationImpl.publication(publicationUUID, channelId, null, null);
// Configure the element selector
final SimpleElementSelector selector = new SimpleElementSelector();
for (String flavor : sourceFlavors) {
selector.addFlavor(MediaPackageElementFlavor.parseFlavor(flavor));
}
for (String tag : sourceTags) {
selector.addTag(tag);
}
if (sourceFlavors.length > 0 || sourceTags.length > 0) {
if (!withPublishedElements) {
Set<MediaPackageElement> elements = distribute(selector.select(mp, false), mp, channelId, mode, checkAvailability);
if (elements.size() > 0) {
for (MediaPackageElement element : elements) {
// Make sure the mediapackage is prompted to create a new identifier for this element
element.setIdentifier(null);
PublicationImpl.addElementToPublication(publication, element);
}
} else {
logger.info("No element found for distribution in media package '{}'", mp);
return createResult(mp, Action.CONTINUE);
}
} else {
List<MediaPackageElement> publishedElements = new ArrayList<>();
for (Publication alreadyPublished : mp.getPublications()) {
publishedElements.addAll(Arrays.asList(alreadyPublished.getAttachments()));
publishedElements.addAll(Arrays.asList(alreadyPublished.getCatalogs()));
publishedElements.addAll(Arrays.asList(alreadyPublished.getTracks()));
}
for (MediaPackageElement element : selector.select(publishedElements, false)) {
PublicationImpl.addElementToPublication(publication, element);
}
}
}
if (!"".equals(urlPattern)) {
publication.setURI(populateUrlWithVariables(urlPattern, mp, publicationUUID));
}
if (mimetype != null) {
publication.setMimeType(mimetype);
}
mp.add(publication);
return createResult(mp, Action.CONTINUE);
}
use of org.opencastproject.workflow.api.WorkflowOperationInstance in project opencast by opencast.
the class ConfigurablePublishWorkflowOperationHandlerTest method testNormal.
@Test
public void testNormal() throws WorkflowOperationException, URISyntaxException, DistributionException, MediaPackageException {
String channelId = "engage-player";
String attachmentId = "attachment-id";
String catalogId = "catalog-id";
String trackId = "track-id";
Attachment attachment = new AttachmentImpl();
attachment.addTag("engage-download");
attachment.setIdentifier(attachmentId);
attachment.setURI(new URI("http://api.com/attachment"));
Catalog catalog = CatalogImpl.newInstance();
catalog.addTag("engage-download");
catalog.setIdentifier(catalogId);
catalog.setURI(new URI("http://api.com/catalog"));
Track track = new TrackImpl();
track.addTag("engage-streaming");
track.setIdentifier(trackId);
track.setURI(new URI("http://api.com/track"));
Publication publicationtest = new PublicationImpl(trackId, channelId, new URI("http://api.com/publication"), MimeType.mimeType(trackId, trackId));
Track unrelatedTrack = new TrackImpl();
unrelatedTrack.addTag("unrelated");
Capture<MediaPackageElement> capturePublication = Capture.newInstance();
MediaPackage mediapackageClone = EasyMock.createNiceMock(MediaPackage.class);
EasyMock.expect(mediapackageClone.getElements()).andStubReturn(new MediaPackageElement[] { attachment, catalog, track, unrelatedTrack });
EasyMock.expect(mediapackageClone.getIdentifier()).andStubReturn(new IdImpl("mp-id-clone"));
EasyMock.expectLastCall();
EasyMock.replay(mediapackageClone);
MediaPackage mediapackage = EasyMock.createNiceMock(MediaPackage.class);
EasyMock.expect(mediapackage.getElements()).andStubReturn(new MediaPackageElement[] { attachment, catalog, track, unrelatedTrack });
EasyMock.expect(mediapackage.clone()).andStubReturn(mediapackageClone);
EasyMock.expect(mediapackage.getIdentifier()).andStubReturn(new IdImpl("mp-id"));
mediapackage.add(EasyMock.capture(capturePublication));
mediapackage.add(publicationtest);
EasyMock.expect(mediapackage.getPublications()).andStubReturn(new Publication[] { publicationtest });
EasyMock.expectLastCall();
EasyMock.replay(mediapackage);
WorkflowOperationInstance op = EasyMock.createNiceMock(WorkflowOperationInstance.class);
EasyMock.expect(op.getConfiguration(ConfigurablePublishWorkflowOperationHandler.CHANNEL_ID_KEY)).andStubReturn(channelId);
EasyMock.expect(op.getConfiguration(ConfigurablePublishWorkflowOperationHandler.MIME_TYPE)).andStubReturn("text/html");
EasyMock.expect(op.getConfiguration(ConfigurablePublishWorkflowOperationHandler.URL_PATTERN)).andStubReturn("http://api.opencast.org/api/events/${event_id}");
EasyMock.expect(op.getConfiguration(ConfigurablePublishWorkflowOperationHandler.SOURCE_TAGS)).andStubReturn("engage-download,engage-streaming");
EasyMock.expect(op.getConfiguration(ConfigurablePublishWorkflowOperationHandler.CHECK_AVAILABILITY)).andStubReturn("true");
EasyMock.expect(op.getConfiguration(ConfigurablePublishWorkflowOperationHandler.STRATEGY)).andStubReturn("retract");
EasyMock.expect(op.getConfiguration(ConfigurablePublishWorkflowOperationHandler.MODE)).andStubReturn("single");
EasyMock.replay(op);
WorkflowInstance workflowInstance = EasyMock.createNiceMock(WorkflowInstance.class);
EasyMock.expect(workflowInstance.getMediaPackage()).andStubReturn(mediapackage);
EasyMock.expect(workflowInstance.getCurrentOperation()).andStubReturn(op);
EasyMock.replay(workflowInstance);
JobContext jobContext = EasyMock.createNiceMock(JobContext.class);
EasyMock.replay(jobContext);
Job attachmentJob = EasyMock.createNiceMock(Job.class);
EasyMock.expect(attachmentJob.getPayload()).andReturn(MediaPackageElementParser.getAsXml(attachment));
EasyMock.replay(attachmentJob);
Job catalogJob = EasyMock.createNiceMock(Job.class);
EasyMock.expect(catalogJob.getPayload()).andReturn(MediaPackageElementParser.getAsXml(catalog));
EasyMock.replay(catalogJob);
Job trackJob = EasyMock.createNiceMock(Job.class);
EasyMock.expect(trackJob.getPayload()).andReturn(MediaPackageElementParser.getAsXml(track));
EasyMock.replay(trackJob);
Job retractJob = EasyMock.createNiceMock(Job.class);
EasyMock.expect(retractJob.getPayload()).andReturn(MediaPackageElementParser.getAsXml(track));
EasyMock.replay(retractJob);
DownloadDistributionService distributionService = EasyMock.createNiceMock(DownloadDistributionService.class);
// Make sure that all of the elements are distributed.
EasyMock.expect(distributionService.distribute(channelId, mediapackage, attachmentId, true)).andReturn(attachmentJob);
EasyMock.expect(distributionService.distribute(channelId, mediapackage, catalogId, true)).andReturn(catalogJob);
EasyMock.expect(distributionService.distribute(channelId, mediapackage, trackId, true)).andReturn(trackJob);
EasyMock.expect(distributionService.retract(channelId, mediapackage, channelId)).andReturn(retractJob);
EasyMock.replay(distributionService);
SecurityService securityService = EasyMock.createNiceMock(SecurityService.class);
EasyMock.expect(securityService.getOrganization()).andStubReturn(org);
EasyMock.replay(securityService);
ServiceRegistry serviceRegistry = EasyMock.createNiceMock(ServiceRegistry.class);
EasyMock.replay(serviceRegistry);
// Override the waitForStatus method to not block the jobs
ConfigurablePublishWorkflowOperationHandler configurePublish = new ConfigurablePublishWorkflowOperationHandler() {
@Override
protected Result waitForStatus(long timeout, Job... jobs) {
HashMap<Job, Status> map = Stream.mk(jobs).foldl(new HashMap<Job, Status>(), new Fn2<HashMap<Job, Status>, Job, HashMap<Job, Status>>() {
@Override
public HashMap<Job, Status> apply(HashMap<Job, Status> a, Job b) {
a.put(b, Status.FINISHED);
return a;
}
});
return new Result(map);
}
};
configurePublish.setDownloadDistributionService(distributionService);
configurePublish.setSecurityService(securityService);
configurePublish.setServiceRegistry(serviceRegistry);
WorkflowOperationResult result = configurePublish.start(workflowInstance, jobContext);
assertNotNull(result.getMediaPackage());
assertTrue("The publication element has not been added to the mediapackage.", capturePublication.hasCaptured());
assertTrue("Some other type of element has been added to the mediapackage instead of the publication element.", capturePublication.getValue().getElementType().equals(MediaPackageElement.Type.Publication));
Publication publication = (Publication) capturePublication.getValue();
assertEquals(1, publication.getAttachments().length);
assertNotEquals(attachment.getIdentifier(), publication.getAttachments()[0].getIdentifier());
attachment.setIdentifier(publication.getAttachments()[0].getIdentifier());
assertEquals(attachment, publication.getAttachments()[0]);
assertEquals(1, publication.getCatalogs().length);
assertNotEquals(catalog.getIdentifier(), publication.getCatalogs()[0].getIdentifier());
catalog.setIdentifier(publication.getCatalogs()[0].getIdentifier());
assertEquals(catalog, publication.getCatalogs()[0]);
assertEquals(1, publication.getTracks().length);
assertNotEquals(track.getIdentifier(), publication.getTracks()[0].getIdentifier());
track.setIdentifier(publication.getTracks()[0].getIdentifier());
assertEquals(track, publication.getTracks()[0]);
}
use of org.opencastproject.workflow.api.WorkflowOperationInstance in project opencast by opencast.
the class EmailWorkflowOperationHandlerTest method setUp.
@Before
public void setUp() throws Exception {
MediaPackageBuilder builder = MediaPackageBuilderFactory.newInstance().newMediaPackageBuilder();
uriMP = EmailWorkflowOperationHandlerTest.class.getResource("/email_mediapackage.xml").toURI();
mp = builder.loadFromXml(uriMP.toURL().openStream());
operationHandler = new EmailWorkflowOperationHandler();
EmailTemplateService emailTemplateService = EasyMock.createMock(EmailTemplateService.class);
EasyMock.expect(emailTemplateService.applyTemplate("DCE_workflow_2_body", "This is the media package: ${mediaPackage.identifier}", workflowInstance)).andReturn("This is the media package: 3e7bb56d-2fcc-4efe-9f0e-d6e56422f557");
EasyMock.expect(emailTemplateService.applyTemplate("template1", null, workflowInstance)).andReturn("This is the media package: 3e7bb56d-2fcc-4efe-9f0e-d6e56422f557");
EasyMock.expect(emailTemplateService.applyTemplate("templateNotFound", null, workflowInstance)).andReturn("TEMPLATE NOT FOUND!");
EasyMock.replay(emailTemplateService);
operationHandler.setEmailTemplateService(emailTemplateService);
SmtpService smtpService = EasyMock.createMock(SmtpService.class);
capturedTo = Capture.newInstance();
capturedCC = Capture.newInstance();
capturedBCC = Capture.newInstance();
capturedSubject = Capture.newInstance();
capturedBody = Capture.newInstance();
smtpService.send(EasyMock.capture(capturedTo), EasyMock.capture(capturedCC), EasyMock.capture(capturedBCC), EasyMock.capture(capturedSubject), EasyMock.capture(capturedBody));
EasyMock.expectLastCall().once();
EasyMock.replay(smtpService);
operationHandler.setSmtpService(smtpService);
workflowInstance.setId(1);
workflowInstance.setState(WorkflowState.RUNNING);
workflowInstance.setTemplate("DCE-workflow");
workflowInstance.setMediaPackage(mp);
WorkflowOperationInstanceImpl failedOperation1 = new WorkflowOperationInstanceImpl("operation1", OperationState.FAILED);
failedOperation1.setFailWorkflowOnException(true);
WorkflowOperationInstanceImpl failedOperation2 = new WorkflowOperationInstanceImpl("operation2", OperationState.FAILED);
failedOperation2.setFailWorkflowOnException(false);
operation = new WorkflowOperationInstanceImpl("email", OperationState.RUNNING);
List<WorkflowOperationInstance> operationList = new ArrayList<WorkflowOperationInstance>();
operationList.add(failedOperation1);
operationList.add(failedOperation2);
operationList.add(operation);
workflowInstance.setOperations(operationList);
}
Aggregations