Search in sources :

Example 6 with WorkflowSet

use of org.opencastproject.workflow.api.WorkflowSet in project opencast by opencast.

the class WorkflowRestService method getWorkflowsAsXml.

@GET
@Produces(MediaType.TEXT_XML)
@Path("instances.xml")
@RestQuery(name = "workflowsasxml", description = "List all workflow instances matching the query parameters", returnDescription = "An XML representation of the set of workflows matching these query parameters", restParameters = { @RestParameter(name = "state", isRequired = false, description = "Filter results by workflows' current state", type = STRING), @RestParameter(name = "q", isRequired = false, description = "Filter results by free text query", type = STRING), @RestParameter(name = "seriesId", isRequired = false, description = "Filter results by series identifier", type = STRING), @RestParameter(name = "seriesTitle", isRequired = false, description = "Filter results by series title", type = STRING), @RestParameter(name = "creator", isRequired = false, description = "Filter results by the mediapackage's creator", type = STRING), @RestParameter(name = "contributor", isRequired = false, description = "Filter results by the mediapackage's contributor", type = STRING), @RestParameter(name = "fromdate", isRequired = false, description = "Filter results by workflow start date.", type = STRING), @RestParameter(name = "todate", isRequired = false, description = "Filter results by workflow start date.", type = STRING), @RestParameter(name = "language", isRequired = false, description = "Filter results by mediapackage's language.", type = STRING), @RestParameter(name = "license", isRequired = false, description = "Filter results by mediapackage's license.", type = STRING), @RestParameter(name = "title", isRequired = false, description = "Filter results by mediapackage's title.", type = STRING), @RestParameter(name = "subject", isRequired = false, description = "Filter results by mediapackage's subject.", type = STRING), @RestParameter(name = "workflowdefinition", isRequired = false, description = "Filter results by workflow definition.", type = STRING), @RestParameter(name = "mp", isRequired = false, description = "Filter results by mediapackage identifier.", type = STRING), @RestParameter(name = "op", isRequired = false, description = "Filter results by workflows' current operation.", type = STRING), @RestParameter(name = "sort", isRequired = false, description = "The sort order.  May include any " + "of the following: DATE_CREATED, TITLE, SERIES_TITLE, SERIES_ID, MEDIA_PACKAGE_ID, WORKFLOW_DEFINITION_ID, CREATOR, " + "CONTRIBUTOR, LANGUAGE, LICENSE, SUBJECT.  Add '_DESC' to reverse the sort order (e.g. TITLE_DESC).", type = STRING), @RestParameter(name = "startPage", isRequired = false, description = "The paging offset", type = INTEGER), @RestParameter(name = "count", isRequired = false, description = "The number of results to return.", type = INTEGER), @RestParameter(name = "compact", isRequired = false, description = "Whether to return a compact version of " + "the workflow instance, with mediapackage elements, workflow and workflow operation configurations and " + "non-current operations removed.", type = STRING) }, reponses = { @RestResponse(responseCode = SC_OK, description = "An XML representation of the workflow set.") })
public // So for now, we disable checkstyle here.
Response getWorkflowsAsXml(@QueryParam("state") List<String> states, @QueryParam("q") String text, @QueryParam("seriesId") String seriesId, @QueryParam("seriesTitle") String seriesTitle, @QueryParam("creator") String creator, @QueryParam("contributor") String contributor, @QueryParam("fromdate") String fromDate, @QueryParam("todate") String toDate, @QueryParam("language") String language, @QueryParam("license") String license, @QueryParam("title") String title, @QueryParam("subject") String subject, @QueryParam("workflowdefinition") String workflowDefinitionId, @QueryParam("mp") String mediapackageId, @QueryParam("op") List<String> currentOperations, @QueryParam("sort") String sort, @QueryParam("startPage") int startPage, @QueryParam("count") int count, @QueryParam("compact") boolean compact) throws Exception {
    // CHECKSTYLE:ON
    if (count < 1)
        count = DEFAULT_LIMIT;
    WorkflowQuery q = new WorkflowQuery();
    q.withCount(count);
    q.withStartPage(startPage);
    if (states != null && states.size() > 0) {
        try {
            for (String state : states) {
                if (StringUtils.isBlank(state)) {
                    continue;
                }
                if (state.startsWith(NEGATE_PREFIX)) {
                    q.withoutState(WorkflowState.valueOf(state.substring(1).toUpperCase()));
                } else {
                    q.withState(WorkflowState.valueOf(state.toUpperCase()));
                }
            }
        } catch (IllegalArgumentException e) {
            logger.debug("Unknown workflow state.", e);
        }
    }
    q.withText(text);
    q.withSeriesId(seriesId);
    q.withSeriesTitle(seriesTitle);
    q.withSubject(subject);
    q.withMediaPackage(mediapackageId);
    q.withCreator(creator);
    q.withContributor(contributor);
    q.withDateAfter(SolrUtils.parseDate(fromDate));
    q.withDateBefore(SolrUtils.parseDate(toDate));
    q.withLanguage(language);
    q.withLicense(license);
    q.withTitle(title);
    q.withWorkflowDefintion(workflowDefinitionId);
    if (currentOperations != null && currentOperations.size() > 0) {
        for (String op : currentOperations) {
            if (StringUtils.isBlank(op)) {
                continue;
            }
            if (op.startsWith(NEGATE_PREFIX)) {
                q.withoutCurrentOperation(op.substring(1));
            } else {
                q.withCurrentOperation(op);
            }
        }
    }
    if (StringUtils.isNotBlank(sort)) {
        // Parse the sort field and direction
        Sort sortField = null;
        if (sort.endsWith(DESCENDING_SUFFIX)) {
            String enumKey = sort.substring(0, sort.length() - DESCENDING_SUFFIX.length()).toUpperCase();
            try {
                sortField = Sort.valueOf(enumKey);
                q.withSort(sortField, false);
            } catch (IllegalArgumentException e) {
                logger.debug("No sort enum matches '{}'", enumKey);
            }
        } else {
            try {
                sortField = Sort.valueOf(sort);
                q.withSort(sortField);
            } catch (IllegalArgumentException e) {
                logger.debug("No sort enum matches '{}'", sort);
            }
        }
    }
    WorkflowSet set = service.getWorkflowInstances(q);
    // Marshalling of a full workflow takes a long time. Therefore, we strip everything that's not needed.
    if (compact) {
        for (WorkflowInstance instance : set.getItems()) {
            // Remove all operations but the current one
            WorkflowOperationInstance currentOperation = instance.getCurrentOperation();
            List<WorkflowOperationInstance> operations = instance.getOperations();
            // instance.getOperations() is a copy
            operations.clear();
            if (currentOperation != null) {
                for (String key : currentOperation.getConfigurationKeys()) {
                    currentOperation.removeConfiguration(key);
                }
                operations.add(currentOperation);
            }
            instance.setOperations(operations);
            // Remove all mediapackage elements (but keep the duration)
            MediaPackage mediaPackage = instance.getMediaPackage();
            Long duration = instance.getMediaPackage().getDuration();
            for (MediaPackageElement element : mediaPackage.elements()) {
                mediaPackage.remove(element);
            }
            mediaPackage.setDuration(duration);
        }
    }
    return Response.ok(set).build();
}
Also used : WorkflowSet(org.opencastproject.workflow.api.WorkflowSet) WorkflowQuery(org.opencastproject.workflow.api.WorkflowQuery) WorkflowOperationInstance(org.opencastproject.workflow.api.WorkflowOperationInstance) MediaPackageElement(org.opencastproject.mediapackage.MediaPackageElement) MediaPackage(org.opencastproject.mediapackage.MediaPackage) Sort(org.opencastproject.workflow.api.WorkflowQuery.Sort) WorkflowInstance(org.opencastproject.workflow.api.WorkflowInstance) Path(javax.ws.rs.Path) Produces(javax.ws.rs.Produces) GET(javax.ws.rs.GET) RestQuery(org.opencastproject.util.doc.rest.RestQuery)

