Search in sources :

Example 11 with AQueryBuilder

use of org.opencastproject.assetmanager.api.query.AQueryBuilder in project opencast by opencast.

the class SchedulerServiceImpl method getCalendar.

@Override
public String getCalendar(Opt<String> captureAgentId, Opt<String> seriesId, Opt<Date> cutoff) throws SchedulerException {
    try {
        AQueryBuilder query = assetManager.createQuery();
        Props p = new Props(query);
        Predicate predicate = withOrganization(query).and(withOwner(query)).and(query.hasPropertiesOf(p.namespace())).and(p.optOut().eq(false)).and(withVersion(query)).and(p.end().ge(DateTime.now().minusHours(1).toDate()));
        for (String agentId : captureAgentId) {
            predicate = predicate.and(p.agent().eq(agentId));
        }
        for (String series : seriesId) {
            predicate = predicate.and(query.seriesId().eq(series));
        }
        for (Date d : cutoff) {
            predicate = predicate.and(p.start().le(d));
        }
        ASelectQuery select = query.select(query.snapshot(), p.agent().target(), p.start().target(), p.end().target(), query.propertiesOf(CA_NAMESPACE)).where(predicate);
        Stream<ARecord> records = select.run().getRecords();
        CalendarGenerator cal = new CalendarGenerator(seriesService);
        for (ARecord record : records) {
            boolean blacklisted;
            // isBlacklisted() methods are not implemented in the persistence layer and return always false
            // try {
            // //blacklisted = isBlacklisted(record.getMediaPackageId());
            // } catch (NotFoundException e) {
            // continue;
            // }
            blacklisted = false;
            // Skip blacklisted events
            if (blacklisted)
                continue;
            Opt<MediaPackage> optMp = record.getSnapshot().map(episodeToMp);
            // If the event media package is empty, skip the event
            if (optMp.isNone()) {
                logger.warn("Mediapackage for event '{}' can't be found, event is not recorded", record.getMediaPackageId());
                continue;
            }
            Opt<DublinCoreCatalog> catalogOpt = loadEpisodeDublinCoreFromAsset(record.getSnapshot().get());
            if (catalogOpt.isNone()) {
                logger.warn("No episode catalog available, skipping!");
                continue;
            }
            Map<String, String> caMetadata = record.getProperties().filter(filterByNamespace._2(CA_NAMESPACE)).group(toKey, toValue);
            // If the even properties are empty, skip the event
            if (caMetadata.isEmpty()) {
                logger.warn("Properties for event '{}' can't be found, event is not recorded", record.getMediaPackageId());
                continue;
            }
            String agentId = record.getProperties().apply(Properties.getString(AGENT_CONFIG));
            Date start = record.getProperties().apply(Properties.getDate(START_DATE_CONFIG));
            Date end = record.getProperties().apply(Properties.getDate(END_DATE_CONFIG));
            Date lastModified = record.getSnapshot().get().getArchivalDate();
            // Add the entry to the calendar, skip it with a warning if adding fails
            try {
                cal.addEvent(optMp.get(), catalogOpt.get(), agentId, start, end, lastModified, toPropertyString(caMetadata));
            } catch (Exception e) {
                logger.warn("Error adding event '{}' to calendar, event is not recorded: {}", record.getMediaPackageId(), getStackTrace(e));
                continue;
            }
        }
        // Only validate calendars with events. Without any events, the iCalendar won't validate
        if (cal.getCalendar().getComponents().size() > 0) {
            try {
                cal.getCalendar().validate();
            } catch (ValidationException e) {
                logger.warn("Recording calendar could not be validated (returning it anyways): {}", getStackTrace(e));
            }
        }
        return cal.getCalendar().toString();
    } catch (Exception e) {
        if (e instanceof SchedulerException)
            throw e;
        logger.error("Failed getting calendar: {}", getStackTrace(e));
        throw new SchedulerException(e);
    }
}
Also used : ValidationException(net.fortuna.ical4j.model.ValidationException) SchedulerException(org.opencastproject.scheduler.api.SchedulerException) AQueryBuilder(org.opencastproject.assetmanager.api.query.AQueryBuilder) Log.getHumanReadableTimeString(org.opencastproject.util.Log.getHumanReadableTimeString) Date(java.util.Date) SchedulerException(org.opencastproject.scheduler.api.SchedulerException) SchedulerConflictException(org.opencastproject.scheduler.api.SchedulerConflictException) IOException(java.io.IOException) ServiceException(org.osgi.framework.ServiceException) SchedulerTransactionLockException(org.opencastproject.scheduler.api.SchedulerTransactionLockException) ConfigurationException(org.osgi.service.cm.ConfigurationException) SeriesException(org.opencastproject.series.api.SeriesException) MediaPackageException(org.opencastproject.mediapackage.MediaPackageException) ValidationException(net.fortuna.ical4j.model.ValidationException) UnauthorizedException(org.opencastproject.security.api.UnauthorizedException) NotFoundException(org.opencastproject.util.NotFoundException) Predicate(org.opencastproject.assetmanager.api.query.Predicate) ARecord(org.opencastproject.assetmanager.api.query.ARecord) MediaPackage(org.opencastproject.mediapackage.MediaPackage) ASelectQuery(org.opencastproject.assetmanager.api.query.ASelectQuery) DublinCoreCatalog(org.opencastproject.metadata.dublincore.DublinCoreCatalog)

