示例#1
0
    def get_samples(sample_filter, limit=None):
        """Return an iterable of model.Sample instances.

        :param sample_filter: Filter.
        :param limit: Maximum number of results to return.
        """
        raise report.NotImplementedError('Samples not implemented')
示例#2
0
    def get_resources(user=None,
                      project=None,
                      source=None,
                      start_timestamp=None,
                      start_timestamp_op=None,
                      end_timestamp=None,
                      end_timestamp_op=None,
                      metaquery=None,
                      resource=None,
                      pagination=None):
        """Return an iterable of models.Resource instances.

        Iterable items containing resource information.
        :param user: Optional ID for user that owns the resource.
        :param project: Optional ID for project that owns the resource.
        :param source: Optional source filter.
        :param start_timestamp: Optional modified timestamp start range.
        :param start_timestamp_op: Optional timestamp start range operation.
        :param end_timestamp: Optional modified timestamp end range.
        :param end_timestamp_op: Optional timestamp end range operation.
        :param metaquery: Optional dict with metadata to match on.
        :param resource: Optional resource filter.
        :param pagination: Optional pagination query.
        """
        raise report.NotImplementedError('Resources not implemented')
    def QualifierFilter(args, rows):
        """This is filter for testing "in-memory HBase".

        This method is called from scan() when 'QualifierFilter' is found in
        the 'filter' argument
        """
        op = args[0]
        value = args[1]
        is_regex = False
        if value.startswith('binaryprefix:'):
            value = value[len('binaryprefix:'):]
        if value.startswith('regexstring:'):
            value = value[len('regexstring:'):]
            is_regex = True
        column = 'f:' + value
        r = {}
        for row in rows:
            data = rows[row]
            r_data = {}
            for key in data:
                if ((op == '=' and key.startswith(column)) or
                        (op == '>=' and key >= column) or
                        (op == '<=' and key <= column) or
                        (op == '>' and key > column) or
                        (op == '<' and key < column) or
                        (is_regex and re.search(value, key))):
                    r_data[key] = data[key]
                else:
                    raise report.NotImplementedError(
                        "In-memory QualifierFilter "
                        "doesn't support the %s "
                        "operation yet" % op)
            if r_data:
                r[row] = r_data
        return r
    def RowFilter(args, rows):
        """This is filter for testing "in-memory HBase".

        This method is called from scan() when 'RowFilter' is found in the
        'filter' argument.

        :param args: a list of filter arguments, it contains operator and
          sought string
        :param rows: a dict of rows which are filtered
        """
        op = args[0]
        value = args[1]
        if value.startswith('regexstring:'):
            value = value[len('regexstring:'):]
        r = {}
        for row, data in rows.items():
            try:
                g = re.search(value, row).group()
                if op == '=':
                    if g == row:
                        r[row] = data
                else:
                    raise report.NotImplementedError(
                        "In-memory "
                        "RowFilter doesn't support "
                        "the %s operation yet" % op)
            except AttributeError:
                pass
        return r
示例#5
0
    def clear_expired_metering_data(ttl):
        """Clear expired data from the backend storage system.

        Clearing occurs according to the time-to-live.

        :param ttl: Number of seconds to keep records for.
        """
        raise report.NotImplementedError('Clearing samples not implemented')
示例#6
0
    def get_meter_statistics(sample_filter,
                             period=None,
                             groupby=None,
                             aggregate=None):
        """Return an iterable of model.Statistics instances.

        The filter must have a meter value set.
        """
        raise report.NotImplementedError('Statistics not implemented')
示例#7
0
    def get_meters(self,
                   user=None,
                   project=None,
                   resource=None,
                   source=None,
                   metaquery=None,
                   pagination=None):
        """Return an iterable of models.Meter instances

        :param user: Optional ID for user that owns the resource.
        :param project: Optional ID for project that owns the resource.
        :param resource: Optional resource filter.
        :param source: Optional source filter.
        :param metaquery: Optional dict with metadata to match on.
        :param pagination: Optional pagination query.
        """

        metaquery = metaquery or {}

        if pagination:
            raise report.NotImplementedError(_('Pagination not implemented'))
        with self.conn_pool.connection() as conn:
            resource_table = conn.table(self.RESOURCE_TABLE)
            q = hbase_utils.make_query(metaquery=metaquery,
                                       user_id=user,
                                       project_id=project,
                                       resource_id=resource,
                                       source=source)
            LOG.debug(_("Query Resource table: %s") % q)

            gen = resource_table.scan(filter=q)
            # We need result set to be sure that user doesn't receive several
            # same meters. Please see bug
            # https://bugs.launchpad.net/report/+bug/1301371
            result = set()
            for ignored, data in gen:
                flatten_result, s, meters, md = hbase_utils.deserialize_entry(
                    data)
                for m in meters:
                    _m_rts, m_source, name, m_type, unit = m[0]
                    meter_dict = {
                        'name': name,
                        'type': m_type,
                        'unit': unit,
                        'resource_id': flatten_result['resource_id'],
                        'project_id': flatten_result['project_id'],
                        'user_id': flatten_result['user_id']
                    }
                    frozen_meter = frozenset(meter_dict.items())
                    if frozen_meter in result:
                        continue
                    result.add(frozen_meter)
                    meter_dict.update(
                        {'source': m_source if m_source else None})

                    yield models.Meter(**meter_dict)
