Exemple #1
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']

    # preprocess and validate each entity update
    for entity in payload:
        # Validate entity update
        error = _validate_payload(entity)
        if error:
            return error, 400
        # Add TIME_INDEX attribute
        custom_index = request.headers.get(TIME_INDEX_HEADER_NAME, None)
        entity[TIME_INDEX_NAME] = \
            select_time_index_value_as_iso(custom_index, entity)
        # Add GEO-DATE if enabled
        add_geodata(entity)
        # Always normalize location if there's one
        normalize_location(entity)

    # 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
    res_entity = []
    e = None
    for entity in payload:
        # Validate entity update
        e = _filter_empty_entities(entity)
        if e is not None:
            e_new = _filter_no_type_no_value_entities(e)
            res_entity.append(e_new)
    payload = res_entity

    # Send valid entities to translator
    try:
        with translator_for(fiware_s) as trans:
            trans.insert(payload, fiware_s, fiware_sp)
    except:
        msg = "Notification not processed or not updated"
        log().error(msg)
        return msg, 500
    msg = 'Notification successfully processed'
    log().info(msg)
    return msg
Exemple #2
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']

    # preprocess and validate each entity update
    for entity in payload:
        # Validate entity update
        error = _validate_payload(entity)
        if error:
            # TODO in this way we return error for even if only one entity
            #  is wrong
            return error, 400
        # Add TIME_INDEX attribute
        custom_index = request.headers.get(TIME_INDEX_HEADER_NAME, None)
        entity[TIME_INDEX_NAME] = \
            select_time_index_value_as_iso(custom_index, entity)
        # Add GEO-DATE if enabled
        if not entity.get(LOCATION_ATTR_NAME, None):
            add_geodata(entity)
        # Always normalize location if there's one
        normalize_location(entity)

    res_entity = []
    e = None
    for entity in payload:
        # Validate entity update
        e = _filter_empty_entities(entity)
        if e is not None:
            # this is not NGSI-LD compliant for `modifiedAt` and similar
            # the logic should be as well changed if we introduce support
            # for `keyValues` formatting
            e_new = _filter_no_type_no_value_entities(e)
            res_entity.append(e_new)
    payload = res_entity
    try:
        InsertAction(fiware_s(), fiware_sp(), fiware_correlator(), payload) \
            .enqueue()
    except Exception as e:
        msg = "Notification not processed or not updated: {}".format(e)
        log().error(msg, exc_info=True)
        error_code = 500
        if e.__class__ == InvalidHeaderValue or \
                e.__class__ == InvalidParameterValue or \
                e.__class__ == NGSIUsageError:
            error_code = 400
        return msg, error_code
    msg = "Notification successfully processed"
    log().info(msg)
    return msg
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
Exemple #4
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']

    # preprocess and validate each entity update
    for entity in payload:
        # Validate entity update
        error = _validate_payload(entity)
        if error:
            # TODO in this way we return error for even if only one entity is wrong
            return error, 400
        # Add TIME_INDEX attribute
        custom_index = request.headers.get(TIME_INDEX_HEADER_NAME, None)
        entity[TIME_INDEX_NAME] = \
            select_time_index_value_as_iso(custom_index, entity)
        # Add GEO-DATE if enabled
        add_geodata(entity)
        # Always normalize location if there's one
        normalize_location(entity)

    # 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
    res_entity = []
    e = None
    for entity in payload:
        # Validate entity update
        e = _filter_empty_entities(entity)
        if e is not None:
            e_new = _filter_no_type_no_value_entities(e)
            res_entity.append(e_new)
    payload = res_entity
    entity_id = [i["id"] for i in payload]
    # Send valid entities to translator
    try:
        with translator_for(fiware_s) as trans:
            trans.insert(payload, fiware_s, fiware_sp)
    except Exception as e:
        msg = "Notification not processed or not updated for payload: %s. " \
              "%s" % (payload, str(e))
        log().error(msg)
        error_code = 500
        if e.__class__ == InvalidHeaderValue or \
                e.__class__ == InvalidParameterValue or \
                e.__class__ == NGSIUsageError:
            error_code = 400
        return msg, error_code
    msg = "Notification successfully processed for : 'tenant' %s, " \
          "'fiwareServicePath' %s, " \
          "'entity_id' %s" % (fiware_s, fiware_sp, entity_id)
    log().info(msg)
    return msg