Search in sources :

Example 1 with InlineWorkflowActivity

use of org.alien4cloud.tosca.model.workflow.activities.InlineWorkflowActivity in project alien4cloud by alien4cloud.

the class WorkflowUtils method processInlineWorkflow.

private static void processInlineWorkflow(Map<String, Workflow> workflowMap, Workflow workflow) {
    final Set<String> newInlinedStepNames = new HashSet<>();
    // Clone the map as we iterate and in the same time modify it
    Maps.newHashMap(workflow.getSteps()).entrySet().stream().filter(entry -> entry.getValue().getActivity() instanceof InlineWorkflowActivity).forEach(inlinedStepEntry -> {
        String inlinedStepName = inlinedStepEntry.getKey();
        WorkflowStep inlinedStep = inlinedStepEntry.getValue();
        InlineWorkflowActivity inlineWorkflowActivity = (InlineWorkflowActivity) inlinedStep.getActivity();
        String inlinedName = inlineWorkflowActivity.getInline();
        Workflow inlined = workflowMap.get(inlinedName);
        if (inlined == null) {
            throw new NotFoundException("Inlined workflow " + inlinedName);
        }
        Map<String, WorkflowStep> generatedSteps = cloneSteps(inlined.getSteps());
        Map<String, WorkflowStep> generatedStepsWithNewNames = generatedSteps.entrySet().stream().collect(Collectors.toMap(entry -> {
            String newName = generateNewWfStepNameWithPrefix(inlinedStepEntry.getKey() + "_", workflow.getSteps().keySet(), newInlinedStepNames, entry.getKey());
            newInlinedStepNames.add(newName);
            if (!newName.equals(entry.getKey())) {
                entry.getValue().setName(newName);
                generatedSteps.forEach((generatedStepId, generatedStep) -> {
                    if (generatedStep.removeFollowing(entry.getKey())) {
                        generatedStep.addFollowing(newName);
                    }
                    if (generatedStep.removePreceding(entry.getKey())) {
                        generatedStep.addPreceding(newName);
                    }
                });
            }
            return newName;
        }, Map.Entry::getValue));
        // Find all root steps of the workflow and link them to the parent workflows
        final Map<String, WorkflowStep> rootInlinedSteps = generatedStepsWithNewNames.values().stream().filter(generatedStepWithNewName -> generatedStepWithNewName.getPrecedingSteps().isEmpty()).peek(rootInlinedStep -> rootInlinedStep.addAllPrecedings(inlinedStep.getPrecedingSteps())).collect(Collectors.toMap(WorkflowStep::getName, rootInlinedStep -> rootInlinedStep));
        inlinedStep.getPrecedingSteps().forEach(precedingStepName -> {
            WorkflowStep precedingStep = workflow.getSteps().get(precedingStepName);
            precedingStep.removeFollowing(inlinedStepName);
            precedingStep.addAllFollowings(rootInlinedSteps.keySet());
        });
        // Find all leaf steps of the workflow and link them to the parent workflows
        final Map<String, WorkflowStep> leafInlinedSteps = generatedStepsWithNewNames.values().stream().filter(generatedStepWithNewName -> generatedStepWithNewName.getOnSuccess().isEmpty()).peek(leafInlinedStep -> leafInlinedStep.addAllFollowings(inlinedStep.getOnSuccess())).collect(Collectors.toMap(WorkflowStep::getName, leafInlinedStep -> leafInlinedStep));
        inlinedStep.getOnSuccess().forEach(onSuccessStepName -> {
            WorkflowStep onSuccessStep = workflow.getSteps().get(onSuccessStepName);
            onSuccessStep.removePreceding(inlinedStepName);
            onSuccessStep.addAllPrecedings(leafInlinedSteps.keySet());
        });
        // Remove the inlined step and replace by other workflow's steps
        workflow.getSteps().remove(inlinedStepName);
        workflow.addAllSteps(generatedStepsWithNewNames);
    });
    // Check if the workflow contains inline activity event after processing
    boolean processedWorkflowContainsInline = workflow.getSteps().values().stream().anyMatch(step -> step.getActivity() instanceof InlineWorkflowActivity);
    if (processedWorkflowContainsInline) {
        // Recursively process inline workflow until no step is inline workflow
        processInlineWorkflow(workflowMap, workflow);
    }
}
Also used : NormativeComputeConstants(org.alien4cloud.tosca.normative.constants.NormativeComputeConstants) SetStateWorkflowActivity(org.alien4cloud.tosca.model.workflow.activities.SetStateWorkflowActivity) Workflow(org.alien4cloud.tosca.model.workflow.Workflow) DelegateWorkflowActivity(org.alien4cloud.tosca.model.workflow.activities.DelegateWorkflowActivity) NodeType(org.alien4cloud.tosca.model.types.NodeType) StringUtils(org.apache.commons.lang3.StringUtils) AlienUtils.safe(alien4cloud.utils.AlienUtils.safe) TopologyNavigationUtil(org.alien4cloud.tosca.utils.TopologyNavigationUtil) STOP(org.alien4cloud.tosca.normative.constants.NormativeWorkflowNameConstants.STOP) HashSet(java.util.HashSet) START(org.alien4cloud.tosca.normative.constants.NormativeWorkflowNameConstants.START) INSTALL(org.alien4cloud.tosca.normative.constants.NormativeWorkflowNameConstants.INSTALL) RelationshipWorkflowStep(org.alien4cloud.tosca.model.workflow.RelationshipWorkflowStep) InvalidNameException(alien4cloud.exception.InvalidNameException) InlineWorkflowActivity(org.alien4cloud.tosca.model.workflow.activities.InlineWorkflowActivity) Map(java.util.Map) Interface(org.alien4cloud.tosca.model.definitions.Interface) Operation(org.alien4cloud.tosca.model.definitions.Operation) Set(java.util.Set) TopologyContext(alien4cloud.paas.wf.TopologyContext) NodeWorkflowStep(org.alien4cloud.tosca.model.workflow.NodeWorkflowStep) Collectors(java.util.stream.Collectors) Maps(com.google.common.collect.Maps) CallOperationWorkflowActivity(org.alien4cloud.tosca.model.workflow.activities.CallOperationWorkflowActivity) NotFoundException(alien4cloud.exception.NotFoundException) NodeTemplate(org.alien4cloud.tosca.model.templates.NodeTemplate) UNINSTALL(org.alien4cloud.tosca.normative.constants.NormativeWorkflowNameConstants.UNINSTALL) Pattern(java.util.regex.Pattern) WorkflowStep(org.alien4cloud.tosca.model.workflow.WorkflowStep) ToscaTypeUtils.isOfType(org.alien4cloud.tosca.utils.ToscaTypeUtils.isOfType) RelationshipTemplate(org.alien4cloud.tosca.model.templates.RelationshipTemplate) InlineWorkflowActivity(org.alien4cloud.tosca.model.workflow.activities.InlineWorkflowActivity) RelationshipWorkflowStep(org.alien4cloud.tosca.model.workflow.RelationshipWorkflowStep) NodeWorkflowStep(org.alien4cloud.tosca.model.workflow.NodeWorkflowStep) WorkflowStep(org.alien4cloud.tosca.model.workflow.WorkflowStep) Workflow(org.alien4cloud.tosca.model.workflow.Workflow) NotFoundException(alien4cloud.exception.NotFoundException) Map(java.util.Map) HashSet(java.util.HashSet)

