use of org.opencastproject.metadata.dublincore.DublinCoreCatalog in project opencast by opencast.
the class SchedulerServiceImpl method getDublinCore.
@Override
public DublinCoreCatalog getDublinCore(String mediaPackageId) throws NotFoundException, SchedulerException {
notEmpty(mediaPackageId, "mediaPackageId");
try {
AQueryBuilder query = assetManager.createQuery();
Props p = new Props(query);
AResult result = query.select(query.snapshot()).where(withOrganization(query).and(query.mediaPackageId(mediaPackageId)).and(withVersion(query)).and(query.hasPropertiesOf(p.namespace()))).run();
Opt<ARecord> record = result.getRecords().head();
if (record.isNone())
throw new NotFoundException();
Opt<DublinCoreCatalog> dublinCore = loadEpisodeDublinCoreFromAsset(record.get().getSnapshot().get());
if (dublinCore.isNone())
throw new NotFoundException("No dublincore catalog found " + mediaPackageId);
return dublinCore.get();
} catch (NotFoundException e) {
throw e;
} catch (Exception e) {
logger.error("Failed to get dublin core catalog of event '{}': {}", mediaPackageId, getStackTrace(e));
throw new SchedulerException(e);
}
}
use of org.opencastproject.metadata.dublincore.DublinCoreCatalog in project opencast by opencast.
the class SchedulerServiceImpl method addMultipleEventInternal.
private Map<String, Period> addMultipleEventInternal(List<Period> periods, String captureAgentId, Set<String> userIds, MediaPackage templateMp, Map<String, String> wfProperties, Map<String, String> caMetadata, String modificationOrigin, Opt<Boolean> optOutStatus, Opt<String> schedulingSource, Opt<String> trxId) throws SchedulerException {
notNull(periods, "periods");
requireTrue(periods.size() > 0, "periods");
notEmpty(captureAgentId, "captureAgentId");
notNull(userIds, "userIds");
notNull(templateMp, "mediaPackages");
notNull(wfProperties, "wfProperties");
notNull(caMetadata, "caMetadata");
notEmpty(modificationOrigin, "modificationOrigin");
notNull(optOutStatus, "optOutStatus");
notNull(schedulingSource, "schedulingSource");
notNull(trxId, "trxId");
Map<String, Period> scheduledEvents = new LinkedHashMap<>();
try {
LinkedList<Id> ids = new LinkedList<>();
AQueryBuilder qb = assetManager.createQuery();
Predicate p = null;
// While we don't have a list of IDs equal to the number of periods
while (ids.size() <= periods.size()) {
// Create a list of IDs equal to the number of periods, along with a set of AM predicates
while (ids.size() <= periods.size()) {
Id id = new IdImpl(UUID.randomUUID().toString());
ids.add(id);
Predicate np = qb.mediaPackageId(id.compact());
// Haha, p = np jokes with the AM query language. Ha. Haha. Ha. (Sob...)
if (null == p) {
p = np;
} else {
p = p.or(np);
}
}
// Select the list of ids which alread exist. Hint: this needs to be zero
AResult result = qb.select(qb.nothing()).where(withOrganization(qb).and(p).and(qb.version().isLatest())).run();
// If there is conflict, clear the list and start over
if (result.getTotalSize() > 0) {
ids.clear();
}
}
Opt<String> seriesId = Opt.nul(StringUtils.trimToNull(templateMp.getSeries()));
// Get opt out status
boolean optOut = getOptOutStatus(seriesId, optOutStatus);
if (trxId.isNone()) {
// Check for locked transactions
if (schedulingSource.isSome() && persistence.hasTransaction(schedulingSource.get())) {
logger.warn("Unable to add events, source '{}' is currently locked due to an active transaction!", schedulingSource.get());
throw new SchedulerTransactionLockException("Unable to add event, locked source " + schedulingSource.get());
}
// Check for conflicting events if not opted out
if (!optOut) {
List<MediaPackage> conflictingEvents = findConflictingEvents(periods, captureAgentId, TimeZone.getDefault());
if (conflictingEvents.size() > 0) {
logger.info("Unable to add events, conflicting events found: {}", conflictingEvents);
throw new SchedulerConflictException("Unable to add event, conflicting events found");
}
}
}
// counter for index into the list of mediapackages
int counter = 0;
for (Period event : periods) {
MediaPackage mediaPackage = (MediaPackage) templateMp.clone();
Date startDate = new Date(event.getStart().getTime());
Date endDate = new Date(event.getEnd().getTime());
Id id = ids.get(counter);
// Get, or make, the DC catalog
DublinCoreCatalog dc;
Opt<DublinCoreCatalog> dcOpt = DublinCoreUtil.loadEpisodeDublinCore(workspace, templateMp);
if (dcOpt.isSome()) {
dc = dcOpt.get();
dc = (DublinCoreCatalog) dc.clone();
// make sure to bind the OC_PROPERTY namespace
dc.addBindings(XmlNamespaceContext.mk(XmlNamespaceBinding.mk(DublinCores.OC_PROPERTY_NS_PREFIX, DublinCores.OC_PROPERTY_NS_URI)));
} else {
dc = DublinCores.mkOpencastEpisode().getCatalog();
}
// Set the new media package identifier
mediaPackage.setIdentifier(id);
// Update dublincore title and temporal
String newTitle = dc.getFirst(DublinCore.PROPERTY_TITLE) + String.format(" %0" + Integer.toString(periods.size()).length() + "d", ++counter);
dc.set(DublinCore.PROPERTY_TITLE, newTitle);
DublinCoreValue eventTime = EncodingSchemeUtils.encodePeriod(new DCMIPeriod(startDate, endDate), Precision.Second);
dc.set(DublinCore.PROPERTY_TEMPORAL, eventTime);
mediaPackage = updateDublincCoreCatalog(mediaPackage, dc);
mediaPackage.setTitle(newTitle);
String mediaPackageId = mediaPackage.getIdentifier().compact();
// Converting from iCal4j DateTime objects to plain Date objects to prevent AMQ issues below
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
cal.setTime(event.getStart());
Date startDateTime = cal.getTime();
cal.setTime(event.getEnd());
Date endDateTime = cal.getTime();
// Load dublincore and acl for update
Opt<DublinCoreCatalog> dublinCore = DublinCoreUtil.loadEpisodeDublinCore(workspace, mediaPackage);
Option<AccessControlList> acl = authorizationService.getAcl(mediaPackage, AclScope.Episode);
// Get updated agent properties
Map<String, String> finalCaProperties = getFinalAgentProperties(caMetadata, wfProperties, captureAgentId, seriesId, dublinCore);
// Persist asset
String checksum = calculateChecksum(workspace, getEventCatalogUIAdapterFlavors(), startDateTime, endDateTime, captureAgentId, userIds, mediaPackage, dublinCore, wfProperties, finalCaProperties, optOut, acl.toOpt().getOr(new AccessControlList()));
persistEvent(mediaPackageId, modificationOrigin, checksum, Opt.some(startDateTime), Opt.some(endDateTime), Opt.some(captureAgentId), Opt.some(userIds), Opt.some(mediaPackage), Opt.some(wfProperties), Opt.some(finalCaProperties), Opt.some(optOut), schedulingSource, trxId);
if (trxId.isNone()) {
// Send updates
sendUpdateAddEvent(mediaPackageId, acl.toOpt(), dublinCore, Opt.some(startDateTime), Opt.some(endDateTime), Opt.some(userIds), Opt.some(captureAgentId), Opt.some(finalCaProperties), Opt.some(optOut));
// Update last modified
touchLastEntry(captureAgentId);
}
scheduledEvents.put(mediaPackageId, event);
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 scheduledEvents;
} catch (SchedulerException e) {
throw e;
} catch (Exception e) {
logger.error("Failed to create events: {}", getStackTrace(e));
throw new SchedulerException(e);
}
}
use of org.opencastproject.metadata.dublincore.DublinCoreCatalog in project opencast by opencast.
the class SchedulerUtil method toHumanReadableString.
/**
* Converts a scheduler event to a human readable string
*
* @param workspace
* the workspace
* @param catalogFlavors
* the event catalog flavors
* @param event
* the scheduler event
* @return a human readable string
*/
public static String toHumanReadableString(Workspace workspace, List<MediaPackageElementFlavor> catalogFlavors, SchedulerEvent event) {
TechnicalMetadata technicalMetadata = event.getTechnicalMetadata();
StringBuilder sb = new StringBuilder("Event: ").append(CharUtils.LF);
sb.append("- ").append(event.getEventId()).append(CharUtils.LF);
sb.append(CharUtils.LF);
sb.append("Version").append(CharUtils.LF);
sb.append("- ").append(event.getVersion()).append(CharUtils.LF);
sb.append(CharUtils.LF);
sb.append("Start").append(CharUtils.LF);
sb.append("- ").append(DateTimeSupport.toUTC(technicalMetadata.getStartDate().getTime())).append(CharUtils.LF);
sb.append(CharUtils.LF);
sb.append("End").append(CharUtils.LF);
sb.append("- ").append(DateTimeSupport.toUTC(technicalMetadata.getEndDate().getTime())).append(CharUtils.LF);
sb.append(CharUtils.LF);
sb.append("Room").append(CharUtils.LF);
sb.append("- ").append(technicalMetadata.getAgentId()).append(CharUtils.LF);
sb.append(CharUtils.LF);
sb.append("Scheduling configuration").append(CharUtils.LF);
sb.append("- optout: ").append(technicalMetadata.isOptOut()).append(CharUtils.LF);
for (Entry<String, String> entry : technicalMetadata.getCaptureAgentConfiguration().entrySet()) {
sb.append("- ").append(entry.getKey()).append(": ").append(entry.getValue()).append(CharUtils.LF);
}
sb.append(CharUtils.LF);
sb.append("Presenters").append(CharUtils.LF);
for (String presenter : technicalMetadata.getPresenters()) {
sb.append("- ").append(presenter).append(CharUtils.LF);
}
sb.append(CharUtils.LF);
sb.append("Workflow configuration").append(CharUtils.LF);
for (Entry<String, String> entry : technicalMetadata.getWorkflowProperties().entrySet()) {
sb.append("- ").append(entry.getKey()).append(": ").append(entry.getValue()).append(CharUtils.LF);
}
sb.append(CharUtils.LF);
for (Catalog c : $(event.getMediaPackage().getCatalogs())) {
if (!catalogFlavors.contains(c.getFlavor()))
continue;
DublinCoreCatalog dublinCore;
try {
dublinCore = DublinCoreUtil.loadDublinCore(workspace, c);
} catch (Exception e) {
logger.error("Unable to read event dublincore: {}", ExceptionUtils.getStackTrace(e));
continue;
}
sb.append("Event metadata ").append("(").append(c.getFlavor().toString()).append(")").append(CharUtils.LF);
for (Entry<EName, List<DublinCoreValue>> entry : dublinCore.getValues().entrySet()) {
EName eName = entry.getKey();
for (DublinCoreValue value : entry.getValue()) {
sb.append("- ").append(eName.getNamespaceURI()).append(":").append(eName.getLocalName()).append(": ").append(value.getValue());
boolean hasLanguageDefined = !DublinCore.LANGUAGE_UNDEFINED.equals(value.getLanguage());
if (hasLanguageDefined || value.getEncodingScheme().isSome()) {
sb.append(" (");
if (hasLanguageDefined) {
sb.append("lang:").append(value.getLanguage());
if (value.getEncodingScheme().isSome())
sb.append("/");
}
for (EName schema : value.getEncodingScheme()) {
sb.append(schema.getLocalName());
}
sb.append(")");
}
sb.append(CharUtils.LF);
}
}
sb.append(CharUtils.LF);
}
return sb.toString();
}
use of org.opencastproject.metadata.dublincore.DublinCoreCatalog in project opencast by opencast.
the class SchedulerUtil method calculateChecksum.
public static String calculateChecksum(Workspace workspace, List<MediaPackageElementFlavor> eventCatalogUIAdapterFlavors, Date startDateTime, Date endDateTime, String captureAgentId, Set<String> userIds, MediaPackage mediaPackage, Opt<DublinCoreCatalog> episodeDublincore, Map<String, String> wfProperties, Map<String, String> finalCaProperties, boolean optOut, AccessControlList acl) {
List<String> userIdsList = new ArrayList<>(userIds);
Collections.sort(userIdsList);
final MessageDigest messageDigest = mkMd5MessageDigest();
messageDigest.update(mkChecksumInput(startDateTime));
messageDigest.update(mkChecksumInput(endDateTime));
messageDigest.update(mkChecksumInput(captureAgentId));
for (String user : userIdsList) {
messageDigest.update(mkChecksumInput(user));
}
if (episodeDublincore.isSome()) {
Catalog episodeCatalog = $(mediaPackage.getCatalogs()).filter(MediaPackageSupport.Filters.isEpisodeDublinCore.toFn()).head2();
Checksum checksum = episodeCatalog.getChecksum();
if (checksum == null) {
checksum = DublinCoreUtil.calculateChecksum(episodeDublincore.get());
episodeCatalog.setChecksum(checksum);
}
messageDigest.update(mkChecksumInput(checksum.toString()));
}
// Add extended metadata to calculation
for (Catalog c : $(mediaPackage.getCatalogs()).sort(sortCatalogById)) {
if (eventCatalogUIAdapterFlavors.contains(c.getFlavor())) {
Checksum checksum = c.getChecksum();
if (checksum == null) {
DublinCoreCatalog dublinCore = DublinCoreUtil.loadDublinCore(workspace, c);
checksum = DublinCoreUtil.calculateChecksum(dublinCore);
c.setChecksum(checksum);
}
messageDigest.update(mkChecksumInput(checksum.toString()));
}
}
messageDigest.update(mkChecksumInput(AccessControlUtil.calculateChecksum(acl).toString()));
for (Entry<String, String> entry : new TreeMap<>(wfProperties).entrySet()) {
messageDigest.update(mkChecksumInput(entry.getKey()));
messageDigest.update(mkChecksumInput(entry.getValue()));
}
for (Entry<String, String> entry : new TreeMap<>(finalCaProperties).entrySet()) {
messageDigest.update(mkChecksumInput(entry.getKey()));
messageDigest.update(mkChecksumInput(entry.getValue()));
}
messageDigest.update(mkChecksumInput(optOut));
return Checksum.convertToHex(messageDigest.digest());
}
use of org.opencastproject.metadata.dublincore.DublinCoreCatalog in project opencast by opencast.
the class SchedulerServiceImplTest method testTransactionCommit.
@Test
public void testTransactionCommit() throws Exception {
Date start = new Date();
Date end = new Date(System.currentTimeMillis() + 60000);
String captureDeviceID = "demo";
String seriesId = "series1";
Set<String> userIds = new HashSet<>();
userIds.add("user1");
userIds.add("user2");
MediaPackage mp = generateEvent(Opt.<String>none());
mp.setSeries(seriesId);
DublinCoreCatalog event = generateEvent(captureDeviceID, start, end);
addDublinCore(Opt.<String>none(), mp, event);
Map<String, String> caProperties = generateCaptureAgentMetadata("demo");
try {
schedSvc.addEvent(start, end, captureDeviceID, userIds, mp, wfProperties, caProperties, Opt.<Boolean>none(), Opt.some("new"), "new");
} catch (SchedulerTransactionLockException e) {
fail("Transaction create lock not working!");
}
SchedulerTransaction trx = schedSvc.createTransaction("new");
assertEquals("new", trx.getSource());
AQueryBuilder query = assetManager.createQuery();
AResult result = query.select(query.snapshot(), query.properties()).where(query.organizationId().eq(new DefaultOrganization().getId()).and(query.mediaPackageId(mp.getIdentifier().compact()))).run();
assertEquals(1, result.getSize());
trx.addEvent(start, end, captureDeviceID, userIds, mp, wfPropertiesUpdated, caProperties, Opt.<Boolean>none());
query = assetManager.createQuery();
result = query.select(query.snapshot(), query.properties()).where(query.organizationId().eq(new DefaultOrganization().getId()).and(query.mediaPackageId(mp.getIdentifier().compact()))).run();
assertEquals(2, result.getSize());
trx.commit();
query = assetManager.createQuery();
result = query.select(query.snapshot(), query.properties()).where(query.organizationId().eq(new DefaultOrganization().getId()).and(query.mediaPackageId(mp.getIdentifier().compact())).and(query.hasPropertiesOf(SchedulerServiceImpl.TRX_NAMESPACE).not())).run();
assertEquals(1, result.getSize());
ARecord record = result.getRecords().head2();
assertEquals(VersionImpl.mk(1), record.getSnapshot().get().getVersion());
try {
schedSvc.getTransaction(trx.getId());
fail("Deleted transaction found!");
} catch (NotFoundException e) {
assertNotNull(e);
}
}
Aggregations