Example 7 with WorkflowSet

use of org.opencastproject.workflow.api.WorkflowSet in project opencast by opencast.

the class IndexServiceImpl method getCurrentWorkflowInstance.

@Override
public Opt<WorkflowInstance> getCurrentWorkflowInstance(String mpId) throws IndexServiceException {
    WorkflowQuery query = new WorkflowQuery().withMediaPackage(mpId);
    WorkflowSet workflowInstances;
    try {
        workflowInstances = workflowService.getWorkflowInstances(query);
        if (workflowInstances.size() == 0) {
            logger.info("No workflow instance found for mediapackage {}.", mpId);
            return Opt.none();
        }
    } catch (WorkflowDatabaseException e) {
        logger.error("Unable to get workflows for event {} because {}", mpId, getStackTrace(e));
        throw new IndexServiceException("Unable to get current workflow for event " + mpId);
    }
    // Get the newest workflow instance
    // TODO This presuppose knowledge of the Database implementation and should be fixed sooner or later!
    WorkflowInstance workflowInstance = workflowInstances.getItems()[0];
    for (WorkflowInstance instance : workflowInstances.getItems()) {
        if (instance.getId() > workflowInstance.getId())
            workflowInstance = instance;
    }
    return Opt.some(workflowInstance);
}
Also used : WorkflowSet(org.opencastproject.workflow.api.WorkflowSet) WorkflowDatabaseException(org.opencastproject.workflow.api.WorkflowDatabaseException) WorkflowQuery(org.opencastproject.workflow.api.WorkflowQuery) WorkflowInstance(org.opencastproject.workflow.api.WorkflowInstance) IndexServiceException(org.opencastproject.index.service.exception.IndexServiceException)

