Search in sources :

Example 1 with WorkflowState

use of org.opencastproject.workflow.api.WorkflowInstance.WorkflowState in project opencast by opencast.

the class WorkflowServiceImpl method update.

/**
 * {@inheritDoc}
 *
 * @see org.opencastproject.workflow.api.WorkflowService#update(org.opencastproject.workflow.api.WorkflowInstance)
 */
@Override
public void update(final WorkflowInstance workflowInstance) throws WorkflowException, UnauthorizedException {
    final Lock lock = updateLock.get(workflowInstance.getId());
    lock.lock();
    try {
        WorkflowInstance originalWorkflowInstance = null;
        try {
            originalWorkflowInstance = getWorkflowById(workflowInstance.getId());
        } catch (NotFoundException e) {
        // That's fine, it's a new workflow instance
        }
        if (originalWorkflowInstance != null) {
            try {
                assertPermission(originalWorkflowInstance, Permissions.Action.WRITE.toString());
            } catch (MediaPackageException e) {
                throw new WorkflowParsingException(e);
            }
        }
        MediaPackage updatedMediaPackage = null;
        try {
            // Before we persist this, extract the metadata
            updatedMediaPackage = workflowInstance.getMediaPackage();
            populateMediaPackageMetadata(updatedMediaPackage);
            String seriesId = updatedMediaPackage.getSeries();
            if (seriesId != null && workflowInstance.getCurrentOperation() != null) {
                // If the mediapackage contains a series, find the series ACLs and add the security information to the
                // mediapackage
                AccessControlList acl = seriesService.getSeriesAccessControl(seriesId);
                Option<AccessControlList> activeSeriesAcl = authorizationService.getAcl(updatedMediaPackage, AclScope.Series);
                if (activeSeriesAcl.isNone() || !AccessControlUtil.equals(activeSeriesAcl.get(), acl))
                    authorizationService.setAcl(updatedMediaPackage, AclScope.Series, acl);
            }
        } catch (SeriesException e) {
            throw new WorkflowDatabaseException(e);
        } catch (NotFoundException e) {
            logger.warn("Metadata for mediapackage {} could not be updated because it wasn't found", updatedMediaPackage, e);
        } catch (Exception e) {
            logger.error("Metadata for mediapackage {} could not be updated", updatedMediaPackage, e);
        }
        // Synchronize the job status with the workflow
        WorkflowState workflowState = workflowInstance.getState();
        String xml;
        try {
            xml = WorkflowParser.toXml(workflowInstance);
        } catch (Exception e) {
            // Can't happen, since we are converting from an in-memory object
            throw new IllegalStateException("In-memory workflow instance could not be serialized", e);
        }
        Job job = null;
        try {
            job = serviceRegistry.getJob(workflowInstance.getId());
            job.setPayload(xml);
            // Synchronize workflow and job state
            switch(workflowState) {
                case FAILED:
                    job.setStatus(Status.FAILED);
                    break;
                case FAILING:
                    break;
                case INSTANTIATED:
                    job.setDispatchable(true);
                    job.setStatus(Status.QUEUED);
                    break;
                case PAUSED:
                    job.setStatus(Status.PAUSED);
                    break;
                case RUNNING:
                    job.setStatus(Status.RUNNING);
                    break;
                case STOPPED:
                    job.setStatus(Status.CANCELED);
                    break;
                case SUCCEEDED:
                    job.setStatus(Status.FINISHED);
                    break;
                default:
                    throw new IllegalStateException("Found a workflow state that is not handled");
            }
        } catch (ServiceRegistryException e) {
            logger.error(e, "Unable to read workflow job %s from service registry", workflowInstance.getId());
            throw new WorkflowDatabaseException(e);
        } catch (NotFoundException e) {
            logger.error("Job for workflow %s not found in service registry", workflowInstance.getId());
            throw new WorkflowDatabaseException(e);
        }
        // Update both workflow and workflow job
        try {
            job = serviceRegistry.updateJob(job);
            messageSender.sendObjectMessage(WorkflowItem.WORKFLOW_QUEUE, MessageSender.DestinationType.Queue, WorkflowItem.updateInstance(workflowInstance));
            index(workflowInstance);
        } catch (ServiceRegistryException e) {
            logger.error("Update of workflow job %s in the service registry failed, service registry and workflow index may be out of sync", workflowInstance.getId());
            throw new WorkflowDatabaseException(e);
        } catch (NotFoundException e) {
            logger.error("Job for workflow %s not found in service registry", workflowInstance.getId());
            throw new WorkflowDatabaseException(e);
        } catch (Exception e) {
            logger.error("Update of workflow job %s in the service registry failed, service registry and workflow index may be out of sync", job.getId());
            throw new WorkflowException(e);
        }
        if (workflowStatsCollect) {
            workflowsStatistics.updateWorkflow(getBeanStatistics(), getHoldWorkflows());
        }
        try {
            WorkflowInstance clone = WorkflowParser.parseWorkflowInstance(WorkflowParser.toXml(workflowInstance));
            fireListeners(originalWorkflowInstance, clone);
        } catch (Exception e) {
            // Can't happen, since we are converting from an in-memory object
            throw new IllegalStateException("In-memory workflow instance could not be serialized", e);
        }
    } finally {
        lock.unlock();
    }
}
Also used : AccessControlList(org.opencastproject.security.api.AccessControlList) MediaPackageException(org.opencastproject.mediapackage.MediaPackageException) WorkflowException(org.opencastproject.workflow.api.WorkflowException) NotFoundException(org.opencastproject.util.NotFoundException) Collections.mkString(org.opencastproject.util.data.Collections.mkString) SeriesException(org.opencastproject.series.api.SeriesException) WorkflowInstance(org.opencastproject.workflow.api.WorkflowInstance) ServiceRegistryException(org.opencastproject.serviceregistry.api.ServiceRegistryException) UndispatchableJobException(org.opencastproject.serviceregistry.api.UndispatchableJobException) WorkflowOperationException(org.opencastproject.workflow.api.WorkflowOperationException) IOException(java.io.IOException) ConfigurationException(org.osgi.service.cm.ConfigurationException) SeriesException(org.opencastproject.series.api.SeriesException) InvalidSyntaxException(org.osgi.framework.InvalidSyntaxException) WorkflowException(org.opencastproject.workflow.api.WorkflowException) MediaPackageException(org.opencastproject.mediapackage.MediaPackageException) WorkflowParsingException(org.opencastproject.workflow.api.WorkflowParsingException) UnauthorizedException(org.opencastproject.security.api.UnauthorizedException) NotFoundException(org.opencastproject.util.NotFoundException) WorkflowDatabaseException(org.opencastproject.workflow.api.WorkflowDatabaseException) WorkflowStateException(org.opencastproject.workflow.api.WorkflowStateException) ServiceRegistryException(org.opencastproject.serviceregistry.api.ServiceRegistryException) Lock(java.util.concurrent.locks.Lock) WorkflowDatabaseException(org.opencastproject.workflow.api.WorkflowDatabaseException) WorkflowState(org.opencastproject.workflow.api.WorkflowInstance.WorkflowState) MediaPackage(org.opencastproject.mediapackage.MediaPackage) Job(org.opencastproject.job.api.Job) WorkflowParsingException(org.opencastproject.workflow.api.WorkflowParsingException)

