use of com.emc.storageos.db.client.model.WorkflowStepData in project coprhd-controller by CoprHD.
the class WorkflowService method destroyWorkflow.
/**
* Remove workflow from Zookeeper if necessary.
*
* @param workflow
*/
public void destroyWorkflow(Workflow workflow) {
String id = workflow.getOrchTaskId();
try {
destroyNestedWorkflows(workflow);
// Remove all the Step data nodes.
List<WorkflowStepData> dataRecords = CustomQueryUtility.queryActiveResourcesByRelation(_dbClient, workflow.getWorkflowURI(), WorkflowStepData.class, "workflow");
if (dataRecords != null && !dataRecords.isEmpty()) {
_dbClient.markForDeletion(dataRecords);
}
// Remove the steo to workflow path for all steps in the workflow.
for (String stepId : workflow.getStepMap().keySet()) {
Stat stat = _dataManager.checkExists(getZKStep2WorkflowPath(stepId));
if (stat != null) {
_dataManager.removeNode(getZKStep2WorkflowPath(stepId));
}
}
// Destroy the workflow under /workflow/workflows
String path = getZKWorkflowPath(workflow);
Stat stat = _dataManager.checkExists(path);
if (stat != null) {
_dataManager.removeNode(path);
_log.info("Removed ZK workflow: " + workflow.getWorkflowURI());
}
} catch (Exception ex) {
_log.error("Cannot destroy Workflow: " + id, ex);
}
}
use of com.emc.storageos.db.client.model.WorkflowStepData in project coprhd-controller by CoprHD.
the class WorkflowService method loadStepData.
/**
* Retrieve step data for a class.
*
* @param workflowURI -- required workflow URI
* @param key - optional string key
* @param stepId -- The step identifier (optional).
* @return -- A Java serializable object, or null if no data found.
* @throws Exception
*/
public Object loadStepData(URI workflowURI, String key, String stepId) {
try {
Workflow workflow = loadWorkflowFromUri(workflowURI);
if (workflow == null) {
Exception ex = WorkflowException.exceptions.workflowNotFound(stepId);
_log.error("Can't load step state for step: " + stepId, ex);
return null;
}
String path = getZKStepDataPath(stepId);
Stat stat = _dataManager.checkExists(path);
if (stat != null) {
// Legacy path for old workflows
Object data = _dataManager.getData(path, false);
_log.info(String.format("Loaded WorkflowStepData for %s %s %s", workflowURI, stepId, key));
return data;
}
Object data = null;
WorkflowStepData stepData = getWorkflowStepData(workflow.getWorkflowURI(), stepId, key);
if (stepData == null) {
// If we were not able to find step data, it could be that the step we are trying to load is a rollback
// step. Rollback step ids are only determined during rollback execution and therefore step data
// for these steps may not be stored in the database yet. In this case we need to determine if the rollback
// step has a founding step (primary execution step) that we can load from the database. The founding
// step data can be used to form a context of executed step operations.
Map<String, Step> stepMap = workflow.getStepMap();
if (stepMap != null) {
Step workflowStep = stepMap.get(stepId);
if (workflowStep != null && workflowStep.isRollbackStep() && workflowStep.foundingStepId != null) {
_log.info(String.format("Step data for rollback step %s does not exist. Attempting to load step data for founding step %s", stepId, workflowStep.foundingStepId));
stepData = getWorkflowStepData(workflow.getWorkflowURI(), workflowStep.foundingStepId, key);
}
}
}
if (stepData != null) {
data = GenericSerializer.deserialize(stepData.getData());
_log.info(String.format("Loaded WorkflowStepData for %s %s %s", workflowURI, stepId, key));
} else {
_log.info(String.format("No WorkflowStepData found for %s %s %s", workflowURI, stepId, key));
}
return data;
} catch (Exception ex) {
_log.error("Can't load step data for step: " + stepId);
}
return null;
}
use of com.emc.storageos.db.client.model.WorkflowStepData in project coprhd-controller by CoprHD.
the class WorkflowTest method test24_test_workflow_scrubber.
/**
* workflow scrubber does the following:
* deletes workflows older than some predetermined amount of time
* deletes all associated workflow steps if the workflow is deleted
* deletes all orphaned workflow steps
*/
@Test
public void test24_test_workflow_scrubber() {
final String testname = new Object() {
}.getClass().getEnclosingMethod().getName();
printLog(testname + " started");
WorkflowScrubberExecutor scrubber = new WorkflowScrubberExecutor();
scrubber.setDbClient(dbClient);
// it's required for this test that there are no previously existing workflows or workflow steps
Iterator<com.emc.storageos.db.client.model.Workflow> wfs = dbClient.queryIterativeObjects(com.emc.storageos.db.client.model.Workflow.class, dbClient.queryByType(com.emc.storageos.db.client.model.Workflow.class, true));
while (wfs.hasNext()) {
dbClient.removeObject(wfs.next());
}
Iterator<WorkflowStep> wfSteps = dbClient.queryIterativeObjects(WorkflowStep.class, dbClient.queryByType(WorkflowStep.class, true));
while (wfSteps.hasNext()) {
dbClient.removeObject(wfSteps.next());
}
Iterator<WorkflowStepData> wfStepData = dbClient.queryIterativeObjects(WorkflowStepData.class, dbClient.queryByType(WorkflowStepData.class, true));
while (wfStepData.hasNext()) {
dbClient.removeObject(wfStepData.next());
}
Object[] args = new Object[1];
String taskId = UUID.randomUUID().toString();
args[0] = taskId;
long maxWFAge = WorkflowScrubberExecutor.WORKFLOW_HOLDING_TIME_MSEC;
Long currentTime = System.currentTimeMillis();
Calendar dateInPast = Calendar.getInstance();
dateInPast.setTime(new Date(currentTime - maxWFAge));
// create a completed workflow with one step (scrubber should leave this one alone)
com.emc.storageos.db.client.model.Workflow completedWorkflow = new com.emc.storageos.db.client.model.Workflow();
completedWorkflow.setId(URIUtil.createId(com.emc.storageos.db.client.model.Workflow.class));
completedWorkflow.setCompleted(true);
dbClient.createObject(completedWorkflow);
WorkflowStep completedWorkflowStep = new WorkflowStep();
completedWorkflowStep.setId(URIUtil.createId(WorkflowStep.class));
completedWorkflowStep.setWorkflowId(completedWorkflow.getId());
dbClient.createObject(completedWorkflowStep);
WorkflowStepData completedWorkflowStepData = new WorkflowStepData();
completedWorkflowStepData.setId(URIUtil.createId(WorkflowStepData.class));
completedWorkflowStepData.setWorkflowId(completedWorkflow.getId());
dbClient.createObject(completedWorkflowStepData);
// Create a workflow older than max age (one step)
com.emc.storageos.db.client.model.Workflow dbWorkflow = new com.emc.storageos.db.client.model.Workflow();
dbWorkflow.setId(URIUtil.createId(com.emc.storageos.db.client.model.Workflow.class));
dbWorkflow.setCompleted(true);
dbClient.createObject(dbWorkflow);
dbWorkflow.setCreationTime(dateInPast);
dbClient.updateObject(dbWorkflow);
WorkflowStep step = new WorkflowStep();
step.setId(URIUtil.createId(WorkflowStep.class));
step.setWorkflowId(dbWorkflow.getId());
dbClient.createObject(step);
WorkflowStepData stepData = new WorkflowStepData();
stepData.setId(URIUtil.createId(WorkflowStepData.class));
stepData.setWorkflowId(dbWorkflow.getId());
dbClient.createObject(stepData);
// create a workflow step with a null workflow reference (orphaned step)
step = new WorkflowStep();
step.setId(URIUtil.createId(WorkflowStep.class));
dbClient.createObject(step);
stepData = new WorkflowStepData();
stepData.setId(URIUtil.createId(WorkflowStepData.class));
dbClient.createObject(stepData);
// create a workflow step with a valid but non-existing workflow id (orphaned step)
step = new WorkflowStep();
step.setId(URIUtil.createId(WorkflowStep.class));
step.setWorkflowId(URIUtil.createId(com.emc.storageos.db.client.model.Workflow.class));
dbClient.createObject(step);
stepData = new WorkflowStepData();
stepData.setId(URIUtil.createId(WorkflowStepData.class));
step.setWorkflowId(URIUtil.createId(com.emc.storageos.db.client.model.Workflow.class));
dbClient.createObject(stepData);
// create a workflow with one step then delete the workflow only (orphaned step)
dbWorkflow = new com.emc.storageos.db.client.model.Workflow();
dbWorkflow.setId(URIUtil.createId(com.emc.storageos.db.client.model.Workflow.class));
dbClient.createObject(dbWorkflow);
step = new WorkflowStep();
step.setId(URIUtil.createId(WorkflowStep.class));
step.setWorkflowId(dbWorkflow.getId());
dbClient.createObject(step);
stepData = new WorkflowStepData();
stepData.setId(URIUtil.createId(WorkflowStepData.class));
stepData.setWorkflowId(dbWorkflow.getId());
dbClient.createObject(stepData);
dbClient.removeObject(dbWorkflow);
List<URI> wfUris = copyUriList(dbClient.queryByType(com.emc.storageos.db.client.model.Workflow.class, true));
assertTrue(wfUris.size() == 2);
List<URI> wfStepUris = copyUriList(dbClient.queryByType(WorkflowStep.class, true));
assertTrue(wfStepUris.size() == 5);
List<URI> wfStepDataUris = copyUriList(dbClient.queryByType(WorkflowStepData.class, true));
assertTrue(wfStepDataUris.size() == 5);
scrubber.deleteOldWorkflows();
wfUris = copyUriList(dbClient.queryByType(com.emc.storageos.db.client.model.Workflow.class, true));
assertTrue(wfUris.size() == 1);
assertTrue(wfUris.contains(completedWorkflow.getId()));
wfStepUris = copyUriList(dbClient.queryByType(WorkflowStep.class, true));
assertTrue(wfStepUris.size() == 1);
assertTrue(wfStepUris.contains(completedWorkflowStep.getId()));
wfStepDataUris = copyUriList(dbClient.queryByType(WorkflowStepData.class, true));
assertTrue(wfStepDataUris.size() == 1);
assertTrue(wfStepDataUris.contains(completedWorkflowStepData.getId()));
// clean up
dbClient.removeObject(completedWorkflow);
dbClient.removeObject(completedWorkflowStep);
printLog(testname + " completed");
}
use of com.emc.storageos.db.client.model.WorkflowStepData in project coprhd-controller by CoprHD.
the class WorkflowScrubberExecutor method deleteOldWorkflows.
/**
* Scan all the workflows, delete:
* workflows older than WORKFLOW_HOLDING_TIME_MSEC
* workflow steps associated with any workflow deleted
* workflowStepData associated with any workflow deleted
* Also finds and deletes:
* orphaned workflow steps (steps without a valid workflow)
* orphaned workflowStepData (without a workflow)
*/
public void deleteOldWorkflows() {
log.info("Scanning for old workflows to be deleted");
List<URI> workflowURIs = dbClient.queryByType(Workflow.class, true);
Iterator<Workflow> workflowItr = dbClient.queryIterativeObjects(Workflow.class, workflowURIs);
Long currentTime = System.currentTimeMillis();
int workflowCount = 0, workflowsDeletedCount = 0, stepsDeletedCount = 0, stepDataDeletedCount = 0;
while (workflowItr.hasNext()) {
workflowCount++;
Workflow workflow = workflowItr.next();
URI uri = workflow.getId();
try {
Long creationTime = (workflow.getCreationTime() == null) ? (currentTime - WORKFLOW_HOLDING_TIME_MSEC) : workflow.getCreationTime().getTimeInMillis();
Long age = currentTime - creationTime;
if (age >= WORKFLOW_HOLDING_TIME_MSEC) {
log.info("Processing workflow {} age (msec) {}", uri, age);
// Find all the WorkflowSteps for this Workflow, and them mark them for deletion.
URIQueryResultList stepURIs = new URIQueryResultList();
dbClient.queryByConstraint(ContainmentConstraint.Factory.getWorkflowWorkflowStepConstraint(uri), stepURIs);
Iterator<WorkflowStep> wfStepItr = dbClient.queryIterativeObjects(WorkflowStep.class, stepURIs);
while (wfStepItr.hasNext()) {
WorkflowStep step = wfStepItr.next();
URI stepURI = step.getId();
stepsDeletedCount++;
dbClient.removeObject(step);
log.info("Workflow step {} for workflow {} marked inactive", stepURI, uri);
}
// Find all the WorkflowStepData for this Workflow, and them mark them for deletion.
URIQueryResultList stepDataURIs = new URIQueryResultList();
dbClient.queryByConstraint(ContainmentConstraint.Factory.getWorkflowStepDataConstraint(uri), stepDataURIs);
Iterator<WorkflowStepData> wfStepDataItr = dbClient.queryIterativeObjects(WorkflowStepData.class, stepDataURIs);
while (wfStepDataItr.hasNext()) {
WorkflowStepData stepData = wfStepDataItr.next();
stepDataDeletedCount++;
dbClient.removeObject(stepData);
log.info("Workflow step data {} for workflow {} marked inactive", stepData.getId(), uri);
}
// Mark the workflow itself for deletion
if (!workflow.getInactive()) {
workflowsDeletedCount++;
dbClient.removeObject(workflow);
log.info("Workflow {} marked inactive", uri);
}
}
} catch (Exception ex) {
log.error("Exception processing workflow: " + uri, ex);
}
}
// now query workflow steps and clean up any orphaned steps
Iterator<WorkflowStep> workflowStepItr = dbClient.queryIterativeObjects(WorkflowStep.class, dbClient.queryByType(WorkflowStep.class, true));
while (workflowStepItr.hasNext()) {
WorkflowStep step = workflowStepItr.next();
if (NullColumnValueGetter.isNullURI(step.getWorkflowId())) {
// step is orphaned -- delete it
stepsDeletedCount++;
dbClient.removeObject(step);
log.info("Orphaned workflow step {} marked inactive", step.getId());
} else {
Workflow wf = dbClient.queryObject(Workflow.class, step.getWorkflowId());
if (wf == null || wf.getInactive()) {
// step is orphaned -- delete it
stepsDeletedCount++;
dbClient.removeObject(step);
log.info("Orphaned workflow step {} marked inactive", step.getId());
}
}
}
// now query workflow step data and clean up any orphaned step data
Iterator<WorkflowStepData> workflowStepDataItr = dbClient.queryIterativeObjects(WorkflowStepData.class, dbClient.queryByType(WorkflowStepData.class, true));
while (workflowStepDataItr.hasNext()) {
WorkflowStepData stepData = workflowStepDataItr.next();
if (NullColumnValueGetter.isNullURI(stepData.getWorkflowId())) {
// step data is orphaned -- delete it
stepDataDeletedCount++;
dbClient.removeObject(stepData);
log.info("Orphaned workflow step data {} marked inactive", stepData.getId());
} else {
Workflow wf = dbClient.queryObject(Workflow.class, stepData.getWorkflowId());
if (wf == null || wf.getInactive()) {
// step data is orphaned -- delete it
stepDataDeletedCount++;
dbClient.removeObject(stepData);
log.info("Orphaned workflow step data {} marked inactive", stepData.getId());
}
}
}
log.info("Done scanning for old workflows; {} workflows analyzed; {} old workflows deleted; {} workflow steps deleted; {} workflow step data deleted", workflowCount, workflowsDeletedCount, stepsDeletedCount, stepDataDeletedCount);
}
use of com.emc.storageos.db.client.model.WorkflowStepData in project coprhd-controller by CoprHD.
the class WorkflowService method storeStepData.
/**
* Saves data on behalf of a step.
* The workflow URI and at least a stepId or key (or both) must be supplied.
* Note: The stepOrWorkflow argument must be either a valid workflowURI (obtained
* when the workflow is created)
* The data is available until the workflow is destroyed.
*
* @param workflowURI -- Mandatory, the URI of the containing workflow
* @param key --String key (optional).
* @param stepId -- The step identifier. (optional)
* @param data -- A Java Serializable object.
*/
public void storeStepData(URI workflowURI, String key, String stepId, Object data) {
WorkflowStepData dataRecord = getWorkflowStepData(workflowURI, stepId, key);
boolean created = false;
if (dataRecord == null) {
dataRecord = new WorkflowStepData();
dataRecord.setId(URIUtil.createId(WorkflowStepData.class));
dataRecord.setWorkflowId(workflowURI);
dataRecord.setStepId(stepId);
dataRecord.setLabel(key);
created = true;
}
dataRecord.setData(GenericSerializer.serialize(data, key, false));
if (created) {
_dbClient.createObject(dataRecord);
_log.info(String.format("Created WorkflowStepData for %s %s %s", workflowURI, stepId, key));
} else {
_dbClient.updateObject(dataRecord);
_log.info(String.format("Updated WorkflowStepData for %s %s %s", workflowURI, stepId, key));
}
}
Aggregations