python API: work towards python/vpp api separation
This change improves vpp_papi behaviour by introducing alternate way of calling vpp APIs. The common code is the same: vpp = VPP(...) vpp.connect(...) Calling VPP API is different, instead of deprecated: vpp.show_version() # deprecated one should write vpp.api.show_version() this allows VPP messages like "connect" and "disconnect" to be used, once the old API is dropped (in 17.07). Also part of this patch is a check for name conflict, to prevent VPP object overwriting its own functionality with generated code based on json files. Change-Id: I22e573b6a45f8b2a1f0340c5c2597c194fe42ca4 Signed-off-by: Klement Sekera <ksekera@cisco.com>
This commit is contained in:

committed by
Ole Trøan

parent
a80ab84531
commit
7112c542ea
@ -31,6 +31,20 @@ def vpp_atexit(self):
|
||||
eprint ('Cleaning up VPP on exit')
|
||||
self.disconnect()
|
||||
|
||||
|
||||
class Empty(object):
|
||||
pass
|
||||
|
||||
|
||||
class FuncWrapper(object):
|
||||
def __init__(self, func):
|
||||
self._func = func
|
||||
self.__name__ = func.__name__
|
||||
|
||||
def __call__(self, **kwargs):
|
||||
return self._func(**kwargs)
|
||||
|
||||
|
||||
class VPP():
|
||||
"""VPP interface.
|
||||
|
||||
@ -309,9 +323,16 @@ class VPP():
|
||||
f.__doc__ = ", ".join(["%s %s" % (argtypes[k], k) for k in args.keys()])
|
||||
return f
|
||||
|
||||
@property
|
||||
def api(self):
|
||||
if not hasattr(self, "_api"):
|
||||
raise Exception("Not connected, api definitions not available")
|
||||
return self._api
|
||||
|
||||
def _register_functions(self, async=False):
|
||||
self.id_names = [None] * (self.vpp_dictionary_maxid + 1)
|
||||
self.id_msgdef = [None] * (self.vpp_dictionary_maxid + 1)
|
||||
self._api = Empty()
|
||||
for name, msgdef in self.messages.iteritems():
|
||||
if name in self.vpp_dictionary:
|
||||
if self.messages[name]['crc'] != self.vpp_dictionary[name]['crc']:
|
||||
@ -322,7 +343,15 @@ class VPP():
|
||||
self.id_msgdef[i] = msgdef
|
||||
self.id_names[i] = name
|
||||
multipart = True if name.find('_dump') > 0 else False
|
||||
setattr(self, name, self.make_function(name, i, msgdef, multipart, async))
|
||||
f = self.make_function(name, i, msgdef, multipart, async)
|
||||
setattr(self._api, name, FuncWrapper(f))
|
||||
|
||||
# olf API stuff starts here - will be removed in 17.07
|
||||
if hasattr(self, name):
|
||||
raise NameError(
|
||||
3, "Conflicting name in JSON definition: `%s'" % name)
|
||||
setattr(self, name, f)
|
||||
# old API stuff ends here
|
||||
|
||||
def _write (self, buf):
|
||||
"""Send a binary-packed message to VPP."""
|
||||
|
@ -1,5 +1,4 @@
|
||||
import os
|
||||
import socket
|
||||
import fnmatch
|
||||
import time
|
||||
from hook import Hook
|
||||
@ -56,7 +55,7 @@ class VppPapiProvider(object):
|
||||
for filename in fnmatch.filter(filenames, '*.api.json'):
|
||||
jsonfiles.append(os.path.join(root, filename))
|
||||
|
||||
self.papi = VPP(jsonfiles)
|
||||
self.vpp = VPP(jsonfiles)
|
||||
self._events = deque()
|
||||
|
||||
def __enter__(self):
|
||||
@ -124,12 +123,13 @@ class VppPapiProvider(object):
|
||||
|
||||
def connect(self):
|
||||
"""Connect the API to VPP"""
|
||||
self.papi.connect(self.name, self.shm_prefix)
|
||||
self.papi.register_event_callback(self)
|
||||
self.vpp.connect(self.name, self.shm_prefix)
|
||||
self.papi = self.vpp.api
|
||||
self.vpp.register_event_callback(self)
|
||||
|
||||
def disconnect(self):
|
||||
"""Disconnect the API from VPP"""
|
||||
self.papi.disconnect()
|
||||
self.vpp.disconnect()
|
||||
|
||||
def api(self, api_fn, api_args, expected_retval=0):
|
||||
""" Call API function and check it's return value.
|
||||
@ -190,7 +190,7 @@ class VppPapiProvider(object):
|
||||
|
||||
def show_version(self):
|
||||
""" """
|
||||
return self.papi.show_version()
|
||||
return self.api(self.papi.show_version, {})
|
||||
|
||||
def pg_create_interface(self, pg_index):
|
||||
"""
|
||||
|
Reference in New Issue
Block a user