Exemple #1
0
class DefFileManagerTest(unittest.TestCase):
    def setUp(self):
        self.def_file_manager = FieldDefManager()

    def test_get_field_defs(self):
        field_defs = self.def_file_manager.get_field_defs()
        self.assertEqual(len(field_defs), 51)

    def test_get_field_vals(self):
        field_vals = self.def_file_manager.get_field_vals()
        self.assertEqual(len(field_vals), 1)

    def test_get_field(self):
        # Field found
        field_found = self.def_file_manager.get_field("templatelist")
        self.assertEqual(field_found['type'], DataType.STRING)

        # Field not found
        with self.assertRaises(ValueError):
            field_not_found = self.def_file_manager.get_field("templatelist0")

    def test_get_field_by_code(self):
        field_found = self.def_file_manager.get_field_by_code(0, 31)
        self.assertEqual(field_found['name'], "AlgorithmName")

        # Field not found
        with self.assertRaises(ValueError):
            field_not_found = self.def_file_manager.get_field_by_code(0, 310)

        # Field not found
        with self.assertRaises(ValueError):
            field_not_found = self.def_file_manager.get_field_by_code(100, 31)

    def test_get_field_value(self):
        field_value = self.def_file_manager.get_field_value('IpAddr', 'srcip')
        self.assertEqual(field_value, '190.0.0.1')

        # Field Value not found
        with self.assertRaises(ValueError):
            field_value = self.def_file_manager.get_field_value(
                'Type', 'srcip0')

        # Field Value not found
        with self.assertRaises(ValueError):
            field_value = self.def_file_manager.get_field_value(
                'Type2', 'srcip')
