Beispiel #1
0
def translator_for(fiware_service: str):
    backend = backend_id_for(fiware_service)

    if backend == CRATE_BACKEND:
        translator = CrateTranslatorInstance()
        selected = CRATE_BACKEND
    elif backend == TIMESCALE_BACKEND:
        translator = postgres_translator_instance()
        selected = TIMESCALE_BACKEND
    else:
        translator = CrateTranslatorInstance()
        selected = CRATE_BACKEND

    log().debug(
        f"Backend selected for tenant '{fiware_service}' is: {selected}")
    return translator
Beispiel #2
0
def delete_entity(entity_id, type_=None, from_date=None, to_date=None):
    if type_ is None:
        r = {
            "error": "Not Implemented",
            "description": "For now, you must always specify entity type."
        }
        return r, 400

    fiware_s = request.headers.get('fiware-service', None)
    fiware_sp = request.headers.get('fiware-servicepath', None)

    with CrateTranslatorInstance() as trans:
        deleted = trans.delete_entity(
            entity_id=entity_id,
            entity_type=type_,
            from_date=from_date,
            to_date=to_date,
            fiware_service=fiware_s,
            fiware_servicepath=fiware_sp,
        )
        if deleted == 0:
            r = {
                "error": "Not Found",
                "description": "No records were found for such query."
            }
            return r, 404

        if deleted > 0:
            return '{} records successfully deleted.'.format(deleted), 204
Beispiel #3
0
def translator_for(fiware_service: str):
    backend = lookup_backend(fiware_service)
    backend = backend.strip().lower() if backend is not None else ''

    if backend == CRATE_BACKEND:
        translator = CrateTranslatorInstance()
        selected = CRATE_BACKEND
    elif backend == TIMESCALE_BACKEND:
        translator = postgres_translator_instance()
        selected = TIMESCALE_BACKEND
    else:
        translator = CrateTranslatorInstance()
        selected = CRATE_BACKEND

    log().info(
        f"Backend selected for tenant '{fiware_service}' is: {selected}")
    return translator
Beispiel #4
0
def check_crate():
    """
    crateDB is the default backend of QuantumLeap, so it is required by
    default.
    """
    from translators.crate import CrateTranslatorInstance
    with CrateTranslatorInstance() as trans:
        crate_health = trans.get_health()
        return crate_health
Beispiel #5
0
def translator_for(fiware_service: str):
    reader = YamlReader(log=log().debug)
    config = reader.from_env_file(QL_CONFIG_ENV_VAR, defaults={})

    backend = maybe_string_match(config, 'tenants', fiware_service, 'backend')\
        or maybe_string_match(config, 'default-backend')
    backend = backend.strip().lower() if backend is not None else ''

    if backend == CRATE_BACKEND:
        translator = CrateTranslatorInstance()
        selected = CRATE_BACKEND
    elif backend == TIMESCALE_BACKEND:
        translator = postgres_translator_instance()
        selected = TIMESCALE_BACKEND
    else:
        translator = CrateTranslatorInstance()
        selected = CRATE_BACKEND

    log().info(
        f"Backend selected for tenant '{fiware_service}' is: {selected}")
    return translator
Beispiel #6
0
def notify():
    if request.json is None:
        return 'Discarding notification due to lack of request body. ' \
               'Lost in a redirect maybe?', 400

    if 'data' not in request.json:
        return 'Discarding notification due to lack of request body ' \
               'content.', 400

    payload = request.json['data']
    if len(payload) > 1:
        return 'Multiple data elements in notifications not supported yet', 400
    payload = payload[0]

    log().info('Received payload: {}'.format(payload))

    # Validate notification
    error = _validate_payload(payload)
    if error:
        return error, 400

    # Add TIME_INDEX attribute
    payload[CrateTranslator.TIME_INDEX_NAME] = \
        select_time_index_value_as_iso(request.headers, payload)

    # Add GEO-DATE if enabled
    add_geodata(payload)

    # Always normalize location if there's one
    normalize_location(payload)

    # Define FIWARE tenant
    fiware_s = request.headers.get('fiware-service', None)
    # It seems orion always sends a 'Fiware-Servicepath' header with value '/'
    # But this is not correctly documented in the API, so in order not to
    # depend on this, QL will not treat servicepath if there's no service
    # specified.
    if fiware_s:
        fiware_sp = request.headers.get('fiware-servicepath', None)
    else:
        fiware_sp = None

    # Send valid entities to translator
    with CrateTranslatorInstance() as trans:
        trans.insert([payload], fiware_s, fiware_sp)

    msg = 'Notification successfully processed'
    log().info(msg)
    return msg