Example 2 with WorkflowState

use of org.opencastproject.workflow.api.WorkflowInstance.WorkflowState in project opencast by opencast.

the class WorkflowServiceSolrIndex method getStatistics.

/**
 * {@inheritDoc}
 *
 * @see org.opencastproject.workflow.impl.WorkflowServiceIndex#getStatistics()
 */
@Override
public WorkflowStatistics getStatistics() throws WorkflowDatabaseException {
    long total = 0;
    long paused = 0;
    long failed = 0;
    long failing = 0;
    long instantiated = 0;
    long running = 0;
    long stopped = 0;
    long succeeded = 0;
    WorkflowStatistics stats = new WorkflowStatistics();
    // Get all definitions and then query for the numbers and the current operation per definition
    try {
        String orgId = securityService.getOrganization().getId();
        StringBuilder queryString = new StringBuilder().append(ORG_KEY).append(":").append(escapeQueryChars(orgId));
        appendSolrAuthFragment(queryString, Permissions.Action.WRITE.toString());
        SolrQuery solrQuery = new SolrQuery(queryString.toString());
        solrQuery.addFacetField(WORKFLOW_DEFINITION_KEY);
        solrQuery.addFacetField(OPERATION_KEY);
        solrQuery.setFacetMinCount(0);
        solrQuery.setFacet(true);
        QueryResponse response = solrServer.query(solrQuery);
        FacetField templateFacet = response.getFacetField(WORKFLOW_DEFINITION_KEY);
        FacetField operationFacet = response.getFacetField(OPERATION_KEY);
        // For every template and every operation
        if (templateFacet != null && templateFacet.getValues() != null) {
            for (Count template : templateFacet.getValues()) {
                WorkflowDefinitionReport templateReport = new WorkflowDefinitionReport();
                templateReport.setId(template.getName());
                long templateTotal = 0;
                long templatePaused = 0;
                long templateFailed = 0;
                long templateFailing = 0;
                long templateInstantiated = 0;
                long templateRunning = 0;
                long templateStopped = 0;
                long templateSucceeded = 0;
                if (operationFacet != null && operationFacet.getValues() != null) {
                    for (Count operation : operationFacet.getValues()) {
                        OperationReport operationReport = new OperationReport();
                        operationReport.setId(operation.getName());
                        StringBuilder baseSolrQuery = new StringBuilder().append(ORG_KEY).append(":").append(escapeQueryChars(orgId));
                        appendSolrAuthFragment(baseSolrQuery, Permissions.Action.WRITE.toString());
                        solrQuery = new SolrQuery(baseSolrQuery.toString());
                        solrQuery.addFacetField(STATE_KEY);
                        solrQuery.addFacetQuery(STATE_KEY + ":" + WorkflowState.FAILED);
                        solrQuery.addFacetQuery(STATE_KEY + ":" + WorkflowState.FAILING);
                        solrQuery.addFacetQuery(STATE_KEY + ":" + WorkflowState.INSTANTIATED);
                        solrQuery.addFacetQuery(STATE_KEY + ":" + WorkflowState.PAUSED);
                        solrQuery.addFacetQuery(STATE_KEY + ":" + WorkflowState.RUNNING);
                        solrQuery.addFacetQuery(STATE_KEY + ":" + WorkflowState.STOPPED);
                        solrQuery.addFacetQuery(STATE_KEY + ":" + WorkflowState.SUCCEEDED);
                        solrQuery.addFilterQuery(WORKFLOW_DEFINITION_KEY + ":" + template.getName());
                        solrQuery.addFilterQuery(OPERATION_KEY + ":" + operation.getName());
                        solrQuery.setFacetMinCount(0);
                        solrQuery.setFacet(true);
                        response = solrServer.query(solrQuery);
                        // Add the states
                        FacetField stateFacet = response.getFacetField(STATE_KEY);
                        for (Count stateValue : stateFacet.getValues()) {
                            WorkflowState state = WorkflowState.valueOf(stateValue.getName().toUpperCase());
                            templateTotal += stateValue.getCount();
                            total += stateValue.getCount();
                            switch(state) {
                                case FAILED:
                                    operationReport.setFailed(stateValue.getCount());
                                    templateFailed += stateValue.getCount();
                                    failed += stateValue.getCount();
                                    break;
                                case FAILING:
                                    operationReport.setFailing(stateValue.getCount());
                                    templateFailing += stateValue.getCount();
                                    failing += stateValue.getCount();
                                    break;
                                case INSTANTIATED:
                                    operationReport.setInstantiated(stateValue.getCount());
                                    templateInstantiated += stateValue.getCount();
                                    instantiated += stateValue.getCount();
                                    break;
                                case PAUSED:
                                    operationReport.setPaused(stateValue.getCount());
                                    templatePaused += stateValue.getCount();
                                    paused += stateValue.getCount();
                                    break;
                                case RUNNING:
                                    operationReport.setRunning(stateValue.getCount());
                                    templateRunning += stateValue.getCount();
                                    running += stateValue.getCount();
                                    break;
                                case STOPPED:
                                    operationReport.setStopped(stateValue.getCount());
                                    templateStopped += stateValue.getCount();
                                    stopped += stateValue.getCount();
                                    break;
                                case SUCCEEDED:
                                    operationReport.setFinished(stateValue.getCount());
                                    templateSucceeded += stateValue.getCount();
                                    succeeded += stateValue.getCount();
                                    break;
                                default:
                                    throw new IllegalStateException("State '" + state + "' is not handled");
                            }
                        }
                        templateReport.getOperations().add(operationReport);
                    }
                }
                // Update the template statistics
                templateReport.setTotal(templateTotal);
                templateReport.setFailed(templateFailed);
                templateReport.setFailing(templateFailing);
                templateReport.setInstantiated(templateInstantiated);
                templateReport.setPaused(templatePaused);
                templateReport.setRunning(templateRunning);
                templateReport.setStopped(templateStopped);
                templateReport.setFinished(templateSucceeded);
                // Add the definition report to the statistics
                stats.getDefinitions().add(templateReport);
            }
        }
    } catch (SolrServerException e) {
        throw new WorkflowDatabaseException(e);
    }
    stats.setTotal(total);
    stats.setFailed(failed);
    stats.setFailing(failing);
    stats.setInstantiated(instantiated);
    stats.setPaused(paused);
    stats.setRunning(running);
    stats.setStopped(stopped);
    stats.setFinished(succeeded);
    return stats;
}
Also used : WorkflowDefinitionReport(org.opencastproject.workflow.api.WorkflowStatistics.WorkflowDefinitionReport) SolrServerException(org.apache.solr.client.solrj.SolrServerException) FacetField(org.apache.solr.client.solrj.response.FacetField) Count(org.apache.solr.client.solrj.response.FacetField.Count) WorkflowStatistics(org.opencastproject.workflow.api.WorkflowStatistics) SolrQuery(org.apache.solr.client.solrj.SolrQuery) WorkflowDatabaseException(org.opencastproject.workflow.api.WorkflowDatabaseException) WorkflowState(org.opencastproject.workflow.api.WorkflowInstance.WorkflowState) QueryResponse(org.apache.solr.client.solrj.response.QueryResponse) OperationReport(org.opencastproject.workflow.api.WorkflowStatistics.WorkflowDefinitionReport.OperationReport)

