Search in sources :

Example 56 with SchedulerException

use of org.opencastproject.scheduler.api.SchedulerException in project opencast by opencast.

the class SchedulerServiceImpl method addEventInternal.

private void addEventInternal(Date startDateTime, Date endDateTime, String captureAgentId, Set<String> userIds, MediaPackage mediaPackage, Map<String, String> wfProperties, Map<String, String> caMetadata, String modificationOrigin, Opt<Boolean> optOutStatus, Opt<String> schedulingSource, Opt<String> trxId) throws SchedulerException {
    notNull(startDateTime, "startDateTime");
    notNull(endDateTime, "endDateTime");
    notEmpty(captureAgentId, "captureAgentId");
    notNull(userIds, "userIds");
    notNull(mediaPackage, "mediaPackage");
    notNull(wfProperties, "wfProperties");
    notNull(caMetadata, "caMetadata");
    notEmpty(modificationOrigin, "modificationOrigin");
    notNull(optOutStatus, "optOutStatus");
    notNull(schedulingSource, "schedulingSource");
    notNull(trxId, "trxId");
    if (endDateTime.before(startDateTime))
        throw new IllegalArgumentException("The end date is before the start date");
    final String mediaPackageId = mediaPackage.getIdentifier().compact();
    try {
        AQueryBuilder query = assetManager.createQuery();
        // TODO this query runs twice if called from SchedulerTransactionImpl#addEvent
        AResult result = query.select(query.nothing()).where(withOrganization(query).and(query.mediaPackageId(mediaPackageId).and(query.version().isLatest()))).run();
        Opt<ARecord> record = result.getRecords().head();
        if (record.isSome()) {
            logger.warn("Mediapackage with id '{}' already exists!", mediaPackageId);
            throw new SchedulerConflictException("Mediapackage with id '" + mediaPackageId + "' already exists!");
        }
        Opt<String> seriesId = Opt.nul(StringUtils.trimToNull(mediaPackage.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 event '{}', source '{}' is currently locked due to an active transaction!", mediaPackageId, 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(captureAgentId, startDateTime, endDateTime);
                if (conflictingEvents.size() > 0) {
                    logger.info("Unable to add event {}, conflicting events found: {}", mediaPackageId, conflictingEvents);
                    throw new SchedulerConflictException("Unable to add event, conflicting events found for event " + mediaPackageId);
                }
            }
        }
        // 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);
        }
    } catch (SchedulerException e) {
        throw e;
    } catch (Exception e) {
        logger.error("Failed to create event with id '{}': {}", mediaPackageId, getStackTrace(e));
        throw new SchedulerException(e);
    }
}
Also used : AccessControlList(org.opencastproject.security.api.AccessControlList) SchedulerException(org.opencastproject.scheduler.api.SchedulerException) SchedulerConflictException(org.opencastproject.scheduler.api.SchedulerConflictException) AQueryBuilder(org.opencastproject.assetmanager.api.query.AQueryBuilder) 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) SchedulerTransactionLockException(org.opencastproject.scheduler.api.SchedulerTransactionLockException) MediaPackage(org.opencastproject.mediapackage.MediaPackage) AResult(org.opencastproject.assetmanager.api.query.AResult) DublinCoreCatalog(org.opencastproject.metadata.dublincore.DublinCoreCatalog)

Example 57 with SchedulerException

use of org.opencastproject.scheduler.api.SchedulerException in project opencast by opencast.

the class SchedulerServiceImpl method isOptOut.