Beispiel #7
0
def check_db(db=CRATE_BACKEND):
    """
    crateDB is the default backend of QuantumLeap, so it is required by
    default.
    """
    if db == CRATE_BACKEND:
        from translators.crate import CrateTranslatorInstance
        with CrateTranslatorInstance() as trans:
            health = trans.get_health()
            return health
    if db == TIMESCALE_BACKEND:
        from translators.timescale import PostgresTranslator
        with PostgresTranslator() as trans:
            health = trans.get_health()
            return health
def query_NTNE(
        limit=10000,
        type_=None,  # In Query
        from_date=None,
        to_date=None,
        offset=0):
    """
    See /entities in API Specification
    quantumleap.yml
    """
    fiware_s = request.headers.get('fiware-service', None)
    fiware_sp = request.headers.get('fiware-servicepath', None)

    entities = None
    try:
        with CrateTranslatorInstance() as trans:
            entities = trans.query_ids(limit=limit,
                                       entity_type=type_,
                                       from_date=from_date,
                                       to_date=to_date,
                                       offset=offset,
                                       fiware_service=fiware_s,
                                       fiware_servicepath=fiware_sp)
    except NGSIUsageError as e:
        msg = "Bad Request Error: {}".format(e)
        logging.getLogger().error(msg, exc_info=True)
        return msg, 400

    except Exception as e:
        msg = "Internal server Error: {}".format(e)
        logging.getLogger().error(msg, exc_info=True)
        return msg, 500

    if entities:
        res = []
        for entity in entities:
            res.append(entity)

        return res

    r = {
        "error": "Not Found",
        "description": "No records were found for such query."
    }
    return r, 404
Beispiel #9
0
def query_1TNE1A(
        attr_name,  # In Path
        entity_type,
        id_=None,  # In Query
        aggr_method=None,
        aggr_period=None,
        aggr_scope=None,
        options=None,
        from_date=None,
        to_date=None,
        last_n=None,
        limit=10000,
        offset=0):
    """
    See /types/{entityType}/attrs/{attrName} in API Specification
    quantumleap.yml
    """
    r, c = _validate_query_params([attr_name], aggr_period, aggr_method,
                                  aggr_scope, options)
    if c != 200:
        return r, c

    fiware_s = request.headers.get('fiware-service', None)
    fiware_sp = request.headers.get('fiware-servicepath', None)

    entities = None
    entity_ids = None
    if id_:
        entity_ids = [s.strip() for s in id_.split(',') if s]
    try:
        with CrateTranslatorInstance() as trans:
            entities = trans.query(
                attr_names=[attr_name],
                entity_type=entity_type,
                entity_ids=entity_ids,
                aggr_method=aggr_method,
                aggr_period=aggr_period,
                aggr_scope=aggr_scope,
                from_date=from_date,
                to_date=to_date,
                last_n=last_n,
                limit=limit,
                offset=offset,
                fiware_service=fiware_s,
                fiware_servicepath=fiware_sp,
            )
    except AmbiguousNGSIIdError as e:
        return {"error": "AmbiguousNGSIIdError", "description": str(e)}, 409

    except Exception as e:
        # Temp workaround to debug test_not_found
        msg = "Something went wrong with QL. Error: {}".format(e)
        logging.getLogger().error(msg, exc_info=True)
        return msg, 500

    if entities:
        res = _prepare_response(
            entities,
            attr_name,
            entity_type,
            entity_ids,
            aggr_method,
            aggr_period,
            from_date,
            to_date,
        )
        return res

    r = {
        "error": "Not Found",
        "description": "No records were found for such query."
    }
    return r, 404