示例#8
0
    def query_samples(filter_expr=None, orderby=None, limit=None):
        """Return an iterable of model.Sample objects.

        :param filter_expr: Filter expression for query.
        :param orderby: List of field name and direction pairs for order by.
        :param limit: Maximum number of results to return.
        """

        raise report.NotImplementedError('Complex query for samples '
                                         'is not implemented.')
示例#9
0
    def record_metering_data(data):
        """Write the data to the backend storage system.

        :param data: a dictionary such as returned by
                     ceilometer.meter.meter_message_from_counter

        All timestamps must be naive utc datetime object.
        """
        raise report.NotImplementedError(
            'Recording metering data is not implemented')
示例#10
0
 def _handle_metadata(self, op, field_name, value):
     if op == self.operators["in"]:
         raise report.NotImplementedError('Metadata query with in '
                                          'operator is not implemented')
     field_name = field_name[len('resource_metadata.'):]
     meta_table = META_TYPE_MAP[type(value)]
     meta_alias = aliased(meta_table)
     on_clause = and_(self.table.internal_id == meta_alias.id,
                      meta_alias.meta_key == field_name)
     # outer join is needed to support metaquery
     # with or operator on non existent metadata field
     # see: test_query_non_existing_metadata_with_result
     # test case.
     self.query = self.query.outerjoin(meta_alias, on_clause)
     return op(meta_alias.value, value)
示例#11
0
    def get_meters(user=None,
                   project=None,
                   resource=None,
                   source=None,
                   metaquery=None,
                   pagination=None):
        """Return an iterable of model.Meter instances.

        Iterable items containing meter information.
        :param user: Optional ID for user that owns the resource.
        :param project: Optional ID for project that owns the resource.
        :param resource: Optional resource filter.
        :param source: Optional source filter.
        :param metaquery: Optional dict with metadata to match on.
        :param pagination: Optional pagination query.
        """
        raise report.NotImplementedError('Meters not implemented')
    def scan(self, filter=None, columns=None, row_start=None, row_stop=None,
             limit=None):
        columns = columns or []
        sorted_keys = sorted(self._rows_with_ts)
        # copy data between row_start and row_stop into a dict
        rows = {}
        for row in sorted_keys:
            if row_start and row < row_start:
                continue
            if row_stop and row > row_stop:
                break
            rows[row] = self._get_latest_dict(row)

        if columns:
            ret = {}
            for row, data in six.iteritems(rows):
                for key in data:
                    if key in columns:
                        ret[row] = data
            rows = ret
        if filter:
            # TODO(jdanjou): we should really parse this properly,
            # but at the moment we are only going to support AND here
            filters = filter.split('AND')
            for f in filters:
                # Extract filter name and its arguments
                g = re.search("(.*)\((.*),?\)", f)
                fname = g.group(1).strip()
                fargs = [s.strip().replace('\'', '')
                         for s in g.group(2).split(',')]
                m = getattr(self, fname)
                if callable(m):
                    # overwrite rows for filtering to take effect
                    # in case of multiple filters
                    rows = m(fargs, rows)
                else:
                    raise report.NotImplementedError(
                        "%s filter is not implemented, "
                        "you may want to add it!")
        for k in sorted(rows)[:limit]:
            yield k, rows[k]
