Search in sources :

Example 1 with WorkflowParsingException

use of org.opencastproject.workflow.api.WorkflowParsingException 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 WorkflowParsingException

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

the class LoggingWorkflowOperationHandler method start.

/**
 * {@inheritDoc}
 *
 * @see org.opencastproject.workflow.api.WorkflowOperationHandler#start(org.opencastproject.workflow.api.WorkflowInstance,
 *      JobContext)
 */
@Override
public WorkflowOperationResult start(WorkflowInstance workflowInstance, JobContext context) throws WorkflowOperationException {
    WorkflowOperationInstance operation = workflowInstance.getCurrentOperation();
    String directoryPath = StringUtils.trimToNull(operation.getConfiguration("directory"));
    File directory = null;
    if (directoryPath != null) {
        directory = new File(directoryPath);
        try {
            FileUtils.forceMkdir(directory);
        } catch (IOException e) {
            throw new WorkflowOperationException(String.format("Failed to create output directory '%s'", directoryPath), e);
        }
    }
    boolean logMediaPackageJSON = BooleanUtils.toBoolean(operation.getConfiguration("mediapackage-json"));
    boolean logMediaPackageXML = BooleanUtils.toBoolean(operation.getConfiguration("mediapackage-xml"));
    boolean logWorkflowInstance = BooleanUtils.toBoolean(operation.getConfiguration("workflowinstance-xml"));
    if (!(logMediaPackageJSON || logMediaPackageXML || logWorkflowInstance)) {
        logMediaPackageJSON = true;
    }
    MediaPackage mediaPackage = workflowInstance.getMediaPackage();
    // Log media package as JSON
    if (logMediaPackageJSON) {
        String filename = String.format("workflow-%d-%d-mediapackage-%s.json", workflowInstance.getId(), operation.getId(), mediaPackage.getIdentifier());
        saveOrLog(MediaPackageParser.getAsJSON(mediaPackage), directory, filename);
    }
    // Log media package as XML
    if (logMediaPackageXML) {
        String filename = String.format("workflow-%d-%d-mediapackage-%s.xml", workflowInstance.getId(), operation.getId(), mediaPackage.getIdentifier());
        saveOrLog(MediaPackageParser.getAsXml(mediaPackage), directory, filename);
    }
    // Log workflow instance as XML
    if (logWorkflowInstance) {
        String filename = String.format("workflow-%d-%d.xml", workflowInstance.getId(), operation.getId());
        try {
            saveOrLog(WorkflowParser.toXml(workflowInstance), directory, filename);
        } catch (WorkflowParsingException e) {
            throw new WorkflowOperationException(e);
        }
    }
    // Continue with unmodified media package
    return createResult(mediaPackage, Action.CONTINUE);
}
Also used : WorkflowOperationInstance(org.opencastproject.workflow.api.WorkflowOperationInstance) WorkflowOperationException(org.opencastproject.workflow.api.WorkflowOperationException) MediaPackage(org.opencastproject.mediapackage.MediaPackage) IOException(java.io.IOException) File(java.io.File) WorkflowParsingException(org.opencastproject.workflow.api.WorkflowParsingException)

Example 3 with WorkflowParsingException

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

the class WorkflowServiceImpl method cleanupWorkflowInstances.

@Override
public synchronized void cleanupWorkflowInstances(int buffer, WorkflowState state) throws UnauthorizedException, WorkflowDatabaseException {
    logger.info("Start cleaning up workflow instances older than {} days with status '{}'", buffer, state);
    int instancesCleaned = 0;
    int cleaningFailed = 0;
    WorkflowQuery query = new WorkflowQuery().withState(state).withDateBefore(DateUtils.addDays(new Date(), -buffer)).withCount(Integer.MAX_VALUE);
    for (WorkflowInstance workflowInstance : getWorkflowInstances(query).getItems()) {
        try {
            remove(workflowInstance.getId());
            instancesCleaned++;
        } catch (WorkflowDatabaseException e) {
            throw e;
        } catch (UnauthorizedException e) {
            throw e;
        } catch (NotFoundException e) {
            // Since we are in a cleanup operation, we don't have to care about NotFoundExceptions
            logger.debug("Workflow instance '{}' could not be removed: {}", workflowInstance.getId(), ExceptionUtils.getStackTrace(e));
        } catch (WorkflowParsingException e) {
            logger.warn("Workflow instance '{}' could not be removed: {}", workflowInstance.getId(), ExceptionUtils.getStackTrace(e));
            cleaningFailed++;
        } catch (WorkflowStateException e) {
            logger.warn("Workflow instance '{}' could not be removed: {}", workflowInstance.getId(), ExceptionUtils.getStackTrace(e));
            cleaningFailed++;
        }
    }
    if (instancesCleaned == 0 && cleaningFailed == 0) {
        logger.info("No workflow instances found to clean up");
        return;
    }
    if (instancesCleaned > 0)
        logger.info("Cleaned up '%d' workflow instances", instancesCleaned);
    if (cleaningFailed > 0) {
        logger.warn("Cleaning failed for '%d' workflow instances", cleaningFailed);
        throw new WorkflowDatabaseException("Unable to clean all workflow instances, see logs!");
    }
}
Also used : WorkflowDatabaseException(org.opencastproject.workflow.api.WorkflowDatabaseException) WorkflowQuery(org.opencastproject.workflow.api.WorkflowQuery) WorkflowStateException(org.opencastproject.workflow.api.WorkflowStateException) UnauthorizedException(org.opencastproject.security.api.UnauthorizedException) NotFoundException(org.opencastproject.util.NotFoundException) WorkflowInstance(org.opencastproject.workflow.api.WorkflowInstance) Date(java.util.Date) WorkflowParsingException(org.opencastproject.workflow.api.WorkflowParsingException)

