added an llsd builder and more stubs for the message system, now only to implement it

This commit is contained in:
locklainn.linden
2008-07-31 20:58:51 +00:00
committed by Salad Dais
parent 6eced948b9
commit 4b5a1fdc1b
7 changed files with 232 additions and 3 deletions

View File

@@ -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

View 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

View File

@@ -0,0 +1 @@
#implentations of the HTTPSender

View 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)

View File

@@ -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

View File

@@ -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

View 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