Skip to content

Commit

Permalink
Keep headers object in reporter module
Browse files Browse the repository at this point in the history
  • Loading branch information
taliaga committed Aug 23, 2019
1 parent 162cf52 commit e4e2850
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 61 deletions.
13 changes: 7 additions & 6 deletions src/reporter/reporter.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,16 @@
from flask import request
from geocoding.geocache import GeoCodingCache
from requests import RequestException
from translators.crate import CrateTranslator, CrateTranslatorInstance, \
NGSI_TO_CRATE, NGSI_TEXT, NGSI_DATETIME, NGSI_ISO8601
from translators.crate import NGSI_TO_CRATE, NGSI_TEXT
from translators.factory import translator_for
from utils.common import iter_entity_attrs
from utils.common import iter_entity_attrs, TIME_INDEX_NAME
import json
import logging
import os
import requests
from reporter.subscription_builder import build_subscription
from reporter.timex import select_time_index_value_as_iso
from reporter.timex import select_time_index_value_as_iso, \
TIME_INDEX_HEADER_NAME
from geocoding.location import normalize_location


Expand Down Expand Up @@ -127,8 +127,9 @@ def notify():
return error, 400

# Add TIME_INDEX attribute
entity[CrateTranslator.TIME_INDEX_NAME] = \
select_time_index_value_as_iso(dict(request.headers), entity)
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)
Expand Down
53 changes: 10 additions & 43 deletions src/reporter/tests/test_timex.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,38 +63,15 @@ def build_notification_timepoints(base_point):


def test_custom_index_takes_priority():
headers = {
TIME_INDEX_HEADER_NAME: 'customTimeIndex'
}
custom_time_index_value = datetime(2019, 1, 1)
ts = build_notification_timepoints(custom_time_index_value)
notification = build_notification(*ts)

assert custom_time_index_value == \
select_time_index_value(headers, notification)


@pytest.mark.parametrize('header_name', [
TIME_INDEX_HEADER_NAME,
TIME_INDEX_HEADER_NAME.lower(),
TIME_INDEX_HEADER_NAME.swapcase()
])
def test_headers_are_case_insensitive(header_name):
headers = {
header_name: 'customTimeIndex'
}
custom_time_index_value = datetime(2019, 1, 1)
ts = build_notification_timepoints(custom_time_index_value)
notification = build_notification(*ts)

assert custom_time_index_value == \
select_time_index_value(headers, notification)
select_time_index_value('customTimeIndex', notification)


def test_use_latest_meta_custom_index():
headers = {
TIME_INDEX_HEADER_NAME: 'customTimeIndex'
}
base_point = datetime(2019, 1, 1)

ts = build_notification_timepoints(base_point)
Expand All @@ -104,13 +81,10 @@ def test_use_latest_meta_custom_index():

# latest meta custom index slot = 8
assert ts[8] == \
select_time_index_value(headers, notification).isoformat()
select_time_index_value('customTimeIndex', notification).isoformat()


def test_skip_custom_index_if_it_has_no_value():
headers = {
TIME_INDEX_HEADER_NAME: 'customTimeIndex'
}
base_point = datetime(2019, 1, 1)
ts = build_notification_timepoints(base_point)
ts[0] = None # custom index slot
Expand All @@ -119,21 +93,19 @@ def test_skip_custom_index_if_it_has_no_value():
notification = build_notification(*ts)

assert ts[1] == \
select_time_index_value(headers, notification).isoformat()
select_time_index_value('customTimeIndex', notification).isoformat()


def test_use_time_instant():
headers = {}
base_point = datetime(2019, 1, 1)
ts = build_notification_timepoints(base_point)
notification = build_notification(*ts)

assert ts[1] == \
select_time_index_value(headers, notification).isoformat()
select_time_index_value(None, notification).isoformat()


def test_use_latest_meta_time_instant():
headers = {}
base_point = datetime(2019, 1, 1)

ts = build_notification_timepoints(base_point)
Expand All @@ -143,11 +115,10 @@ def test_use_latest_meta_time_instant():

# latest meta time instant slot = 9
assert ts[9] == \
select_time_index_value(headers, notification).isoformat()
select_time_index_value(None, notification).isoformat()