Example 12 with AQueryBuilder

use of org.opencastproject.assetmanager.api.query.AQueryBuilder in project opencast by opencast.

the class SchedulerServiceImpl method updateRecordingState.

@Override
public boolean updateRecordingState(String id, String state) throws NotFoundException, SchedulerException {
    notEmpty(id, "id");
    notEmpty(state, "state");
    if (!RecordingState.KNOWN_STATES.contains(state)) {
        logger.warn("Invalid recording state: {}.", state);
        return false;
    }
    try {
        AQueryBuilder query = assetManager.createQuery();
        Props p = new Props(query);
        AResult result = query.select(p.recordingStatus().target(), p.recordingLastHeard().target()).where(withOrganization(query).and(query.mediaPackageId(id).and(query.version().isLatest()).and(query.hasPropertiesOf(p.namespace())))).run();
        Opt<ARecord> record = result.getRecords().head();
        if (record.isNone())
            throw new NotFoundException();
        Opt<String> recordingState = record.get().getProperties().apply(Properties.getStringOpt(RECORDING_STATE_CONFIG));
        Opt<Long> lastHeard = record.get().getProperties().apply(Properties.getLongOpt(RECORDING_LAST_HEARD_CONFIG));
        if (recordingState.isSome() && lastHeard.isSome()) {
            Recording r = new RecordingImpl(id, recordingState.get(), lastHeard.get());
            if (state.equals(r.getState())) {
                logger.debug("Recording state not changed");
                // Reset the state anyway so that the last-heard-from time is correct...
                r.setState(state);
            } else {
                logger.debug("Setting Recording {} to state {}.", id, state);
                r.setState(state);
                sendRecordingUpdate(r);
            }
            assetManager.setProperty(p.recordingStatus().mk(id, r.getState()));
            assetManager.setProperty(p.recordingLastHeard().mk(id, r.getLastCheckinTime()));
            return true;
        } else {
            Recording r = new RecordingImpl(id, state);
            assetManager.setProperty(p.recordingStatus().mk(id, r.getState()));
            assetManager.setProperty(p.recordingLastHeard().mk(id, r.getLastCheckinTime()));
            sendRecordingUpdate(r);
            return true;
        }
    } catch (NotFoundException e) {
        throw e;
    } catch (Exception e) {
        logger.error("Failed to update recording status of event with mediapackage '{}': {}", id, getStackTrace(e));
        throw new SchedulerException(e);
    }
}
Also used : SchedulerException(org.opencastproject.scheduler.api.SchedulerException) AQueryBuilder(org.opencastproject.assetmanager.api.query.AQueryBuilder) NotFoundException(org.opencastproject.util.NotFoundException) RecordingImpl(org.opencastproject.scheduler.api.RecordingImpl) Log.getHumanReadableTimeString(org.opencastproject.util.Log.getHumanReadableTimeString) SchedulerException(org.opencastproject.scheduler.api.SchedulerException) SchedulerConflictException(org.opencastproject.scheduler.api.SchedulerConflictException) IOException(java.io.IOException) ServiceException(org.osgi.framework.ServiceException) SchedulerTransactionLockException(org.opencastproject.scheduler.api.SchedulerTransactionLockException) ConfigurationException(org.osgi.service.cm.ConfigurationException) SeriesException(org.opencastproject.series.api.SeriesException) MediaPackageException(org.opencastproject.mediapackage.MediaPackageException) ValidationException(net.fortuna.ical4j.model.ValidationException) UnauthorizedException(org.opencastproject.security.api.UnauthorizedException) NotFoundException(org.opencastproject.util.NotFoundException) ARecord(org.opencastproject.assetmanager.api.query.ARecord) AResult(org.opencastproject.assetmanager.api.query.AResult) Recording(org.opencastproject.scheduler.api.Recording)