示例#13
0
    def get_meter_statistics(self,
                             sample_filter,
                             period=None,
                             groupby=None,
                             aggregate=None):
        """Return an iterable of models.Statistics instances.

        Items are containing meter statistics described by the query
        parameters. The filter must have a meter value set.

        .. note::

          Due to HBase limitations the aggregations are implemented
          in the driver itself, therefore this method will be quite slow
          because of all the Thrift traffic it is going to create.
        """
        if groupby:
            raise report.NotImplementedError("Group by not implemented.")

        if aggregate:
            raise report.NotImplementedError(
                'Selectable aggregates not implemented')

        with self.conn_pool.connection() as conn:
            meter_table = conn.table(self.METER_TABLE)
            q, start, stop, columns = (
                hbase_utils.make_sample_query_from_filter(sample_filter))
            # These fields are used in statistics' calculating
            columns.extend(
                ['f:timestamp', 'f:counter_volume', 'f:counter_unit'])
            meters = map(
                hbase_utils.deserialize_entry,
                list(meter for (ignored, meter) in meter_table.scan(
                    filter=q, row_start=start, row_stop=stop,
                    columns=columns)))

        if sample_filter.start_timestamp:
            start_time = sample_filter.start_timestamp
        elif meters:
            start_time = meters[-1][0]['timestamp']
        else:
            start_time = None

        if sample_filter.end_timestamp:
            end_time = sample_filter.end_timestamp
        elif meters:
            end_time = meters[0][0]['timestamp']
        else:
            end_time = None

        results = []

        if not period:
            period = 0
            period_start = start_time
            period_end = end_time

        # As our HBase meters are stored as newest-first, we need to iterate
        # in the reverse order
        for meter in meters[::-1]:
            ts = meter[0]['timestamp']
            if period:
                offset = int(
                    timeutils.delta_seconds(start_time, ts) / period) * period
                period_start = start_time + datetime.timedelta(0, offset)

            if not results or not results[-1].period_start == period_start:
                if period:
                    period_end = period_start + datetime.timedelta(0, period)
                results.append(
                    models.Statistics(unit='',
                                      count=0,
                                      min=0,
                                      max=0,
                                      avg=0,
                                      sum=0,
                                      period=period,
                                      period_start=period_start,
                                      period_end=period_end,
                                      duration=None,
                                      duration_start=None,
                                      duration_end=None,
                                      groupby=None))
            self._update_meter_stats(results[-1], meter[0])
        return results
示例#14
0
    def get_resources(self,
                      user=None,
                      project=None,
                      source=None,
                      start_timestamp=None,
                      start_timestamp_op=None,
                      end_timestamp=None,
                      end_timestamp_op=None,
                      metaquery=None,
                      resource=None,
                      pagination=None):
        """Return an iterable of models.Resource instances

        :param user: Optional ID for user that owns the resource.
        :param project: Optional ID for project that owns the resource.
        :param source: Optional source filter.
        :param start_timestamp: Optional modified timestamp start range.
        :param start_timestamp_op: Optional start time operator, like ge, gt.
        :param end_timestamp: Optional modified timestamp end range.
        :param end_timestamp_op: Optional end time operator, like lt, le.
        :param metaquery: Optional dict with metadata to match on.
        :param resource: Optional resource filter.
        :param pagination: Optional pagination query.
        """
        if pagination:
            raise report.NotImplementedError('Pagination not implemented')

        q = hbase_utils.make_query(metaquery=metaquery,
                                   user_id=user,
                                   project_id=project,
                                   resource_id=resource,
                                   source=source)
        q = hbase_utils.make_meter_query_for_resource(start_timestamp,
                                                      start_timestamp_op,
                                                      end_timestamp,
                                                      end_timestamp_op, source,
                                                      q)
        with self.conn_pool.connection() as conn:
            resource_table = conn.table(self.RESOURCE_TABLE)
            LOG.debug(_("Query Resource table: %s") % q)
            for resource_id, data in resource_table.scan(filter=q):
                f_res, sources, meters, md = hbase_utils.deserialize_entry(
                    data)
                resource_id = hbase_utils.encode_unicode(resource_id)
                # Unfortunately happybase doesn't keep ordered result from
                # HBase. So that's why it's needed to find min and max
                # manually
                first_ts = min(meters, key=operator.itemgetter(1))[1]
                last_ts = max(meters, key=operator.itemgetter(1))[1]
                source = meters[0][0][1]
                # If we use QualifierFilter then HBase returnes only
                # qualifiers filtered by. It will not return the whole entry.
                # That's why if we need to ask additional qualifiers manually.
                if 'project_id' not in f_res and 'user_id' not in f_res:
                    row = resource_table.row(resource_id,
                                             columns=[
                                                 'f:project_id', 'f:user_id',
                                                 'f:resource_metadata'
                                             ])
                    f_res, _s, _m, md = hbase_utils.deserialize_entry(row)
                yield models.Resource(resource_id=resource_id,
                                      first_sample_timestamp=first_ts,
                                      last_sample_timestamp=last_ts,
                                      project_id=f_res['project_id'],
                                      source=source,
                                      user_id=f_res['user_id'],
                                      metadata=md)