use of org.opencastproject.workflow.api.WorkflowOperationHandler in project opencast by opencast.
the class WorkflowServiceImpl method getRegisteredHandlers.
/**
* Gets the currently registered workflow operation handlers.
*
* @return All currently registered handlers
*/
public Set<HandlerRegistration> getRegisteredHandlers() {
Set<HandlerRegistration> set = new HashSet<HandlerRegistration>();
ServiceReference[] refs;
try {
refs = componentContext.getBundleContext().getServiceReferences(WorkflowOperationHandler.class.getName(), null);
} catch (InvalidSyntaxException e) {
throw new IllegalStateException(e);
}
if (refs != null) {
for (ServiceReference ref : refs) {
WorkflowOperationHandler handler = (WorkflowOperationHandler) componentContext.getBundleContext().getService(ref);
set.add(new HandlerRegistration((String) ref.getProperty(WORKFLOW_OPERATION_PROPERTY), handler));
}
} else {
logger.warn("No registered workflow operation handlers found");
}
return set;
}
use of org.opencastproject.workflow.api.WorkflowOperationHandler in project opencast by opencast.
the class WorkflowStatisticsTest method setUp.
@Before
public void setUp() throws Exception {
// always start with a fresh solr root directory
sRoot = new File(getStorageRoot());
try {
FileUtils.forceMkdir(sRoot);
} catch (IOException e) {
Assert.fail(e.getMessage());
}
workflowDefinitions = new ArrayList<WorkflowDefinition>();
workflowHandlers = new HashSet<HandlerRegistration>();
String opId = "op";
WorkflowOperationDefinition op = new WorkflowOperationDefinitionImpl(opId, "Pausing operation", null, true);
WorkflowOperationHandler opHandler = new ResumableTestWorkflowOperationHandler(opId, Action.PAUSE, Action.CONTINUE);
HandlerRegistration handler = new HandlerRegistration(opId, opHandler);
workflowHandlers.add(handler);
// create operation handlers for our workflows
for (int i = 1; i <= WORKFLOW_DEFINITION_COUNT; i++) {
WorkflowDefinition workflowDef = new WorkflowDefinitionImpl();
workflowDef.setId("def-" + i);
for (int opCount = 1; opCount <= OPERATION_COUNT; opCount++) {
workflowDef.add(op);
}
workflowDefinitions.add(workflowDef);
}
// instantiate a service implementation and its DAO, overriding the methods that depend on the osgi runtime
service = new WorkflowServiceImpl() {
@Override
public Set<HandlerRegistration> getRegisteredHandlers() {
return workflowHandlers;
}
};
scanner = new WorkflowDefinitionScanner();
service.addWorkflowDefinitionScanner(scanner);
// security service
securityService = EasyMock.createNiceMock(SecurityService.class);
EasyMock.expect(securityService.getUser()).andReturn(SecurityServiceStub.DEFAULT_ORG_ADMIN).anyTimes();
EasyMock.expect(securityService.getOrganization()).andReturn(new DefaultOrganization()).anyTimes();
EasyMock.replay(securityService);
service.setSecurityService(securityService);
AuthorizationService authzService = EasyMock.createNiceMock(AuthorizationService.class);
EasyMock.expect(authzService.getActiveAcl((MediaPackage) EasyMock.anyObject())).andReturn(Tuple.tuple(acl, AclScope.Series)).anyTimes();
EasyMock.replay(authzService);
service.setAuthorizationService(authzService);
UserDirectoryService userDirectoryService = EasyMock.createMock(UserDirectoryService.class);
EasyMock.expect(userDirectoryService.loadUser((String) EasyMock.anyObject())).andReturn(DEFAULT_ORG_ADMIN).anyTimes();
EasyMock.replay(userDirectoryService);
service.setUserDirectoryService(userDirectoryService);
Organization organization = new DefaultOrganization();
List<Organization> organizationList = new ArrayList<Organization>();
organizationList.add(organization);
OrganizationDirectoryService organizationDirectoryService = EasyMock.createMock(OrganizationDirectoryService.class);
EasyMock.expect(organizationDirectoryService.getOrganizations()).andReturn(organizationList).anyTimes();
EasyMock.expect(organizationDirectoryService.getOrganization((String) EasyMock.anyObject())).andReturn(organization).anyTimes();
EasyMock.replay(organizationDirectoryService);
service.setOrganizationDirectoryService(organizationDirectoryService);
MessageSender messageSender = EasyMock.createNiceMock(MessageSender.class);
EasyMock.replay(messageSender);
service.setMessageSender(messageSender);
MediaPackageMetadataService mds = EasyMock.createNiceMock(MediaPackageMetadataService.class);
EasyMock.replay(mds);
service.addMetadataService(mds);
// Register the workflow definitions
for (WorkflowDefinition workflowDefinition : workflowDefinitions) {
service.registerWorkflowDefinition(workflowDefinition);
}
// Mock the workspace
workspace = EasyMock.createNiceMock(Workspace.class);
EasyMock.expect(workspace.getCollectionContents((String) EasyMock.anyObject())).andReturn(new URI[0]);
EasyMock.replay(workspace);
// Mock the service registry
ServiceRegistryInMemoryImpl serviceRegistry = new ServiceRegistryInMemoryImpl(service, securityService, userDirectoryService, organizationDirectoryService, EasyMock.createNiceMock(IncidentService.class));
// Create the workflow database (solr)
dao = new WorkflowServiceSolrIndex();
dao.solrRoot = sRoot + File.separator + "solr." + System.currentTimeMillis();
dao.setSecurityService(securityService);
dao.setServiceRegistry(serviceRegistry);
dao.setAuthorizationService(authzService);
dao.setOrgDirectory(organizationDirectoryService);
dao.activate("System Admin");
service.setDao(dao);
service.setServiceRegistry(serviceRegistry);
service.setSecurityService(securityService);
service.activate(null);
// Crate a media package
InputStream is = null;
try {
MediaPackageBuilder mediaPackageBuilder = MediaPackageBuilderFactory.newInstance().newMediaPackageBuilder();
mediaPackageBuilder.setSerializer(new DefaultMediaPackageSerializerImpl(new File("target/test-classes")));
is = WorkflowStatisticsTest.class.getResourceAsStream("/mediapackage-1.xml");
mediaPackage = mediaPackageBuilder.loadFromXml(is);
IOUtils.closeQuietly(is);
Assert.assertNotNull(mediaPackage.getIdentifier());
} catch (Exception e) {
Assert.fail(e.getMessage());
}
// Register the workflow service with the service registry
serviceRegistry.registerService(service);
}
use of org.opencastproject.workflow.api.WorkflowOperationHandler in project opencast by opencast.
the class MediaPackagePostOperationHandlerTest method createWorkflow.
/**
* Creates a new workflow and readies the engine for processing
*/
private InstanceAndHandler createWorkflow(String url, String format) {
WorkflowOperationHandler handler = new MediaPackagePostOperationHandler();
WorkflowInstanceImpl workflowInstance = new WorkflowInstanceImpl();
workflowInstance.setId(1);
workflowInstance.setState(WorkflowState.RUNNING);
WorkflowOperationInstanceImpl operation = new WorkflowOperationInstanceImpl("op", OperationState.RUNNING);
List<WorkflowOperationInstance> operationsList = new ArrayList<WorkflowOperationInstance>();
operationsList.add(operation);
workflowInstance.setOperations(operationsList);
operation.setConfiguration("url", url);
operation.setConfiguration("format", format);
operation.setConfiguration("mediapackage.type", "workflow");
return new InstanceAndHandler(workflowInstance, handler);
}
use of org.opencastproject.workflow.api.WorkflowOperationHandler 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;
}
use of org.opencastproject.workflow.api.WorkflowOperationHandler in project opencast by opencast.
the class WorkflowServiceImpl method isReadyToAccept.
/**
* {@inheritDoc}
*
* If we are already running the maximum number of workflows, don't accept another START_WORKFLOW job
*
* @see org.opencastproject.job.api.AbstractJobProducer#isReadyToAccept(org.opencastproject.job.api.Job)
*/
@Override
public boolean isReadyToAccept(Job job) throws ServiceRegistryException, UndispatchableJobException {
String operation = job.getOperation();
// Only restrict execution of new jobs
if (!Operation.START_WORKFLOW.toString().equals(operation))
return true;
// If the first operation is guaranteed to pause, run the job.
if (job.getArguments().size() > 1 && job.getArguments().get(0) != null) {
try {
WorkflowDefinition workflowDef = WorkflowParser.parseWorkflowDefinition(job.getArguments().get(0));
if (workflowDef.getOperations().size() > 0) {
String firstOperationId = workflowDef.getOperations().get(0).getId();
WorkflowOperationHandler handler = getWorkflowOperationHandler(firstOperationId);
if (handler instanceof ResumableWorkflowOperationHandler) {
if (((ResumableWorkflowOperationHandler) handler).isAlwaysPause()) {
return true;
}
}
}
} catch (WorkflowParsingException e) {
throw new UndispatchableJobException(job + " is not a proper job to start a workflow", e);
}
}
WorkflowInstance workflow = null;
WorkflowSet workflowInstances = null;
String mediaPackageId = null;
// Fetch all workflows that are running with the current mediapackage
try {
workflow = getWorkflowById(job.getId());
mediaPackageId = workflow.getMediaPackage().getIdentifier().toString();
workflowInstances = getWorkflowInstances(new WorkflowQuery().withMediaPackage(workflow.getMediaPackage().getIdentifier().toString()).withState(RUNNING).withState(PAUSED).withState(FAILING));
} catch (NotFoundException e) {
logger.error("Trying to start workflow with id %s but no corresponding instance is available from the workflow service", job.getId());
throw new UndispatchableJobException(e);
} catch (UnauthorizedException e) {
logger.error("Authorization denied while requesting to loading workflow instance %s: %s", job.getId(), e.getMessage());
throw new UndispatchableJobException(e);
} catch (WorkflowDatabaseException e) {
logger.error("Error loading workflow instance %s: %s", job.getId(), e.getMessage());
return false;
}
// If more than one workflow is running working on this mediapackage, then we don't start this one
boolean toomany = workflowInstances.size() > 1;
// Make sure we are not excluding ourselves
toomany |= workflowInstances.size() == 1 && workflow.getId() != workflowInstances.getItems()[0].getId();
// Avoid running multiple workflows with same media package id at the same time
if (toomany) {
if (!delayedWorkflows.contains(workflow.getId())) {
logger.info("Delaying start of workflow %s, another workflow on media package %s is still running", workflow.getId(), mediaPackageId);
delayedWorkflows.add(workflow.getId());
}
return false;
}
return true;
}
Aggregations