@Override
public boolean isOptOut(String mediaPackageId) throws NotFoundException, SchedulerException {
    notEmpty(mediaPackageId, "mediaPackageId");
    try {
        AQueryBuilder query = assetManager.createQuery();
        Props p = new Props(query);
        Opt<Property> optOut = query.select(p.optOut().target()).where(withOrganization(query).and(query.mediaPackageId(mediaPackageId)).and(query.version().isLatest()).and(p.optOut().exists())).run().getRecords().bind(ARecords.getProperties).head();
        if (optOut.isNone())
            throw new NotFoundException();
        return optOut.get().getValue().get(Value.BOOLEAN);
    } catch (NotFoundException e) {
        throw e;
    } catch (Exception e) {
        logger.error("Failed to get opt out status of event with mediapackage '{}': {}", mediaPackageId, 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) Property(org.opencastproject.assetmanager.api.Property) 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 58 with SchedulerException

use of org.opencastproject.scheduler.api.SchedulerException in project opencast by opencast.

the class SchedulerServiceImpl method updateEventInternal.

private void updateEventInternal(final String mpId, String modificationOrigin, Opt<Date> startDateTime, Opt<Date> endDateTime, Opt<String> captureAgentId, Opt<Set<String>> userIds, Opt<MediaPackage> mediaPackage, Opt<Map<String, String>> wfProperties, Opt<Map<String, String>> caMetadata, Opt<Opt<Boolean>> optOutOption, Opt<String> trxId) throws NotFoundException, SchedulerException {
    notEmpty(mpId, "mpId");
    notEmpty(modificationOrigin, "modificationOrigin");
    notNull(startDateTime, "startDateTime");
    notNull(endDateTime, "endDateTime");
    notNull(captureAgentId, "captureAgentId");
    notNull(userIds, "userIds");
    notNull(mediaPackage, "mediaPackage");
    notNull(wfProperties, "wfProperties");
    notNull(caMetadata, "caMetadata");
    notNull(optOutOption, "optOutStatus");
    notNull(trxId, "trxId");
    try {
        AQueryBuilder query = assetManager.createQuery();
        Props p = new Props(query);
        ASelectQuery select = query.select(query.snapshot(), p.start().target(), p.end().target(), query.propertiesOf(WORKFLOW_NAMESPACE, CA_NAMESPACE), p.agent().target(), p.source().target(), p.checksum().target(), p.optOut().target(), p.presenters().target()).where(withOrganization(query).and(query.mediaPackageId(mpId).and(query.version().isLatest()).and(query.hasPropertiesOf(p.namespace()))));
        Opt<ARecord> optEvent = select.run().getRecords().head();
        if (optEvent.isNone())
            throw new NotFoundException("No event found while updating event " + mpId);
        ARecord record = optEvent.get();
        if (record.getSnapshot().isNone())
            throw new NotFoundException("No mediapackage found while updating event " + mpId);
        Opt<DublinCoreCatalog> dublinCoreOpt = loadEpisodeDublinCoreFromAsset(record.getSnapshot().get());
        if (dublinCoreOpt.isNone())
            throw new NotFoundException("No dublincore found while updating event " + mpId);
        verifyActive(mpId, record);
        Date start = record.getProperties().apply(Properties.getDate(START_DATE_CONFIG));
        Date end = record.getProperties().apply(Properties.getDate(END_DATE_CONFIG));
        if ((startDateTime.isSome() || endDateTime.isSome()) && endDateTime.getOr(end).before(startDateTime.getOr(start)))
            throw new SchedulerException("The end date is before the start date");
        String agentId = record.getProperties().apply(Properties.getString(AGENT_CONFIG));
        Opt<String> seriesId = Opt.nul(record.getSnapshot().get().getMediaPackage().getSeries());
        boolean oldOptOut = record.getProperties().apply(Properties.getBoolean(OPTOUT_CONFIG));
        // Get opt out status
        Opt<Boolean> optOut = Opt.none();
        for (Opt<Boolean> optOutToUpdate : optOutOption) {
            optOut = Opt.some(getOptOutStatus(seriesId, optOutToUpdate));
        }
        if (trxId.isNone()) {
            // Check for locked transactions
            Opt<String> source = record.getProperties().apply(Properties.getStringOpt(SOURCE_CONFIG));
            if (source.isSome() && persistence.hasTransaction(source.get())) {
                logger.warn("Unable to update event '{}', source '{}' is currently locked due to an active transaction!", mpId, source.get());
                throw new SchedulerTransactionLockException("Unable to update event, locked source " + source.get());
            }
            // Set to opted out
            boolean isNewOptOut = optOut.isSome() && optOut.get();
            // Changed to ready for recording
            boolean readyForRecording = optOut.isSome() && !optOut.get();
            // Has a conflict related property be changed?
            boolean propertyChanged = captureAgentId.isSome() || startDateTime.isSome() || endDateTime.isSome();
            // Check for conflicting events
            if (!isNewOptOut && (readyForRecording || (propertyChanged && !oldOptOut))) {
                List<MediaPackage> conflictingEvents = $(findConflictingEvents(captureAgentId.getOr(agentId), startDateTime.getOr(start), endDateTime.getOr(end))).filter(new Fn<MediaPackage, Boolean>() {

                    @Override
                    public Boolean apply(MediaPackage mp) {
                        return !mpId.equals(mp.getIdentifier().compact());
                    }
                }).toList();
                if (conflictingEvents.size() > 0) {
                    logger.info("Unable to update event {}, conflicting events found: {}", mpId, conflictingEvents);
                    throw new SchedulerConflictException("Unable to update event, conflicting events found for event " + mpId);
                }
            }
        }
        Set<String> presenters = getPresenters(record.getProperties().apply(getStringOpt(PRESENTERS_CONFIG)).getOr(""));
        Map<String, String> wfProps = record.getProperties().filter(filterByNamespace._2(WORKFLOW_NAMESPACE)).group(toKey, toValue);
        Map<String, String> caProperties = record.getProperties().filter(filterByNamespace._2(CA_NAMESPACE)).group(toKey, toValue);
        boolean propertiesChanged = false;
        boolean dublinCoreChanged = false;
        // Get workflow properties
        for (Map<String, String> wfPropsToUpdate : wfProperties) {
            propertiesChanged = true;
            wfProps = wfPropsToUpdate;
        }
        // Get capture agent properties
        for (Map<String, String> caMetadataToUpdate : caMetadata) {
            propertiesChanged = true;
            caProperties = caMetadataToUpdate;
        }
        if (captureAgentId.isSome())
            propertiesChanged = true;
        Opt<AccessControlList> acl = Opt.none();
        Opt<DublinCoreCatalog> dublinCore = Opt.none();
        Opt<AccessControlList> aclOld = loadEpisodeAclFromAsset(record.getSnapshot().get());
        for (MediaPackage mpToUpdate : mediaPackage) {
            // Check for series change
            if (ne(record.getSnapshot().get().getMediaPackage().getSeries(), mpToUpdate.getSeries())) {
                propertiesChanged = true;
                seriesId = Opt.nul(mpToUpdate.getSeries());
            }
            // Check for ACL change and send update
            Option<AccessControlList> aclNew = authorizationService.getAcl(mpToUpdate, AclScope.Episode);
            if (aclNew.isSome()) {
                if (aclOld.isNone() || !AccessControlUtil.equals(aclNew.get(), aclOld.get())) {
                    acl = aclNew.toOpt();
                }
            }
            // Check for dublin core change and send update
            Opt<DublinCoreCatalog> dublinCoreNew = DublinCoreUtil.loadEpisodeDublinCore(workspace, mpToUpdate);
            if (dublinCoreNew.isSome() && !DublinCoreUtil.equals(dublinCoreOpt.get(), dublinCoreNew.get())) {
                dublinCoreChanged = true;
                propertiesChanged = true;
                dublinCore = dublinCoreNew;
            }
        }
        Opt<Map<String, String>> finalCaProperties = Opt.none();
        if (propertiesChanged) {
            finalCaProperties = Opt.some(getFinalAgentProperties(caProperties, wfProps, captureAgentId.getOr(agentId), seriesId, some(dublinCore.getOr(dublinCoreOpt.get()))));
        }
        String checksum = calculateChecksum(workspace, getEventCatalogUIAdapterFlavors(), startDateTime.getOr(start), endDateTime.getOr(end), captureAgentId.getOr(agentId), userIds.getOr(presenters), mediaPackage.getOr(record.getSnapshot().get().getMediaPackage()), some(dublinCore.getOr(dublinCoreOpt.get())), wfProperties.getOr(wfProps), finalCaProperties.getOr(caProperties), optOut.getOr(oldOptOut), acl.getOr(aclOld.getOr(new AccessControlList())));
        if (trxId.isNone()) {
            String oldChecksum = record.getProperties().apply(Properties.getString(CHECKSUM));
            if (checksum.equals(oldChecksum)) {
                logger.debug("Updated event {} has same checksum, ignore update", mpId);
                return;
            }
        }
        // Update asset
        persistEvent(mpId, modificationOrigin, checksum, startDateTime, endDateTime, captureAgentId, userIds, mediaPackage, wfProperties, finalCaProperties, optOut, Opt.<String>none(), trxId);
        if (trxId.isNone()) {
            // Send updates
            sendUpdateAddEvent(mpId, acl, dublinCore, startDateTime, endDateTime, userIds, Opt.some(agentId), finalCaProperties, optOut);
            // Update last modified
            if (propertiesChanged || dublinCoreChanged || optOutOption.isSome() || startDateTime.isSome() || endDateTime.isSome()) {
                touchLastEntry(agentId);
                for (String agent : captureAgentId) {
                    touchLastEntry(agent);
                }
            }
        }
    } catch (NotFoundException e) {
        throw e;
    } catch (SchedulerException e) {
        throw e;
    } catch (Exception e) {
        logger.error("Failed to update event with id '{}': {}", mpId, 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) ARecord(org.opencastproject.assetmanager.api.query.ARecord) SchedulerTransactionLockException(org.opencastproject.scheduler.api.SchedulerTransactionLockException) Fn(com.entwinemedia.fn.Fn) SchedulerConflictException(org.opencastproject.scheduler.api.SchedulerConflictException) 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) ASelectQuery(org.opencastproject.assetmanager.api.query.ASelectQuery) DublinCoreCatalog(org.opencastproject.metadata.dublincore.DublinCoreCatalog) Map(java.util.Map) LinkedHashMap(java.util.LinkedHashMap) HashMap(java.util.HashMap)

Example 59 with SchedulerException

use of org.opencastproject.scheduler.api.SchedulerException in project opencast by opencast.

the class SchedulerServiceImpl method getRecordingState.

@Override
public Recording getRecordingState(String id) throws NotFoundException, SchedulerException {
    notEmpty(id, "id");
    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())).and(p.recordingStatus().exists()).and(p.recordingLastHeard().exists())).run();
        Opt<ARecord> record = result.getRecords().head();
        if (record.isNone() || record.get().getProperties().isEmpty())
            throw new NotFoundException();
        String recordingState = record.get().getProperties().apply(Properties.getString(RECORDING_STATE_CONFIG));
        Long lastHeard = record.get().getProperties().apply(Properties.getLong(RECORDING_LAST_HEARD_CONFIG));
        return new RecordingImpl(id, recordingState, lastHeard);
    } catch (NotFoundException e) {
        throw e;
    } catch (Exception e) {
        logger.error("Failed to get recording status of event with mediapackage '{}': {}", id, 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) 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)

