Skip to content

Commit f19c3bd

Browse files
Merge pull request #425 from OP-TED/feature/TED-1177
Feature/ted 1177
2 parents 92bc274 + 8c10a52 commit f19c3bd

6 files changed

Lines changed: 48 additions & 21 deletions

File tree

ted_sws/notice_validator/resources/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@
33
NOTICE_VALIDATOR_RESOURCES_PATH = pathlib.Path(__file__).parent.resolve()
44
SPARQL_QUERY_TEMPLATES_PATH = NOTICE_VALIDATOR_RESOURCES_PATH / "sparql_query_templates"
55
NOTICE_AVAILABILITY_SPARQL_QUERY_TEMPLATE_PATH = SPARQL_QUERY_TEMPLATES_PATH / "check_notice_availability.rq"
6-
NOTICES_AVAILABILITY_SPARQL_QUERY_TEMPLATE_PATH = SPARQL_QUERY_TEMPLATES_PATH / "check_notices_availability.rq"
6+
NOTICES_AVAILABILITY_SPARQL_QUERY_TEMPLATE_PATH = SPARQL_QUERY_TEMPLATES_PATH / "check_notices_availability.rq"
7+
GET_NOTICE_URI_SPARQL_QUERY_TEMPLATE_PATH = SPARQL_QUERY_TEMPLATES_PATH / "get_notice_uri.rq"
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
PREFIX epo: <http://data.europa.eu/a4g/ontology#>
2+
select distinct ?s
3+
{
4+
?s a epo:Notice .
5+
?s epo:hasDispatchDate ?o .
6+
}

ted_sws/notice_validator/services/check_availability_of_notice_in_cellar.py

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
import time
22
from typing import List, Set
3-
43
from pymongo import MongoClient
54
from ted_sws.core.model.notice import Notice, NoticeStatus
65
from ted_sws.core.service.batch_processing import chunks
76
from ted_sws.data_manager.adapters.notice_repository import NoticeRepository
8-
from ted_sws.data_manager.adapters.sparql_endpoint import SPARQLTripleStoreEndpoint
7+
from ted_sws.data_manager.adapters.sparql_endpoint import SPARQLTripleStoreEndpoint, SPARQLStringEndpoint
8+
from ted_sws.event_manager.services.log import log_notice_error
99
from ted_sws.notice_validator.resources import NOTICE_AVAILABILITY_SPARQL_QUERY_TEMPLATE_PATH, \
10-
NOTICES_AVAILABILITY_SPARQL_QUERY_TEMPLATE_PATH
10+
NOTICES_AVAILABILITY_SPARQL_QUERY_TEMPLATE_PATH, GET_NOTICE_URI_SPARQL_QUERY_TEMPLATE_PATH
1111