Example 13 with AQueryBuilder

use of org.opencastproject.assetmanager.api.query.AQueryBuilder in project opencast by opencast.

the class SchedulerServiceImpl method getScheduledEvents.

/*
   * FIXME: This query is unsafe since it may fetch many many rows. It would be better to do conflict checking directly
   * in the database instead of fetching all scheduled events for the capture agent and then doing the checks in memory.
   * Unfortunately, the current database schema is not suitable to do this in an efficient manner. Especially the generic
   * concept of 'properties' would lead to many nested queries.
   */
private ARecord[] getScheduledEvents(Opt<String> captureAgentId) {
    AQueryBuilder query = assetManager.createQuery();
    Props p = new Props(query);
    Predicate predicate = withOrganization(query).and(withOwner(query)).and(query.hasPropertiesOf(p.namespace())).and(withVersion(query));
    for (String agentId : captureAgentId) {
        predicate = predicate.and(p.agent().eq(agentId));
    }
    return query.select(query.snapshot(), p.start().target(), p.end().target()).where(predicate).run().getRecords().toList().toArray(new ARecord[0]);
}
Also used : AQueryBuilder(org.opencastproject.assetmanager.api.query.AQueryBuilder) Log.getHumanReadableTimeString(org.opencastproject.util.Log.getHumanReadableTimeString) Predicate(org.opencastproject.assetmanager.api.query.Predicate)

Example 14 with AQueryBuilder

use of org.opencastproject.assetmanager.api.query.AQueryBuilder 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);
    }
}
Also used : ARecord(org.opencastproject.assetmanager.api.query.ARecord) SchedulerException(org.opencastproject.scheduler.api.SchedulerException) AQueryBuilder(org.opencastproject.assetmanager.api.query.AQueryBuilder) AResult(org.opencastproject.assetmanager.api.query.AResult) NotFoundException(org.opencastproject.util.NotFoundException) DublinCoreCatalog(org.opencastproject.metadata.dublincore.DublinCoreCatalog) SchedulerException(org.opencastproject.scheduler.api.SchedulerException) SchedulerConflictException(org.opencastproject.scheduler.api.SchedulerConflictException) IOException(java.io.IOException) ServiceException(org.osgi.framework.ServiceException) SchedulerTransactionLockException(org.opencastproject.scheduler.api.SchedulerTransactionLockException) ConfigurationException(org.osgi.service.cm.ConfigurationException) SeriesException(org.opencastproject.series.api.SeriesException) MediaPackageException(org.opencastproject.mediapackage.MediaPackageException) ValidationException(net.fortuna.ical4j.model.ValidationException) UnauthorizedException(org.opencastproject.security.api.UnauthorizedException) NotFoundException(org.opencastproject.util.NotFoundException)

Example 15 with AQueryBuilder