Example 8 with WorkflowSet

use of org.opencastproject.workflow.api.WorkflowSet in project opencast by opencast.

the class IndexServiceImpl method removeEvent.

@Override
public boolean removeEvent(String id) throws NotFoundException, UnauthorizedException {
    boolean unauthorizedScheduler = false;
    boolean notFoundScheduler = false;
    boolean removedScheduler = true;
    try {
        schedulerService.removeEvent(id);
    } catch (NotFoundException e) {
        notFoundScheduler = true;
    } catch (UnauthorizedException e) {
        unauthorizedScheduler = true;
    } catch (SchedulerException e) {
        removedScheduler = false;
        logger.error("Unable to remove the event '{}' from scheduler service: {}", id, getStackTrace(e));
    }
    boolean unauthorizedWorkflow = false;
    boolean notFoundWorkflow = false;
    boolean removedWorkflow = true;
    try {
        WorkflowQuery workflowQuery = new WorkflowQuery().withMediaPackage(id);
        WorkflowSet workflowSet = workflowService.getWorkflowInstances(workflowQuery);
        if (workflowSet.size() == 0)
            notFoundWorkflow = true;
        for (WorkflowInstance instance : workflowSet.getItems()) {
            workflowService.stop(instance.getId());
            workflowService.remove(instance.getId());
        }
    } catch (NotFoundException e) {
        notFoundWorkflow = true;
    } catch (UnauthorizedException e) {
        unauthorizedWorkflow = true;
    } catch (WorkflowDatabaseException e) {
        removedWorkflow = false;
        logger.error("Unable to remove the event '{}' because removing workflow failed: {}", id, getStackTrace(e));
    } catch (WorkflowException e) {
        removedWorkflow = false;
        logger.error("Unable to remove the event '{}' because removing workflow failed: {}", id, getStackTrace(e));
    }
    boolean unauthorizedArchive = false;
    boolean notFoundArchive = false;
    boolean removedArchive = true;
    try {
        final AQueryBuilder q = assetManager.createQuery();
        final Predicate p = q.organizationId().eq(securityService.getOrganization().getId()).and(q.mediaPackageId(id));
        final AResult r = q.select(q.nothing()).where(p).run();
        if (r.getSize() > 0)
            q.delete(DEFAULT_OWNER, q.snapshot()).where(p).run();
    } catch (AssetManagerException e) {
        if (e.getCause() instanceof UnauthorizedException) {
            unauthorizedArchive = true;
        } else if (e.getCause() instanceof NotFoundException) {
            notFoundArchive = true;
        } else {
            removedArchive = false;
            logger.error("Unable to remove the event '{}' from the archive: {}", id, getStackTrace(e));
        }
    }
    if (notFoundScheduler && notFoundWorkflow && notFoundArchive)
        throw new NotFoundException("Event id " + id + " not found.");
    if (unauthorizedScheduler || unauthorizedWorkflow || unauthorizedArchive)
        throw new UnauthorizedException("Not authorized to remove event id " + id);
    try {
        eventCommentService.deleteComments(id);
    } catch (EventCommentException e) {
        logger.error("Unable to remove comments for event '{}': {}", id, getStackTrace(e));
    }
    return removedScheduler && removedWorkflow && removedArchive;
}
Also used : WorkflowSet(org.opencastproject.workflow.api.WorkflowSet) WorkflowQuery(org.opencastproject.workflow.api.WorkflowQuery) SchedulerException(org.opencastproject.scheduler.api.SchedulerException) WorkflowException(org.opencastproject.workflow.api.WorkflowException) NotFoundException(org.opencastproject.util.NotFoundException) AQueryBuilder(org.opencastproject.assetmanager.api.query.AQueryBuilder) EventCommentException(org.opencastproject.event.comment.EventCommentException) AssetManagerException(org.opencastproject.assetmanager.api.AssetManagerException) WorkflowInstance(org.opencastproject.workflow.api.WorkflowInstance) Predicate(org.opencastproject.assetmanager.api.query.Predicate) WorkflowDatabaseException(org.opencastproject.workflow.api.WorkflowDatabaseException) UnauthorizedException(org.opencastproject.security.api.UnauthorizedException) AResult(org.opencastproject.assetmanager.api.query.AResult)