Example 2 with InlineWorkflowActivity

use of org.alien4cloud.tosca.model.workflow.activities.InlineWorkflowActivity in project alien4cloud by alien4cloud.

the class SemanticValidation method validate.

@Override
public List<AbstractWorkflowError> validate(TopologyContext topologyContext, Workflow workflow) throws WorkflowException {
    if (workflow.getSteps() == null || workflow.getSteps().isEmpty()) {
        return null;
    }
    List<AbstractWorkflowError> errors = Lists.newArrayList();
    for (WorkflowStep step : workflow.getSteps().values()) {
        if (step.getActivity() instanceof InlineWorkflowActivity) {
            // TODO when the tosca model is clear we should create InlineWorkflowStep
            String inlinedWorkflow = ((InlineWorkflowActivity) step.getActivity()).getInline();
            if (topologyContext.getTopology().getWorkflows() == null || !topologyContext.getTopology().getWorkflows().containsKey(inlinedWorkflow)) {
                errors.add(new InlinedWorkflowNotFoundError(step.getName(), inlinedWorkflow));
            }
        } else if (StringUtils.isEmpty(step.getTarget())) {
            errors.add(new UnknownNodeError(step.getName(), "undefined target in non inline workflow activity"));
        } else {
            String nodeId = step.getTarget();
            NodeTemplate nodeTemplate = null;
            if (topologyContext.getTopology().getNodeTemplates() != null) {
                nodeTemplate = topologyContext.getTopology().getNodeTemplates().get(nodeId);
            }
            if (nodeTemplate == null) {
                errors.add(new UnknownNodeError(step.getName(), nodeId));
            } else if (step instanceof RelationshipWorkflowStep) {
                RelationshipWorkflowStep relationshipWorkflowStep = (RelationshipWorkflowStep) step;
                String relationshipId = relationshipWorkflowStep.getTargetRelationship();
                if (nodeTemplate.getRelationships() == null || !nodeTemplate.getRelationships().containsKey(relationshipId)) {
                    errors.add(new UnknownRelationshipError(step.getName(), nodeId, relationshipId));
                }
            }
        // TODO: here we should check interface & operation
        }
    }
    return errors;
}
Also used : InlineWorkflowActivity(org.alien4cloud.tosca.model.workflow.activities.InlineWorkflowActivity) NodeTemplate(org.alien4cloud.tosca.model.templates.NodeTemplate) RelationshipWorkflowStep(org.alien4cloud.tosca.model.workflow.RelationshipWorkflowStep) WorkflowStep(org.alien4cloud.tosca.model.workflow.WorkflowStep) RelationshipWorkflowStep(org.alien4cloud.tosca.model.workflow.RelationshipWorkflowStep)

