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();
}
}
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;
}
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();
}
}
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;
}
Aggregations