class IpapMessageParser:
    def __init__(self, domain: int):
        self.domain = domain
        self.field_def_manager = FieldDefManager()
        self.field_container = IpapFieldContainer()
        self.field_container.initialize_reverse()
        self.field_container.initialize_forward()

    @staticmethod
    def parse_name(id_auction: str) -> (str, str):
        """
        Parses an object name (auction or bid).

        :param id_auction: Identifier formated as 'setname.objectname'
        :return: (set_name, name)
        """
        if len(id_auction) == 0:
            raise ValueError(
                "malformed identifier {0}, use <identifier> or <set>.<identifier> "
                .format(id_auction))

        ids = id_auction.split(".")

        if len(ids) == 0:
            raise ValueError(
                "malformed identifier {0}, use <identifier> or <set>.<identifier> "
                .format(id_auction))

        elif len(ids) == 1:
            set_name = ""
            name = ids[0]
            return set_name, name

        elif len(ids) == 2:
            set_name = ids[0]
            name = ids[1]
            return set_name, name
        else:
            raise ValueError(
                "malformed identifier {0}, use <identifier> or <set>.<identifier> "
                .format(id_auction))

    @staticmethod
    def parse_object_type(s_type: str) -> ObjectType:
        """
        Parses the type of bidding object

        :param s_type: object type represented as string
        :return:
        """
        if (s_type == "auction") or (s_type == "0"):
            obj_type = ObjectType.IPAP_AUCTION
            return obj_type

        elif (s_type == "bid") or (s_type == "1"):
            obj_type = ObjectType.IPAP_BID
            return obj_type

        elif (s_type == "ask") or (s_type == "2"):
            obj_type = ObjectType.IPAP_ASK
            return obj_type

        elif (s_type == "allocation") or (s_type == "3"):
            obj_type = ObjectType.IPAP_ALLOCATION
            return obj_type

        else:
            raise ValueError(
                "Bidding Object Parser Error: invalid bidding object type {0}".
                format(s_type))

    @staticmethod
    def parse_template_type(obj_type: ObjectType,
                            templ_type: str) -> TemplateType:
        """
        Parses a template type

        :param obj_type: object type for which this template type belongs to
        :param templ_type: template type represented as string
        :return: template type
        """
        if obj_type == ObjectType.IPAP_AUCTION:
            if templ_type == "data":
                return TemplateType.IPAP_SETID_AUCTION_TEMPLATE
            elif templ_type == "option":
                return TemplateType.IPAP_OPTNS_AUCTION_TEMPLATE

        elif obj_type == ObjectType.IPAP_BID:
            if templ_type == "data":
                return TemplateType.IPAP_SETID_BID_OBJECT_TEMPLATE
            elif templ_type == "option":
                return TemplateType.IPAP_OPTNS_BID_OBJECT_TEMPLATE

        elif obj_type == ObjectType.IPAP_ASK:
            if templ_type == "data":
                return TemplateType.IPAP_SETID_ASK_OBJECT_TEMPLATE
            elif templ_type == "option":
                return TemplateType.IPAP_OPTNS_ASK_OBJECT_TEMPLATE

        elif obj_type == ObjectType.IPAP_ALLOCATION:
            if templ_type == "data":
                return TemplateType.IPAP_SETID_ALLOC_OBJECT_TEMPLATE
            elif templ_type == "option":
                return TemplateType.IPAP_OPTNS_ALLOC_OBJECT_TEMPLATE

        raise ValueError("Bidding Object Parser Error: invalid template type")

    @staticmethod
    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")

    @staticmethod
    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 include_non_mandatory_fields(self, mandatory_fields: list,
                                     config_params: dict,
                                     ipap_record: IpapDataRecord):
        """
        Includes non mandatory fields in record

        :param mandatory_fields: list of mandatory fields
        :param config_params: params to include. We should check that are non mandatory fields.
        :param ipap_record: record where we want to include config params
        :return:
        """
        for item in config_params.values():
            field = self.field_def_manager.get_field(item.name)

            # Checks it is not a mandatory field.
            is_mandatory: bool = False
            for mandatory_field in mandatory_fields:
                if mandatory_field.get_eno(
                ) == field['eno'] and mandatory_field.get_ftype(
                ) == field['ftype']:
                    is_mandatory = True
                    break

            if not is_mandatory:
                # check the field is a valid field for the message
                field_act = self.field_container.get_field(
                    field['eno'], field['ftype'])
                act_f_value = field_act.parse(item.value)
                ipap_record.insert_field(field['eno'], field['ftype'],
                                         act_f_value)

    def insert_auction_templates(
        self, object_type: ObjectType, templates: list,
        ipap_template_container: IpapTemplateContainer
    ) -> (IpapTemplate, IpapTemplate):
        """
        Insert auction templates (data and options)
        :param object_type: object type for which we want to insert the templates
        :param templates: list of templates
        :param ipap_template_container: template container where we have to include templates.
        :return: return data and options templates
        """
        data_template = None
        opts_template = None

        # Insert record and options templates for the auction.
        for template in templates:
            if template.get_type() == IpapTemplate.get_data_template(
                    object_type):
                data_template = template
            elif template.get_type() == IpapTemplate.get_opts_template(
                    object_type):
                opts_template = template

        if data_template is None:
            raise ValueError(
                "The message is incomplete Data template was not included")

        if opts_template is None:
            raise ValueError(
                "The message is incomplete Options template was not included")

        # Verify templates
        self.verify_insert_template(data_template, ipap_template_container)
        self.verify_insert_template(opts_template, ipap_template_container)

        return data_template, opts_template

    @staticmethod
    def verify_insert_template(template: IpapTemplate,
                               ipap_template_container: IpapTemplateContainer):
        """
        Verifies and in case of not included before inserts the template given in the template container

        :param template: template to include
        :param ipap_template_container: template container where templates should be verified.
        """
        # Insert templates in case of not created in the template container.
        if ipap_template_container.exists_template(template.get_template_id()):
            template_ret = ipap_template_container.get_template(
                template.get_template_id())
            if not template_ret.__eq__(template):
                raise ValueError(
                    "Data Template {0} given is different from the template already stored"
                    .format(template.get_template_id()))

        else:
            ipap_template_container.add_template(template)

    @staticmethod
    def parse_type(s_type: str) -> ObjectType:
        """
        parses the type of bidding object

        :param s_type string representing the type
        :return: object type
        """
        if (s_type == "auction") or (s_type == "0"):
            object_type = ObjectType.IPAP_AUCTION

        elif (s_type == "bid") or (s_type == "1"):
            object_type = ObjectType.IPAP_BID

        elif (s_type == "ask") or (s_type == "2"):
            object_type = ObjectType.IPAP_ASK

        elif (s_type == "allocation") or (s_type == "3"):
            object_type = ObjectType.IPAP_ALLOCATION

        else:
            raise ValueError(
                "Bidding Object Parser Error: invalid bidding object type {0}".
                format(s_type))

        return object_type

    @staticmethod
    def get_auctioning_object_type(
            object_type: ObjectType) -> AuctioningObjectType:
        """
        Gets the auctioning object type for the object type in the ipap_message

        :param object_type: object type to get the corresponding auctioning object type
        :return: auctioning object type
        """
        if object_type == ObjectType.IPAP_AUCTION:
            return AuctioningObjectType.AUCTION
        elif object_type == ObjectType.IPAP_BID:
            return AuctioningObjectType.BID
        elif object_type == ObjectType.IPAP_ALLOCATION:
            return AuctioningObjectType.ALLOCATION
        else:
            raise ValueError(
                "invalid object type, it does not represent a valid auctioning object type"
            )

    def get_domain(self) -> int:
        """
        Get the domaid id used by the ipapmessage.The domain id corresponds to the agent identifier.
        :return: domain
        """
        return self.domain

    def read_record(self, template: IpapTemplate,
                    record: IpapDataRecord) -> dict:
        """
        Reads an auction data record
        :param template: record's template
        :param record: data record
        :return: config values
        """
        config_params = {}
        for field_pos in range(0, record.get_num_fields()):
            ipap_field_key = record.get_field_at_pos(field_pos)
            ipap_field_value = record.get_field(ipap_field_key.get_eno(),
                                                ipap_field_key.get_ftype())
            f_item = self.field_def_manager.get_field_by_code(
                ipap_field_key.get_eno(), ipap_field_key.get_ftype())

            # ipap_field_value.print_value()

            ipap_field = template.get_field(ipap_field_key.get_eno(),
                                            ipap_field_key.get_ftype())
            config_param = ConfigParam(
                name=f_item['key'],
                p_type=f_item['type'],
                value=ipap_field.write_value(ipap_field_value))
            config_params[config_param.name] = config_param
        return config_params

    def get_misc_val(self, config_items: dict, item_name: str) -> str:

        if item_name in config_items:
            item: ConfigParam = config_items[item_name]
            value = item.value.lower()
            return value
        else:
            raise ValueError(
                "item with name {0} not found in config items".format(
                    item_name))

    @staticmethod
    def extract_param(config_items: dict, item_name: str) -> ConfigParam:
        """
        Extracts a parameter by name from the list of config items, returns the config param.
        the list config items is altered by removing the parameter.

        :param config_items: config params
        :param item_name: config item name to find.
        :return: the config param
        """
        if item_name in config_items:
            return config_items.pop(item_name)
        else:
            raise ValueError(
                "item with name {0} not found in config items".format(
                    item_name))

    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 insert_string_field(self, field_name: str, value: str,
                            record: IpapDataRecord):
        """
        Inserts a field value in the data record given as parameter

        :param field_name: field to be inserted
        :param value: value to insert
        :param record: data record where the field is going to be inserted.
        """
        field_def = self.field_def_manager.get_field(field_name)
        field: IpapField = self.field_container.get_field(
            int(field_def['eno']), int(field_def['ftype']))

        # It is required to encode as ascii because the C++ wrapper requires it.
        value_encoded = value.encode('ascii')
        field_val = field.get_ipap_field_value_string(value_encoded)
        record.insert_field(int(field_def['eno']), int(field_def['ftype']),
                            field_val)

    def insert_integer_field(self, field_name: str, value: int,
                             record: IpapDataRecord):
        """
        Inserts a field value in the data record given as parameter

        :param field_name: field to be inserted
        :param value: value to insert
        :param record: data record where the field is going to be inserted.
        """
        field_def = self.field_def_manager.get_field(field_name)
        field: IpapField = self.field_container.get_field(
            int(field_def['eno']), int(field_def['ftype']))

        if field.get_length() == 1:
            record.insert_field(int(field_def['eno']), int(field_def['ftype']),
                                field.get_ipap_field_value_uint8(value))
        elif field.get_length() == 2:
            record.insert_field(int(field_def['eno']), int(field_def['ftype']),
                                field.get_ipap_field_value_uint16(value))
        elif field.get_length() == 4:
            record.insert_field(int(field_def['eno']), int(field_def['ftype']),
                                field.get_ipap_field_value_uint32(value))
        elif field.get_length() == 8:
            record.insert_field(int(field_def['eno']), int(field_def['ftype']),
                                field.get_ipap_field_value_uint64(value))

    def insert_float_field(self, field_name: str, value: float,
                           record: IpapDataRecord):
        """
        Inserts a field value in the data record given as parameter

        :param field_name: field to be inserted
        :param value: value to insert
        :param record: data record where the field is going to be inserted.
        """
        field_def = self.field_def_manager.get_field(field_name)
        field: IpapField = self.field_container.get_field(
            int(field_def['eno']), int(field_def['ftype']))
        record.insert_field(int(field_def['eno']), int(field_def['ftype']),
                            field.get_ipap_field_value_float(value))

    def insert_double_field(self, field_name: str, value: float,
                            record: IpapDataRecord):
        """
        Inserts a field value (double) in the data record given as parameter

        :param field_name: field to be inserted
        :param value: value to insert
        :param record: data record where the field is going to be inserted.
        """
        field_def = self.field_def_manager.get_field(field_name)
        field: IpapField = self.field_container.get_field(
            int(field_def['eno']), int(field_def['ftype']))
        record.insert_field(int(field_def['eno']), int(field_def['ftype']),
                            field.get_ipap_field_value_double(value))

    def insert_ipv4_field(self, field_name: str, value: str,
                          record: IpapDataRecord):
        """
        Inserts a field value (ip address 4) in the data record given as parameter

        :param field_name: field to be inserted
        :param value: value to insert
        :param record: data record where the field is going to be inserted.
        """
        field_def = self.field_def_manager.get_field(field_name)
        field: IpapField = self.field_container.get_field(
            int(field_def['eno']), int(field_def['ftype']))
        value_encoded = value.encode('ascii')
        record.insert_field(int(field_def['eno']), int(field_def['ftype']),
                            field.get_ipap_field_value_ipv4(value_encoded))

    def insert_ipv6_field(self, field_name: str, value: str,
                          record: IpapDataRecord):
        """
        Inserts a field value (ip address 6) in the data record given as parameter

        :param field_name: field to be inserted
        :param value: value to insert
        :param record: data record where the field is going to be inserted.
        """
        field_def = self.field_def_manager.get_field(field_name)
        field: IpapField = self.field_container.get_field(
            int(field_def['eno']), int(field_def['ftype']))
        value_encoded = value.encode('ascii')
        record.insert_field(int(field_def['eno']), int(field_def['ftype']),
                            field.get_ipap_field_value_ipv6(value_encoded))

    def insert_datetime_field(self, field_name: str, value: datetime,
                              record: IpapDataRecord):
        """
        Inserts a field value (datetime) in the data record given as parameter

        :param field_name: field to be inserted
        :param value: value to insert
        :param record: data record where the field is going to be inserted.
        """
        seconds = int((value - datetime.fromtimestamp(0)).total_seconds())
        self.insert_integer_field(field_name, seconds, record)