Example 3 with InlineWorkflowActivity

use of org.alien4cloud.tosca.model.workflow.activities.InlineWorkflowActivity in project alien4cloud by alien4cloud.

the class RemoveWorkflowProcessor method processWorkflowOperation.

@Override
protected void processWorkflowOperation(Csar csar, Topology topology, RemoveWorkflowOperation operation, Workflow workflow) {
    ensureNotStandard(workflow, "standard workflow <" + workflow.getName() + "> can not be removed");
    log.debug("removing workflow [ {} ] from topology [ {} ]", operation.getWorkflowName(), topology.getId());
    topology.getWorkflows().remove(operation.getWorkflowName());
    topology.getWorkflows().values().forEach(wf -> wf.getSteps().values().forEach(step -> {
        if (step.getActivity() instanceof InlineWorkflowActivity) {
            InlineWorkflowActivity inlineWorkflowActivity = (InlineWorkflowActivity) step.getActivity();
            if (inlineWorkflowActivity.getInline().equals(workflow.getName())) {
                throw new BadWorkflowOperationException("Workflow " + inlineWorkflowActivity.getInline() + " is inlined in workflow " + wf.getName() + " in step " + step.getName());
            }
        }
    }));
}
Also used : Component(org.springframework.stereotype.Component) Slf4j(lombok.extern.slf4j.Slf4j) RemoveWorkflowOperation(org.alien4cloud.tosca.editor.operations.workflow.RemoveWorkflowOperation) Csar(org.alien4cloud.tosca.model.Csar) InlineWorkflowActivity(org.alien4cloud.tosca.model.workflow.activities.InlineWorkflowActivity) Workflow(org.alien4cloud.tosca.model.workflow.Workflow) BadWorkflowOperationException(alien4cloud.paas.wf.exception.BadWorkflowOperationException) EditionContextManager(org.alien4cloud.tosca.editor.EditionContextManager) Topology(org.alien4cloud.tosca.model.templates.Topology) InlineWorkflowActivity(org.alien4cloud.tosca.model.workflow.activities.InlineWorkflowActivity) BadWorkflowOperationException(alien4cloud.paas.wf.exception.BadWorkflowOperationException)

Example 4 with InlineWorkflowActivity

use of org.alien4cloud.tosca.model.workflow.activities.InlineWorkflowActivity in project alien4cloud by alien4cloud.

the class WorkflowGraphUtils method isStepEmpty.

