blob: 8c9c8f9f906c29962f883665a2302ab94e48d917 [file] [log] [blame]
Scott Bakerbba67b62019-01-28 17:38:21 -08001# Copyright 2017-present Open Networking Foundation
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
Scott Bakerbba67b62019-01-28 17:38:21 -080015# TODO: Moved this into the synchronizer, as it appeared to require model
16# access. Verify whether or not that's true and reconcile with
17# generate/dependency_walker.py
18
Zack Williams5c2ea232019-01-30 15:23:01 -070019from __future__ import absolute_import, print_function
20
Scott Bakerbba67b62019-01-28 17:38:21 -080021import json
22
Scott Bakerbba67b62019-01-28 17:38:21 -080023from multistructlog import create_logger
Zack Williams5c2ea232019-01-30 15:23:01 -070024from xosconfig import Config
Scott Bakerbba67b62019-01-28 17:38:21 -080025
26log = create_logger(Config().get("logging"))
27
28missing_links = {}
29
30if Config.get("dependency_graph"):
31 dep_data = open(Config.get("dependency_graph")).read()
32else:
33 dep_data = "{}"
34
35dependencies = json.loads(dep_data)
36dependencies = {k: [item[0] for item in items] for k, items in dependencies.items()}
37
38inv_dependencies = {}
39for k, lst in dependencies.items():
40 for v in lst:
41 try:
42 inv_dependencies[v].append(k)
43 except KeyError:
44 inv_dependencies[v] = [k]
45
46
47def plural(name):
48 if name.endswith("s"):
49 return name + "es"
50 else:
51 return name + "s"
52
53
54def walk_deps(fn, object):
55 model = object.__class__.__name__
56 try:
57 deps = dependencies[model]
58 except BaseException:
59 deps = []
60 return __walk_deps(fn, object, deps)
61
62
63def walk_inv_deps(fn, object):
64 model = object.__class__.__name__
65 try:
66 deps = inv_dependencies[model]
67 except BaseException:
68 deps = []
69 return __walk_deps(fn, object, deps)
70
71
72def __walk_deps(fn, object, deps):
73 model = object.__class__.__name__
74 ret = []
75 for dep in deps:
76 # print "Checking dep %s"%dep
77 peer = None
78 link = dep.lower()
79 try:
80 peer = getattr(object, link)
81 except AttributeError:
82 link = plural(link)
83 try:
84 peer = getattr(object, link)
85 except AttributeError:
86 if model + "." + link not in missing_links:
87 print("Model %s missing link for dependency %s" % (model, link))
88 log.exception(
89 "WARNING: Model missing link for dependency.",
90 model=model,
91 link=link,
92 )
93 missing_links[model + "." + link] = True
94
95 if peer:
96 try:
97 peer_objects = peer.all()
98 except AttributeError:
99 peer_objects = [peer]
100 except BaseException:
101 peer_objects = []
102
103 for o in peer_objects:
104 if hasattr(o, "updated"):
105 fn(o, object)
106 ret.append(o)
107 # Uncomment the following line to enable recursion
108 # walk_inv_deps(fn, o)
109 return ret