Example 9 with WorkflowSet

use of org.opencastproject.workflow.api.WorkflowSet in project opencast by opencast.

the class IndexServiceImpl method startAddAssetWorkflow.

/**
 * Parses the processing information, including the workflowDefinitionId, from the metadataJson and starts the
 * workflow with the passed mediapackage.
 *
 * TODO NOTE: This checks for running workflows, then takes a snapshot prior to starting a new workflow. This causes a
 * potential race condition:
 *
 * 1. An existing workflow is running, the add asset workflow cannot start.
 *
 * 2. The snapshot(4x) archive(3x) is saved and the new workflow is started.
 *
 * 3. Possible race condition: No running workflow, a snapshot is saved but the workflow cannot start because another
 * workflow has started between the time of checking and starting running.
 *
 * 4. If race condition: the Admin UI shows error that the workflow could not start.
 *
 * 5. If race condition: The interim snapshot(4x) archive(3x) is updated(4x-3x) by the running workflow's snapshots
 * and resolves the inconsistency, eventually.
 *
 * Example of processing json:
 *
 * ...., "processing": { "workflow": "full", "configuration": { "videoPreview": "false", "trimHold": "false",
 * "captionHold": "false", "archiveOp": "true", "publishEngage": "true", "publishHarvesting": "true" } }, ....
 *
 * @param metadataJson
 * @param mp
 * @return the created workflow instance id
 * @throws IndexServiceException
 */