1212
WEBAPI_SPARQL_URL = "https://publications.europa.eu/webapi/rdf/sparql"
1313
WEBAPI_SPARQL_RUN_FORMAT = "application/sparql-results+json"
@@ -44,13 +44,22 @@ def check_availability_of_notices_in_cellar(notice_uries: List[str], endpoint_ur
4444
return set(result['s'].to_list())
4545

4646

47-
def generate_notice_uri_from_notice_id(notice_id: str) -> str:
47+
def generate_notice_uri_from_notice(notice: Notice) -> str:
4848
"""
4949
This service generates Cellar URI for a notice, determined by notice_id
50-
:param notice_id:
50+
:param notice:
5151
:return:
5252
"""
53-
# TODO: implement notice_uri logic
53+
if notice.distilled_rdf_manifestation and notice.distilled_rdf_manifestation.object_data:
54+
sparql_endpoint = SPARQLStringEndpoint(rdf_content=notice.distilled_rdf_manifestation.object_data)
55+
sparql_query = GET_NOTICE_URI_SPARQL_QUERY_TEMPLATE_PATH.read_text(encoding="utf-8")
56+
notice_uries = sparql_endpoint.with_query(sparql_query=sparql_query).fetch_tabular()["s"].to_list()
57+
if len(notice_uries) == 1:
58+
return notice_uries[0]
59+
else:
60+
log_notice_error(message="Invalid extraction of notice URI from distilled RDF manifestation!",
61+
notice_id=notice.ted_id)
62+
5463
return INVALID_NOTICE_URI
5564

5665

@@ -63,7 +72,7 @@ def validate_notice_availability_in_cellar(notice: Notice, notice_uri: str = Non
6372
"""
6473
if notice.status in [NoticeStatus.PUBLISHED, NoticeStatus.PUBLICLY_UNAVAILABLE]:
6574
if not notice_uri:
66-
notice_uri = generate_notice_uri_from_notice_id(notice_id=notice.ted_id)
75+
notice_uri = generate_notice_uri_from_notice(notice=notice)
6776
if check_availability_of_notice_in_cellar(notice_uri=notice_uri):
6877
notice.update_status_to(new_status=NoticeStatus.PUBLICLY_AVAILABLE)
6978
else:
@@ -85,7 +94,7 @@ def validate_notices_availability_in_cellar(notice_statuses: List[NoticeStatus],
8594
selected_notices = notice_repository.get_notices_by_status(notice_status=notice_status)
8695
for selected_notices_chunk in chunks(selected_notices, chunk_size=DEFAULT_NOTICES_BATCH_SIZE):
8796
selected_notices_map = {
88-
generate_notice_uri_from_notice_id(notice_id=notice.ted_id): notice
97+
generate_notice_uri_from_notice(notice=notice): notice
8998
for notice in selected_notices_chunk
9099
}
91100
selected_notices_uries = list(selected_notices_map.keys())

tests/e2e/notice_validator/conftest.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import pytest
22

3-
from ted_sws.core.model.manifestation import XMLManifestation
3+
from ted_sws.core.model.manifestation import XMLManifestation, RDFManifestation
44
from ted_sws.core.model.notice import Notice
5+
from tests import TEST_DATA_PATH
56

67

78
@pytest.fixture
@@ -25,11 +26,16 @@ def fake_notice_F03_content(fake_repository_path, fake_mapping_suite_F03_id):
2526
notice_content = f.read()
2627
return notice_content
2728

29+
@pytest.fixture
30+
def fake_notice_F03_rdf_content():
31+
return (TEST_DATA_PATH / "rdf_manifestations" / "002705-2021.ttl").read_text(encoding="utf-8")
2832

2933
@pytest.fixture
30-
def fake_notice_F03(fake_notice_F03_content, fake_notice_id):
34+
def fake_notice_F03(fake_notice_F03_content, fake_notice_id, fake_notice_F03_rdf_content):
3135
xml_manifestation = XMLManifestation(object_data=fake_notice_F03_content)
32-
return Notice(ted_id=fake_notice_id, xml_manifestation=xml_manifestation)
36+
notice = Notice(ted_id=fake_notice_id, xml_manifestation=xml_manifestation)
37+
notice._distilled_rdf_manifestation = RDFManifestation(object_data=fake_notice_F03_rdf_content)
38+
return notice
3339

3440

3541
@pytest.fixture

tests/e2e/notice_validator/test_check_availability_of_notice_in_cellar.py

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,21 @@
11
from ted_sws.core.model.notice import NoticeStatus
22
from ted_sws.notice_validator.services.check_availability_of_notice_in_cellar import \
33
check_availability_of_notice_in_cellar, validate_notice_availability_in_cellar, \
4-
check_availability_of_notices_in_cellar, DEFAULT_NOTICES_BATCH_SIZE
4+
check_availability_of_notices_in_cellar, DEFAULT_NOTICES_BATCH_SIZE, generate_notice_uri_from_notice, \
5+
INVALID_NOTICE_URI
56

67

8+
def test_generate_notice_uri_from_notice(fake_notice_F03):
9+
notice_uri = generate_notice_uri_from_notice(notice=fake_notice_F03)
10+
assert notice_uri != INVALID_NOTICE_URI
11+
12+
13+
def test_validate_notices_availability_in_cellar(valid_cellar_uri, invalid_cellar_uri):
14+
notice_uries = [valid_cellar_uri] * DEFAULT_NOTICES_BATCH_SIZE + [invalid_cellar_uri]
15+
available_uries = check_availability_of_notices_in_cellar(notice_uries=notice_uries)
16+
assert valid_cellar_uri in available_uries
17+
assert invalid_cellar_uri not in available_uries
18+
719
def test_check_availability_of_notice_in_cellar(valid_cellar_uri, invalid_cellar_uri):
820
assert check_availability_of_notice_in_cellar(notice_uri=valid_cellar_uri)
921
assert not check_availability_of_notice_in_cellar(notice_uri=invalid_cellar_uri)
@@ -20,10 +32,3 @@ def test_validate_notice_availability_in_cellar(fake_notice_F03, valid_cellar_ur
2032
fake_notice_F03._status = NoticeStatus.PUBLISHED
2133
validate_notice_availability_in_cellar(notice=fake_notice_F03, notice_uri=invalid_cellar_uri)
2234
assert fake_notice_F03.status == NoticeStatus.PUBLICLY_UNAVAILABLE
23-
24-
25-
def test_validate_notices_availability_in_cellar(valid_cellar_uri, invalid_cellar_uri):
26-
notice_uries = [valid_cellar_uri] * DEFAULT_NOTICES_BATCH_SIZE + [invalid_cellar_uri]
27-
available_uries = check_availability_of_notices_in_cellar(notice_uries=notice_uries)
28-
assert valid_cellar_uri in available_uries
29-
assert invalid_cellar_uri not in available_uries

tests/test_data/rdf_manifestations/002705-2021.ttl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1630,7 +1630,7 @@
16301630
epo:concernsProcedure <http://data.europa.eu/a4g/resource/Procedure/2021-S-002-002705/58509ec4-99dc-3865-9935-58d7ebd66d29> .
16311631

16321632
<http://data.europa.eu/a4g/resource/ResultNotice/2021-S-002-002705/58509ec4-99dc-3865-9935-58d7ebd66d29>
1633-
a epo:ResultNotice;
1633+
a epo:Notice, epo:ResultNotice;;
16341634
epo:announcesContract <http://data.europa.eu/a4g/resource/Contract/2021-S-002-002705/0c434fb4-13b2-3f81-9fb1-7ec07b891bd2>;
16351635
epo:announcesNoticeAwardInformation <http://data.europa.eu/a4g/resource/NoticeAwardInformation/2021-S-002-002705/58509ec4-99dc-3865-9935-58d7ebd66d29>;
16361636
epo:announcesRole <http://data.europa.eu/a4g/resource/WinnerRole/2021-S-002-002705/b9a7c460-794b-36b5-a069-6e9a637315f4>;

0 commit comments

Comments
 (0)