Example 3 with WorkflowState

use of org.opencastproject.workflow.api.WorkflowInstance.WorkflowState in project opencast by opencast.

the class WorkflowStateListener method stateChanged.

/**
 * {@inheritDoc}
 *
 * @see org.opencastproject.workflow.api.WorkflowListener#stateChanged(org.opencastproject.workflow.api.WorkflowInstance)
 */
@Override
public void stateChanged(WorkflowInstance workflow) {
    synchronized (this) {
        if (!workflowInstanceIds.isEmpty() && !workflowInstanceIds.contains(workflow.getId()))
            return;
        WorkflowState currentState = workflow.getState();
        if (!notifyStates.isEmpty() && !notifyStates.containsKey(currentState))
            return;
        if (notifyStates.containsKey(currentState)) {
            notifyStates.get(currentState).incrementAndGet();
        }
        total.incrementAndGet();
        logger.debug("Workflow {} state updated to {}", workflow.getId(), workflow.getState());
        notifyAll();
    }
}
Also used : WorkflowState(org.opencastproject.workflow.api.WorkflowInstance.WorkflowState)

Example 4 with WorkflowState

use of org.opencastproject.workflow.api.WorkflowInstance.WorkflowState in project opencast by opencast.

the class WorkflowServiceImpl method runWorkflowOperation.