def query_1T1E1A(attr_name,   # In Path
                 entity_id,
                 type_=None,  # In Query
                 aggr_method=None,
                 aggr_period=None,
                 options=None,
                 from_date=None,
                 to_date=None,
                 last_n=None,
                 limit=10000,
                 offset=0):
    """
    See /entities/{entityId}/attrs/{attrName} in API Specification
    quantumleap.yml
    """
    r, c = _validate_query_params([attr_name], aggr_period, aggr_method,
                                  options=options)
    if c != 200:
        return r, c

    fiware_s = request.headers.get('fiware-service', None)
    fiware_sp = request.headers.get('fiware-servicepath', None)

    entities = None
    try:
        with CrateTranslatorInstance() as trans:
            entities = trans.query(attr_names=[attr_name],
                                   entity_type=type_,
                                   entity_id=entity_id,
                                   aggr_method=aggr_method,
                                   aggr_period=aggr_period,
                                   from_date=from_date,
                                   to_date=to_date,
                                   last_n=last_n,
                                   limit=limit,
                                   offset=offset,
                                   fiware_service=fiware_s,
                                   fiware_servicepath=fiware_sp,)
    except AmbiguousNGSIIdError as e:
        return {
            "error": "AmbiguousNGSIIdError",
            "description": str(e)
        }, 409

    except Exception as e:
        # Temp workaround to debug test_not_found
        msg = "Something went wrong with QL. Error: {}".format(e)
        logging.getLogger().error(msg, exc_info=True)
        return msg, 500

    if entities:
        if len(entities) > 1:
            import warnings
            warnings.warn("Not expecting more than one result for a 1T1E1A.")

        index = [] if aggr_method and not aggr_period else entities[0]['index']
        res = {
            'data': {
                'entityId': entities[0]['id'],
                'attrName': attr_name,
                'index': index,
                'values': entities[0][attr_name]['values']
            }
        }
        return res

    r = {
        "error": "Not Found",
        "description": "No records were found for such query."
    }
    return r, 404
def query_NTNENA(
        id_=None,  # In Query
        attrs=None,
        type_=None,
        aggr_method=None,
        aggr_period=None,
        aggr_scope=None,
        options=None,
        from_date=None,
        to_date=None,
        last_n=None,
        limit=10000,
        offset=0,
        georel=None,
        geometry=None,
        coords=None):
    """
    See /v2/attrs in API Specification
    quantumleap.yml
    """
    r, c = _validate_query_params(attrs, aggr_period, aggr_method, aggr_scope,
                                  options)
    if c != 200:
        return r, c

    r, c, geo_query = handle_geo_query(georel, geometry, coords)
    if r:
        return r, c

    if attrs is not None:
        attrs = attrs.split(',')

    fiware_s = request.headers.get('fiware-service', None)
    fiware_sp = request.headers.get('fiware-servicepath', None)

    entities = None
    entity_ids = None
    if id_:
        entity_ids = [s.strip() for s in id_.split(',') if s]

    try:
        with CrateTranslatorInstance() as trans:
            entities = trans.query(attr_names=attrs,
                                   entity_type=type_,
                                   entity_ids=entity_ids,
                                   aggr_method=aggr_method,
                                   aggr_period=aggr_period,
                                   aggr_scope=aggr_scope,
                                   from_date=from_date,
                                   to_date=to_date,
                                   last_n=last_n,
                                   limit=limit,
                                   offset=offset,
                                   fiware_service=fiware_s,
                                   fiware_servicepath=fiware_sp,
                                   geo_query=geo_query)
    except NGSIUsageError as e:
        msg = "Bad Request Error: {}".format(e)
        logging.getLogger().error(msg, exc_info=True)
        return msg, 400
    except Exception as e:
        msg = "Something went wrong with QL. Error: {}".format(e)
        logging.getLogger().error(msg, exc_info=True)
        return msg, 500

    attributes = []
    entries = []
    attrs_names = []
    attrs_values = []
    ignore = ('id', 'index', 'type')

    if entities:
        for e in entities:
            attrs = [at for at in sorted(e.keys()) if at not in ignore]
            for at in attrs:
                if at not in attrs_names:
                    attrs_names.append(at)

        for at in attrs_names:
            entity_type = []
            entity_types = []
            entity_value = []
            for e in entities:
                matched_attr = lookup_string_match(e, at)
                if matched_attr is not None:
                    index = [
                        from_date or '', to_date or ''
                    ] if aggr_method and not aggr_period else e['index']
                    entity = {
                        'entityId': e['id'],
                        'index': index,
                        'values':
                        matched_attr['values'] if matched_attr else [],
                    }
                    if e['type'] not in entity_types:
                        entity_value = []
                        entity_value.append(entity)
                        entity_ty = {
                            'entityType': e['type'],
                            'entities': entity_value
                        }
                        entity_type.append(entity_ty)
                        entity_types.append(e['type'])
                    else:
                        entity_value.append(entity)
                        entity_type.pop()
                        entity_ty = {
                            'entityType': e['type'],
                            'entities': entity_value
                        }
                        entity_type.append(entity_ty)
            attrs_value = {'attrName': at, 'types': entity_type}
            attrs_values.append(attrs_value)
        res = {'attrs': attrs_values}
        return res
    r = {
        "error": "Not Found",
        "description": "No records were found for such query."
    }
    return r, 404
