use of org.opencastproject.mediapackage.MediaPackageElement in project opencast by opencast.
the class JobUtilTest method testPayloadAsMediaPackageElement.
@Test
public void testPayloadAsMediaPackageElement() throws Exception {
MediaPackageElement element = new MediaPackageElementBuilderImpl().newElement(Type.Track, MediaPackageElements.PRESENTATION_SOURCE);
JobImpl job = new JobImpl(20);
job.setStatus(Status.FINISHED);
job.setPayload(MediaPackageElementParser.getAsXml(element));
Function<Job, MediaPackageElement> payloadAsMediaPackageElement = payloadAsMediaPackageElement(job, serviceRegistry);
assertEquals(element, payloadAsMediaPackageElement.apply(job));
}
use of org.opencastproject.mediapackage.MediaPackageElement in project opencast by opencast.
the class IndexServiceImpl method updateMediaPackageMetadata.
private void updateMediaPackageMetadata(MediaPackage mp, MetadataList metadataList) {
String oldSeriesId = mp.getSeries();
for (EventCatalogUIAdapter catalogUIAdapter : getEventCatalogUIAdapters()) {
Opt<MetadataCollection> metadata = metadataList.getMetadataByAdapter(catalogUIAdapter);
if (metadata.isSome() && metadata.get().isUpdated()) {
catalogUIAdapter.storeFields(mp, metadata.get());
}
}
// update series catalogs
if (!StringUtils.equals(oldSeriesId, mp.getSeries())) {
List<String> seriesDcTags = new ArrayList<>();
List<String> seriesAclTags = new ArrayList<>();
Map<String, List<String>> seriesExtDcTags = new HashMap<>();
if (StringUtils.isNotBlank(oldSeriesId)) {
// remove series dublincore from the media package
for (MediaPackageElement mpe : mp.getElementsByFlavor(MediaPackageElements.SERIES)) {
mp.remove(mpe);
for (String tag : mpe.getTags()) {
seriesDcTags.add(tag);
}
}
// remove series ACL from the media package
for (MediaPackageElement mpe : mp.getElementsByFlavor(MediaPackageElements.XACML_POLICY_SERIES)) {
mp.remove(mpe);
for (String tag : mpe.getTags()) {
seriesAclTags.add(tag);
}
}
// remove series extended metadata from the media package
try {
Opt<Map<String, byte[]>> oldSeriesElementsOpt = seriesService.getSeriesElements(oldSeriesId);
for (Map<String, byte[]> oldSeriesElements : oldSeriesElementsOpt) {
for (String oldSeriesElementType : oldSeriesElements.keySet()) {
for (MediaPackageElement mpe : mp.getElementsByFlavor(MediaPackageElementFlavor.flavor(oldSeriesElementType, "series"))) {
mp.remove(mpe);
String elementType = mpe.getFlavor().getType();
if (StringUtils.isNotBlank(elementType)) {
// remember the tags for this type of element
if (!seriesExtDcTags.containsKey(elementType)) {
// initialize the tags list on the first occurrence of this element type
seriesExtDcTags.put(elementType, new ArrayList<>());
}
for (String tag : mpe.getTags()) {
seriesExtDcTags.get(elementType).add(tag);
}
}
}
}
}
} catch (SeriesException e) {
logger.info("Unable to retrieve series element types from series service for the series {}", oldSeriesId, e);
}
}
if (StringUtils.isNotBlank(mp.getSeries())) {
// add updated series dublincore to the media package
try {
DublinCoreCatalog seriesDC = seriesService.getSeries(mp.getSeries());
if (seriesDC != null) {
mp.setSeriesTitle(seriesDC.getFirst(DublinCore.PROPERTY_TITLE));
try (InputStream in = IOUtils.toInputStream(seriesDC.toXmlString(), "UTF-8")) {
String elementId = UUID.randomUUID().toString();
URI catalogUrl = workspace.put(mp.getIdentifier().compact(), elementId, "dublincore.xml", in);
MediaPackageElement mpe = mp.add(catalogUrl, MediaPackageElement.Type.Catalog, MediaPackageElements.SERIES);
mpe.setIdentifier(elementId);
mpe.setChecksum(Checksum.create(ChecksumType.DEFAULT_TYPE, workspace.read(catalogUrl)));
if (StringUtils.isNotBlank(oldSeriesId)) {
for (String tag : seriesDcTags) {
mpe.addTag(tag);
}
} else {
// add archive tag to the element if the media package had no series set before
mpe.addTag("archive");
}
} catch (IOException e) {
throw new IllegalStateException("Unable to add the series dublincore to the media package " + mp.getIdentifier(), e);
}
}
} catch (SeriesException e) {
throw new IllegalStateException("Unable to retrieve series dublincore catalog for the series " + mp.getSeries(), e);
} catch (NotFoundException | UnauthorizedException e) {
throw new IllegalArgumentException("Unable to retrieve series dublincore catalog for the series " + mp.getSeries(), e);
}
// add updated series ACL to the media package
try {
AccessControlList seriesAccessControl = seriesService.getSeriesAccessControl(mp.getSeries());
if (seriesAccessControl != null) {
mp = authorizationService.setAcl(mp, AclScope.Series, seriesAccessControl).getA();
for (MediaPackageElement seriesAclMpe : mp.getElementsByFlavor(MediaPackageElements.XACML_POLICY_SERIES)) {
if (StringUtils.isNotBlank(oldSeriesId)) {
for (String tag : seriesAclTags) {
seriesAclMpe.addTag(tag);
}
} else {
// add archive tag to the element if the media package had no series set before
seriesAclMpe.addTag("archive");
}
}
}
} catch (SeriesException e) {
throw new IllegalStateException("Unable to retrieve series ACL for series " + oldSeriesId, e);
} catch (NotFoundException e) {
logger.debug("There is no ACL set for the series {}", mp.getSeries());
}
// add updated series extended metadata to the media package
try {
Opt<Map<String, byte[]>> seriesElementsOpt = seriesService.getSeriesElements(mp.getSeries());
for (Map<String, byte[]> seriesElements : seriesElementsOpt) {
for (String seriesElementType : seriesElements.keySet()) {
try (InputStream in = new ByteArrayInputStream(seriesElements.get(seriesElementType))) {
String elementId = UUID.randomUUID().toString();
URI catalogUrl = workspace.put(mp.getIdentifier().compact(), elementId, "dublincore.xml", in);
MediaPackageElement mpe = mp.add(catalogUrl, MediaPackageElement.Type.Catalog, MediaPackageElementFlavor.flavor(seriesElementType, "series"));
mpe.setIdentifier(elementId);
mpe.setChecksum(Checksum.create(ChecksumType.DEFAULT_TYPE, workspace.read(catalogUrl)));
if (StringUtils.isNotBlank(oldSeriesId)) {
if (seriesExtDcTags.containsKey(seriesElementType)) {
for (String tag : seriesExtDcTags.get(seriesElementType)) {
mpe.addTag(tag);
}
}
} else {
// add archive tag to the element if the media package had no series set before
mpe.addTag("archive");
}
} catch (IOException e) {
throw new IllegalStateException(String.format("Unable to serialize series element %s for the series %s", seriesElementType, mp.getSeries()), e);
} catch (NotFoundException e) {
throw new IllegalArgumentException("Unable to retrieve series element dublincore catalog for the series " + mp.getSeries(), e);
}
}
}
} catch (SeriesException e) {
throw new IllegalStateException("Unable to retrieve series elements for the series " + mp.getSeries(), e);
}
}
}
}
use of org.opencastproject.mediapackage.MediaPackageElement in project opencast by opencast.
the class IndexServiceImpl method createEvent.
@Override
public String createEvent(EventHttpServletRequest eventHttpServletRequest) throws ParseException, IOException, MediaPackageException, IngestException, NotFoundException, SchedulerException, UnauthorizedException {
// Preconditions
if (eventHttpServletRequest.getAcl().isNone()) {
throw new IllegalArgumentException("No access control list available to create new event.");
}
if (eventHttpServletRequest.getMediaPackage().isNone()) {
throw new IllegalArgumentException("No mediapackage available to create new event.");
}
if (eventHttpServletRequest.getMetadataList().isNone()) {
throw new IllegalArgumentException("No metadata list available to create new event.");
}
if (eventHttpServletRequest.getProcessing().isNone()) {
throw new IllegalArgumentException("No processing metadata available to create new event.");
}
if (eventHttpServletRequest.getSource().isNone()) {
throw new IllegalArgumentException("No source field metadata available to create new event.");
}
// Get Workflow
String workflowTemplate = (String) eventHttpServletRequest.getProcessing().get().get("workflow");
if (workflowTemplate == null)
throw new IllegalArgumentException("No workflow template in metadata");
// Get Type of Source
SourceType type = getSourceType(eventHttpServletRequest.getSource().get());
MetadataCollection eventMetadata = eventHttpServletRequest.getMetadataList().get().getMetadataByAdapter(eventCatalogUIAdapter).get();
JSONObject sourceMetadata = (JSONObject) eventHttpServletRequest.getSource().get().get("metadata");
if (sourceMetadata != null && (type.equals(SourceType.SCHEDULE_SINGLE) || type.equals(SourceType.SCHEDULE_MULTIPLE))) {
try {
MetadataField<?> current = eventMetadata.getOutputFields().get("location");
eventMetadata.updateStringField(current, (String) sourceMetadata.get("device"));
} catch (Exception e) {
logger.warn("Unable to parse device {}", sourceMetadata.get("device"));
throw new IllegalArgumentException("Unable to parse device");
}
}
Date currentStartDate = null;
MetadataField<?> starttime = eventMetadata.getOutputFields().get(DublinCore.PROPERTY_TEMPORAL.getLocalName());
if (starttime != null && starttime.isUpdated() && starttime.getValue().isSome()) {
DCMIPeriod period = EncodingSchemeUtils.decodeMandatoryPeriod((DublinCoreValue) starttime.getValue().get());
currentStartDate = period.getStart();
}
MetadataField<?> created = eventMetadata.getOutputFields().get(DublinCore.PROPERTY_CREATED.getLocalName());
if (created == null || !created.isUpdated() || created.getValue().isNone()) {
eventMetadata.removeField(created);
MetadataField<String> newCreated = MetadataUtils.copyMetadataField(created);
if (currentStartDate != null) {
newCreated.setValue(EncodingSchemeUtils.encodeDate(currentStartDate, Precision.Second).getValue());
} else {
newCreated.setValue(EncodingSchemeUtils.encodeDate(new Date(), Precision.Second).getValue());
}
eventMetadata.addField(newCreated);
}
// Get presenter usernames for use as technical presenters
Set<String> presenterUsernames = new HashSet<>();
Opt<Set<String>> technicalPresenters = updatePresenters(eventMetadata);
if (technicalPresenters.isSome()) {
presenterUsernames = technicalPresenters.get();
}
eventHttpServletRequest.getMetadataList().get().add(eventCatalogUIAdapter, eventMetadata);
updateMediaPackageMetadata(eventHttpServletRequest.getMediaPackage().get(), eventHttpServletRequest.getMetadataList().get());
DublinCoreCatalog dc = getDublinCoreCatalog(eventHttpServletRequest);
String captureAgentId = null;
TimeZone tz = null;
org.joda.time.DateTime start = null;
org.joda.time.DateTime end = null;
long duration = 0L;
Properties caProperties = new Properties();
RRule rRule = null;
if (sourceMetadata != null && (type.equals(SourceType.SCHEDULE_SINGLE) || type.equals(SourceType.SCHEDULE_MULTIPLE))) {
Properties configuration;
try {
captureAgentId = (String) sourceMetadata.get("device");
configuration = captureAgentStateService.getAgentConfiguration((String) sourceMetadata.get("device"));
} catch (Exception e) {
logger.warn("Unable to parse device {}: because: {}", sourceMetadata.get("device"), getStackTrace(e));
throw new IllegalArgumentException("Unable to parse device");
}
String durationString = (String) sourceMetadata.get("duration");
if (StringUtils.isBlank(durationString))
throw new IllegalArgumentException("No duration in source metadata");
// Create timezone based on CA's reported TZ.
String agentTimeZone = configuration.getProperty("capture.device.timezone");
if (StringUtils.isNotBlank(agentTimeZone)) {
tz = TimeZone.getTimeZone(agentTimeZone);
dc.set(DublinCores.OC_PROPERTY_AGENT_TIMEZONE, tz.getID());
} else {
// No timezone was present, assume the serve's local timezone.
tz = TimeZone.getDefault();
logger.debug("The field 'capture.device.timezone' has not been set in the agent configuration. The default server timezone will be used.");
}
org.joda.time.DateTime now = new org.joda.time.DateTime(DateTimeZone.UTC);
start = now.withMillis(DateTimeSupport.fromUTC((String) sourceMetadata.get("start")));
end = now.withMillis(DateTimeSupport.fromUTC((String) sourceMetadata.get("end")));
duration = Long.parseLong(durationString);
DublinCoreValue period = EncodingSchemeUtils.encodePeriod(new DCMIPeriod(start.toDate(), start.plus(duration).toDate()), Precision.Second);
String inputs = (String) sourceMetadata.get("inputs");
caProperties.putAll(configuration);
dc.set(DublinCore.PROPERTY_TEMPORAL, period);
caProperties.put(CaptureParameters.CAPTURE_DEVICE_NAMES, inputs);
}
if (type.equals(SourceType.SCHEDULE_MULTIPLE)) {
rRule = new RRule((String) sourceMetadata.get("rrule"));
}
Map<String, String> configuration = new HashMap<>();
if (eventHttpServletRequest.getProcessing().get().get("configuration") != null) {
configuration = new HashMap<>((JSONObject) eventHttpServletRequest.getProcessing().get().get("configuration"));
}
for (Entry<String, String> entry : configuration.entrySet()) {
caProperties.put(WORKFLOW_CONFIG_PREFIX.concat(entry.getKey()), entry.getValue());
}
caProperties.put(CaptureParameters.INGEST_WORKFLOW_DEFINITION, workflowTemplate);
eventHttpServletRequest.setMediaPackage(authorizationService.setAcl(eventHttpServletRequest.getMediaPackage().get(), AclScope.Episode, eventHttpServletRequest.getAcl().get()).getA());
MediaPackage mediaPackage;
switch(type) {
case UPLOAD:
case UPLOAD_LATER:
eventHttpServletRequest.setMediaPackage(updateDublincCoreCatalog(eventHttpServletRequest.getMediaPackage().get(), dc));
configuration.put("workflowDefinitionId", workflowTemplate);
WorkflowInstance ingest = ingestService.ingest(eventHttpServletRequest.getMediaPackage().get(), workflowTemplate, configuration);
return eventHttpServletRequest.getMediaPackage().get().getIdentifier().compact();
case SCHEDULE_SINGLE:
mediaPackage = updateDublincCoreCatalog(eventHttpServletRequest.getMediaPackage().get(), dc);
eventHttpServletRequest.setMediaPackage(mediaPackage);
try {
schedulerService.addEvent(start.toDate(), start.plus(duration).toDate(), captureAgentId, presenterUsernames, mediaPackage, configuration, (Map) caProperties, Opt.<Boolean>none(), Opt.<String>none(), SchedulerService.ORIGIN);
} finally {
for (MediaPackageElement mediaPackageElement : mediaPackage.getElements()) {
try {
workspace.delete(mediaPackage.getIdentifier().toString(), mediaPackageElement.getIdentifier());
} catch (NotFoundException | IOException e) {
logger.warn("Failed to delete media package element", e);
}
}
}
return mediaPackage.getIdentifier().compact();
case SCHEDULE_MULTIPLE:
List<Period> periods = schedulerService.calculatePeriods(rRule, start.toDate(), end.toDate(), duration, tz);
Map<String, Period> scheduled = new LinkedHashMap<>();
scheduled = schedulerService.addMultipleEvents(rRule, start.toDate(), end.toDate(), duration, tz, captureAgentId, presenterUsernames, eventHttpServletRequest.getMediaPackage().get(), configuration, (Map) caProperties, Opt.none(), Opt.none(), SchedulerService.ORIGIN);
return StringUtils.join(scheduled.keySet(), ",");
default:
logger.warn("Unknown source type {}", type);
throw new IllegalArgumentException("Unknown source type");
}
}
use of org.opencastproject.mediapackage.MediaPackageElement in project opencast by opencast.
the class ImageToVideoWorkflowOperationHandler method imageToVideo.
private WorkflowOperationResult imageToVideo(MediaPackage mp, WorkflowInstance wi) throws Exception {
// read cfg
final List<String> sourceTags = getCfg(wi, OPT_SOURCE_TAGS).map(asList).getOrElse(nil(String.class));
final Option<MediaPackageElementFlavor> sourceFlavor = getCfg(wi, OPT_SOURCE_FLAVOR).map(MediaPackageElementFlavor.parseFlavor);
if (sourceFlavor.isNone() && sourceTags.isEmpty()) {
logger.warn("No source tags or flavor are given to determine the image to use");
return createResult(mp, Action.SKIP);
}
final List<String> targetTags = getCfg(wi, OPT_TARGET_TAGS).map(asList).getOrElse(nil(String.class));
final Option<MediaPackageElementFlavor> targetFlavor = getCfg(wi, OPT_TARGET_FLAVOR).map(MediaPackageElementFlavor.parseFlavor);
final double duration = getCfg(wi, OPT_DURATION).bind(Strings.toDouble).getOrElse(this.<Double>cfgKeyMissing(OPT_DURATION));
final String profile = getCfg(wi, OPT_PROFILE).getOrElse(this.<String>cfgKeyMissing(OPT_PROFILE));
// run image to video jobs
final List<Job> jobs = Monadics.<MediaPackageElement>mlist(mp.getAttachments()).filter(sourceFlavor.map(Filters.matchesFlavor).getOrElse(Booleans.<MediaPackageElement>yes())).filter(Filters.hasTagAny(sourceTags)).map(Misc.<MediaPackageElement, Attachment>cast()).map(imageToVideo(profile, duration)).value();
if (JobUtil.waitForJobs(serviceRegistry, jobs).isSuccess()) {
for (final Job job : jobs) {
if (job.getPayload().length() > 0) {
Track track = (Track) MediaPackageElementParser.getFromXml(job.getPayload());
track.setURI(workspace.moveTo(track.getURI(), mp.getIdentifier().toString(), track.getIdentifier(), FilenameUtils.getName(track.getURI().toString())));
// Adjust the target tags
for (String tag : targetTags) {
track.addTag(tag);
}
// Adjust the target flavor.
for (MediaPackageElementFlavor flavor : targetFlavor) {
track.setFlavor(flavor);
}
// store new tracks to mediaPackage
mp.add(track);
logger.debug("Image to video operation completed");
} else {
logger.info("Image to video operation unsuccessful, no payload returned: {}", job);
return createResult(mp, Action.SKIP);
}
}
return createResult(mp, Action.CONTINUE, mlist(jobs).foldl(0L, new Function2<Long, Job, Long>() {
@Override
public Long apply(Long max, Job job) {
return Math.max(max, job.getQueueTime());
}
}));
} else {
throw new WorkflowOperationException("The image to video encoding jobs did not return successfully");
}
}
use of org.opencastproject.mediapackage.MediaPackageElement in project opencast by opencast.
the class PartialImportWorkflowOperationHandler 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 {
logger.debug("Running partial import workflow operation on workflow {}", workflowInstance.getId());
List<MediaPackageElement> elementsToClean = new ArrayList<MediaPackageElement>();
try {
return concat(workflowInstance.getMediaPackage(), workflowInstance.getCurrentOperation(), elementsToClean);
} catch (Exception e) {
throw new WorkflowOperationException(e);
} finally {
for (MediaPackageElement elem : elementsToClean) {
try {
workspace.delete(elem.getURI());
} catch (Exception e) {
logger.warn("Unable to delete element {}: {}", elem, e);
}
}
}
}
Aggregations