added an llsd builder and more stubs for the message system, now only to implement it
This commit is contained in:
committed by
Salad Dais
parent
6eced948b9
commit
4b5a1fdc1b
@@ -14,10 +14,10 @@ class Circuit(object):
|
||||
""" Some statistics things we may need: bytes/packets in, bytes/packets out,
|
||||
unacked packet count/bytes, acked packet count/bytes"""
|
||||
|
||||
def __init__(self, host, circuit_code, secure_session_id):
|
||||
def __init__(self, host, circuit_code, remote_session_id):
|
||||
self.host = host
|
||||
self.circuit_code = circuit_code
|
||||
self.secure_session_id = secure_session_id
|
||||
self.session_id = remote_session_id
|
||||
self.is_alive = True
|
||||
self.is_blocked = False
|
||||
self.allow_timeout = True
|
||||
|
||||
61
pyogp/lib/base/message/interfaces.py
Normal file
61
pyogp/lib/base/message/interfaces.py
Normal file
@@ -0,0 +1,61 @@
|
||||
from zope.interface import Interface, Attribute
|
||||
|
||||
class IMessageData(Interface):
|
||||
"""base interface for data that can be serialized to be sent over
|
||||
a network, or deserialized from networked received data. """
|
||||
name = Attribute("""name of the message""")
|
||||
size = Attribute("""size of the message""")
|
||||
block_map = Attribute("""map of the blocks for the message""")
|
||||
|
||||
def add_block(block):
|
||||
""" adds a given block to the message """
|
||||
def get_block(block_name):
|
||||
""" gets one of the message's blocks """
|
||||
|
||||
def add_data(block_name, var_name, data, data_size):
|
||||
""" adds data to one of the message's blocks """
|
||||
|
||||
class IMessageBuilder(Interface):
|
||||
"""base interface for a message builder"""
|
||||
current_msg = Attribute("""the message built/being built""")
|
||||
|
||||
def build_message():
|
||||
""" returns the message and its size in serialized form. """
|
||||
|
||||
def new_message(message_name):
|
||||
""" creates a new message that will be used to build into. """
|
||||
|
||||
def next_block(block_name):
|
||||
""" sets the next block of the current message that we will be
|
||||
adding data to. """
|
||||
#NOTE: might be helpful to have a way to have this method mixed
|
||||
#with the add_data method. It IS Python btw.
|
||||
|
||||
def add_data(var_name, data, data_type):
|
||||
""" adds data to the current block of message being built """
|
||||
|
||||
class IMessageReader(Interface):
|
||||
"""base interface for a message builder"""
|
||||
current_msg = Attribute("""message read/being read""")
|
||||
|
||||
def validate_message(message_buffer, buffer_size):
|
||||
""" makes sure the message is a valid message that can be read """
|
||||
|
||||
def read_message(message_buffer):
|
||||
""" reads the message and parses its data """
|
||||
|
||||
def get_data(block_name, var_name, data_type, block_number = 0):
|
||||
""" gets data from a block in the message """
|
||||
|
||||
def clear_message():
|
||||
""" clears the message being read """
|
||||
|
||||
"""
|
||||
Due to the fact that LLSD can be sent multiple different ways, we have can
|
||||
have different types of senders for an LLSD message. We can send to
|
||||
eventqueue, http, or to capabilities. There should then be something that
|
||||
maps destination (host) to a sender type. Sending an llsd message is then
|
||||
delgated to the sender, rather than sent directly by the messaging system.
|
||||
"""
|
||||
class HTTPSender(Interface):
|
||||
pass
|
||||
1
pyogp/lib/base/message/llsd_sender.py
Normal file
1
pyogp/lib/base/message/llsd_sender.py
Normal file
@@ -0,0 +1 @@
|
||||
#implentations of the HTTPSender
|
||||
60
pyogp/lib/base/message/message_llsd_builder.py
Normal file
60
pyogp/lib/base/message/message_llsd_builder.py
Normal file
@@ -0,0 +1,60 @@
|
||||
#third party
|
||||
from zope.interface import implements
|
||||
|
||||
#local
|
||||
from pyogp.lib.base.message.interfaces import IMessageBuilder
|
||||
from pyogp.lib.base.message.message_template import MsgData, MsgBlockData, \
|
||||
MsgVariableData
|
||||
|
||||
class LLSDMessageBuilder(object):
|
||||
implements(IMessageBuilder)
|
||||
|
||||
def __init__(self):
|
||||
self.current_template = None
|
||||
self.current_msg = None
|
||||
self.current_block = None
|
||||
|
||||
self.cur_msg_name = ''
|
||||
self.cur_block_name = ''
|
||||
|
||||
def build_message(self):
|
||||
""" this does not serialize it for this type of builder. The message
|
||||
will be put in standard Python form and will need to be formatted
|
||||
based on who the target is (xml? something else?) """
|
||||
msg = {}
|
||||
for block in self.current_msg.block_map:
|
||||
#message can have multiple of the same block names, so
|
||||
#message actually holds a block list
|
||||
block_list = self.current_msg.block_map[block]
|
||||
|
||||
for block_data in block_list:
|
||||
#set up the block list
|
||||
if block_data.name not in msg:
|
||||
msg[block_data.name] = []
|
||||
#each block in the block list is a map
|
||||
block = {}
|
||||
msg[block_data.name].append(block)
|
||||
|
||||
#go through the variables for the data
|
||||
for variable in block_data.variable_map.values():
|
||||
#the variable holds the key-value pairs of data
|
||||
#for the block
|
||||
block[variable.name] = variable.data
|
||||
|
||||
return msg, len(msg)
|
||||
|
||||
def new_message(self, message_name):
|
||||
self.current_msg = MsgData(message_name)
|
||||
self.cur_msg_name = message_name
|
||||
|
||||
def next_block(self, block_name):
|
||||
block = MsgBlockData(block_name)
|
||||
self.current_msg.add_block(block)
|
||||
self.current_block = block
|
||||
self.cur_block_name = block_name
|
||||
|
||||
def add_data(self, var_name, data, data_type):
|
||||
var = MsgVariableData(var_name, data_type)
|
||||
self.current_block.add_variable(var)
|
||||
#size doesn't matter for llsd, formatter will take care of it
|
||||
self.current_block.add_data(var_name, data, -1)
|
||||
@@ -1,6 +1,13 @@
|
||||
from zope.component import getGlobalSiteManager
|
||||
gsm = getGlobalSiteManager()
|
||||
|
||||
from pyogp.lib.base.data import msg_tmpl
|
||||
from pyogp.lib.base.message.message_llsd_builder import LLSDMessageBuilder
|
||||
from pyogp.lib.base.message.message_template_parser import MessageTemplateParser
|
||||
from pyogp.lib.base.message.message_template_builder import MessageTemplateBuilder
|
||||
from pyogp.lib.base.message.message_template_reader import MessageTemplateReader
|
||||
from pyogp.lib.base.message.message_template_dict import TemplateDictionary
|
||||
|
||||
class MessageSystem(object):
|
||||
def __init__():
|
||||
self.builder = None
|
||||
@@ -8,6 +15,19 @@ class MessageSystem(object):
|
||||
self.circuit_info = None
|
||||
self.socket = None
|
||||
|
||||
self.llsd_builder = LLSDMessageBuilder()
|
||||
#self.llsd_reader = LLSDMessageReader()
|
||||
|
||||
template_dict = self.load_template(msg_tmpl)
|
||||
self.template_builder = MessageTemplateBuilder(template_dict)
|
||||
self.template_reader = MessageTemplateReader(template_dict)
|
||||
|
||||
def load_template(self, template_file):
|
||||
#use the parser to load the message_template.msg message templates
|
||||
parser = MessageTemplateParser(msg_tmpl)
|
||||
template_list = parser.message_templates
|
||||
return TemplateDictionary(self.template_list)
|
||||
|
||||
def receive_check(self):
|
||||
#determine if we have any messages that can be received through UDP
|
||||
#also, check and decode the message we have received
|
||||
@@ -31,11 +51,23 @@ class MessageSystem(object):
|
||||
#acks are just the packet_id that we are acking
|
||||
pass
|
||||
|
||||
def send_message_circuit(self, circuit):
|
||||
""" allows someone to send a message only knowing the circuit """
|
||||
#send_message(map_circuit_to_host(circuit))
|
||||
pass
|
||||
|
||||
def send_message_llsd(self, host, name, message):
|
||||
""" sends an llsd message without going through builder """
|
||||
pass
|
||||
|
||||
def send_message(self, host):
|
||||
""" Sends the message that is currently built to the desired host """
|
||||
#build it if it isn't built
|
||||
|
||||
#make sure host is OK (ip and address aren't null)
|
||||
|
||||
|
||||
#IF UDP/template message
|
||||
#use circuit manager to get the circuit to send on
|
||||
|
||||
#if the packet is reliable, add it to the circuit manager's list of
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import socket
|
||||
|
||||
|
||||
#maybe put this isnt' a class
|
||||
|
||||
#returns true if packet was sent successfully
|
||||
def send_packet(socket, send_buffer, size, ip_addr, port):
|
||||
@@ -8,3 +9,13 @@ def send_packet(socket, send_buffer, size, ip_addr, port):
|
||||
#returns message and size, or None if error
|
||||
def receive_packet(socket):
|
||||
pass
|
||||
|
||||
def start_udp_connection(port):
|
||||
""" Starts a udp connection, returning socket and port. """
|
||||
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||
#error check - make sure sock is good
|
||||
|
||||
#will probably be other setup for this
|
||||
return sock
|
||||
|
||||
|
||||
|
||||
64
pyogp/lib/base/tests/test_llsd_builder.py
Normal file
64
pyogp/lib/base/tests/test_llsd_builder.py
Normal file
@@ -0,0 +1,64 @@
|
||||
#standard libraries
|
||||
import unittest, doctest
|
||||
|
||||
#third party
|
||||
from indra.base import llsd
|
||||
|
||||
#local libraries
|
||||
from pyogp.lib.base.message.message_llsd_builder import LLSDMessageBuilder
|
||||
from pyogp.lib.base.message.message_types import MsgType
|
||||
|
||||
class TestLLSDBuilder(unittest.TestCase):
|
||||
|
||||
def tearDown(self):
|
||||
pass
|
||||
|
||||
def setUp(self):
|
||||
pass
|
||||
|
||||
def test_builder(self):
|
||||
builder = LLSDMessageBuilder()
|
||||
builder.new_message('TestMessage')
|
||||
|
||||
builder.next_block('TestBlock1')
|
||||
builder.add_data('Test1', 0x00000001, MsgType.MVT_U32)
|
||||
|
||||
builder.next_block('TestBlock1')
|
||||
builder.add_data('Test2', 0x00000001, MsgType.MVT_U32)
|
||||
|
||||
builder.next_block('NeighborBlock')
|
||||
builder.add_data('Test0', 0x00000001, MsgType.MVT_U32)
|
||||
builder.add_data('Test1', 0x00000001, MsgType.MVT_U32)
|
||||
builder.add_data('Test2', 0x00000001, MsgType.MVT_U32)
|
||||
|
||||
builder.next_block('NeighborBlock')
|
||||
builder.add_data('Test1', 0x00000001, MsgType.MVT_U32)
|
||||
builder.add_data('Test1', 0x00000001, MsgType.MVT_U32)
|
||||
builder.add_data('Test1', 0x00000001, MsgType.MVT_U32)
|
||||
|
||||
builder.next_block('NeighborBlock')
|
||||
builder.add_data('Test2', 0x00000001, MsgType.MVT_U32)
|
||||
builder.add_data('Test2', 0x00000001, MsgType.MVT_U32)
|
||||
builder.add_data('Test2', 0x00000001, MsgType.MVT_U32)
|
||||
|
||||
builder.next_block('TestBlock2')
|
||||
builder.add_data('Test1', 0x00000001, MsgType.MVT_U32)
|
||||
|
||||
msg, size = builder.build_message()
|
||||
|
||||
try:
|
||||
assert len(msg['NeighborBlock']) == 3, "Multiple blocks not" + \
|
||||
" correct"
|
||||
except:
|
||||
assert False, "Message not set up properly"
|
||||
|
||||
try:
|
||||
msg = llsd.format_xml(msg)
|
||||
except:
|
||||
assert False, "Message not built correctly so it can be formatted"
|
||||
|
||||
def test_suite():
|
||||
from unittest import TestSuite, makeSuite
|
||||
suite = TestSuite()
|
||||
suite.addTest(makeSuite(TestLLSDBuilder))
|
||||
return suite
|
||||
Reference in New Issue
Block a user