def query_1T1ENA(entity_id,   # In Path
                 type_=None,  # In Query
                 attrs=None,
                 aggr_method=None,
                 aggr_period=None,
                 options=None,
                 from_date=None,
                 to_date=None,
                 last_n=None,
                 limit=10000,
                 offset=0,
                 georel=None,
                 geometry=None,
                 coords=None):
    """
    See /entities/{entityId}/attrs/{attrName} in API Specification
    quantumleap.yml
    """
    r, c = _validate_query_params(attrs, aggr_period, aggr_method,
                                  options=options)
    if c != 200:
        return r, c

    r, c, geo_query = handle_geo_query(georel, geometry, coords)
    if r:
        return r, c

    if attrs is not None:
        attrs = attrs.split(',')

    fiware_s = request.headers.get('fiware-service', None)
    fiware_sp = request.headers.get('fiware-servicepath', None)

    entities = None
    try:
        with CrateTranslatorInstance() as trans:
            entities = trans.query(attr_names=attrs,
                                   entity_type=type_,
                                   entity_id=entity_id,
                                   aggr_method=aggr_method,
                                   aggr_period=aggr_period,
                                   from_date=from_date,
                                   to_date=to_date,
                                   last_n=last_n,
                                   limit=limit,
                                   offset=offset,
                                   fiware_service=fiware_s,
                                   fiware_servicepath=fiware_sp,
                                   geo_query=geo_query)
    except AmbiguousNGSIIdError as e:
        return {
            "error": "AmbiguousNGSIIdError",
            "description": str(e)
        }, 409

    except Exception as e:
        # Temp workaround to debug test_not_found
        msg = "Something went wrong with QL. Error: {}".format(e)
        logging.getLogger().error(msg, exc_info=True)
        return msg, 500

    if entities:
        if len(entities) > 1:
            import warnings
            warnings.warn("Not expecting more than one result for a 1T1ENA.")

        attributes = []
        ignore = ('type', 'id', 'index')
        attrs = [at for at in sorted(entities[0].keys()) if at not in ignore]
        for at in attrs:
            attributes.append({
                'attrName': at,
                'values': entities[0][at]['values']
            })

        index = [] if aggr_method and not aggr_period else entities[0]['index']
        res = {
            'entityId': entity_id,
            'index': index,
            'attributes': attributes
        }
        return res

    r = {
        "error": "Not Found",
        "description": "No records were found for such query."
    }
    return r, 404