Exemple #3
0
class AuctionProcessor(IpapMessageParser, metaclass=Singleton):
    """
    This class manages and executes algorithms for a set of auctions.

    Attributes
    ----------
    """

    def __init__(self, domain: int, module_directory: str=None):
        super(AuctionProcessor, self).__init__(domain)
        self.auctions = {}
        self.config = Config().get_config()
        self.field_sets = {}
        self.logger = log().get_logger()
        self.field_def_manager = FieldDefManager()

        if not module_directory:
            if 'AUMProcessor' in self.config:
                if 'ModuleDir' in self.config['AUMProcessor']:
                    module_directory = self.config['AUMProcessor']['ModuleDir']
                else:
                    ValueError(
                        'Configuration file does not have {0} entry within {1}'.format('ModuleDir', 'AumProcessor'))
            else:
                ValueError('Configuration file does not have {0} entry,please include it'.format('AumProcessor'))

        if 'AUMProcessor' in self.config:
            if 'Modules' in self.config['AUMProcessor']:
                modules = self.config['AUMProcessor']['Modules']
                self.module_loader = ModuleLoader(module_directory, 'AUMProcessor', modules)
            else:
                ValueError(
                    'Configuration file does not have {0} entry within {1}'.format('Modules', 'AumProcessor'))
        else:
            ValueError('Configuration file does not have {0} entry,please include it'.format('AumProcessor'))

        self.build_field_sets()

    def read_misc_data(self, ipap_template: IpapTemplate, ipap_record: IpapDataRecord) -> dict:
        """
        read the data given in the data record

        :param ipap_template: templete followed by data record
        :param ipap_record: record with the data.
        :return: dictionary with config values.
        """
        config_params = {}
        num_fields = ipap_record.get_num_fields()
        for pos in range(0, num_fields):
            try:

                field_key = ipap_record.get_field_at_pos(pos)

            except ValueError as e:
                self.logger.error(str(e))
                raise e

            try:
                field_def = self.field_def_manager.get_field_by_code(field_key.get_eno(), field_key.get_ftype())
                field = ipap_template.get_field(field_key.get_eno(), field_key.get_ftype())
                config_param = ConfigParam(field_def['name'], field_def['type'],
                                           field.write_value(ipap_record.get_field(
                                               field_key.get_eno(), field_key.get_ftype())))

                config_params[config_param.name.lower()] = config_param
            except ValueError as e:
                self.logger.error("Field with eno {0} and ftype {1} was \
                                    not parametrized".format(str(field_key.get_eno()),
                                                             str(field_key.get_ftype())))
                raise e
        return config_params

    def build_field_sets(self):
        """
        Builds the field sets required for managing message between the server and the agents.
        """
        # Fill data auctions fields
        agent_session = set()
        agent_session.add(IpapFieldKey(self.field_def_manager.get_field('ipversion')['eno'],
                                       self.field_def_manager.get_field('ipversion')['ftype']))
        agent_session.add(IpapFieldKey(self.field_def_manager.get_field('srcipv4')['eno'],
                                       self.field_def_manager.get_field('srcipv4')['ftype']))
        agent_session.add(IpapFieldKey(self.field_def_manager.get_field('srcipv6')['eno'],
                                       self.field_def_manager.get_field('srcipv6')['ftype']))
        agent_session.add(IpapFieldKey(self.field_def_manager.get_field('srcauctionport')['eno'],
                                       self.field_def_manager.get_field('srcauctionport')['ftype']))
        self.field_sets[AgentFieldSet.SESSION_FIELD_SET_NAME] = agent_session

        # Fill option auctions fields
        agent_search_fields = set()
        agent_search_fields.add(IpapFieldKey(self.field_def_manager.get_field('start')['eno'],
                                             self.field_def_manager.get_field('start')['ftype']))
        agent_search_fields.add(IpapFieldKey(self.field_def_manager.get_field('stop')['eno'],
                                             self.field_def_manager.get_field('stop')['ftype']))
        agent_search_fields.add(IpapFieldKey(self.field_def_manager.get_field('resourceid')['eno'],
                                             self.field_def_manager.get_field('resourceid')['ftype']))
        self.field_sets[AgentFieldSet.REQUEST_FIELD_SET_NAME] = agent_search_fields

    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 execute_auction(self, key: str, start: datetime, end: datetime) -> List[BiddingObject]:
        """
        Executes the allocation algorithm for the auction
        :return:
        """
        if key not in self.auctions:
            raise ValueError("auction process with index:{0} was not found".format(key))

        action_process = self.auctions[key]
        module = action_process.get_module()

        # Sends for auctioning only active bids
        bids = action_process.get_bids()
        active_bids = {}
        for bidding_object_key in bids:
            bidding_object: BiddingObject = bids[bidding_object_key]
            if bidding_object.get_state() == AuctioningObjectState.ACTIVE:
                active_bids[bidding_object_key] = bidding_object

        allocations = module.execute(action_process.get_config_params(), key, start, end, active_bids)

        # Updates the periods executed for the bidding object (include those inactive)
        for bidding_object_key in bids:
            bidding_object: BiddingObject = bids[bidding_object_key]
            bidding_object.increase_execution_periods()
            self.logger.info("bidding object key: {0} - number of periods:{1}".format(
                bidding_object.get_key(), str(bidding_object.get_execution_periods())))

        return allocations

    def add_bidding_object_to_auction_process(self, key: str, bidding_object: BiddingObject):
        """
        adds a bidding Object to auction process

        :param key: key of the auction process
        :param bidding_object: bidding object to add
        :return:
        """
        if key not in self.auctions:
            raise ValueError("auction process with index:{0} was not found".format(key))
        action_process = self.auctions[key]

        self.logger.info("auction process bids already included: {0} - bid to include: {1}".format(
            str(len(action_process.get_bids())), bidding_object.get_key()))

        if bidding_object.get_parent_key() != action_process.key:
            raise ValueError("bidding object given {0} is not for the auction {1}".format(
                bidding_object.get_key(), key))

        if bidding_object.get_type() == AuctioningObjectType.BID:
            action_process.insert_bid(bidding_object)
            bidding_object.associate_auction_process(key)
        else:
            raise ValueError("bidding object is not BID type")

        self.logger.info("auction process bids included after: {0} - bid to include: {1}".format(
            str(len(action_process.get_bids())), bidding_object.get_key()))

    def delete_bidding_object_from_auction_process(self, key: str, bidding_object: BiddingObject):
        """
        deletes a bidding Object from auction process

        :param key: key of the auction process
        :param bidding_object: bidding object to delete
        :return:
        """
        if key not in self.auctions:
            raise ValueError("auction process with index:{0} was not found".format(key))

        action_process = self.auctions[key]
        action_process.bids.pop(bidding_object.get_key(), None)
        bidding_object.disassociate_auction_process(key)

    def delete_auction_process(self, key: str):
        """
        Deletes an auction process from the list.
        The caller must to remove all loop entries created for this process
        auction.
        :param key key of the auction process
        :return:
        """
        if key not in self.auctions:
            raise ValueError("auction process with index:{0} was not found".format(key))

        action_process = self.auctions.pop(key, None)
        if action_process:
            self.module_loader.release_module(action_process.get_module().get_module_name())

    def get_auction_process(self, key: str) -> AuctionProcess:
        """
        Gets the auction process with the key given
        :param key: key to find
        :return: auction process
        """
        if key not in self.auctions:
            raise ValueError("auction process with index:{0} was not found".format(key))

        return self.auctions.get(key)

    def get_set_field(self, set_name: AgentFieldSet):
        """
        Returns teh requested field set

        :param set_name: set of field to get
        :return:
        """
        return self.field_sets[set_name]

    def get_session_information(self, message: IpapMessage) -> dict:
        """
        Gets the session information within the message.

        If the option template is empty, then the returned auction must be zero.
        If the option template has more that a record, then we assume all records have the same session information.

        :param message message from where to extract the session information.
        :return: map of values that identify the session
        """
        session_info = {}
        try:
            templ_opt_auction = self.read_template(message, TemplateType.IPAP_OPTNS_ASK_OBJECT_TEMPLATE)
            data_records = self.read_data_records(message, templ_opt_auction.get_template_id())
            for data_record in data_records:
                config_items = self.read_misc_data(templ_opt_auction, data_record)
                field_keys = self.get_set_field(AgentFieldSet.SESSION_FIELD_SET_NAME)
                for field_key in field_keys:
                    field = self.field_def_manager.get_field_by_code(
                        field_key.get_eno(), field_key.get_ftype())
                    field_name = field['name'].lower()
                    val = self.get_misc_val(config_items, field_name)
                    session_info[field_name] = val

                break
            return session_info

        except ValueError as e:
            self.logger.error("Error during processing of get session information - error:{0} ".format(str(e)))

    def delete_auction(self, auction: Auction):
        """
        deletes an auction
        :param auction: auction to be deleted
        :return:
        """
        self.delete_auction_process(auction.get_key())

    def insersect(self, start_dttm: datetime, stop_dttm: datetime, resource_id: str) -> list:
        """
        Finds auctions that are executed for the selected resource and for the time range

        :param start_dttm: start of the time interval
        :param stop_dttm: end of the time interval
        :param resource_id: resource for which we want to perform bidding.
        :return: list of applicable auctions
        """
        auctions_ret = []
        for auction_key in self.auctions:
            auction = self.auctions[auction_key].auction
            include = True
            if stop_dttm <= auction.get_start():
                include = False

            if auction.get_stop() <= start_dttm:
                include = False

            if (auction.get_resource_key() != resource_id) \
                    and (resource_id.lower() != "any"):
                include = False

            if include:
                auctions_ret.append(auction)

        return auctions_ret

    def get_applicable_auctions(self, message: IpapMessage) -> list:
        """
        Gets the auctions applicable given the options within the message.

        :rtype: list
        :param message:  message with the options to filter.
        :return: list of application auctions.
        """
        try:
            templ_opt_auction = self.read_template(message, TemplateType.IPAP_OPTNS_ASK_OBJECT_TEMPLATE)
            data_records = self.read_data_records(message, templ_opt_auction.get_template_id())

            for data_record in data_records:
                config_items = self.read_misc_data(templ_opt_auction, data_record)

                s_start_dttm = self.get_misc_val(config_items, "start")
                ipap_field = templ_opt_auction.get_field(self.field_def_manager.get_field("start")['eno'],
                                                         self.field_def_manager.get_field("start")['ftype'])
                start_dttm = datetime.fromtimestamp(ipap_field.parse(s_start_dttm).get_value_uint64())

                s_stop_dttm = self.get_misc_val(config_items, "stop")
                ipap_field = templ_opt_auction.get_field(self.field_def_manager.get_field("stop")['eno'],
                                                         self.field_def_manager.get_field("stop")['ftype'])
                stop_dttm = datetime.fromtimestamp(ipap_field.parse(s_stop_dttm).get_value_uint64())

                resource_id = self.get_misc_val(config_items, "resourceid")

                auctions = self.insersect(start_dttm, stop_dttm, resource_id)

                return auctions

        except ValueError as e:
            self.logger.error("Error during processing of applicable auctions - error:{0} ".format(str(e)))

    def get_number_auction_processes(self):
        """
        Gets the number of auction processes registered in the container

        :return:
        """
        return len(self.auctions)