Search in sources :

Example 1 with WorkflowStepData

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);
    }
}
Also used : Stat(org.apache.zookeeper.data.Stat) WorkflowStepData(com.emc.storageos.db.client.model.WorkflowStepData) InternalException(com.emc.storageos.svcs.errorhandling.resources.InternalException) DatabaseException(com.emc.storageos.db.exceptions.DatabaseException) DeviceControllerException(com.emc.storageos.exceptions.DeviceControllerException) ControllerException(com.emc.storageos.volumecontroller.ControllerException) LockRetryException(com.emc.storageos.locking.LockRetryException)

Example 2 with WorkflowStepData

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;
}
Also used : Stat(org.apache.zookeeper.data.Stat) WorkflowStepData(com.emc.storageos.db.client.model.WorkflowStepData) DataObject(com.emc.storageos.db.client.model.DataObject) Step(com.emc.storageos.workflow.Workflow.Step) InternalException(com.emc.storageos.svcs.errorhandling.resources.InternalException) DatabaseException(com.emc.storageos.db.exceptions.DatabaseException) DeviceControllerException(com.emc.storageos.exceptions.DeviceControllerException) ControllerException(com.emc.storageos.volumecontroller.ControllerException) LockRetryException(com.emc.storageos.locking.LockRetryException)

Example 3 with WorkflowStepData

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");
}
Also used : WorkflowStep(com.emc.storageos.db.client.model.WorkflowStep) Calendar(java.util.Calendar) NamedURI(com.emc.storageos.db.client.model.NamedURI) URI(java.net.URI) Date(java.util.Date) WorkflowStepData(com.emc.storageos.db.client.model.WorkflowStepData) DataObject(com.emc.storageos.db.client.model.DataObject) Test(org.junit.Test)

Example 4 with WorkflowStepData

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);
}
Also used : WorkflowStep(com.emc.storageos.db.client.model.WorkflowStep) WorkflowStepData(com.emc.storageos.db.client.model.WorkflowStepData) Workflow(com.emc.storageos.db.client.model.Workflow) URI(java.net.URI) ContainmentConstraint(com.emc.storageos.db.client.constraint.ContainmentConstraint) URIQueryResultList(com.emc.storageos.db.client.constraint.URIQueryResultList)

Example 5 with WorkflowStepData

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));
    }
}
Also used : WorkflowStepData(com.emc.storageos.db.client.model.WorkflowStepData)

Aggregations

WorkflowStepData (com.emc.storageos.db.client.model.WorkflowStepData)6 DataObject (com.emc.storageos.db.client.model.DataObject)2 WorkflowStep (com.emc.storageos.db.client.model.WorkflowStep)2 DatabaseException (com.emc.storageos.db.exceptions.DatabaseException)2 DeviceControllerException (com.emc.storageos.exceptions.DeviceControllerException)2 LockRetryException (com.emc.storageos.locking.LockRetryException)2 InternalException (com.emc.storageos.svcs.errorhandling.resources.InternalException)2 ControllerException (com.emc.storageos.volumecontroller.ControllerException)2 URI (java.net.URI)2 Stat (org.apache.zookeeper.data.Stat)2 AlternateIdConstraint (com.emc.storageos.db.client.constraint.AlternateIdConstraint)1 ContainmentConstraint (com.emc.storageos.db.client.constraint.ContainmentConstraint)1 URIQueryResultList (com.emc.storageos.db.client.constraint.URIQueryResultList)1 NamedURI (com.emc.storageos.db.client.model.NamedURI)1 Workflow (com.emc.storageos.db.client.model.Workflow)1 Step (com.emc.storageos.workflow.Workflow.Step)1 Calendar (java.util.Calendar)1 Date (java.util.Date)1 Test (org.junit.Test)1