Example 4 with WorkflowParsingException

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

the class WorkflowServiceImpl method remove.

/**
 * {@inheritDoc}
 *
 * @see org.opencastproject.workflow.api.WorkflowService#remove(long)
 */
@Override
public void remove(long workflowInstanceId) throws WorkflowDatabaseException, NotFoundException, UnauthorizedException, WorkflowParsingException, WorkflowStateException {
    final Lock lock = this.lock.get(workflowInstanceId);
    lock.lock();
    try {
        WorkflowQuery query = new WorkflowQuery();
        query.withId(Long.toString(workflowInstanceId));
        WorkflowSet workflows = index.getWorkflowInstances(query, Permissions.Action.READ.toString(), false);
        if (workflows.size() == 1) {
            WorkflowInstance instance = workflows.getItems()[0];
            WorkflowInstance.WorkflowState state = instance.getState();
            if (state != WorkflowState.SUCCEEDED && state != WorkflowState.FAILED && state != WorkflowState.STOPPED)
                throw new WorkflowStateException("Workflow instance with state '" + state + "' cannot be removed. Only states SUCCEEDED, FAILED & STOPPED are allowed");
            try {
                assertPermission(instance, Permissions.Action.WRITE.toString());
            } catch (MediaPackageException e) {
                throw new WorkflowParsingException(e);
            }
            // First, remove temporary files DO THIS BEFORE REMOVING FROM INDEX
            try {
                removeTempFiles(instance);
            } catch (NotFoundException e) {
                // If the files aren't their anymore, we don't have to cleanup up them :-)
                logger.debug("Temporary files of workflow instance %d seem to be gone already...", workflowInstanceId);
            }
            // Second, remove jobs related to a operation which belongs to the workflow instance
            List<WorkflowOperationInstance> operations = instance.getOperations();
            List<Long> jobsToDelete = new ArrayList<>();
            for (WorkflowOperationInstance op : operations) {
                if (op.getId() != null) {
                    long workflowOpId = op.getId();
                    if (workflowOpId != workflowInstanceId) {
                        jobsToDelete.add(workflowOpId);
                    }
                }
            }
            try {
                serviceRegistry.removeJobs(jobsToDelete);
            } catch (ServiceRegistryException e) {
                logger.warn("Problems while removing jobs related to workflow operations '%s': %s", jobsToDelete, e.getMessage());
            } catch (NotFoundException e) {
                logger.debug("No jobs related to one of the workflow operations '%s' found in the service registry", jobsToDelete);
            }
            // Third, remove workflow instance job itself
            try {
                serviceRegistry.removeJobs(Collections.singletonList(workflowInstanceId));
                messageSender.sendObjectMessage(WorkflowItem.WORKFLOW_QUEUE, MessageSender.DestinationType.Queue, WorkflowItem.deleteInstance(workflowInstanceId, instance));
            } catch (ServiceRegistryException e) {
                logger.warn("Problems while removing workflow instance job '%d': %s", workflowInstanceId, ExceptionUtils.getStackTrace(e));
            } catch (NotFoundException e) {
                logger.info("No workflow instance job '%d' found in the service registry", workflowInstanceId);
            }
            // At last, remove workflow instance from the index
            try {
                index.remove(workflowInstanceId);
            } catch (NotFoundException e) {
                // This should never happen, because we got workflow instance by querying the index...
                logger.warn("Workflow instance could not be removed from index: %s", ExceptionUtils.getStackTrace(e));
            }
        } else if (workflows.size() == 0) {
            throw new NotFoundException("Workflow instance with id '" + Long.toString(workflowInstanceId) + "' could not be found");
        } else {
            throw new WorkflowDatabaseException("More than one workflow found with id: " + Long.toString(workflowInstanceId));
        }
    } finally {
        lock.unlock();
    }
}
Also used : WorkflowSet(org.opencastproject.workflow.api.WorkflowSet) MediaPackageException(org.opencastproject.mediapackage.MediaPackageException) WorkflowQuery(org.opencastproject.workflow.api.WorkflowQuery) WorkflowState(org.opencastproject.workflow.api.WorkflowInstance.WorkflowState) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) ArrayList(java.util.ArrayList) NotFoundException(org.opencastproject.util.NotFoundException) WorkflowInstance(org.opencastproject.workflow.api.WorkflowInstance) ServiceRegistryException(org.opencastproject.serviceregistry.api.ServiceRegistryException) Lock(java.util.concurrent.locks.Lock) WorkflowDatabaseException(org.opencastproject.workflow.api.WorkflowDatabaseException) WorkflowOperationInstance(org.opencastproject.workflow.api.WorkflowOperationInstance) WorkflowStateException(org.opencastproject.workflow.api.WorkflowStateException) WorkflowParsingException(org.opencastproject.workflow.api.WorkflowParsingException)

