use of org.alien4cloud.tosca.model.workflow.Workflow in project alien4cloud by alien4cloud.
the class ToscaParserAlien200Test method parseTopologyTemplateWithRelationshipWorkflow.
@Test
public void parseTopologyTemplateWithRelationshipWorkflow() throws ParsingException {
Mockito.reset(csarRepositorySearchService);
Mockito.when(csarRepositorySearchService.getArchive("tosca-normative-types", "1.0.0-ALIEN14")).thenReturn(Mockito.mock(Csar.class));
NodeType mockCompute = new NodeType();
mockCompute.setElementId(NormativeComputeConstants.COMPUTE_TYPE);
mockCompute.setArchiveName("tosca-normative-types");
mockCompute.setArchiveVersion("1.0.0-ALIEN14");
Mockito.when(csarRepositorySearchService.getElementInDependencies(Mockito.eq(NodeType.class), Mockito.eq(NormativeComputeConstants.COMPUTE_TYPE), Mockito.any(Set.class))).thenReturn(mockCompute);
RelationshipType mockHostedOn = Mockito.mock(RelationshipType.class);
Mockito.when(mockHostedOn.getElementId()).thenReturn(NormativeRelationshipConstants.HOSTED_ON);
Mockito.when(csarRepositorySearchService.getElementInDependencies(Mockito.eq(RelationshipType.class), Mockito.eq(NormativeRelationshipConstants.HOSTED_ON), Mockito.any(Set.class))).thenReturn(mockHostedOn);
ParsingResult<ArchiveRoot> parsingResult = parser.parseFile(Paths.get(getRootDirectory(), "tosca-topology-template-relationship-workflow.yml"));
Assert.assertFalse(parsingResult.getResult().getTopology().getWorkflows().isEmpty());
Assert.assertTrue(parsingResult.getResult().getTopology().getWorkflows().get("install") != null);
Workflow wf = parsingResult.getResult().getTopology().getWorkflows().get("install");
WorkflowStep relStep = wf.getSteps().get("OracleJDK_hostedOnComputeHost_pre_configure_source");
Assert.assertNotNull(relStep);
Assert.assertTrue(relStep instanceof RelationshipWorkflowStep);
RelationshipWorkflowStep relationshipWorkflowStep = (RelationshipWorkflowStep) relStep;
Assert.assertNotNull(relationshipWorkflowStep.getTargetRelationship());
Assert.assertNotNull(relationshipWorkflowStep.getSourceHostId());
Assert.assertNotNull(relationshipWorkflowStep.getTargetHostId());
WorkflowStep nStep = wf.getSteps().get("OracleJDK_start");
Assert.assertNotNull(nStep);
Assert.assertTrue(nStep instanceof NodeWorkflowStep);
NodeWorkflowStep nodeWorkflowStep = (NodeWorkflowStep) nStep;
Assert.assertNotNull(nodeWorkflowStep.getHostId());
}
use of org.alien4cloud.tosca.model.workflow.Workflow in project alien4cloud by alien4cloud.
the class ToscaParserAlien200Test method parseTopologyTemplateWithRelationshipWorkflowMultipleActivities.
@Test
public void parseTopologyTemplateWithRelationshipWorkflowMultipleActivities() throws ParsingException {
ParsingResult<ArchiveRoot> parsingResult = parser.parseFile(Paths.get(getRootDirectory(), "tosca-topology-template-workflow-relationship-operation.yml"));
assertFalse(parsingResult.getResult().getTopology().getWorkflows().isEmpty());
assertNotNull(parsingResult.getResult().getTopology().getWorkflows().get("install"));
Workflow wf = parsingResult.getResult().getTopology().getWorkflows().get("install");
assertNotNull(wf.getSteps().get("SoftwareComponent_hostedOnComputeHost_pre_configure_source"));
WorkflowStep step = wf.getSteps().get("SoftwareComponent_hostedOnComputeHost_pre_configure_source");
assertTrue(step instanceof RelationshipWorkflowStep);
RelationshipWorkflowStep relStep = (RelationshipWorkflowStep) step;
assertTrue(relStep.getTarget().equals("SoftwareComponent"));
assertTrue(relStep.getTargetRelationship().equals("hostedOnComputeHost"));
assertTrue(relStep.getOperationHost().equals("SOURCE"));
assertEquals(1, relStep.getActivities().size());
assertEquals(1, relStep.getOnSuccess().size());
assertTrue(relStep.getOnSuccess().contains("SoftwareComponent_hostedOnComputeHost_pre_configure_source_0"));
// test the second step, create to split activities into steps
WorkflowStep step_0 = wf.getSteps().get("SoftwareComponent_hostedOnComputeHost_pre_configure_source_0");
assertTrue(step_0 instanceof RelationshipWorkflowStep);
RelationshipWorkflowStep relStep_0 = (RelationshipWorkflowStep) step_0;
assertTrue(relStep_0.getTarget().equals("SoftwareComponent"));
assertTrue(relStep_0.getTargetRelationship().equals("hostedOnComputeHost"));
assertTrue(relStep_0.getOperationHost().equals("SOURCE"));
assertEquals(1, relStep_0.getActivities().size());
assertEquals(1, relStep_0.getOnSuccess().size());
assertTrue(relStep_0.getOnSuccess().contains("SoftwareComponent_install"));
}
use of org.alien4cloud.tosca.model.workflow.Workflow 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.Workflow in project alien4cloud by alien4cloud.
the class DefaultWorkflowBuilder method addRelationship.
@Override
public void addRelationship(Workflow workflow, String nodeId, NodeTemplate nodeTemplate, String relationshipName, RelationshipTemplate relationshipTemplate, TopologyContext topologyContext) {
boolean sourceIsNative = WorkflowUtils.isNativeOrSubstitutionNode(nodeId, topologyContext);
boolean targetIsNative = WorkflowUtils.isNativeOrSubstitutionNode(relationshipTemplate.getTarget(), topologyContext);
if (!sourceIsNative || !targetIsNative) {
// source or target is native or abstract
// for native types we don't care about relation ships in workflows
RelationshipDeclarativeWorkflow relationshipDeclarativeWorkflow = defaultDeclarativeWorkflows.getRelationshipWorkflows().get(workflow.getName());
// only trigger this method if it's a default workflow
if (relationshipDeclarativeWorkflow != null) {
Map<String, WorkflowStep> relationshipOperationSteps = safe(relationshipDeclarativeWorkflow.getOperations()).entrySet().stream().filter(operationEntry -> !targetIsNative || operationEntry.getValue().getOperationHost() == RelationshipOperationHost.SOURCE).filter(operationEntry -> !sourceIsNative || operationEntry.getValue().getOperationHost() == RelationshipOperationHost.TARGET).collect(Collectors.toMap(Map.Entry::getKey, operationEntry -> WorkflowUtils.addRelationshipOperationStep(workflow, nodeId, relationshipTemplate.getName(), ToscaRelationshipLifecycleConstants.CONFIGURE_SHORT, operationEntry.getKey(), operationEntry.getValue().getOperationHost().toString())));
Steps sourceSteps = new Steps(workflow, nodeId);
Steps targetSteps = new Steps(workflow, relationshipTemplate.getTarget());
safe(relationshipDeclarativeWorkflow.getOperations()).forEach((relationshipOperationName, relationshipOperationDependencies) -> {
WorkflowStep currentStep = relationshipOperationSteps.get(relationshipOperationName);
if (currentStep != null) {
// It might be filtered if source or target is native
declareStepDependencies(relationshipOperationDependencies.getSource(), currentStep, sourceSteps);
declareStepDependencies(relationshipOperationDependencies.getTarget(), currentStep, targetSteps);
declareStepDependencies(relationshipOperationDependencies, currentStep, new Steps(relationshipOperationSteps, Collections.emptyMap(), null));
}
});
RelationshipWeavingDeclarativeWorkflow relationshipWeavingDeclarativeWorkflow = getRelationshipWeavingDeclarativeWorkflow(relationshipTemplate.getType(), topologyContext, workflow.getName());
declareWeaving(relationshipWeavingDeclarativeWorkflow.getSource(), sourceSteps, targetSteps);
declareWeaving(relationshipWeavingDeclarativeWorkflow.getTarget(), targetSteps, sourceSteps);
}
} else {
// both source and target are native then the relationship does not have any operation implemented
// we will just try to declare weaving between source node operations and target node operations
Steps sourceSteps = new Steps(workflow, nodeId);
Steps targetSteps = new Steps(workflow, relationshipTemplate.getTarget());
RelationshipWeavingDeclarativeWorkflow relationshipWeavingDeclarativeWorkflow = getRelationshipWeavingDeclarativeWorkflow(relationshipTemplate.getType(), topologyContext, workflow.getName());
declareWeaving(relationshipWeavingDeclarativeWorkflow.getSource(), sourceSteps, targetSteps);
declareWeaving(relationshipWeavingDeclarativeWorkflow.getTarget(), targetSteps, sourceSteps);
}
}
use of org.alien4cloud.tosca.model.workflow.Workflow 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++;
}
}
Aggregations