blob: 6267b8fd3aad997384be0a935b6ae72c7e0550ff [file] [log] [blame]
Khen Nursimulu8ffb8932017-01-26 13:40:49 -05001#
2# Copyright 2017 the original author or authors.
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15#
16import os
17import sys
18import inspect
19from structlog import get_logger
Khen Nursimulu3676b7c2017-01-31 13:48:38 -050020from netconf.constants import Constants as C
Khen Nursimulu8ffb8932017-01-26 13:40:49 -050021
22log = get_logger()
23
24
25class NetconfRPCMapper:
26 # Keeps the mapping between a Netconf RPC request and a voltha GPRC
27 # request. Singleton class.
28
29
30 instance = None
31
32 def __init__(self, work_dir, grpc_client):
33 self.work_dir = work_dir
34 self.grpc_client = grpc_client
35 self.rpc_map = {}
Khen Nursimulu3676b7c2017-01-31 13:48:38 -050036 self.yang_defs = {}
Khen Nursimulu8ffb8932017-01-26 13:40:49 -050037
38 def _add_rpc_map(self, func_name, func_ref):
39 if not self.rpc_map.has_key(func_name):
40 log.debug('adding-function', name=func_name, ref=func_ref)
41 self.rpc_map[func_name] = func_ref
42
43 def _add_module_rpc(self, mod):
44 for name, ref in self.list_functions(mod):
45 self._add_rpc_map(name, ref)
46
Khen Nursimulu3676b7c2017-01-31 13:48:38 -050047 def _add_m(self, mod):
48 for name, ref in self.list_functions(mod):
49 self._add_rpc_map(name, ref)
50
Khen Nursimulu8ffb8932017-01-26 13:40:49 -050051 def is_mod_function(self, mod, func):
52 return inspect.isfunction(func) and inspect.getmodule(func) == mod
53
54 def list_functions(self, mod):
55 return [(func.__name__, func) for func in mod.__dict__.itervalues()
56 if self.is_mod_function(mod, func)]
57
58 def load_modules(self):
59 if self.work_dir not in sys.path:
60 sys.path.insert(0, self.work_dir)
61
62 for fname in [f for f in os.listdir(self.work_dir)
63 if f.endswith('_rpc_gw.py')]:
64 modname = fname[:-len('.py')]
65 log.debug('load-modules', modname=modname)
66 try:
67 m = __import__(modname)
68 self._add_module_rpc(m)
69 except Exception, e:
70 log.exception('loading-module-exception', modname=modname, e=e)
71
Khen Nursimulu3676b7c2017-01-31 13:48:38 -050072 # load the yang definition
73 for fname in [f for f in os.listdir(self.work_dir)
74 if f.endswith(C.YANG_MESSAGE_DEFINITIONS_FILE)]:
75 modname = fname[:-len('.py')]
76 try:
77 m = __import__(modname)
78 for name, ref in self.list_functions(m):
79 self.yang_defs[name] = ref
80 except Exception, e:
81 log.exception('loading-yang-module-exception', modname=modname,
82 e=e)
83
84 def get_fields_from_yang_defs(self, service, method):
85 # Get the return type of that method
86 func_name = self._get_function_name(service, method)
87 return_type_func_name = ''.join(['get_return_type_', func_name])
88 if self.rpc_map.has_key(return_type_func_name):
89 type_name = self.rpc_map[return_type_func_name]()
90 log.info('get-yang-defs', type_name=type_name, service=service,
91 method=method)
92 if type_name:
93 # Type name is in the form "<package-name>_pb2".<message_name>
94 name = type_name.split('.')
95 if len(name) == 2:
96 package = name[0][:-len('_pb2')]
97 message_name = name[1]
98 if self.yang_defs.has_key('get_fields'):
99 return self.yang_defs['get_fields'](package,
100 message_name)
101 else:
102 log.info('Incorrect-type-format', type_name=type_name,
103 service=service,
104 method=method)
105 return None
106
107 def get_fields_from_type_name(self, module_name, type_name):
108 if self.yang_defs.has_key('get_fields'):
109 return self.yang_defs['get_fields'](module_name,
110 type_name)
111
Khen Nursimulu8ffb8932017-01-26 13:40:49 -0500112 def get_function(self, service, method):
Khen Nursimulu3676b7c2017-01-31 13:48:38 -0500113
114 func_name = self._get_function_name(service, method)
Khen Nursimulu8ffb8932017-01-26 13:40:49 -0500115
116 if self.rpc_map.has_key(func_name):
117 return self.rpc_map[func_name]
118 else:
119 return None
120
Khen Nursimulu3676b7c2017-01-31 13:48:38 -0500121 def get_xml_tag(self, service, method):
122 func_name = self._get_function_name(service, method)
123 xml_tag_func_name = ''.join(['get_xml_tag_', func_name])
124 if self.rpc_map.has_key(xml_tag_func_name):
125 tag = self.rpc_map[xml_tag_func_name]()
126 if tag == '':
127 return None
128 else:
129 return tag
130 else:
131 return None
132
133 def get_list_items_name(self, service, method):
134 func_name = self._get_function_name(service, method)
135 list_items_name = ''.join(['get_list_items_name_', func_name])
136 if self.rpc_map.has_key(list_items_name):
137 name = self.rpc_map[list_items_name]()
138 if name == '':
139 return None
140 else:
141 return name
142 else:
143 return None
144
Khen Nursimulu8ffb8932017-01-26 13:40:49 -0500145 def is_rpc_exist(self, rpc_name):
146 return self.rpc_map.has_key(rpc_name)
147
Khen Nursimulu3676b7c2017-01-31 13:48:38 -0500148 def _get_function_name(self, service, method):
149 if service:
150 return ''.join([service, '_', method])
151 else:
152 return method
153
Khen Nursimulu8ffb8932017-01-26 13:40:49 -0500154
155def get_nc_rpc_mapper_instance(work_dir=None, grpc_client=None):
156 if NetconfRPCMapper.instance == None:
157 NetconfRPCMapper.instance = NetconfRPCMapper(work_dir, grpc_client)
158 return NetconfRPCMapper.instance