private String startAddAssetWorkflow(JSONObject metadataJson, MediaPackage mediaPackage) throws IndexServiceException {
    String wfId = null;
    String mpId = mediaPackage.getIdentifier().toString();
    JSONObject processing = (JSONObject) metadataJson.get("processing");
    if (processing == null)
        throw new IllegalArgumentException("No processing field in metadata");
    String workflowDefId = (String) processing.get("workflow");
    if (workflowDefId == null)
        throw new IllegalArgumentException("No workflow definition field in processing metadata");
    JSONObject configJson = (JSONObject) processing.get("configuration");
    try {
        // 1. Check if any active workflows are running for this mediapackage id
        WorkflowSet workflowSet = workflowService.getWorkflowInstances(new WorkflowQuery().withMediaPackage(mpId));
        for (WorkflowInstance wf : Arrays.asList(workflowSet.getItems())) {
            if (wf.isActive()) {
                logger.warn("Unable to start new workflow '{}' on archived media package '{}', existing workfow {} is running", workflowDefId, mediaPackage, wf.getId());
                throw new IllegalArgumentException("A workflow is already active for mp " + mpId + ", cannot start this workflow.");
            }
        }
        // 2. Save the snapshot
        assetManager.takeSnapshot(DEFAULT_OWNER, mediaPackage);
        // 3. start the new workflow on the snapshot
        // Workflow params are assumed to be String (not mixed with Number)
        Map<String, String> params = new HashMap<String, String>();
        if (configJson != null) {
            for (Object key : configJson.keySet()) {
                params.put((String) key, (String) configJson.get(key));
            }
        }
        Set<String> mpIds = new HashSet<String>();
        mpIds.add(mpId);
        final Workflows workflows = new Workflows(assetManager, workspace, workflowService);
        List<WorkflowInstance> wfList = workflows.applyWorkflowToLatestVersion(mpIds, ConfiguredWorkflow.workflow(workflowService.getWorkflowDefinitionById(workflowDefId), params)).toList();
        wfId = wfList.size() > 0 ? Long.toString(wfList.get(0).getId()) : "Unknown";
        logger.info("Asset update and publish workflow {} scheduled for mp {}", wfId, mpId);
    } catch (AssetManagerException e) {
        logger.warn("Unable to start workflow '{}' on archived media package '{}': {}", workflowDefId, mediaPackage, getStackTrace(e));
        throw new IndexServiceException("Unable to start workflow " + workflowDefId + " on " + mpId);
    } catch (WorkflowDatabaseException e) {
        logger.warn("Unable to load workflow '{}' from workflow service: {}", wfId, getStackTrace(e));
    } catch (NotFoundException e) {
        logger.warn("Workflow '{}' not found", wfId);
    }
    return wfId;
}
Also used : WorkflowSet(org.opencastproject.workflow.api.WorkflowSet) WorkflowQuery(org.opencastproject.workflow.api.WorkflowQuery) LinkedHashMap(java.util.LinkedHashMap) HashMap(java.util.HashMap) Workflows(org.opencastproject.assetmanager.util.Workflows) NotFoundException(org.opencastproject.util.NotFoundException) AssetManagerException(org.opencastproject.assetmanager.api.AssetManagerException) WorkflowInstance(org.opencastproject.workflow.api.WorkflowInstance) WorkflowDatabaseException(org.opencastproject.workflow.api.WorkflowDatabaseException) JSONObject(org.json.simple.JSONObject) JSONObject(org.json.simple.JSONObject) IndexServiceException(org.opencastproject.index.service.exception.IndexServiceException) HashSet(java.util.HashSet)

Example 10 with WorkflowSet

use of org.opencastproject.workflow.api.WorkflowSet in project opencast by opencast.

the class WorkflowPermissionsUpdatedEventHandler method handleEvent.