public static boolean isStepEmpty(WorkflowStep step, TopologyContext topologyContext) {
    // No activity
    if (step.getActivity() == null) {
        return true;
    }
    // Inline activity is never empty
    if (step.getActivity() instanceof DelegateWorkflowActivity || step.getActivity() instanceof SetStateWorkflowActivity || step.getActivity() instanceof InlineWorkflowActivity) {
        return false;
    }
    CallOperationWorkflowActivity callOperationWorkflowActivity = (CallOperationWorkflowActivity) step.getActivity();
    NodeTemplate nodeTemplate = topologyContext.getTopology().getNodeTemplates().get(step.getTarget());
    String stepInterfaceName = ToscaNormativeUtil.getLongInterfaceName(callOperationWorkflowActivity.getInterfaceName());
    String stepOperationName = callOperationWorkflowActivity.getOperationName();
    if (step instanceof NodeWorkflowStep) {
        return !hasImplementation(nodeTemplate, NodeType.class, topologyContext, stepInterfaceName, stepOperationName);
    } else if (step instanceof RelationshipWorkflowStep) {
        RelationshipWorkflowStep relationshipWorkflowStep = (RelationshipWorkflowStep) step;
        RelationshipTemplate relationshipTemplate = nodeTemplate.getRelationships().get(relationshipWorkflowStep.getTargetRelationship());
        return !hasImplementation(relationshipTemplate, RelationshipType.class, topologyContext, stepInterfaceName, stepOperationName);
    } else {
        return false;
    }
}
Also used : InlineWorkflowActivity(org.alien4cloud.tosca.model.workflow.activities.InlineWorkflowActivity) NodeTemplate(org.alien4cloud.tosca.model.templates.NodeTemplate) RelationshipTemplate(org.alien4cloud.tosca.model.templates.RelationshipTemplate) NodeType(org.alien4cloud.tosca.model.types.NodeType) SetStateWorkflowActivity(org.alien4cloud.tosca.model.workflow.activities.SetStateWorkflowActivity) NodeWorkflowStep(org.alien4cloud.tosca.model.workflow.NodeWorkflowStep) RelationshipWorkflowStep(org.alien4cloud.tosca.model.workflow.RelationshipWorkflowStep) DelegateWorkflowActivity(org.alien4cloud.tosca.model.workflow.activities.DelegateWorkflowActivity) CallOperationWorkflowActivity(org.alien4cloud.tosca.model.workflow.activities.CallOperationWorkflowActivity)

Example 5 with InlineWorkflowActivity

use of org.alien4cloud.tosca.model.workflow.activities.InlineWorkflowActivity in project alien4cloud by alien4cloud.

the class ToscaParserAlien200Test method parseTopologyTemplateWithInlineWorkflow.

