예제 #1
0
파일: handler.py 프로젝트: liZe/azafea
    def id_from_serialized(cls, serialized: bytes, dbsession: DbSession) -> int:
        record = json.loads(serialized.decode('utf-8'))

        columns = inspect(cls).attrs
        record = {k: v for (k, v) in record.items() if k in columns}

        record['vendor'] = normalize_vendor(record.get('vendor', 'unknown'))

        # Let's make the case of a missing "image" fail at the SQL level
        if 'image' in record:  # pragma: no branch
            record.update(**parse_endless_os_image(record['image']))

        # Postgresql's 'INSERT … ON CONFLICT …' is not available at the ORM layer, so let's
        # drop down to the SQL layer
        stmt = insert(PingConfiguration.__table__).values(**record)
        stmt = stmt.returning(PingConfiguration.__table__.c.id)

        # We have to use 'ON CONFLICT … DO UPDATE …' because 'ON CONFLICT DO NOTHING' does not
        # return anything, and we need to get the id back; in addition we have to actually
        # update something, anything, so let's arbitrarily update the image to its existing value
        stmt = stmt.on_conflict_do_update(
            constraint='uq_ping_configuration_v1_image_vendor_product_dualboot',
            set_={'image': record['image']}
        )
        result = dbsession.connection().execute(stmt)
        dbsession.commit()

        return result.first()[0]
예제 #2
0
def process(dbsession: DbSession, record: bytes) -> None:
    log.debug('Processing metric v2 record: %s', record)

    request_builder = RequestBuilder.parse_bytes(record)
    request = request_builder.build_request()
    dbsession.add(request)

    for event_variant in request_builder.singulars:
        singular_event = new_singular_event(request, event_variant, dbsession)

        if singular_event is not None:
            log.debug('Inserting singular metric:\n%s', singular_event)

    for event_variant in request_builder.aggregates:
        aggregate_event = new_aggregate_event(request, event_variant,
                                              dbsession)
        log.debug('Inserting aggregate metric:\n%s', aggregate_event)

    for event_variant in request_builder.sequences:
        sequence_event = new_sequence_event(request, event_variant, dbsession)

        if sequence_event is not None:
            log.debug('Inserting sequence event:\n%s', sequence_event)

    try:
        dbsession.commit()

    except IntegrityError as e:
        # FIXME: This is fragile, can we do better?
        if "uq_metrics_request_v2_sha512" in str(e):
            log.debug('Request had already been processed in the past')
            return

        # FIXME: Given how the request is built, this shouldn't ever happen; if it does though, we
        # absolutely need an integration test
        raise  # pragma: no cover