public void handleEvent(final SeriesItem seriesItem) {
    // A series or its ACL has been updated. Find any mediapackages with that series, and update them.
    logger.debug("Handling {}", seriesItem);
    String seriesId = seriesItem.getSeriesId();
    // We must be an administrative user to make this query
    final User prevUser = securityService.getUser();
    final Organization prevOrg = securityService.getOrganization();
    try {
        securityService.setUser(SecurityUtil.createSystemUser(systemAccount, prevOrg));
        // Note: getWorkflowInstances will only return a given number of results (default 20)
        WorkflowQuery q = new WorkflowQuery().withSeriesId(seriesId);
        WorkflowSet result = workflowService.getWorkflowInstancesForAdministrativeRead(q);
        Integer offset = 0;
        while (result.size() > 0) {
            for (WorkflowInstance instance : result.getItems()) {
                if (!instance.isActive())
                    continue;
                Organization org = instance.getOrganization();
                securityService.setOrganization(org);
                MediaPackage mp = instance.getMediaPackage();
                // Update the series XACML file
                if (SeriesItem.Type.UpdateAcl.equals(seriesItem.getType())) {
                    // Build a new XACML file for this mediapackage
                    authorizationService.setAcl(mp, AclScope.Series, seriesItem.getAcl());
                }
                // Update the series dublin core
                if (SeriesItem.Type.UpdateCatalog.equals(seriesItem.getType())) {
                    DublinCoreCatalog seriesDublinCore = seriesItem.getMetadata();
                    mp.setSeriesTitle(seriesDublinCore.getFirst(DublinCore.PROPERTY_TITLE));
                    // Update the series dublin core
                    Catalog[] seriesCatalogs = mp.getCatalogs(MediaPackageElements.SERIES);
                    if (seriesCatalogs.length == 1) {
                        Catalog c = seriesCatalogs[0];
                        String filename = FilenameUtils.getName(c.getURI().toString());
                        URI uri = workspace.put(mp.getIdentifier().toString(), c.getIdentifier(), filename, dublinCoreService.serialize(seriesDublinCore));
                        c.setURI(uri);
                        // setting the URI to a new source so the checksum will most like be invalid
                        c.setChecksum(null);
                    }
                }
                // Remove the series catalog and isPartOf from episode catalog
                if (SeriesItem.Type.Delete.equals(seriesItem.getType())) {
                    mp.setSeries(null);
                    mp.setSeriesTitle(null);
                    for (Catalog c : mp.getCatalogs(MediaPackageElements.SERIES)) {
                        mp.remove(c);
                        try {
                            workspace.delete(c.getURI());
                        } catch (NotFoundException e) {
                            logger.info("No series catalog to delete found {}", c.getURI());
                        }
                    }
                    for (Catalog episodeCatalog : mp.getCatalogs(MediaPackageElements.EPISODE)) {
                        DublinCoreCatalog episodeDublinCore = DublinCoreUtil.loadDublinCore(workspace, episodeCatalog);
                        episodeDublinCore.remove(DublinCore.PROPERTY_IS_PART_OF);
                        String filename = FilenameUtils.getName(episodeCatalog.getURI().toString());
                        URI uri = workspace.put(mp.getIdentifier().toString(), episodeCatalog.getIdentifier(), filename, dublinCoreService.serialize(episodeDublinCore));
                        episodeCatalog.setURI(uri);
                        // setting the URI to a new source so the checksum will most like be invalid
                        episodeCatalog.setChecksum(null);
                    }
                }
                // Update the search index with the modified mediapackage
                workflowService.update(instance);
            }
            offset++;
            q = q.withStartPage(offset);
            result = workflowService.getWorkflowInstancesForAdministrativeRead(q);
        }
    } catch (WorkflowException e) {
        logger.warn(e.getMessage());
    } catch (UnauthorizedException e) {
        logger.warn(e.getMessage());
    } catch (IOException e) {
        logger.warn(e.getMessage());
    } finally {
        securityService.setOrganization(prevOrg);
        securityService.setUser(prevUser);
    }
}
Also used : WorkflowSet(org.opencastproject.workflow.api.WorkflowSet) WorkflowQuery(org.opencastproject.workflow.api.WorkflowQuery) User(org.opencastproject.security.api.User) Organization(org.opencastproject.security.api.Organization) WorkflowException(org.opencastproject.workflow.api.WorkflowException) NotFoundException(org.opencastproject.util.NotFoundException) IOException(java.io.IOException) WorkflowInstance(org.opencastproject.workflow.api.WorkflowInstance) URI(java.net.URI) Catalog(org.opencastproject.mediapackage.Catalog) DublinCoreCatalog(org.opencastproject.metadata.dublincore.DublinCoreCatalog) MediaPackage(org.opencastproject.mediapackage.MediaPackage) UnauthorizedException(org.opencastproject.security.api.UnauthorizedException) DublinCoreCatalog(org.opencastproject.metadata.dublincore.DublinCoreCatalog)

Aggregations

WorkflowSet (org.opencastproject.workflow.api.WorkflowSet)19 WorkflowQuery (org.opencastproject.workflow.api.WorkflowQuery)18 WorkflowInstance (org.opencastproject.workflow.api.WorkflowInstance)12 Test (org.junit.Test)9 WorkflowDatabaseException (org.opencastproject.workflow.api.WorkflowDatabaseException)7 NotFoundException (org.opencastproject.util.NotFoundException)6 ArrayList (java.util.ArrayList)5 UnauthorizedException (org.opencastproject.security.api.UnauthorizedException)4 CopyOnWriteArrayList (java.util.concurrent.CopyOnWriteArrayList)3 Organization (org.opencastproject.security.api.Organization)3 ServiceRegistryException (org.opencastproject.serviceregistry.api.ServiceRegistryException)3 WorkflowException (org.opencastproject.workflow.api.WorkflowException)3 WorkflowParsingException (org.opencastproject.workflow.api.WorkflowParsingException)3 IOException (java.io.IOException)2 Lock (java.util.concurrent.locks.Lock)2 AssetManagerException (org.opencastproject.assetmanager.api.AssetManagerException)2 IndexServiceException (org.opencastproject.index.service.exception.IndexServiceException)2 MediaPackage (org.opencastproject.mediapackage.MediaPackage)2 MediaPackageException (org.opencastproject.mediapackage.MediaPackageException)2 DefaultOrganization (org.opencastproject.security.api.DefaultOrganization)2