@Test
public void parseTopologyTemplateWithInlineWorkflow() throws ParsingException {
    ParsingResult<ArchiveRoot> parsingResult = parser.parseFile(Paths.get(getRootDirectory(), "tosca-topology-template-inline-workflow.yml"));
    assertFalse(parsingResult.getResult().getTopology().getWorkflows().isEmpty());
    assertNotNull(parsingResult.getResult().getTopology().getWorkflows().get("install"));
    Workflow wf = parsingResult.getResult().getTopology().getWorkflows().get("install");
    assertEquals(1, wf.getSteps().get("Compute_install_0").getActivities().size());
    assertTrue(wf.getSteps().get("Compute_install_0").getActivities().get(0) instanceof InlineWorkflowActivity);
    InlineWorkflowActivity activity = (InlineWorkflowActivity) wf.getSteps().get("Compute_install_0").getActivities().get(0);
    assertTrue(activity.getInline().equals("my_custom_wf"));
    WorkflowUtils.processInlineWorkflows(parsingResult.getResult().getTopology().getWorkflows());
    assertFalse(wf.getSteps().containsKey("Compute_install_0"));
    assertTrue(wf.getSteps().containsKey("Compute_install_0_Compute_stop"));
    assertTrue(wf.getSteps().containsKey("Compute_install_0_Compute_uninstall"));
    assertTrue(wf.getSteps().containsKey("Some_other_inline_Compute_stop"));
    assertTrue(wf.getSteps().containsKey("Some_other_inline_Compute_uninstall"));
    assertTrue(wf.getSteps().get("Compute_install").getOnSuccess().contains("Compute_install_0_Compute_stop"));
    assertTrue(wf.getSteps().get("Compute_install_0_Compute_stop").getPrecedingSteps().contains("Compute_install"));
    assertEquals(1, wf.getSteps().get("Compute_install").getOnSuccess().size());
    assertEquals(0, wf.getSteps().get("Compute_install").getPrecedingSteps().size());
    assertEquals(1, wf.getSteps().get("Compute_install_0_Compute_stop").getPrecedingSteps().size());
    assertFalse(wf.getSteps().get("Compute_install").getOnSuccess().contains("Compute_install_0_Compute_uninstall"));
    assertFalse(wf.getSteps().get("Compute_install_0_Compute_uninstall").getPrecedingSteps().contains("Compute_install"));
    assertTrue(wf.getSteps().get("Compute_install_0_Compute_stop").getOnSuccess().contains("Compute_install_0_Compute_uninstall"));
    assertTrue(wf.getSteps().get("Compute_install_0_Compute_uninstall").getPrecedingSteps().contains("Compute_install_0_Compute_stop"));
    assertEquals(1, wf.getSteps().get("Compute_install_0_Compute_stop").getOnSuccess().size());
    assertEquals(1, wf.getSteps().get("Compute_install_0_Compute_uninstall").getPrecedingSteps().size());
    assertEquals(1, wf.getSteps().get("Compute_install_0_Compute_uninstall").getOnSuccess().size());
    assertTrue(wf.getSteps().get("Compute_install_0_Compute_uninstall").getOnSuccess().contains("Compute_start"));
    assertTrue(wf.getSteps().get("Compute_start").getPrecedingSteps().contains("Compute_install_0_Compute_uninstall"));
    assertTrue(wf.getSteps().get("Some_other_inline_Compute_stop").getOnSuccess().contains("Some_other_inline_Compute_uninstall"));
    assertTrue(wf.getSteps().get("Some_other_inline_Compute_uninstall").getPrecedingSteps().contains("Some_other_inline_Compute_stop"));
    assertTrue(wf.getSteps().get("inception_inline_inception_inline_Compute_stop").getOnSuccess().contains("inception_inline_inception_inline_Compute_uninstall"));
    assertTrue(wf.getSteps().get("inception_inline_inception_inline_Compute_uninstall").getPrecedingSteps().contains("inception_inline_inception_inline_Compute_stop"));
}
Also used : InlineWorkflowActivity(org.alien4cloud.tosca.model.workflow.activities.InlineWorkflowActivity) ArchiveRoot(alien4cloud.tosca.model.ArchiveRoot) Workflow(org.alien4cloud.tosca.model.workflow.Workflow) Test(org.junit.Test)

Aggregations

InlineWorkflowActivity (org.alien4cloud.tosca.model.workflow.activities.InlineWorkflowActivity)5 NodeTemplate (org.alien4cloud.tosca.model.templates.NodeTemplate)3 RelationshipWorkflowStep (org.alien4cloud.tosca.model.workflow.RelationshipWorkflowStep)3 Workflow (org.alien4cloud.tosca.model.workflow.Workflow)3 RelationshipTemplate (org.alien4cloud.tosca.model.templates.RelationshipTemplate)2 NodeType (org.alien4cloud.tosca.model.types.NodeType)2 NodeWorkflowStep (org.alien4cloud.tosca.model.workflow.NodeWorkflowStep)2 WorkflowStep (org.alien4cloud.tosca.model.workflow.WorkflowStep)2 CallOperationWorkflowActivity (org.alien4cloud.tosca.model.workflow.activities.CallOperationWorkflowActivity)2 DelegateWorkflowActivity (org.alien4cloud.tosca.model.workflow.activities.DelegateWorkflowActivity)2 SetStateWorkflowActivity (org.alien4cloud.tosca.model.workflow.activities.SetStateWorkflowActivity)2 InvalidNameException (alien4cloud.exception.InvalidNameException)1 NotFoundException (alien4cloud.exception.NotFoundException)1 TopologyContext (alien4cloud.paas.wf.TopologyContext)1 BadWorkflowOperationException (alien4cloud.paas.wf.exception.BadWorkflowOperationException)1 ArchiveRoot (alien4cloud.tosca.model.ArchiveRoot)1 AlienUtils.safe (alien4cloud.utils.AlienUtils.safe)1 Maps (com.google.common.collect.Maps)1 HashSet (java.util.HashSet)1 Map (java.util.Map)1