2626import org .apache .logging .log4j .Logger ;
2727
2828import javax .inject .Inject ;
29- import java .util .ArrayList ;
3029import java .util .Collections ;
3130import java .util .HashMap ;
3231import java .util .HashSet ;
32+ import java .util .LinkedHashMap ;
3333import java .util .List ;
3434import java .util .Map ;
3535import java .util .Set ;
@@ -52,53 +52,41 @@ public class ToscaOrchestrator {
5252 public void deployIacTemplate (String iacTemplateContent ) {
5353 logger .debug ("Parsing service template" );
5454 ToscaServiceTemplate serviceTemplate = toscaParser .parseServiceTemplate (iacTemplateContent , toscaProfile , null );
55- Map <ToscaNodeTemplate , CompletableFuture <String >> provisioningTasksFutures = createProvisioningTasksFutures (serviceTemplate );
55+ Map <String , CompletableFuture <String >> provisioningTasksFutures = createProvisioningTasksFutures (serviceTemplate );
5656 CompletableFuture <Void > serviceTemplateFeature = CompletableFuture .allOf (provisioningTasksFutures .values ().toArray (new CompletableFuture [0 ]));
5757 serviceTemplateFeature .join ();
5858 }
5959
60- private Map <ToscaNodeTemplate , CompletableFuture <String >> createProvisioningTasksFutures (ToscaServiceTemplate serviceTemplate ) {
60+ private Map <String , CompletableFuture <String >> createProvisioningTasksFutures (ToscaServiceTemplate serviceTemplate ) {
6161 logger .debug ("Creating provisioning tasks futures" );
62- Map <ToscaNodeTemplate , CompletableFuture <String >> futures = new HashMap <>();
63- Map <String , Set <ToscaNodeTemplate >> dependencyGraph = serviceTemplate .getDependencyGraph ();
64-
65- List <String > nodesWithoutDependencies = dependencyGraph .keySet ().stream ().filter (node -> dependencyGraph .get (node ).isEmpty ()).collect (Collectors .toList ());
66- logger .debug ("Nodes without dependencies: " + nodesWithoutDependencies );
67- nodesWithoutDependencies .forEach (node -> {
62+ Map <String , CompletableFuture <String >> futures = new HashMap <>();
63+ getServiceTemplateTopologicalSort (serviceTemplate ).forEach ((node , dependencies ) -> {
6864 ToscaNodeTemplate nodeTemplate = serviceTemplate .getNodeTemplates ().get (node );
69- CompletableFuture <String > taskFuture = buildNodeProvisioningTask (nodeTemplate );
70- futures .put (nodeTemplate , taskFuture );
71- });
72- logger .debug ("Built all the features for the nodes without dependencies." );
73-
74- logger .debug ("Service template size: " + serviceTemplate .getNodeTemplates ().size ());
75- while (futures .size () < serviceTemplate .getNodeTemplates ().size ()) {
76- logger .debug ("Futures size: " + futures .size ());
77- List <ToscaNodeTemplate > nodesWhoseDependenciesAlreadyHaveFutures = dependencyGraph .keySet ().stream ()
78- .filter (node -> !dependencyGraph .get (node ).isEmpty () && dependencyGraph .get (node ).stream ().allMatch (futures ::containsKey ))
79- .map (node -> serviceTemplate .getNodeTemplates ().get (node ))
80- .collect (Collectors .toList ());
81-
82- for (ToscaNodeTemplate node : nodesWhoseDependenciesAlreadyHaveFutures ) {
83- CompletableFuture <?>[] dependencies = dependencyGraph .get (node .getName ()).stream ().map (futures ::get ).toArray (CompletableFuture []::new );
84- CompletableFuture <String > taskFuture = CompletableFuture .allOf (dependencies ).thenCompose (v -> {
85- logger .debug ("All dependencies of the node [" + node .getName () + "] are ready." );
65+ CompletableFuture <String > taskFuture ;
66+ if (dependencies .isEmpty ()) {
67+ logger .debug ("Node [{}] has no dependencies. Building its provisioning task." , node );
68+ taskFuture = buildNodeProvisioningTask (nodeTemplate );
69+ } else {
70+ CompletableFuture <?>[] dependenciesFutures = dependencies .stream ()
71+ .map ((dep ) -> futures .get (dep .getName ())).toArray (CompletableFuture []::new );
72+ taskFuture = CompletableFuture .allOf (dependenciesFutures ).thenCompose (v -> {
73+ logger .debug ("All dependencies of the node [{}] are ready." , node );
8674 logger .debug ("Here you'll be able to resolve the unresolved properties by get property and get attribute" );
87- return buildNodeProvisioningTask (node );
75+ return buildNodeProvisioningTask (nodeTemplate );
8876 });
89-
90- futures .put (node , taskFuture );
9177 }
92- }
78+
79+ futures .put (node , taskFuture );
80+ });
9381
9482 return futures ;
9583 }
9684
9785 // O(|V|+|E|)
98- private List <String > getServiceTemplateTopologicalSort (ToscaServiceTemplate serviceTemplate ) {
86+ private LinkedHashMap <String , Set <ToscaNodeTemplate >> getServiceTemplateTopologicalSort (ToscaServiceTemplate serviceTemplate ) {
87+ LinkedHashMap <String , Set <ToscaNodeTemplate >> topologicalSort = new LinkedHashMap <>();
9988 Set <String > visitedNodes = new HashSet <>();
10089 Set <String > branchAncestors = new HashSet <>();
101- List <String > topologicalSort = new ArrayList <>();
10290 for (ToscaNodeTemplate node : serviceTemplate .getNodeTemplates ().values ()) {
10391 if (!visitedNodes .contains (node .getName ())) {
10492 depthFirstSearch (topologicalSort , node .getName (), serviceTemplate .getDependencyGraph (), branchAncestors , visitedNodes );
@@ -107,7 +95,7 @@ private List<String> getServiceTemplateTopologicalSort(ToscaServiceTemplate serv
10795 return topologicalSort ;
10896 }
10997
110- private void depthFirstSearch (List <String > topologicalSort , String node , Map <String , Set <ToscaNodeTemplate >> graph , Set <String > branchAncestors , Set <String > visitedNodes ) {
98+ private void depthFirstSearch (LinkedHashMap <String , Set < ToscaNodeTemplate > > topologicalSort , String node , Map <String , Set <ToscaNodeTemplate >> graph , Set <String > branchAncestors , Set <String > visitedNodes ) {
11199 visitedNodes .add (node );
112100 branchAncestors .add (node );
113101 for (ToscaNodeTemplate dependency : graph .getOrDefault (node , Collections .emptySet ())) {
@@ -121,7 +109,7 @@ private void depthFirstSearch(List<String> topologicalSort, String node, Map<Str
121109 }
122110
123111 branchAncestors .remove (node );
124- topologicalSort .add (node );
112+ topologicalSort .put (node , graph . getOrDefault ( node , Collections . emptySet ()) );
125113 }
126114
127115 private CompletableFuture <String > buildNodeProvisioningTask (ToscaNodeTemplate nodeTemplate ) {
0 commit comments