/**
 * Executes the workflow's current operation.
 *
 * @param workflow
 *          the workflow
 * @param properties
 *          the properties that are passed in on resume
 * @return the processed workflow operation
 * @throws WorkflowException
 *           if there is a problem processing the workflow
 */
protected WorkflowOperationInstance runWorkflowOperation(WorkflowInstance workflow, Map<String, String> properties) throws WorkflowException, UnauthorizedException {
    WorkflowOperationInstance processingOperation = workflow.getCurrentOperation();
    if (processingOperation == null)
        throw new IllegalStateException("Workflow '" + workflow + "' has no operation to run");
    // Keep the current state for later reference, it might have been changed from the outside
    WorkflowState initialState = workflow.getState();
    // Execute the operation handler
    WorkflowOperationHandler operationHandler = selectOperationHandler(processingOperation);
    WorkflowOperationWorker worker = new WorkflowOperationWorker(operationHandler, workflow, properties, this);
    workflow = worker.execute();
    // The workflow has been serialized/deserialized in between, so we need to refresh the reference
    int currentOperationPosition = processingOperation.getPosition();
    processingOperation = workflow.getOperations().get(currentOperationPosition);
    Long currentOperationJobId = processingOperation.getId();
    try {
        updateOperationJob(currentOperationJobId, processingOperation.getState());
    } catch (NotFoundException e) {
        throw new IllegalStateException("Unable to find a job that has already been running");
    } catch (ServiceRegistryException e) {
        throw new WorkflowDatabaseException(e);
    }
    // Move on to the next workflow operation
    WorkflowOperationInstance currentOperation = workflow.getCurrentOperation();
    // Is the workflow done?
    if (currentOperation == null) {
        // If we are in failing mode, we were simply working off an error handling workflow
        if (FAILING.equals(workflow.getState())) {
            workflow.setState(FAILED);
        } else // switched to paused while processing the error handling workflow extension
        if (!FAILED.equals(workflow.getState())) {
            workflow.setState(SUCCEEDED);
            for (WorkflowOperationInstance op : workflow.getOperations()) {
                if (op.getState().equals(WorkflowOperationInstance.OperationState.FAILED)) {
                    if (op.isFailWorkflowOnException()) {
                        workflow.setState(FAILED);
                        break;
                    }
                }
            }
        }
        // Save the updated workflow to the database
        logger.debug("%s has %s", workflow, workflow.getState());
        update(workflow);
    } else {
        // Somebody might have set the workflow to "paused" from the outside, so take a look a the database first
        WorkflowState dbWorkflowState = null;
        try {
            dbWorkflowState = getWorkflowById(workflow.getId()).getState();
        } catch (WorkflowDatabaseException e) {
            throw new IllegalStateException("The workflow with ID " + workflow.getId() + " can not be accessed in the database", e);
        } catch (NotFoundException e) {
            throw new IllegalStateException("The workflow with ID " + workflow.getId() + " can not be found in the database", e);
        } catch (UnauthorizedException e) {
            throw new IllegalStateException("The workflow with ID " + workflow.getId() + " can not be read", e);
        }
        // If somebody changed the workflow state from the outside, that state should take precedence
        if (!dbWorkflowState.equals(initialState)) {
            logger.info("Workflow state for %s was changed to '%s' from the outside", workflow, dbWorkflowState);
            workflow.setState(dbWorkflowState);
        }
        // Save the updated workflow to the database
        Job job = null;
        switch(workflow.getState()) {
            case FAILED:
                update(workflow);
                break;
            case FAILING:
            case RUNNING:
                try {
                    job = serviceRegistry.createJob(JOB_TYPE, Operation.START_OPERATION.toString(), Arrays.asList(Long.toString(workflow.getId())), null, false, null, WORKFLOW_JOB_LOAD);
                    currentOperation.setId(job.getId());
                    update(workflow);
                    job.setStatus(Status.QUEUED);
                    job.setDispatchable(true);
                    job = serviceRegistry.updateJob(job);
                } catch (ServiceRegistryException e) {
                    throw new WorkflowDatabaseException(e);
                } catch (NotFoundException e) {
                    // this should be impossible
                    throw new IllegalStateException("Unable to find a job that was just created");
                }
                break;
            case PAUSED:
            case STOPPED:
            case SUCCEEDED:
                update(workflow);
                break;
            case INSTANTIATED:
                update(workflow);
                throw new IllegalStateException("Impossible workflow state found during processing");
            default:
                throw new IllegalStateException("Unkown workflow state found during processing");
        }
    }
    return processingOperation;
}
Also used : WorkflowDatabaseException(org.opencastproject.workflow.api.WorkflowDatabaseException) WorkflowOperationInstance(org.opencastproject.workflow.api.WorkflowOperationInstance) WorkflowState(org.opencastproject.workflow.api.WorkflowInstance.WorkflowState) ResumableWorkflowOperationHandler(org.opencastproject.workflow.api.ResumableWorkflowOperationHandler) WorkflowOperationHandler(org.opencastproject.workflow.api.WorkflowOperationHandler) UnauthorizedException(org.opencastproject.security.api.UnauthorizedException) NotFoundException(org.opencastproject.util.NotFoundException) Job(org.opencastproject.job.api.Job) ServiceRegistryException(org.opencastproject.serviceregistry.api.ServiceRegistryException)