use of org.opencastproject.assetmanager.api.query.AQueryBuilder 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);
    }
}
Also used : AccessControlList(org.opencastproject.security.api.AccessControlList) SchedulerException(org.opencastproject.scheduler.api.SchedulerException) AQueryBuilder(org.opencastproject.assetmanager.api.query.AQueryBuilder) NotFoundException(org.opencastproject.util.NotFoundException) Log.getHumanReadableTimeString(org.opencastproject.util.Log.getHumanReadableTimeString) IdImpl(org.opencastproject.mediapackage.identifier.IdImpl) LinkedHashMap(java.util.LinkedHashMap) Predicate(org.opencastproject.assetmanager.api.query.Predicate) SchedulerTransactionLockException(org.opencastproject.scheduler.api.SchedulerTransactionLockException) MediaPackageElement(org.opencastproject.mediapackage.MediaPackageElement) AResult(org.opencastproject.assetmanager.api.query.AResult) DublinCoreValue(org.opencastproject.metadata.dublincore.DublinCoreValue) Calendar(java.util.Calendar) SchedulerConflictException(org.opencastproject.scheduler.api.SchedulerConflictException) DCMIPeriod(org.opencastproject.metadata.dublincore.DCMIPeriod) Period(net.fortuna.ical4j.model.Period) DCMIPeriod(org.opencastproject.metadata.dublincore.DCMIPeriod) IOException(java.io.IOException) LinkedList(java.util.LinkedList) Date(java.util.Date) SchedulerException(org.opencastproject.scheduler.api.SchedulerException) SchedulerConflictException(org.opencastproject.scheduler.api.SchedulerConflictException) IOException(java.io.IOException) ServiceException(org.osgi.framework.ServiceException) SchedulerTransactionLockException(org.opencastproject.scheduler.api.SchedulerTransactionLockException) ConfigurationException(org.osgi.service.cm.ConfigurationException) SeriesException(org.opencastproject.series.api.SeriesException) MediaPackageException(org.opencastproject.mediapackage.MediaPackageException) ValidationException(net.fortuna.ical4j.model.ValidationException) UnauthorizedException(org.opencastproject.security.api.UnauthorizedException) NotFoundException(org.opencastproject.util.NotFoundException) MediaPackage(org.opencastproject.mediapackage.MediaPackage) PropertyId(org.opencastproject.assetmanager.api.PropertyId) Id(org.opencastproject.mediapackage.identifier.Id) DublinCoreCatalog(org.opencastproject.metadata.dublincore.DublinCoreCatalog)

Aggregations

AQueryBuilder (org.opencastproject.assetmanager.api.query.AQueryBuilder)48 AResult (org.opencastproject.assetmanager.api.query.AResult)37 ARecord (org.opencastproject.assetmanager.api.query.ARecord)31 NotFoundException (org.opencastproject.util.NotFoundException)31 SchedulerTransactionLockException (org.opencastproject.scheduler.api.SchedulerTransactionLockException)24 SchedulerConflictException (org.opencastproject.scheduler.api.SchedulerConflictException)23 SchedulerException (org.opencastproject.scheduler.api.SchedulerException)23 UnauthorizedException (org.opencastproject.security.api.UnauthorizedException)23 IOException (java.io.IOException)22 MediaPackageException (org.opencastproject.mediapackage.MediaPackageException)22 ValidationException (net.fortuna.ical4j.model.ValidationException)21 SeriesException (org.opencastproject.series.api.SeriesException)21 ServiceException (org.osgi.framework.ServiceException)21 ConfigurationException (org.osgi.service.cm.ConfigurationException)21 MediaPackage (org.opencastproject.mediapackage.MediaPackage)18 Date (java.util.Date)17 DublinCoreCatalog (org.opencastproject.metadata.dublincore.DublinCoreCatalog)14 Log.getHumanReadableTimeString (org.opencastproject.util.Log.getHumanReadableTimeString)14 Test (org.junit.Test)12 Predicate (org.opencastproject.assetmanager.api.query.Predicate)10