def get_ipap_message_auction(self, auction: Auction, use_ipv6: bool, s_address: str, port: int, message: IpapMessage): """ Updates the ipap_message given as parameter with the infomation of the auction :param auction: auction to include in the message :param use_ipv6: whether or not it use ipv6 :param s_address: source address :param port: source port :param message: ipap message to modify an include the information. """ auction_template_id = auction.get_auction_data_template() auction_template = self.ipap_template_container.get_template(auction_template_id) message.make_template(auction_template) option_template_id = auction.get_option_auction_template() option_template = self.ipap_template_container.get_template(option_template_id) # Following lines are used for inserting only non mandatory fields mandatory_fields = option_template.get_template_type_mandatory_field(option_template.get_type()) optional_fields = self.get_non_mandatory_fields(auction.action, mandatory_fields) option_template.set_max_fields(option_template.get_num_fields() + len(optional_fields)) for field in optional_fields: ipap_field = self.field_container.get_field(field.get_eno(), field.get_ftype()) option_template.add_field(ipap_field.get_length(), UnknownField.KNOWN, True, ipap_field) message.make_template(option_template) self.include_auction_templates(auction_template, auction, message) self.include_auction_data_record(auction_template, auction, message, use_ipv6, s_address, port) self.include_option_data_record(option_template, auction, message)
def include_options_record(self, template: IpapTemplate, bidding_object: BiddingObject, record_id: str, start: datetime, stop: datetime, config_params: dict, message: IpapMessage): ipap_record = IpapDataRecord(obj=None, templ_id=template.get_template_id()) # Insert the auction id field. self.insert_string_field('auctionid', bidding_object.get_parent_key(), ipap_record) # Insert the bidding object id field. self.insert_string_field('biddingobjectid', bidding_object.get_key(), ipap_record) # Add the Record Id self.insert_string_field('recordid', record_id, ipap_record) # Add the start time - Unix time is seconds from 1970-1-1 . self.insert_datetime_field('start', start, ipap_record) # Add the end time. self.insert_datetime_field('stop', stop, ipap_record) # Adds non mandatory fields. mandatory_fields = template.get_template_type_mandatory_field( template.get_type()) self.include_non_mandatory_fields(mandatory_fields, config_params, ipap_record) message.include_data(template.get_template_id(), ipap_record)
def include_option_data_record(self, template: IpapTemplate, auction: Auction, message: IpapMessage): """ Inserts templates associated with the auction :param template auction template :param auction auction being included in the message. :param message: message being built. :return: """ ipap_options_record = IpapDataRecord(obj=None, templ_id=template.get_template_id()) # Add the auction Id self.insert_string_field('auctionid', auction.get_key(), ipap_options_record) # Add the Record Id self.insert_string_field('recordid', "Record_1", ipap_options_record) # Add the action self.insert_string_field('algoritmname', auction.action.name, ipap_options_record) # Adds non mandatory fields. mandatory_fields = template.get_template_type_mandatory_field(TemplateType.IPAP_OPTNS_AUCTION_TEMPLATE) config_params = auction.action.get_config_params() self.include_non_mandatory_fields(mandatory_fields, config_params, ipap_options_record) message.include_data(template.get_template_id(), ipap_options_record)
def include_data_record(self, template: IpapTemplate, allocation: Allocation, record_id: str, config_params: dict, message: IpapMessage): ipap_data_record = IpapDataRecord(obj=None, templ_id=template.get_template_id()) # Insert the auction id field. self.insert_string_field('auctionid', allocation.get_auction_key(), ipap_data_record) # Insert the bidding object id field. self.insert_string_field('biddingobjectid', allocation.get_bid_key(), ipap_data_record) # Insert the allocation id field. self.insert_string_field('allocationid', allocation.get_key(), ipap_data_record) # Add the Record Id self.insert_string_field('recordid', record_id, ipap_data_record) # Add the Status self.insert_integer_field('status', allocation.get_state().value, ipap_data_record) # Add bidding_object type self.insert_integer_field('biddingobjecttype', allocation.get_type().value, ipap_data_record) # Adds non mandatory fields. mandatory_fields = template.get_template_type_mandatory_field(template.get_type()) self.include_non_mandatory_fields(mandatory_fields, config_params, ipap_data_record) # Include the data record in the message. message.include_data(template.get_template_id(), ipap_data_record)
def test_import(self): print('In test import') self.ipap_message2.set_syn(True) self.ipap_message2.set_seqno(300) self.ipap_message2.output() str_msg = self.ipap_message2.get_message() ipap_message3 = IpapMessage(1, 1, True, str_msg) str_msg = 'aqui estoy' with self.assertRaises(ValueError): ipap_message4 = IpapMessage(1, 1, True, str_msg)
def include_auction_templates(self, template: IpapTemplate, auction: Auction, message: IpapMessage): """ Inserts templates associated with the auction :param template auction template :param auction auction being included in the message. :param message: message being built. :return: """ for i in range(1, ObjectType.IPAP_MAX_OBJECT_TYPE.value): list_types = template.get_object_template_types(ObjectType(i)) for templ_type in list_types: templ_id = auction.get_bidding_object_template(ObjectType(i), templ_type) message.make_template(self.ipap_template_container.get_template(templ_id))
def read_data_records(message: IpapMessage, templ_id: int) -> list: """ Reads the data record list from a message templ_id : template identifier. :return: list of data records within the message. """ size = message.get_data_record_size() list_return = [] for i in range(0, size): data_record = message.get_data_record_at_pos(i) if data_record.get_template_id() == templ_id: list_return.append(data_record) return list_return
def read_template(message: IpapMessage, template_type: TemplateType) -> IpapTemplate: """ Reads a template type from a message. :return: Ipap Template """ temp_list = message.get_template_list() for id_template in temp_list: template = message.get_template_object(id_template) if template.get_type() == template_type: return template raise ValueError("Template not found")
def build_syn_ack_message(self, sequence_nbr: int, ack_nbr: int) -> IpapMessage: """ Builds an ack to respond syn_ack message :param sequence_nbr: sequence number for the message :param ack_nbr: ack number to send within the message :return: """ print('build syn ack message {0}.{1}'.format(str(sequence_nbr), str(ack_nbr))) message = IpapMessage(domain_id=int(self.domain), ipap_version=IpapMessage.IPAP_VERSION, _encode_network=True) message.set_syn(True) message.set_ack(True) message.set_seqno(sequence_nbr) message.set_ack_seq_no(ack_nbr) return message
def parse(self, ipap_message: IpapMessage, ipap_template_container: IpapTemplateContainer): """ Parsers the ipap message to get the auctions given. :param ipap_message: ipap message to parse :param ipap_template_container: template container with templates registered for a particular server. :return: """ auction_ret = [] # Splits the message by object. object_templates, object_data_records, templates_not_related = self.split(ipap_message) # insert new templates not related (for example bidding templates to use for the auction) to the object. for template_id in templates_not_related: if not ipap_template_container.exists_template(template_id): template = templates_not_related[template_id] self.logger.debug("From domain {0} arriving template: {1} - num_fields {2}".format( str(ipap_message.get_domain()), str(template_id), str(template.get_num_fields()))) ipap_template_container.add_template(template) # loop through data records and parse the auction data for object_key in object_data_records: if object_key.get_object_type() == ObjectType.IPAP_AUCTION: auction = self.parse_auction(object_key, object_templates[object_key], object_data_records[object_key], ipap_template_container) auction_ret.append(auction) return auction_ret
async def handle_ack(self, server_connection: ServerConnection, ipap_message: IpapMessage): """ The agent received a message witn the ack flag active, it can be a auction message or a disconnect message :param server_connection: websocket and aiohttp session created for the connection :param ipap_message: message sent from the server. """ self.logger.debug('start method handle_ack') # verifies ack sequence number ack_seqno = ipap_message.get_ackseqno() # verifies the connection state if server_connection.state == ServerConnectionState.FIN_WAIT_1: try: server_connection.get_auction_session().confirm_message(ack_seqno) server_connection.set_state(ServerConnectionState.FIN_WAIT_2) except ValueError: self.logger.info("A msg with ack nbr not expected was received, ignoring it") else: from auction_client.auction_client_handler import HandleAuctionMessage when = 0 handle_auction_message = HandleAuctionMessage(server_connection, ipap_message, when) handle_auction_message.start() self.logger.debug('End method handle_ack -new state: {0}'.format(str(server_connection.get_state())))
async def handle_ack(self, session: AuctionSession, ipap_message: IpapMessage): """ Handles the arrival of a ack message. :param session: session that is handling the connection :param ipap_message: message sent from the server. :return: """ self.logger.debug('starting handle_ack') from auction_server.auction_server_handler import HandleAuctionMessage # verifies ack sequence number ack_seqno = ipap_message.get_ackseqno() # verifies the connection state if session.get_connection().state == ClientConnectionState.SYN_RCVD: try: session.confirm_message(ack_seqno) session.get_connection().set_state( ClientConnectionState.ESTABLISHED) self.logger.info('New established connection') except ValueError: self.logger.info( "The message ack is not the expected, so ignore the message" ) # verifies the connection state is in fin wait 1 elif session.get_connection( ).state == ClientConnectionState.FIN_WAIT_1: try: session.confirm_message(ack_seqno) session.get_connection().set_state( ClientConnectionState.FIN_WAIT_2) except ValueError: self.logger.info( "A msg with ack nbr not expected was received, ignoring it" ) elif session.get_connection().state == ClientConnectionState.LAST_ACK: try: session.get_connection().set_state( ClientConnectionState.CLOSED) self.logger.info("The connection has been closed") except ValueError: self.logger.info( "The message ack is not the expected, so ignore the message" ) else: when = 0 handle_auction_message = HandleAuctionMessage( session, ipap_message, when) handle_auction_message.start() self.logger.debug('Ending handle_ack')
async def handle_syn(self, session: AuctionSession, ipap_message: IpapMessage): """ Handles the arrival of a syn message. :param session: session that is handling the connection :param ipap_message: message sent from the server. :return: """ self.logger.debug("starting handle_syn") # verifies the connection state if session.get_connection().state == ClientConnectionState.LISTEN: # send the ack message establishing the session. message = self.build_syn_ack_message(session.get_next_message_id(), ipap_message.get_seqno()) session.add_pending_message(message) await self.send_message(session.get_connection(), message.get_message()) session.get_connection().set_state(ClientConnectionState.SYN_RCVD) else: # The server is not in syn sent state, so ignore the message self.logger.info( "a message with syn was received, but the session \ is not in LISTEN. Ignoring the message") self.logger.debug("Ending handle_syn")
def is_auction_message(msg: str) -> IpapMessage: """ Establishes whether the given message is a valid auction message. :param msg: message to verify :return: An IpapMessage if it is a valid message, raise ValueError otherwise. """ return IpapMessage(0, 0, True, msg)
def get_ipap_message(self, auctions: list, use_ipv6: bool, s_address: str, port: int) -> IpapMessage: """ Gets an ipap_message to transfer the information of the auctions given as parameter. :param auctions: List of auctions to convert to a message :param use_ipv6: whether or not it use ipv6 :param s_address: source address :param port: source port :return: ipap message with auction information. """ message = IpapMessage(self.domain, IpapMessage.IPAP_VERSION, True) for auction in auctions: self.get_ipap_message_auction(auction, use_ipv6, s_address, port, message) message.output() return message
def build_ack_message(self, sequence_nbr: int, ack_nbr: int) -> IpapMessage: """ Builds an ack to respond other messages :param sequence_nbr: sequence number for the message :param ack_nbr: ack number to send within the message :return: """ message = IpapMessage(domain_id=int(self.domain), ipap_version=IpapMessage.IPAP_VERSION, _encode_network=True) message.set_ack(True) message.set_seqno(sequence_nbr) message.set_ack_seq_no(ack_nbr) return message
def build_fin_message(self, sequence_nbr: int, ack_nbr: int) -> IpapMessage: """ Builds a fin message to teardown a connection :param sequence_nbr: sequence number for the message :param ack_nbr: ack number to send within the message :return: message with the fin flag set """ message = IpapMessage(domain_id=int(self.domain), ipap_version=IpapMessage.IPAP_VERSION, _encode_network=True) message.set_fin(True) message.set_seqno(sequence_nbr) message.set_ack_seq_no(ack_nbr) return message
async def handle_syn_ack_message(self, server_connection: ServerConnection, ipap_message: IpapMessage): """ Establishes the session :param server_connection: websocket and aiohttp session created for the connection :param ipap_message: message sent from the server. :return: """ self.logger.debug("Starting handle_syn_ack_message") # verifies ack sequence number ack_seqno = ipap_message.get_ackseqno() self.logger.debug("ack_seqno:{0}".format(str(ack_seqno))) # verifies the connection state if server_connection.state == ServerConnectionState.SYN_SENT: try: server_connection.get_auction_session().confirm_message(ack_seqno) # send the ack message establishing the session. syn_ack_message = self.build_ack_message(server_connection.get_auction_session().get_next_message_id(), ipap_message.get_seqno()) msg = syn_ack_message.get_message() await self.send_message(server_connection, msg) # puts the connection as established. server_connection.set_state(ServerConnectionState.ESTABLISHED) self.logger.info("Connection established with server") except ValueError: self.logger.error("Invalid ack nbr from the server, the session is going to be teardown") await self._disconnect_socket(server_connection) self.auction_session_manager.del_session(server_connection.get_auction_session().get_key()) else: # The server is not in syn sent state, so ignore the message self.logger.info("a message with syn and ack was received, but the session \ is not in SYN_SENT. Ignoring the message") self.logger.debug("Ending handle_syn_ack_message")
def get_ipap_message(self, bidding_object: BiddingObject, auction: Auction, template_container: IpapTemplateContainer, message: IpapMessage): if bidding_object.get_parent_key() != auction.get_key(): raise ValueError( "the auction is not the same as the one referenced in the bidding object" ) # Find both templates types for the bidding object. tempType = IpapTemplate.get_data_template( bidding_object.get_template_object_type()) data_template_id = auction.get_bidding_object_template( bidding_object.get_template_object_type(), tempType) tempType = IpapTemplate.get_opts_template( bidding_object.get_template_object_type()) option_template_id = auction.get_bidding_object_template( bidding_object.get_template_object_type(), tempType) # Insert BiddingObject's templates. data_template = template_container.get_template(data_template_id) message.make_template(data_template) option_template = template_container.get_template(option_template_id) message.make_template(option_template) # Include data records. for element_name in bidding_object.elements: config_params = bidding_object.elements[element_name] self.include_data_record(data_template, bidding_object, element_name, config_params, message) # Include option records. for option_name in bidding_object.options: interval = bidding_object.calculate_interval(option_name) config_params = bidding_object.options[option_name] self.include_options_record(option_template, bidding_object, option_name, interval.start, interval.stop, config_params, message)
def include_options_record(self, template: IpapTemplate, allocation: Allocation, record_id: str, start: datetime, stop: datetime, message: IpapMessage): ipap_record = IpapDataRecord(obj=None, templ_id=template.get_template_id()) # Insert the auction id field. self.insert_string_field('auctionid', allocation.get_auction_key(), ipap_record) # Insert the bidding object id field. self.insert_string_field('biddingobjectid', allocation.get_bid_key(), ipap_record) # Insert the allocation id field. self.insert_string_field('allocationid', allocation.get_key(), ipap_record) # Add the Record Id self.insert_string_field('recordid', record_id, ipap_record) # Add the start time - Unix time is seconds from 1970-1-1 . self.insert_datetime_field('start', start, ipap_record) # Add the end time. self.insert_datetime_field('stop', stop, ipap_record) message.include_data(template.get_template_id(), ipap_record)
def build_syn_message(self, sequence_nbr: int) -> IpapMessage: """ Builds a syn message to start a connection :param sequence_nbr: sequence number for the message :return: message with the syn flag set """ message = IpapMessage(domain_id=int(self.domain), ipap_version=IpapMessage.IPAP_VERSION, _encode_network=True) message.set_syn(True) message.set_seqno(sequence_nbr) return message
def get_ipap_message( self, bidding_objects: List[BiddingObject], template_container: IpapTemplateContainer) -> IpapMessage: """ get the ipap_message that contains all the bidding objects within the list given :param bidding_objects: bidding objects to include in the message. :param template_container: container with all the registered templates :return: ipap_message with the information """ ipap_bidding_object_parser = IpapBiddingObjectParser(self.domain) message = IpapMessage(self.domain, IpapMessage.IPAP_VERSION, True) auction_manager = AuctionManager(self.domain) for bidding_object in bidding_objects: auction = auction_manager.get_auction( bidding_object.get_parent_key()) ipap_bidding_object_parser.get_ipap_message( bidding_object, auction, template_container, message) return message
def test_read_data_records(self): ipap_message = IpapMessage(1, 1, False) template_id = ipap_message.new_data_template( 10, TemplateType.IPAP_SETID_AUCTION_TEMPLATE) ipap_message.add_field(template_id, 0, 30) ipap_data_record = IpapDataRecord(templ_id=template_id) ipap_field_value1 = IpapValueField() value = 12231213 ipap_field_value1.set_value_uint64(value) # Replace the value ipap_data_record.insert_field(0, 30, ipap_field_value1) ipap_message.include_data(template_id, ipap_data_record) lst = self.ipap_message_parser.read_data_records( ipap_message, template_id) self.assertEqual(len(lst), 1) lst = self.ipap_message_parser.read_data_records(ipap_message, 100) self.assertEqual(len(lst), 0)
def test_read_template(self): ipap_message = IpapMessage(1, 1, False) template_id = ipap_message.new_data_template( 10, TemplateType.IPAP_SETID_AUCTION_TEMPLATE) ipap_message.add_field(template_id, 0, 30) ipap_data_record = IpapDataRecord(templ_id=template_id) ipap_field_value1 = IpapValueField() value = 12231213 ipap_field_value1.set_value_uint64(value) # Replace the value ipap_data_record.insert_field(0, 30, ipap_field_value1) ipap_message.include_data(template_id, ipap_data_record) template = self.ipap_message_parser.read_template( ipap_message, TemplateType.IPAP_SETID_AUCTION_TEMPLATE) self.assertEqual(template.get_type(), TemplateType.IPAP_SETID_AUCTION_TEMPLATE) with self.assertRaises(ValueError): template = self.ipap_message_parser.read_template( ipap_message, TemplateType.IPAP_OPTNS_AUCTION_TEMPLATE)
def get_ipap_message(self, allocation: Allocation, template_container: IpapTemplateContainer) -> IpapMessage: """ :return: """ message = IpapMessage(self.domain, IpapMessage.IPAP_VERSION, True) auction_manager = AuctionManager(self.domain) auction = auction_manager.get_auction(allocation.get_auction_key()) # Find both templates types for the bidding object. temp_type = IpapTemplate.get_data_template(allocation.get_template_object_type()) data_template_id = auction.get_bidding_object_template(allocation.get_template_object_type(), temp_type) temp_type = IpapTemplate.get_opts_template(allocation.get_template_object_type()) option_template_id = auction.get_bidding_object_template(allocation.get_template_object_type(), temp_type) # Insert allocations's templates.a data_template = template_container.get_template(data_template_id) message.make_template(data_template) option_template = template_container.get_template(option_template_id) message.make_template(option_template) # Include data records. self.include_data_record(data_template, allocation, 'Record_1', allocation.config_params, message) # Include option records. index = 1 for interval in allocation.intervals: record_id = 'Record_{0}'.format(str(index)) self.include_options_record(option_template, allocation, record_id, interval.start, interval.stop, message) index = index + 1 return message
def setUp(self): self.ipap_message = IpapMessage(1, 1, False) self.ipap_message2 = IpapMessage(1, 1, True)
class IpapMessageTest(unittest.TestCase): """ IpapMessageTest """ def setUp(self): self.ipap_message = IpapMessage(1, 1, False) self.ipap_message2 = IpapMessage(1, 1, True) def test_new_data_template(self): val = self.ipap_message.new_data_template( 10, TemplateType.IPAP_SETID_AUCTION_TEMPLATE) self.assertEqual(val, 256) def test_add_field(self): template_id = self.ipap_message.new_data_template( 10, TemplateType.IPAP_SETID_AUCTION_TEMPLATE) self.ipap_message.add_field(template_id, 0, 30) # test adding an invalid field with self.assertRaises(ValueError): self.ipap_message.add_field(template_id, 0, 3000) # test adding an invalid template id. with self.assertRaises(ValueError): self.ipap_message.add_field(2, 0, 30) def test_delete_template(self): print('start test_delete_template') template_id = self.ipap_message.new_data_template( 10, TemplateType.IPAP_SETID_AUCTION_TEMPLATE) self.ipap_message.add_field(template_id, 0, 30) self.ipap_message.delete_template(template_id) lst = self.ipap_message.get_template_list() self.assertEqual(len(lst), 0) def test_delete_all_templates(self): print('start test_delete_all_templates') template_id = self.ipap_message.new_data_template( 10, TemplateType.IPAP_SETID_AUCTION_TEMPLATE) self.ipap_message.add_field(template_id, 0, 30) self.ipap_message.delete_all_templates() lst = self.ipap_message.get_template_list() self.assertEqual(len(lst), 0) def test_get_template_list(self): print('start test_get_template_list') template_id = self.ipap_message.new_data_template( 10, TemplateType.IPAP_SETID_AUCTION_TEMPLATE) self.ipap_message.add_field(template_id, 0, 30) lst = self.ipap_message.get_template_list() self.assertEqual(lst[0], 256) def test_get_template_object(self): print('start test_get_template_object') template_id = self.ipap_message.new_data_template( 10, TemplateType.IPAP_SETID_AUCTION_TEMPLATE) self.ipap_message.add_field(template_id, 0, 30) template = self.ipap_message.get_template_object(template_id) template_type = template.get_type() self.assertEqual(template_type, TemplateType.IPAP_SETID_AUCTION_TEMPLATE) lst = template.get_fields() print('num fields:', len(lst)) with self.assertRaises(ValueError): template = self.ipap_message.get_template_object(4) def test_include_data(self): print('in test_include_data') template_id = self.ipap_message.new_data_template( 10, TemplateType.IPAP_SETID_AUCTION_TEMPLATE) self.ipap_message.add_field(template_id, 0, 30) template = self.ipap_message.get_template_object(template_id) lst = template.get_fields() ipap_data_record = IpapDataRecord(templ_id=template_id) ipap_field_value1 = IpapValueField() value = 12231213 ipap_field_value1.set_value_uint64(value) template = self.ipap_message.get_template_object(template_id) lst = template.get_fields() # Replace the value ipap_data_record.insert_field(0, 30, ipap_field_value1) self.ipap_message.include_data(template_id, ipap_data_record) record_size = self.ipap_message.get_data_record_size() self.assertEqual(record_size, 1) def test_get_data_record_at_pos(self): template_id = self.ipap_message.new_data_template( 10, TemplateType.IPAP_SETID_AUCTION_TEMPLATE) self.ipap_message.add_field(template_id, 0, 30) ipap_data_record = IpapDataRecord(templ_id=template_id) ipap_field_value1 = IpapValueField() value = 12231213 ipap_field_value1.set_value_uint64(value) # Replace the value ipap_data_record.insert_field(0, 30, ipap_field_value1) self.ipap_message.include_data(template_id, ipap_data_record) ipap_data_record2 = self.ipap_message.get_data_record_at_pos(0) def test_import(self): print('In test import') self.ipap_message2.set_syn(True) self.ipap_message2.set_seqno(300) self.ipap_message2.output() str_msg = self.ipap_message2.get_message() ipap_message3 = IpapMessage(1, 1, True, str_msg) str_msg = 'aqui estoy' with self.assertRaises(ValueError): ipap_message4 = IpapMessage(1, 1, True, str_msg)
def split(self, ipap_message: IpapMessage) -> (dict, dict, dict): """ parse the ipap message by splitting message data by object key ( Auctions, Bids, Allocations). :param ipap_message: message to parse :return: """ data_record_count = ipap_message.get_data_record_size() templates_included = {} object_templates = {} object_data_records = {} templates_not_related = {} for i in range(0, data_record_count): data_record = ipap_message.get_data_record_at_pos(i) template_id = data_record.get_template_id() try: template = ipap_message.get_template_object(template_id) except ValueError: raise ValueError( "required template not included in the message") templates_included[template_id] = template_id templ_type = template.get_type() try: # Obtain template keys data_key = '' key_fields = template.get_template_type_key_field(templ_type) for key_field in key_fields: field = template.get_field(key_field.get_eno(), key_field.get_ftype()) value = data_record.get_field(key_field.get_eno(), key_field.get_ftype()) data_key = data_key + field.write_value(value) object_type = template.get_object_type(templ_type) ipap_object_key = IpapObjectKey(object_type, data_key) if ipap_object_key not in object_templates.keys(): object_templates[ipap_object_key] = [] object_templates[ipap_object_key].append(template) if ipap_object_key not in object_data_records: object_data_records[ipap_object_key] = [] object_data_records[ipap_object_key].append(data_record) except ValueError as e: raise ValueError( "error while reading data record - error: {0}", str(e)) # Copy templates from message that are not related with a record data templates = ipap_message.get_template_list() for template_id in templates: if template_id not in templates_included: templates_not_related[ template_id] = ipap_message.get_template_object( template_id) return object_templates, object_data_records, templates_not_related
def include_auction_data_record(self, template: IpapTemplate, auction: Auction, message: IpapMessage, use_ipv6: bool, s_address: str, port: int): """ Adds the option data record template associated with the option data auction template :param template template used for the data record. :param auction auction being included in the message. :param message: message being built. :param use_ipv6: whether or not it use ipv6 :param s_address: source address :param port: source port """ ipap_data_record = IpapDataRecord(obj=None, templ_id=template.get_template_id()) # Insert the auction id field. self.insert_string_field('auctionid', auction.get_key(), ipap_data_record) # Add the Record Id self.insert_string_field('recordid', "Record_1", ipap_data_record) # Add the Status self.insert_integer_field('status', auction.get_state().value, ipap_data_record) # Add the IP Version if use_ipv6: ipversion = 6 else: ipversion = 4 self.insert_integer_field('ipversion', ipversion, ipap_data_record) # Add the Ipv6 Address value if use_ipv6: self.insert_ipv6_field('dstipv6', s_address, ipap_data_record) else: self.insert_ipv6_field('dstipv6', "0:0:0:0:0:0:0:0", ipap_data_record) # Add the Ipv4 Address value if use_ipv6: self.insert_ipv4_field('dstipv4', "0.0.0.0", ipap_data_record) else: self.insert_ipv4_field('dstipv4', s_address, ipap_data_record) # Add destination port self.insert_integer_field('dstauctionport', port, ipap_data_record) # Add the resource Id. self.insert_string_field('resourceid', auction.get_resource_key(), ipap_data_record) # Add the start time - Unix time is seconds from 1970-1-1 . self.insert_datetime_field('start', auction.get_start(), ipap_data_record) # Add the end time. self.insert_datetime_field('stop', auction.get_stop(), ipap_data_record) # Add the interval. How much time between executions (seconds). u_interval = auction.get_interval().interval self.insert_integer_field('interval', u_interval, ipap_data_record) # Add the template list. self.insert_string_field('templatelist', auction.get_template_list(), ipap_data_record) message.include_data(template.get_template_id(), ipap_data_record)
async def send_ack_disconnect(self, server_connection: ServerConnection, ipap_message: IpapMessage): """ Sends the ack disconnect message. :param server_connection: websocket and aiohttp session created for the connection :param ipap_message: message sent from the server. :return: """ self.logger.debug("Starting send_ack_disconnect") # verifies ack sequence number ack_seqno = ipap_message.get_ackseqno() try: server_connection.get_auction_session().confirm_message(ack_seqno) except ValueError: # nothing was expected to be acknowledged pass # verifies the connection state if server_connection.state == ServerConnectionState.ESTABLISHED: self.logger.debug("starting to disconnect from server connection state established") message = self.build_ack_message(server_connection.get_auction_session().get_next_message_id(), ipap_message.get_seqno()) print('message ack disconnect id:', message.get_seqno()) await self.send_message(server_connection, message.get_message()) self.logger.debug("disconnecting - before putting close_wait ") # server_connection.set_state(ServerConnectionState.CLOSE_WAIT) self.logger.debug("disconnecting - after putting close_wait ") from auction_client.auction_client_handler import HandleResourceRequestTeardown handle_tear_down = HandleResourceRequestTeardown(server_connection.get_auction_session().get_key()) await handle_tear_down.start() self.logger.debug("disconnecting - after removing resource request ") message = self.build_fin_message(server_connection.get_auction_session().get_next_message_id(), 0) server_connection.get_auction_session().add_pending_message(message) print('message fin message id:', message.get_seqno()) await self.send_message(server_connection, message.get_message()) self.logger.debug("disconnecting - after sending fin message ") server_connection.set_state(ServerConnectionState.LAST_ACK) self.logger.debug("ending to disconnect from server connection state established") # verifies the connection state elif server_connection.get_state() == ServerConnectionState.FIN_WAIT_2: # send the ack message establishing the session. message = self.build_ack_message(server_connection.get_auction_session().get_next_message_id(), ipap_message.get_seqno()) print('message fin wait ack id:', message.get_seqno()) await self.send_message(server_connection, message.get_message()) await self._disconnect_socket(server_connection) self.auction_session_manager.del_session(server_connection.get_auction_session().get_key()) server_connection.set_state(ServerConnectionState.CLOSED) else: # The server is not in syn sent state, so ignore the message self.logger.info("A msg with fin state was received,but the server is not in fin_wait state, ignoring it") self.logger.debug("Ending send_ack_disconnect- new state {0}".format(str(server_connection.get_state())))