kytos-ng / pathfinder

Kytos main path finder Network Application (NApp)
https://kytos-ng.github.io/api/pathfinder.html
MIT License
0 stars 7 forks source link

negative metadata filter on ownership attribute #63

Closed italovalcy closed 9 months ago

italovalcy commented 10 months ago

we currently have the metadata filter on ownership attribute based on a predefined function contain. It would be nice if we have similar behavior but using the function not contain. The default value for links not defining the ownership attribute should be an empty dict. In other words, if the link does not define the ownership, it obviously will not match the not_ownwership filter.

Refs: https://github.com/kytos-ng/kytos/blob/master/docs/blueprints/EP023-2.rst Refs: https://github.com/kytos-ng/kytos/blob/master/docs/blueprints/EP023.rst

italovalcy commented 10 months ago

here is one possibility for this feature:

diff --git a/graph.py b/graph.py
index 17de01a..a507a46 100644
--- a/graph.py
+++ b/graph.py
@@ -6,6 +6,7 @@ from itertools import combinations, islice
 from kytos.core import log
 from kytos.core.common import EntityStatus
 from napps.kytos.pathfinder.utils import (filter_ge, filter_in, filter_le,
+                                          filter_not_in,
                                           lazy_filter, nx_edge_data_delay,
                                           nx_edge_data_priority,
                                           nx_edge_data_weight)
@@ -25,6 +26,7 @@ class KytosGraph:
         self.graph = nx.Graph()
         self._filter_functions = {
             "ownership": lazy_filter(str, filter_in("ownership")),
+            "not_ownership": lazy_filter(str, filter_not_in("ownership")),
             "bandwidth": lazy_filter((int, float), filter_ge("bandwidth")),
             "reliability": lazy_filter((int, float), filter_ge("reliability")),
             "priority": lazy_filter((int, float), filter_le("priority")),
diff --git a/utils.py b/utils.py
index ba9bafe..c763ce6 100644
--- a/utils.py
+++ b/utils.py
@@ -52,3 +52,11 @@ def filter_ge(metric):
 def filter_in(metric):
     """Lazy filter_in."""
     return lambda x: (lambda nx_edge_tup: x in nx_edge_tup[2].get(metric, {x}))
+
+def filter_not_in(metric):
+    """Lazy filter_not_in."""
+    return lambda x: (
+        lambda nx_edge_tup: all(
+            i not in nx_edge_tup[2].get(metric, {}) for i in x.split(",")
+        )
+    )
viniarck commented 10 months ago

@italovalcy, yes, @Ktmi initially structured the filters to be composable and lazily, this not_ownership with not in similar to filter_in can be added. If you need help to divide and conquer this task just so you can implement mef_eline PR let me know and we can assign you or someone else too depending on the workload.

One thing to keep in mind is that although filters are composable, it's up to whoever is requesting to not request conflicting filters, for instance {"ownership": "blue"} and "{"not_ownership": "blue"} would end up later on excluding "blue" again, which isn't an actual issue but something to be aware, and ensure validation of all combinations can be tough, so we need to document that it's up to the user to filter based on what's coherent for the topology

italovalcy commented 10 months ago

@italovalcy, yes, @Ktmi initially structured the filters to be composable and lazily, this not_ownership with not in similar to filter_in can be added. If you need help to divide and conquer this task just so you can implement mef_eline PR let me know and we can assign you or someone else too depending on the workload.

One thing to keep in mind is that although filters are composable, it's up to whoever is requesting to not request conflicting filters, for instance {"ownership": "blue"} and "{"not_ownership": "blue"} would end up later on excluding "blue" again, which isn't an actual issue but something to be aware, and ensure validation of all combinations can be tough, so we need to document that it's up to the user to filter based on what's coherent for the topology

Sounds good, @viniarck . As we discussed during Kytos meeting, I would need help, yes.

As I mentioned during the meeting, maybe using the name ownership is not the best approach. Maybe we could use tags or groups (which would also be good to extend the filter_in to also support multiple values).