Example 5 with WorkflowParsingException

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

the class WorkflowServiceImpl method getWorkflowById.

/**
 * {@inheritDoc}
 *
 * @see org.opencastproject.workflow.api.WorkflowService#getWorkflowById(long)
 */
@Override
public WorkflowInstanceImpl getWorkflowById(long id) throws WorkflowDatabaseException, NotFoundException, UnauthorizedException {
    try {
        Job job = serviceRegistry.getJob(id);
        if (Status.DELETED.equals(job.getStatus())) {
            throw new NotFoundException("Workflow '" + id + "' has been deleted");
        }
        if (JOB_TYPE.equals(job.getJobType()) && Operation.START_WORKFLOW.toString().equals(job.getOperation())) {
            WorkflowInstanceImpl workflow = WorkflowParser.parseWorkflowInstance(job.getPayload());
            assertPermission(workflow, Permissions.Action.READ.toString());
            return workflow;
        } else {
            throw new NotFoundException("'" + id + "' is a job identifier, but it is not a workflow identifier");
        }
    } catch (WorkflowParsingException e) {
        throw new IllegalStateException("The workflow job payload is malformed");
    } catch (ServiceRegistryException e) {
        throw new IllegalStateException("Error loading workflow job from the service registry");
    } catch (MediaPackageException e) {
        throw new IllegalStateException("Unable to read mediapackage from workflow " + id, e);
    }
}
Also used : MediaPackageException(org.opencastproject.mediapackage.MediaPackageException) WorkflowInstanceImpl(org.opencastproject.workflow.api.WorkflowInstanceImpl) NotFoundException(org.opencastproject.util.NotFoundException) Job(org.opencastproject.job.api.Job) ServiceRegistryException(org.opencastproject.serviceregistry.api.ServiceRegistryException) WorkflowParsingException(org.opencastproject.workflow.api.WorkflowParsingException)

Aggregations

WorkflowParsingException (org.opencastproject.workflow.api.WorkflowParsingException)10 WorkflowInstance (org.opencastproject.workflow.api.WorkflowInstance)8 WorkflowDatabaseException (org.opencastproject.workflow.api.WorkflowDatabaseException)7 ServiceRegistryException (org.opencastproject.serviceregistry.api.ServiceRegistryException)6 NotFoundException (org.opencastproject.util.NotFoundException)6 IOException (java.io.IOException)5 Collections.mkString (org.opencastproject.util.data.Collections.mkString)5 Job (org.opencastproject.job.api.Job)4 MediaPackageException (org.opencastproject.mediapackage.MediaPackageException)4 UnauthorizedException (org.opencastproject.security.api.UnauthorizedException)4 WorkflowQuery (org.opencastproject.workflow.api.WorkflowQuery)4 WorkflowStateException (org.opencastproject.workflow.api.WorkflowStateException)4 ArrayList (java.util.ArrayList)3 CopyOnWriteArrayList (java.util.concurrent.CopyOnWriteArrayList)3 Lock (java.util.concurrent.locks.Lock)3 Organization (org.opencastproject.security.api.Organization)3 UndispatchableJobException (org.opencastproject.serviceregistry.api.UndispatchableJobException)3 WorkflowOperationException (org.opencastproject.workflow.api.WorkflowOperationException)3 WorkflowOperationInstance (org.opencastproject.workflow.api.WorkflowOperationInstance)3 WorkflowSet (org.opencastproject.workflow.api.WorkflowSet)3