Beispiel #13
0
def query_1TNENA(
        entity_type=None,  # In Path
        id_=None,  # In Query
        attrs=None,
        aggr_method=None,
        aggr_period=None,
        aggr_scope=None,
        options=None,
        from_date=None,
        to_date=None,
        last_n=None,
        limit=10000,
        offset=0,
        georel=None,
        geometry=None,
        coords=None):
    """
    See /types/{entityType} in API Specification
    quantumleap.yml
    """
    r, c = _validate_query_params(attrs, aggr_period, aggr_method, aggr_scope,
                                  options)
    if c != 200:
        return r, c

    r, c, geo_query = handle_geo_query(georel, geometry, coords)
    if r:
        return r, c

    if attrs is not None:
        attrs = attrs.split(',')

    fiware_s = request.headers.get('fiware-service', None)
    fiware_sp = request.headers.get('fiware-servicepath', None)

    entities = None
    entity_ids = None
    if id_:
        entity_ids = [s.strip() for s in id_.split(',') if s]
    try:
        with CrateTranslatorInstance() as trans:
            entities = trans.query(attr_names=attrs,
                                   entity_type=entity_type,
                                   entity_ids=entity_ids,
                                   aggr_method=aggr_method,
                                   aggr_period=aggr_period,
                                   aggr_scope=aggr_scope,
                                   from_date=from_date,
                                   to_date=to_date,
                                   last_n=last_n,
                                   limit=limit,
                                   offset=offset,
                                   fiware_service=fiware_s,
                                   fiware_servicepath=fiware_sp,
                                   geo_query=geo_query)
    except NGSIUsageError as e:
        return {"error": "{}".format(type(e)), "description": str(e)}, 400

    except Exception as e:
        msg = "Something went wrong with QL. Error: {}".format(e)
        logging.getLogger().error(msg, exc_info=True)
        return msg, 500

    if entities:
        res = _prepare_response(
            entities,
            attrs,
            entity_type,
            entity_ids,
            aggr_method,
            aggr_period,
            from_date,
            to_date,
        )
        return res

    r = {
        "error": "Not Found",
        "description": "No records were found for such query."
    }
    return r, 404
Beispiel #14
0
def query_1T1ENA(entity_id,   # In Path
                 type_=None,  # In Query
                 attrs=None,
                 aggr_method=None,
                 aggr_period=None,
                 options=None,
                 from_date=None,
                 to_date=None,
                 last_n=None,
                 limit=10000,
                 offset=0):
    """
    See /entities/{entityId}/attrs/{attrName} in API Specification
    quantumleap.yml
    """
    if type_ is None:
        r = {
            "error": "Not Implemented",
            "description": "For now, you must always specify entity type."
        }
        return r, 400

    if options or aggr_period:
        import warnings
        warnings.warn("Unimplemented query parameters: options, aggrPeriod")

    if aggr_method and not attrs:
        msg = "Specified aggrMethod = {} but missing attrs parameter."
        return msg.format(aggr_method), 400

    if attrs is not None:
        attrs = attrs.split(',')

    fiware_s = request.headers.get('fiware-service', None)
    fiware_sp = request.headers.get('fiware-servicepath', None)

    entities = None
    with CrateTranslatorInstance() as trans:
        entities = trans.query(attr_names=attrs,
                           entity_type=type_,
                           entity_id=entity_id,
                           aggr_method=aggr_method,
                           from_date=from_date,
                           to_date=to_date,
                           last_n=last_n,
                           limit=limit,
                           offset=offset,
                           fiware_service=fiware_s,
                           fiware_servicepath=fiware_sp,)
    if entities:
        if aggr_method:
            index = []
        else:
            index = [str(e[CrateTranslator.TIME_INDEX_NAME]) for e in entities]

        ignore = ('type', 'id', CrateTranslator.TIME_INDEX_NAME)
        attrs = [at for at in sorted(entities[0].keys()) if at not in ignore]

        attributes = []
        for at in attrs:
            attributes.append({
                'attrName': at,
                'values': []
            })

        for i, at in enumerate(attrs):
            for e in entities:
                attributes[i]['values'].append(e[at]['value'])

        res = {
            'data': {
                'entityId': entity_id,
                'index': index,
                'attributes': attributes
            }
        }
        return res

    r = {
        "error": "Not Found",
        "description": "No records were found for such query."
    }
    return r, 404