Example 60 with SchedulerException

use of org.opencastproject.scheduler.api.SchedulerException in project opencast by opencast.

the class SchedulerServiceImpl method getWorkflowConfig.

@Override
public Map<String, String> getWorkflowConfig(String mediaPackageId) throws NotFoundException, SchedulerException {
    notEmpty(mediaPackageId, "mediaPackageId");
    try {
        AQueryBuilder query = assetManager.createQuery();
        Props p = new Props(query);
        AResult result = query.select(query.propertiesOf(WORKFLOW_NAMESPACE)).where(withOrganization(query).and(query.mediaPackageId(mediaPackageId)).and(query.version().isLatest()).and(query.hasPropertiesOf(p.namespace()))).run();
        Opt<ARecord> record = result.getRecords().head();
        if (record.isNone())
            throw new NotFoundException();
        return record.get().getProperties().group(toKey, toValue);
    } catch (NotFoundException e) {
        throw e;
    } catch (Exception e) {
        logger.error("Failed to get workflow configuration 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) 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)

Aggregations

SchedulerException (org.opencastproject.scheduler.api.SchedulerException)83 NotFoundException (org.opencastproject.util.NotFoundException)76 UnauthorizedException (org.opencastproject.security.api.UnauthorizedException)68 SchedulerConflictException (org.opencastproject.scheduler.api.SchedulerConflictException)62 SchedulerTransactionLockException (org.opencastproject.scheduler.api.SchedulerTransactionLockException)60 HttpResponse (org.apache.http.HttpResponse)32 MediaPackageException (org.opencastproject.mediapackage.MediaPackageException)30 IOException (java.io.IOException)29 SeriesException (org.opencastproject.series.api.SeriesException)27 ValidationException (net.fortuna.ical4j.model.ValidationException)26 ServiceException (org.osgi.framework.ServiceException)26 ConfigurationException (org.osgi.service.cm.ConfigurationException)26 AQueryBuilder (org.opencastproject.assetmanager.api.query.AQueryBuilder)22 MediaPackage (org.opencastproject.mediapackage.MediaPackage)22 Date (java.util.Date)21 HttpGet (org.apache.http.client.methods.HttpGet)19 ARecord (org.opencastproject.assetmanager.api.query.ARecord)19 AResult (org.opencastproject.assetmanager.api.query.AResult)19 ArrayList (java.util.ArrayList)16 Log.getHumanReadableTimeString (org.opencastproject.util.Log.getHumanReadableTimeString)16