1) Handles chuncked xml requests from Netconf client, 2) Handles nested xml parameters from Netconf client, 3) Handles all currently exposed rpcs
Change-Id: Id478f355ab53afc876c4f5fd9ad8f1a048a50748
diff --git a/netconf/session/nc_connection.py b/netconf/session/nc_connection.py
index 9043584..b0272a0 100644
--- a/netconf/session/nc_connection.py
+++ b/netconf/session/nc_connection.py
@@ -20,11 +20,13 @@
from twisted.internet.defer import inlineCallbacks, returnValue
from common.utils.message_queue import MessageQueue
from netconf.constants import Constants as C
+import re
log = structlog.get_logger()
MAXSSHBUF = C.MAXSSHBUF
+
class NetconfConnection(protocol.Protocol):
def __init__(self, data=None, avatar=None, max_chunk=MAXSSHBUF):
self.avatar = avatar
@@ -47,7 +49,7 @@
def dataReceived(self, data):
log.debug('data-received', len=len(data),
- received=hexdump(data, result='return'))
+ received=hexdump(data, result='return'))
assert len(data)
self.rx.put(data)
@@ -85,32 +87,52 @@
assert self.connected
msg = yield self.recv(lambda _: True)
if new_framing:
- returnValue(self._receive_11(msg))
+ response = yield self._receive_11(msg)
else:
- returnValue(self._receive_10(msg))
+ response = yield self._receive_10(msg)
+ returnValue(response)
+ @inlineCallbacks
def _receive_10(self, msg):
# search for message end indicator
searchfrom = 0
- eomidx = msg.find(C.DELIMITER, searchfrom)
- if eomidx != -1:
- log.info('received-msg', msg=msg[:eomidx])
- return msg[:eomidx]
- else:
- log.error('no-message-end-indicators', msg=msg)
- return msg
+ partial_msgs = []
+ while 1:
+ eomidx = msg.find(C.DELIMITER, searchfrom)
+ if eomidx != -1:
+ partial_msgs.append(msg[:eomidx])
+ full_msg = ''.join(partial_msgs)
+ log.info('full-msg-received', msg=full_msg)
+ returnValue(full_msg)
+ else:
+ partial_msgs.append(msg)
+ log.debug('partial-msg-received', msg=msg)
+ msg = yield self.recv(lambda _: True)
+ @inlineCallbacks
def _receive_11(self, msg):
- # Message is received in the format "\n#{len}\n{msg}\n##\n"
- # A message may have return characters within it
- if msg:
- log.info('received-msg-full', msg=msg)
+ # A message can be received in chunks where each chunk is formatted as:
+ # /\n#[len]\n
+ # \n##\n
+ # msg\n
+ # msg
+ # \n
+ # \nmsg\n
+ partial_msgs = []
+ while 1:
+ log.info('received-msg', msg=msg)
+ # Remove all reference to length if any, i.e any '#len'
+ msg = re.sub(r'#[0-9]+', "", msg)
msg = msg.split('\n')
- if len(msg) > 2:
- msg = ''.join(msg[2:(len(msg)-2)])
- log.info('parsed-msg\n', msg=msg)
- return msg
- return None
+ if C.DELIMITER_1_1 in msg: # The '##' is the second last ref
+ partial_msgs.append(''.join(msg[0:(len(msg) - 2)]))
+ full_msg = ''.join(partial_msgs)
+ log.debug('full-msg-received', msg=full_msg)
+ returnValue(full_msg)
+ else:
+ partial_msgs.append(''.join(msg))
+ log.debug('partial-msg-received', msg=msg)
+ msg = yield self.recv(lambda _: True)
def close_connection(self):
log.info('closing-connection')