def query_1T1ENA(
        entity_id,  # In Path
        type_=None,  # In Query
        attrs=None,
        aggr_method=None,
        aggr_period=None,
        options=None,
        from_date=None,
        to_date=None,
        last_n=None,
        limit=10000,
        offset=0):
    """
    See /entities/{entityId}/attrs/{attrName} in API Specification
    quantumleap.yml
    """
    r, c = _validate_query_params(aggr_period, aggr_method, attrs, options)
    if c != 200:
        return r, c

    if attrs is not None:
        attrs = attrs.split(',')

    fiware_s = request.headers.get('fiware-service', None)
    fiware_sp = request.headers.get('fiware-servicepath', None)

    entities = None
    try:
        with CrateTranslatorInstance() as trans:
            entities = trans.query(
                attr_names=attrs,
                entity_type=type_,
                entity_id=entity_id,
                aggr_method=aggr_method,
                from_date=from_date,
                to_date=to_date,
                last_n=last_n,
                limit=limit,
                offset=offset,
                fiware_service=fiware_s,
                fiware_servicepath=fiware_sp,
            )
    except AmbiguousNGSIIdError as e:
        return {"error": "AmbiguousNGSIIdError", "description": str(e)}, 409

    except Exception as e:
        # Temp workaround to debug test_not_found
        msg = "Something went wrong with QL. Error: {}".format(e)
        logging.getLogger().error(msg, exc_info=True)
        return msg, 500

    if entities:
        if aggr_method:
            index = []
        else:
            index = [str(e[CrateTranslator.TIME_INDEX_NAME]) for e in entities]

        ignore = ('type', 'id', CrateTranslator.TIME_INDEX_NAME)
        attrs = [at for at in sorted(entities[0].keys()) if at not in ignore]

        attributes = []
        for at in attrs:
            attributes.append({'attrName': at, 'values': []})

        for i, at in enumerate(attrs):
            for e in entities:
                attributes[i]['values'].append(e[at]['value'])

        res = {
            'data': {
                'entityId': entity_id,
                'index': index,
                'attributes': attributes
            }
        }
        return res

    r = {
        "error": "Not Found",
        "description": "No records were found for such query."
    }
    return r, 404
Beispiel #16
0
def query_1T1E1A(
        attr_name,  # In Path
        entity_id,
        type_=None,  # In Query
        aggr_method=None,
        aggr_period=None,
        options=None,
        from_date=None,
        to_date=None,
        last_n=None,
        limit=10000,
        offset=0):
    """
    See /entities/{entityId}/attrs/{attrName} in API Specification
    quantumleap.yml
    """
    if type_ is None:
        r = {
            "error": "Not Implemented",
            "description": "For now, you must always specify entity type."
        }
        return r, 400

    if options or aggr_period:
        import warnings
        warnings.warn("Unimplemented query parameters: options, aggrPeriod")

    fiware_s = request.headers.get('fiware-service', None)
    fiware_sp = request.headers.get('fiware-servicepath', None)

    entities = None
    with CrateTranslatorInstance() as trans:
        entities = trans.query(
            attr_names=[attr_name],
            entity_type=type_,
            entity_id=entity_id,
            aggr_method=aggr_method,
            from_date=from_date,
            to_date=to_date,
            last_n=last_n,
            limit=limit,
            offset=offset,
            fiware_service=fiware_s,
            fiware_servicepath=fiware_sp,
        )
    if entities:
        if aggr_method:
            index = []
        else:
            index = [str(e[CrateTranslator.TIME_INDEX_NAME]) for e in entities]
        res = {
            'data': {
                'entityId': entity_id,
                'attrName': attr_name,
                'index': index,
                'values': [e[attr_name]['value'] for e in entities]
            }
        }
        return res

    r = {
        "error": "Not Found",
        "description": "No records were found for such query."
    }
    return r, 404