Aggregations

WorkflowState (org.opencastproject.workflow.api.WorkflowInstance.WorkflowState)4 WorkflowDatabaseException (org.opencastproject.workflow.api.WorkflowDatabaseException)3 Job (org.opencastproject.job.api.Job)2 UnauthorizedException (org.opencastproject.security.api.UnauthorizedException)2 ServiceRegistryException (org.opencastproject.serviceregistry.api.ServiceRegistryException)2 NotFoundException (org.opencastproject.util.NotFoundException)2 IOException (java.io.IOException)1 Lock (java.util.concurrent.locks.Lock)1 SolrQuery (org.apache.solr.client.solrj.SolrQuery)1 SolrServerException (org.apache.solr.client.solrj.SolrServerException)1 FacetField (org.apache.solr.client.solrj.response.FacetField)1 Count (org.apache.solr.client.solrj.response.FacetField.Count)1 QueryResponse (org.apache.solr.client.solrj.response.QueryResponse)1 MediaPackage (org.opencastproject.mediapackage.MediaPackage)1 MediaPackageException (org.opencastproject.mediapackage.MediaPackageException)1 AccessControlList (org.opencastproject.security.api.AccessControlList)1 SeriesException (org.opencastproject.series.api.SeriesException)1 UndispatchableJobException (org.opencastproject.serviceregistry.api.UndispatchableJobException)1 Collections.mkString (org.opencastproject.util.data.Collections.mkString)1 ResumableWorkflowOperationHandler (org.opencastproject.workflow.api.ResumableWorkflowOperationHandler)1