def test_use_timestamp():
headers = {}
base_point = datetime(2019, 1, 1)
ts = build_notification_timepoints(base_point)
ts[1] = None # TimeInstant slot
Expand All @@ -156,11 +127,10 @@ def test_use_timestamp():
notification = build_notification(*ts)

assert ts[2] == \
select_time_index_value(headers, notification).isoformat()
select_time_index_value(None, notification).isoformat()


def test_use_latest_meta_timestamp():
headers = {}
base_point = datetime(2019, 1, 1)

ts = build_notification_timepoints(base_point)
Expand All @@ -173,11 +143,10 @@ def test_use_latest_meta_timestamp():

# latest meta time instant slot = 10
assert ts[10] == \
select_time_index_value(headers, notification).isoformat()
select_time_index_value(None, notification).isoformat()


def test_use_date_modified():
headers = {}
base_point = datetime(2019, 1, 1)

ts = build_notification_timepoints(base_point)
Expand All @@ -192,11 +161,10 @@ def test_use_date_modified():

# date modified slot = 3
assert ts[3] == \
select_time_index_value(headers, notification).isoformat()
select_time_index_value(None, notification).isoformat()


def test_use_latest_meta_date_modified():
headers = {}
base_point = datetime(2019, 1, 1)

ts = build_notification_timepoints(base_point)
Expand All @@ -212,13 +180,12 @@ def test_use_latest_meta_date_modified():

# latest meta date modified slot = 11
assert ts[11] == \
select_time_index_value(headers, notification).isoformat()
select_time_index_value(None, notification).isoformat()


def test_use_default_value():
headers = {}
notification = build_notification(*([None] * 12))

actual = select_time_index_value(headers, notification)
actual = select_time_index_value(None, notification)
diff = datetime.now() - actual
assert diff < timedelta(seconds=2)
22 changes: 10 additions & 12 deletions src/reporter/timex.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,18 +31,16 @@ def _iter_metadata(notification: dict, meta_name: str) -> Iterable[MaybeString]:
yield _meta_attribute(notification, attr_name, meta_name)


def time_index_priority_list(headers: dict, notification: dict) -> datetime:
def time_index_priority_list(custom_index: str, notification: dict) -> datetime:
"""
Returns the next possible time_index value using the strategy described in
the function select_time_index_value.
"""
custom_attribute = maybe_string_match(headers, TIME_INDEX_HEADER_NAME)

# Custom time index attribute
yield to_datetime(_attribute(notification, custom_attribute))
yield to_datetime(_attribute(notification, custom_index))

# The most recent custom time index metadata
yield latest_from_str_rep(_iter_metadata(notification, custom_attribute))
yield latest_from_str_rep(_iter_metadata(notification, custom_index))

# TimeInstant attribute
yield to_datetime(_attribute(notification, "TimeInstant"))
Expand All @@ -63,7 +61,7 @@ def time_index_priority_list(headers: dict, notification: dict) -> datetime:
yield latest_from_str_rep(_iter_metadata(notification, "dateModified"))


def select_time_index_value(headers: dict, notification: dict) -> datetime:
def select_time_index_value(custom_index: str, notification: dict) -> datetime:
"""
Determine which attribute or metadata value to use as a time index for the
entity being notified.
Expand Down Expand Up @@ -92,23 +90,23 @@ def select_time_index_value(headers: dict, notification: dict) -> datetime:
present or none of the values found can actually be converted to a
``datetime``.
:param headers: the HTTP headers as received from Orion.
:param custom_index: name of the custom_index (if requested, None otherwise)
:param notification: the notification JSON payload as received from Orion.
:return: the value to be used as time index.
"""
current_time = datetime.now()

for time_index_candidate in time_index_priority_list(headers, notification):
if time_index_candidate:
return time_index_candidate
for index_candidate in time_index_priority_list(custom_index, notification):
if index_candidate:
return index_candidate

# use the current time as a last resort
return current_time


def select_time_index_value_as_iso(headers: dict, notification: dict) -> str:
def select_time_index_value_as_iso(custom_index: str, notification: dict) -> str:
"""
Same as ``select_time_index_value`` but formats the returned ``datetime``
as an ISO 8601 string.
"""
return select_time_index_value(headers, notification).isoformat()
return select_time_index_value(custom_index, notification).isoformat()

0 comments on commit e4e2850

Please sign in to comment.