use of org.alien4cloud.tosca.model.workflow.WorkflowStep in project alien4cloud by alien4cloud.
the class WorkflowSimplifyService method removeUnnecessarySteps.
private void removeUnnecessarySteps(TopologyContext topologyContext, Workflow workflow, SubGraph subGraph) {
LastPathGraphConsumer consumer = new LastPathGraphConsumer();
subGraph.browse(consumer);
if (consumer.getAllNodes().isEmpty()) {
// This is really strange as we have a node template without any workflow step
return;
}
Set<String> allStepIds = consumer.getAllNodes().keySet();
List<WorkflowStep> sortedByWeightsSteps = consumer.getLastPath();
List<Integer> nonEmptyIndexes = new ArrayList<>();
LinkedHashSet<Integer> emptyIndexes = new LinkedHashSet<>();
int lastIndexWithOutgoingLinks = -1;
int firstIndexWithOutgoingLinks = -1;
for (int i = 0; i < sortedByWeightsSteps.size(); i++) {
WorkflowStep step = sortedByWeightsSteps.get(i);
if (!allStepIds.containsAll(step.getOnSuccess())) {
lastIndexWithOutgoingLinks = i;
if (firstIndexWithOutgoingLinks == -1) {
firstIndexWithOutgoingLinks = i;
}
}
if (!WorkflowGraphUtils.isStepEmpty(step, topologyContext)) {
nonEmptyIndexes.add(i);
} else {
emptyIndexes.add(i);
}
}
Map<Integer, Integer> emptyIndexToFollowingSubstituteMap = new HashMap<>();
Map<Integer, Integer> emptyIndexToPrecedingSubstituteMap = new HashMap<>();
for (Integer emptyIndex : emptyIndexes) {
Optional<Integer> substitutePrecedingIndex = nonEmptyIndexes.stream().filter(nonEmptyIndex -> nonEmptyIndex > emptyIndex).findFirst();
Optional<Integer> substituteFollowingIndex = nonEmptyIndexes.stream().filter(nonEmptyIndex -> nonEmptyIndex < emptyIndex).reduce((first, second) -> second);
substitutePrecedingIndex.ifPresent(index -> emptyIndexToPrecedingSubstituteMap.put(emptyIndex, index));
substituteFollowingIndex.ifPresent(index -> emptyIndexToFollowingSubstituteMap.put(emptyIndex, index));
}
for (int index = 0; index < sortedByWeightsSteps.size(); index++) {
WorkflowStep step = sortedByWeightsSteps.get(index);
boolean stepIsEmpty = emptyIndexes.contains(index);
Integer followingSubstitutedIndex = emptyIndexToFollowingSubstituteMap.get(index);
Integer precedingSubstitutedIndex = emptyIndexToPrecedingSubstituteMap.get(index);
if (stepIsEmpty) {
if (followingSubstitutedIndex == null && !allStepIds.containsAll(step.getOnSuccess())) {
// the step is empty but no substitute for following links, it means that before the step there are no non empty steps
if (firstIndexWithOutgoingLinks >= 0 && firstIndexWithOutgoingLinks <= index) {
// the step or before the step, outgoing links exist out of the sub graph so we should not remove it, because it will impact the
// structure of the graph
emptyIndexes.remove(index);
continue;
}
}
if (precedingSubstitutedIndex == null && !allStepIds.containsAll(step.getPrecedingSteps())) {
// the step is empty but no substitute for preceding links, it means that after the step there are no non empty steps
if (lastIndexWithOutgoingLinks >= index) {
// the step or after the step, outgoing links exist out of the sub graph so we should not remove it, because it will impact the
// structure of the graph
emptyIndexes.remove(index);
continue;
}
}
// Empty so the step will be removed, so unlink all
for (String following : step.getOnSuccess()) {
workflow.getSteps().get(following).removePreceding(step.getName());
}
for (String preceding : step.getPrecedingSteps()) {
workflow.getSteps().get(preceding).removeFollowing(step.getName());
}
if (followingSubstitutedIndex != null) {
WorkflowStep substitutedFollowingStep = sortedByWeightsSteps.get(followingSubstitutedIndex);
for (String following : step.getOnSuccess()) {
workflow.getSteps().get(following).addPreceding(substitutedFollowingStep.getName());
}
// Copy all links to the substituted node
substitutedFollowingStep.addAllFollowings(step.getOnSuccess());
}
if (precedingSubstitutedIndex != null) {
WorkflowStep substitutedPrecedingStep = sortedByWeightsSteps.get(precedingSubstitutedIndex);
for (String preceding : step.getPrecedingSteps()) {
workflow.getSteps().get(preceding).addFollowing(substitutedPrecedingStep.getName());
}
substitutedPrecedingStep.addAllPrecedings(step.getPrecedingSteps());
}
}
}
int index = 0;
Iterator<WorkflowStep> stepIterator = sortedByWeightsSteps.iterator();
while (stepIterator.hasNext()) {
WorkflowStep step = stepIterator.next();
if (emptyIndexes.contains(index)) {
stepIterator.remove();
workflow.getSteps().remove(step.getName());
}
index++;
}
}
use of org.alien4cloud.tosca.model.workflow.WorkflowStep 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.WorkflowStep in project alien4cloud by alien4cloud.
the class WorkflowStepDefinitions method the_workflow_step_is_preceded_by.
@When("^The workflow step \"(.*?)\" is preceded by: (.*)$")
public void the_workflow_step_is_preceded_by(String stepId, List<String> predecesors) throws Throwable {
String topologyResponseText = Context.getInstance().getRestResponse();
RestResponse<TopologyDTO> topologyResponse = JsonUtil.read(topologyResponseText, TopologyDTO.class, Context.getJsonMapper());
String workflowName = Context.getInstance().getCurrentWorkflowName();
Workflow workflow = topologyResponse.getData().getTopology().getWorkflows().get(workflowName);
WorkflowStep step = workflow.getSteps().get(stepId);
Set<String> actualPredecessors = step.getPrecedingSteps();
assertNotNull(actualPredecessors);
assertEquals(predecesors.size(), actualPredecessors.size());
for (String expectedPredecessor : predecesors) {
// we just remove the surrounding quotes
String predecessor = expectedPredecessor.substring(1, expectedPredecessor.length() - 1);
assertTrue(actualPredecessors.contains(predecessor));
}
}
use of org.alien4cloud.tosca.model.workflow.WorkflowStep in project alien4cloud by alien4cloud.
the class WorkflowStepDefinitions method the_workflow_step_has_no_followers.
@Then("^The workflow step \"(.*?)\" has no followers$")
public void the_workflow_step_has_no_followers(String stepId) throws Throwable {
String topologyResponseText = Context.getInstance().getRestResponse();
RestResponse<TopologyDTO> topologyResponse = JsonUtil.read(topologyResponseText, TopologyDTO.class, Context.getJsonMapper());
String workflowName = Context.getInstance().getCurrentWorkflowName();
Workflow workflow = topologyResponse.getData().getTopology().getWorkflows().get(workflowName);
WorkflowStep step = workflow.getSteps().get(stepId);
assertTrue(step.getOnSuccess() == null || step.getOnSuccess().isEmpty());
}
use of org.alien4cloud.tosca.model.workflow.WorkflowStep in project alien4cloud by alien4cloud.
the class WorkflowStepDefinitions method the_workflow_step_has_no_predecessors.
@Then("^The workflow step \"(.*?)\" has no predecessors$")
public void the_workflow_step_has_no_predecessors(String stepId) throws Throwable {
String topologyResponseText = Context.getInstance().getRestResponse();
RestResponse<TopologyDTO> topologyResponse = JsonUtil.read(topologyResponseText, TopologyDTO.class, Context.getJsonMapper());
String workflowName = Context.getInstance().getCurrentWorkflowName();
Workflow workflow = topologyResponse.getData().getTopology().getWorkflows().get(workflowName);
WorkflowStep step = workflow.getSteps().get(stepId);
assertTrue(step.getPrecedingSteps() == null || step.getPrecedingSteps().isEmpty());
}
Aggregations