aboutsummaryrefslogtreecommitdiffstats
path: root/ms/blueprintsprocessor/modules/blueprints/blueprint-core/src/main/kotlin/org/onap
diff options
context:
space:
mode:
authorJozsef Csongvai <jozsef.csongvai@bell.ca>2021-03-14 19:13:35 -0400
committerKAPIL SINGAL <ks220y@att.com>2021-03-19 19:47:40 +0000
commit8ee06cef9a605d8220a6c5ebafc5da8eb7491f8d (patch)
treee3f3a6892b23b014f8f51995eb326ad1143f2fb6 /ms/blueprintsprocessor/modules/blueprints/blueprint-core/src/main/kotlin/org/onap
parent95de87b0f902a55f1313403a5954b394f022e519 (diff)
Prohibit cycles in imperative workflows
Issue-ID: CCSDK-3221 Change-Id: I767003dde40c0fc53a673c4a41cb2430624d7b04 Signed-off-by: Jozsef Csongvai <jozsef.csongvai@bell.ca>
Diffstat (limited to 'ms/blueprintsprocessor/modules/blueprints/blueprint-core/src/main/kotlin/org/onap')
-rw-r--r--ms/blueprintsprocessor/modules/blueprints/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/GraphExtensionFunctions.kt37
-rw-r--r--ms/blueprintsprocessor/modules/blueprints/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/data/BlueprintGraph.kt6
2 files changed, 30 insertions, 13 deletions
diff --git a/ms/blueprintsprocessor/modules/blueprints/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/GraphExtensionFunctions.kt b/ms/blueprintsprocessor/modules/blueprints/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/GraphExtensionFunctions.kt
index 5995a8a9e..26f74669e 100644
--- a/ms/blueprintsprocessor/modules/blueprints/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/GraphExtensionFunctions.kt
+++ b/ms/blueprintsprocessor/modules/blueprints/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/GraphExtensionFunctions.kt
@@ -33,7 +33,7 @@ fun String.toGraph(): Graph {
if (!startsWith('[') || !endsWith(']')) {
throw IllegalArgumentException("Expected string starting '[' and ending with ']' but it was '$")
}
- val tokens = substring(1, length - 1).split(", ").map { it.split(graphTokenSeparators) }
+ val tokens = substring(1, length - 1).replace("\n", "").split(", ").map { it.trim().split(graphTokenSeparators) }
val nodes = tokens.flatMap { it.take(2) }.toCollection(LinkedHashSet())
val edges = tokens.filter { it.size == 3 }.map { Graph.TermForm.Term(it[0], it[1], EdgeLabel.valueOf(it[2])) }
return Graph.labeledDirectedTerms(Graph.TermForm(nodes, edges))
@@ -41,7 +41,7 @@ fun String.toGraph(): Graph {
fun Graph.toAdjacencyList(): Graph.AdjacencyList<String, EdgeLabel> {
val entries = nodes.values.map { node ->
- val links = node.edges.map { Graph.AdjacencyList.Link(it.target(node).id, it.label) }
+ val links = node.edges.map { Graph.AdjacencyList.Link(it.target.id, it.label) }
Graph.AdjacencyList.Entry(node = node.id, links = links)
}
return Graph.AdjacencyList(entries)
@@ -54,14 +54,33 @@ fun Graph.findAllPaths(from: String, to: String, path: List<String> = emptyList(
.flatMap { findAllPaths(it.id, to, path + from) }
}
-fun Graph.findCycles(node: String): List<List<String>> {
- fun findCycles(path: List<String>): List<List<String>> {
- if (path.size > 3 && path.first() == path.last()) return listOf(path)
- return nodes[path.last()]!!.neighbors()
- .filterNot { path.tail().contains(it.id) }
- .flatMap { findCycles(path + it.id) }
+fun Graph.isAcyclic(): Boolean {
+ val startNodes = startNodes()
+ if (startNodes.isEmpty())
+ return false
+
+ val adj: Map<String, Set<String>> = toAdjacencyList().entries
+ .associate { it.node to it.links }
+ .mapValues { it.value.map { x -> x.node }.toSet() }
+
+ fun hasCycle(node: String, visited: MutableSet<String> = mutableSetOf()): Boolean {
+ if (visited.contains(node))
+ return true
+ visited.add(node)
+
+ if (adj[node]!!.isEmpty()) {
+ visited.remove(node)
+ return false
+ }
+
+ if (adj[node]!!.any { hasCycle(it, visited) })
+ return true
+
+ visited.remove(node)
+ return false
}
- return findCycles(listOf(node))
+
+ return startNodes.none { n -> hasCycle(n.id) }
}
fun Graph.startNodes() = this.nodes.values.filter {
diff --git a/ms/blueprintsprocessor/modules/blueprints/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/data/BlueprintGraph.kt b/ms/blueprintsprocessor/modules/blueprints/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/data/BlueprintGraph.kt
index b833db755..bc6cbe426 100644
--- a/ms/blueprintsprocessor/modules/blueprints/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/data/BlueprintGraph.kt
+++ b/ms/blueprintsprocessor/modules/blueprints/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/data/BlueprintGraph.kt
@@ -97,10 +97,10 @@ class Graph {
val edges: MutableList<Edge> = ArrayList()
- fun neighbors(): List<Node> = edges.map { edge -> edge.target(this) }
+ fun neighbors(): List<Node> = edges.map { it.target }
fun neighbors(label: EdgeLabel): List<Node> = edges.filter { it.label == label }
- .map { edge -> edge.target(this) }
+ .map { it.target }
fun labelEdges(label: EdgeLabel): List<Edge> = edges.filter { it.label == label }
@@ -114,8 +114,6 @@ class Graph {
var status: EdgeStatus = EdgeStatus.NOT_STARTED
) {
- fun target(node: Node): Node = target
-
fun equivalentTo(other: Edge) =
(source == other.source && target == other.target) ||
(source == other.target && target == other.source)