def verify_auction(self, auction: Auction) -> bool: """ Brings the resource and verify that after inserting the auction resource intervals are still valid. :param auction: auction to be verified :return: True if correct, False Otherwise """ # Bring the auction's resource key resource_key = auction.get_resource_key() try: resource = self.get_resource(resource_key) # Auction does not exist in the resource if resource.exist_auction(auction.get_key()): return False # If intervals are not incorrect, then returns true. return resource.verify_auction(auction) except ValueError as e: self.logger.error("The resource with key {0} was not found, \ so the auction is invalid.".format( resource_key)) return False
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 verify_auction(self, auction: Auction) -> bool: """ Verifies whether or not the auction can be added to the resource :param auction: auction to be verified :return: True if it is possible to add, false otherwise. """ start_auction = auction.get_start() stop_auction = auction.get_stop() for key in self.auctions: start = self.auctions[key].get_start() stop = self.auctions[key].get_stop() if (start_auction <= start) and (start <= stop_auction) and ( stop_auction <= stop): return False if (start <= start_auction) and (stop_auction <= stop): return False if (start_auction <= stop) and (stop <= stop_auction): return False return True
def add_auction_request(self, key: str, auction: Auction): """ Adds an auction to auction list in the request. :param key: request process key where the auction is going to be added :param auction: auction to add :return: """ if key not in self.requests: raise ValueError("Request key:{0} was not found".format(key)) request_process = self.requests[key] # Second, look for the auction in the list of auction already inserted, if it exists generates an error if auction.get_key() in request_process.auctions: raise ValueError( "Auction key:{0} is already inserted in the request process {1}" .format(auction.get_key(), key)) # Searches for the module name on those already loaded. module_name = auction.get_action().get_name() + "user" if module_name == request_process.get_module().get_module_name(): request_process.auctions[auction.get_key()] = auction else: raise ValueError( "the module loaded {0} must be the same {1} for request {2}". format(module_name, request_process.get_module().get_module_name(), key))
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 add_request(self, session_id: str, request_params: dict, auction: Auction, server_domain: int, start: datetime, stop: datetime) -> str: """ Adds a new request to the list of request to execute. :param session_id: session Id to be used :param request_params: request parameters for the process :param auction: auction to be used :param server_domain: server domain :param start: start date time :param stop: end date time :return: key for the request process created. """ module_name = auction.get_action().get_name() + "_user" module = self.module_loader.get_module(module_name) key = str(IdSource(True).new_id()) self.logger.info("new request process key {0}".format(key)) request_params = deepcopy(request_params) other_params = self.create_config_params() request_params.update(other_params) request_process = RequestProcess(key, session_id, module, auction, server_domain, request_params, start, stop) module.init_module(request_process.get_request_params()) self.requests[key] = request_process return key
def delete_auction(self, auction: Auction): """ deletes an auction :param auction: auction to be deleted :return: """ self.delete_auction_process(auction.get_key())
def add_auction_process(self, auction: Auction): """ adds a Auction to auction process list :param auction: auction to be added """ key = auction.get_key() action = auction.get_action() module_name = action.name module = self.module_loader.get_module(module_name) config_params = deepcopy(action.get_config_params()) if 'domainid' not in config_params: config_params['domainid'] = ConfigParam('domainid', DataType.UINT32, str(self.domain)) action_process = AuctionProcess(key, module, auction, config_params) module.init_module(action_process.get_config_params()) self.auctions[key] = action_process return key
def delete_auction_request(self, key: str, auction: Auction): """ Deletes an auction to auction list in the request. :param key: request process key where the auction is going to be deletec :param auction: auction to delete :return: """ if key not in self.requests: raise ValueError("Request key:{0} was not found".format(key)) request_process = self.requests[key] if auction.get_key() not in request_process.auctions: raise ValueError( "Auction with key:{0} was not found in request process with key" .format(auction.get_key().key)) else: request_process.auctions.pop(auction.get_key())
def add_auction(self, auction: Auction): """ Adds an auction to the resource :param auction: auction to add :return: """ key = auction.get_key() if key in self.auctions.keys(): raise ValueError( "auction with key:{} is already in the resource".format(key)) else: self.auctions[key] = auction
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_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 build_associated_templates(self, templates: list, auction: Auction, ipap_template_container: IpapTemplateContainer): """ Builds associated templates related to the auction :param templates: list of templates within the message :param auction: auction being created :param ipap_template_container: container to maintain those related templates. :return: """ template_fields = {} for template in templates: if template.get_type() not in [TemplateType.IPAP_SETID_AUCTION_TEMPLATE, TemplateType.IPAP_OPTNS_AUCTION_TEMPLATE]: self.include_template_fields(template, template_fields) build_templates = auction.build_templates(template_fields) for template in build_templates: ipap_template_container.add_template(template)
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)
def _parse_auction(self, node: Element, global_set: str, global_misc_config: dict, global_actions: dict, field_container: IpapFieldContainer): """ Parses an auction node in the xml. :param node: Element element to parse :param global_set: str global set :param global_misc_config: dict dictionary with miscelaneous field configurations. :param global_actions: dict dictionary with actions :param field_container: IpapFieldContainer container with all fields in the system. :return: """ # get the Id property # deep copy global dictionaries, so we can overide them misc_config = deepcopy(global_misc_config) actions = deepcopy(global_actions) auction_id = node.get("ID").lower() (set_name, name) = self.parse_name(auction_id) if not set_name: if global_set.isnumeric(): set_name = global_set else: set_name = str(self.domain) # Get Resource set and resource Id resurce_set = node.get("RESOURCE_SET").lower() resource_id = node.get("RESOURCE_ID").lower() templ_fields = {} # Iterates over children nodes for subitem in node.iterchildren(): if isinstance(subitem.tag, str): if subitem.tag.lower() == "pref": config_param = ConfigParam() config_param.parse_config_item(subitem) misc_config[config_param.name] = config_param elif subitem.tag.lower() == "field": field_name, field = self._parse_field(subitem) templ_fields[field_name] = field elif subitem.tag.lower() == "action": action = Action("", False, dict()) action.parse_action(subitem) action.default_action = True # This is the default action, actions[action.name] = action # get the default action action_default = None for action_name in actions: if actions[action.name].default_action: action_default = action auction_key = set_name + '.' + name resource_key = resurce_set + '.' + resource_id auction = Auction(auction_key, resource_key, action_default, misc_config) templates = auction.build_templates(templ_fields) return auction, templates
def parse_auction(self, object_key: IpapObjectKey, templates: list, data_records: list, ipap_template_container: IpapTemplateContainer) -> Auction: """ Parse an auction from the ipap_message :param templates: templates for the auction :param data_records: records for the auction :param ipap_template_container: template container where we have to include the templates. :return: auction parsed. """ nbr_data_read = 0 nbr_option_read = 0 auction_key = None auction_status = None resource_key = None template_list = None action_name = None data_misc = {} opts_misc = {} data_template, opts_template = self.insert_auction_templates(object_key.get_object_type(), templates, ipap_template_container) # Read data records for data_record in data_records: template_id = data_record.get_template_id() # Read a data record for a data template if template_id == data_template.get_template_id(): data_misc = self.read_record(data_template, data_record) auction_key = self.extract_param(data_misc, 'auctionid') auction_status = self.extract_param(data_misc, 'status') resource_key = self.extract_param(data_misc, 'resourceid') template_list = self.extract_param(data_misc, 'templatelist') nbr_data_read = nbr_data_read + 1 if template_id == opts_template.get_template_id(): opts_misc = self.read_record(opts_template, data_record) action_name = self.extract_param(opts_misc, 'algoritmname') nbr_option_read = nbr_option_read + 1 if nbr_data_read > 1: raise ValueError("The message included more than one data template") if nbr_data_read == 0: raise ValueError("The message not included a data template") if nbr_option_read > 1: raise ValueError("The message included more than one options template") if nbr_option_read == 0: raise ValueError("The message not included a options template") action = Action(action_name.value, True, opts_misc) auction = Auction(auction_key.value, resource_key.value, action, data_misc) auction.set_state(AuctioningObjectState(ParseFormats.parse_int(auction_status.value))) template_ids = template_list.value.split(',') for template_sid in template_ids: template = ipap_template_container.get_template(ParseFormats.parse_int(template_sid)) auction.set_bidding_object_template(template.get_object_type(template.get_type()), template.get_type(), template.get_template_id()) return auction
def insert_auction(self, auction: Auction): if auction.get_key() not in self.auctions: self.auctions[auction.get_key()] = auction else: raise ValueError( "Auction is already inserted in the RequestProcess")