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