Exemple #1
0
    async def run(self):
        """
        Run the client in full-auto mode.
        """
        # if not hasattr(self, 'on_event'):
        #     raise NotImplementedError("You must implement on_event.")
        self.loop = asyncio.get_event_loop()
        await self.create_party_registration(ven_id=self.ven_id)

        if not self.ven_id:
            logger.error("No VEN ID received from the VTN, aborting.")
            await self.stop()
            return

        if self.reports:
            await self.register_reports(self.reports)
            self.report_queue_task = self.loop.create_task(
                self._report_queue_worker())

        await self._poll()

        # Set up automatic polling
        if self.poll_frequency > timedelta(hours=24):
            logger.warning(
                "Polling with intervals of more than 24 hours is not supported. "
                "Will use 24 hours as the polling interval.")
            self.poll_frequency = timedelta(hours=24)
        cron_config = utils.cron_config(self.poll_frequency,
                                        randomize_seconds=self.allow_jitter)

        self.scheduler.add_job(self._poll, trigger='cron', **cron_config)
        self.scheduler.add_job(self._event_cleanup,
                               trigger='interval',
                               seconds=300)
        self.scheduler.start()
Exemple #2
0
    def _add(self, dataset):
        scheduler_id = dataset['id']
        date_start_on = dataset['start_datetime']
        date_start_off = dataset['end_datetime']
        duration = dataset['report_back_duration']

        scheduler_type = 'cron'
        config = utils.cron_config(utils.parse_duration(duration))
        args_on = dict(config,
                       start_date=date_start_on,
                       end_date=date_start_off)

        cb = partial(self.callback,
                     report_request_id=dataset['report_request_id'])

        self.scheduler.add_job(cb,
                               scheduler_type,
                               id='%son' % scheduler_id,
                               **args_on)
        logger.info('add job' + str(args_on))
def test_cron_config():
    assert utils.cron_config(timedelta(seconds=5)) == {
        'second': '*/5',
        'minute': '*',
        'hour': '*'
    }
    assert utils.cron_config(timedelta(minutes=1)) == {
        'second': '0',
        'minute': '*/1',
        'hour': '*'
    }
    assert utils.cron_config(timedelta(minutes=5)) == {
        'second': '0',
        'minute': '*/5',
        'hour': '*'
    }
    assert utils.cron_config(timedelta(hours=1)) == {
        'second': '0',
        'minute': '0',
        'hour': '*/1'
    }
    assert utils.cron_config(timedelta(hours=2)) == {
        'second': '0',
        'minute': '0',
        'hour': '*/2'
    }
    assert utils.cron_config(timedelta(hours=25)) == {
        'second': '0',
        'minute': '0',
        'hour': '0'
    }
    assert utils.cron_config(timedelta(seconds=10),
                             randomize_seconds=True) == {
                                 'second': '*/10',
                                 'minute': '*',
                                 'hour': '*',
                                 'jitter': 1
                             }
Exemple #4
0
    async def create_report(self, report_request):
        """
        Add the requested reports to the reporting mechanism.
        This is called when the VTN requests reports from us.

        :param report_request dict: The oadrReportRequest dict from the VTN.
        """
        # Get the relevant variables from the report requests
        report_request_id = report_request['report_request_id']
        report_specifier_id = report_request['report_specifier']['report_specifier_id']
        report_back_duration = report_request['report_specifier'].get('report_back_duration')
        granularity = report_request['report_specifier']['granularity']

        # Check if this report actually exists
        report = find_by(self.reports, 'report_specifier_id', report_specifier_id)
        if not report:
            logger.error(f"A non-existant report with report_specifier_id "
                         f"{report_specifier_id} was requested.")
            return False

        # Check and collect the requested r_ids for this report
        requested_r_ids = []
        for specifier_payload in report_request['report_specifier']['specifier_payloads']:
            r_id = specifier_payload['r_id']
            # Check if the requested r_id actually exists
            rd = find_by(report.report_descriptions, 'r_id', r_id)
            if not rd:
                logger.error(f"A non-existant report with r_id {r_id} "
                             f"inside report with report_specifier_id {report_specifier_id} "
                             f"was requested.")
                continue

            # Check if the requested measurement exists and if the correct unit is requested
            if 'measurement' in specifier_payload:
                measurement = specifier_payload['measurement']
                if measurement['item_description'] != rd.measurement.item_description:
                    logger.error(f"A non-matching measurement description for report with "
                                 f"report_request_id {report_request_id} and r_id {r_id} was given "
                                 f"by the VTN. Offered: {rd.measurement.item_description}, "
                                 f"requested: {measurement['item_description']}")
                    continue
                if measurement['item_units'] != rd.measurement.item_units:
                    logger.error(f"A non-matching measurement unit for report with "
                                 f"report_request_id {report_request_id} and r_id {r_id} was given "
                                 f"by the VTN. Offered: {rd.measurement.item_units}, "
                                 f"requested: {measurement['item_units']}")
                    continue

            if granularity is not None:
                if not rd.sampling_rate.min_period <= granularity <= rd.sampling_rate.max_period:
                    logger.error(f"An invalid sampling rate {granularity} was requested for report "
                                 f"with report_specifier_id {report_specifier_id} and r_id {r_id}. "
                                 f"The offered sampling rate was between "
                                 f"{rd.sampling_rate.min_period} and "
                                 f"{rd.sampling_rate.max_period}")
                    continue
            else:
                # If no granularity is specified, set it to the lowest sampling rate.
                granularity = rd.sampling_rate.max_period

            requested_r_ids.append(r_id)

        callback = partial(self.update_report, report_request_id=report_request_id)

        reporting_interval = report_back_duration or granularity
        job = self.scheduler.add_job(func=callback,
                                     trigger='cron',
                                     **cron_config(reporting_interval))

        self.report_requests.append({'report_request_id': report_request_id,
                                     'report_specifier_id': report_specifier_id,
                                     'report_back_duration': report_back_duration,
                                     'r_ids': requested_r_ids,
                                     'granularity': granularity,
                                     'job': job})