Skip to content

Commit 965b8ae

Browse files
committed
update
1 parent 5e08212 commit 965b8ae

File tree

13 files changed

+509
-76
lines changed

13 files changed

+509
-76
lines changed

gateway/gateway/__init__.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
gateway.add_endpoint("/collections", func=rpc.data.get_all_products, auth=False, validate=True)
1212
gateway.add_endpoint("/collections/<name>", func=rpc.data.get_product_detail, auth=False, validate=True)
1313
gateway.add_endpoint("/collections/<name>/result", func=rpc.data.get_product_detail_filelist, auth=False, validate=True)
14+
gateway.add_endpoint("/collections/<name>/updatedresult", func=rpc.data.get_product_detail_filelist_updated, auth=False,
15+
validate=True)
1416
gateway.add_endpoint("/collections/<name>/records", func=rpc.data.get_records, auth=True, validate=True)
1517
gateway.add_endpoint("/processes", func=rpc.processes.get_all, auth=True, validate=True)
1618
gateway.add_endpoint("/processes", func=rpc.processes.create, auth=True, validate=True, methods=["POST"], role="admin")
@@ -33,8 +35,13 @@
3335
gateway.add_endpoint("/version/<timestamp>", func=rpc.jobs.version, auth=False, validate=False)
3436
gateway.add_endpoint("/resetjobsdb", func=rpc.jobs.resetdb, auth=False, validate=False)
3537
gateway.add_endpoint("/resetpgdb", func=rpc.processes.resetdb, auth=False, validate=False)
38+
gateway.add_endpoint("/updaterecord", func=rpc.process_graphs.updaterecord, auth=True, validate=True, methods=["POST"])
39+
#gateway.add_endpoint("/updaterecord", func=rpc.data.updaterecord, auth=False, validate=False, methods=["POST"])
40+
gateway.add_endpoint("/updatestate", func=rpc.data.updatestate, auth=False, validate=False)
3641
#gateway.add_endpoint("/jobs/<job_id>/diff", func=rpc.jobs.diff, auth=True, validate=False)
3742
#gateway.add_endpoint("/jobs/<job_id>/diff", func=rpc.jobs.diff, auth=True, validate=False, methods=["POST"])
43+
gateway.add_endpoint("/updatebackend", func=rpc.jobs.updatebackend, auth=True, validate=True,
44+
methods=["POST"])
3845

3946

4047

gateway/openapi.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ paths:
4242
$ref: https://raw.githubusercontent.com/Open-EO/openeo-api/0.3.0/openapi.json#/paths/~1collections~1{name}
4343
/collections/{name}/result:
4444
$ref: https://raw.githubusercontent.com/Open-EO/openeo-api/0.3.0/openapi.json#/paths/~1collections~1{name}
45+
/collections/{name}/updatedresult:
46+
$ref: https://raw.githubusercontent.com/Open-EO/openeo-api/0.3.0/openapi.json#/paths/~1collections~1{name}
4547
/credentials/oidc:
4648
$ref: https://raw.githubusercontent.com/Open-EO/openeo-api/0.3.0/openapi.json#/paths/~1credentials~1oidc
4749
/processes:
@@ -87,6 +89,12 @@ paths:
8789
$ref: https://raw.githubusercontent.com/Open-EO/openeo-api/0.3.0/openapi.json#/paths/~1
8890
/resetpgdb:
8991
$ref: https://raw.githubusercontent.com/Open-EO/openeo-api/0.3.0/openapi.json#/paths/~1
92+
/updaterecord:
93+
$ref: https://raw.githubusercontent.com/Open-EO/openeo-api/0.3.0/openapi.json#/paths/~1validation
94+
/updatebackend:
95+
$ref: https://raw.githubusercontent.com/Open-EO/openeo-api/0.3.0/openapi.json#/paths/~1validation
96+
/updatestate:
97+
$ref: https://raw.githubusercontent.com/Open-EO/openeo-api/0.3.0/openapi.json#/paths/~1
9098
/version/{timestamp}:
9199
$ref: https://raw.githubusercontent.com/Open-EO/openeo-api/0.3.0/openapi.json#/paths/~1
92100
/openapi:

services/data/Dockerfile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,5 @@ RUN pip install -r requirements.txt
99
ADD . /usr/src/app
1010

1111
CMD nameko run --config config.yaml data.service
12+
13+
RUN chmod 777 mockup.json

services/data/data/dependencies/csw.py

Lines changed: 86 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,10 @@
88
from nameko.extensions import DependencyProvider
99

1010
from ..models import ProductRecord, Record, FilePath, SpatialExtent, TemporalExtent
11-
from .xml_templates import xml_base, xml_and, xml_series, xml_product, xml_begin, xml_end, xml_bbox
11+
from .xml_templates import xml_base, xml_and, xml_series, xml_product, xml_begin, xml_end, xml_bbox, xml_timestamp
1212
from .bands import BandsExtractor
1313

14+
import logging
1415

1516
class CWSError(Exception):
1617
''' CWSError raises if a error occures while querying the CSW server. '''
@@ -25,9 +26,25 @@ class CSWHandler:
2526
required output format.
2627
"""
2728

29+
30+
2831
def __init__(self, csw_server_uri: str):
2932
self.csw_server_uri = csw_server_uri
3033
self.bands_extractor = BandsExtractor()
34+
self.updatetime = None
35+
self.deleted = False
36+
37+
def set_updatetime(self, updatetime):
38+
self.updatetime = updatetime
39+
40+
def set_deleted(self, deleted):
41+
self.deleted = deleted
42+
43+
def get_updatetime(self):
44+
return self.updatetime
45+
46+
def get_deleted(self):
47+
return self.deleted
3148

3249
def get_all_products(self) -> list:
3350
"""Returns all products available at the back-end.
@@ -76,12 +93,25 @@ def get_product(self, data_id: str) -> dict:
7693
crs="EPSG:4326"
7794
),
7895
temporal_extent="{0}/{1}".format(data["dc:date"],
79-
datetime.now().strftime('%Y-%m-%d')),
96+
datetime.utcnow().strftime('%Y-%m-%d')),
8097
bands=self.bands_extractor.get_bands(data_id)
8198
)
8299

83100
return product_record
84101

102+
def get_mockup_state(self):
103+
"""
104+
Returns the current version of the back end.
105+
:return: version_info: Dict of the current back end version.
106+
"""
107+
import json
108+
state = None
109+
110+
with open('mockup.json', 'r') as f:
111+
state = json.load(f)
112+
113+
return state
114+
85115
def get_records_full(self, product: str, bbox: list, start: str, end: str) -> list:
86116
"""Returns the full information of the records of the specified products
87117
in the temporal and spatial extents.
@@ -142,7 +172,8 @@ def get_records_shorts(self, product: str, bbox: list, start: str, end: str) ->
142172

143173
return response
144174

145-
def get_file_paths(self, product: str, bbox: list, start: str, end: str, timestamp: str) -> list:
175+
def get_file_paths(self, product: str, bbox: list, start: str, end: str, timestamp: str,
176+
updated: str=None, deleted: bool=False) -> list:
146177
"""Returns the file paths of the records of the specified products
147178
in the temporal and spatial extents.
148179
@@ -152,17 +183,25 @@ def get_file_paths(self, product: str, bbox: list, start: str, end: str, timesta
152183
start {str} -- The start date of the temporal extent
153184
end {str} -- The end date of the temporal extent
154185
timestamp {str} -- The timestamp of the data version, filters by data that was available at that time.
155-
186+
updated {bool} -- If true it simulates that one file got updated.
187+
deleted {bool} -- If false it Simulates that one file got deleted.
156188
Returns:
157189
list -- The records data
158190
"""
159191

160-
date_filter_timestamp = datetime.strptime(timestamp, "%Y-%m-%d")
161-
192+
state = self.get_mockup_state()
193+
#logging.info("Mockupstate: {}".format(str(state)))
194+
updated = state["updatetime"]
195+
deleted = state["deleted"]
196+
logging.info("Deleted: {}".format(str(deleted)))
197+
logging.info("Updatetime: {}".format(str(updated)))
198+
date_filter_timestamp = datetime.strptime(timestamp, '%Y-%m-%d %H:%M:%S.%f')
199+
logging.info("Query Timestamp: {}".format(str(timestamp)))
162200
records=self._get_records(product, bbox, start, end)
163201

164202
# TODO: Better solution than this bulls** xml paths
165203
response=[]
204+
first = True
166205
for item in records:
167206
path=item["gmd:distributionInfo"]["gmd:MD_Distribution"]["gmd:transferOptions"][
168207
"gmd:MD_DigitalTransferOptions"]["gmd:onLine"][0]["gmd:CI_OnlineResource"]["gmd:linkage"]["gmd:URL"]
@@ -176,14 +215,39 @@ def get_file_paths(self, product: str, bbox: list, start: str, end: str, timesta
176215
date_data_timestamp = datetime.strptime(data_timestamp, "%Y-%m-%d")
177216

178217
if date_data_timestamp <= date_filter_timestamp:
179-
response.append(
180-
FilePath(
181-
date=date,
182-
name=name,
183-
path=path,
184-
timestamp=data_timestamp
218+
if not (first and deleted):
219+
response.append(
220+
FilePath(
221+
date=date,
222+
name=name,
223+
path=path,
224+
timestamp=data_timestamp
225+
)
185226
)
186-
)
227+
else:
228+
logging.info("Ignored first file")
229+
else:
230+
logging.info("{} > {}".format(data_timestamp,timestamp))
231+
232+
if updated and first:
233+
path = path + "_new"
234+
name = name + "_new"
235+
236+
date_data_timestamp = datetime.strptime(updated, '%Y-%m-%d %H:%M:%S.%f')
237+
238+
if date_data_timestamp <= date_filter_timestamp:
239+
logging.info("FIRST: Appended additional file")
240+
response.append(
241+
FilePath(
242+
date=date,
243+
name=name,
244+
path=path,
245+
timestamp=data_timestamp
246+
))
247+
else:
248+
logging.info("FIRST: {} > {}".format(data_timestamp, timestamp))
249+
250+
first = False
187251

188252
return response
189253

@@ -308,7 +372,8 @@ def _get_single_records(self, start_position: int, filter_parsed: dict, output_s
308372
return record_next, records
309373

310374

311-
def get_query(self, product: str=None, bbox: list=None, start: str=None, end: str=None, series: bool=False) -> list:
375+
def get_query(self, product: str=None, bbox: list=None, start: str=None, end: str=None,
376+
series: bool=False, timestamp: str=None) -> list:
312377
"""Parses the XML request for the CSW server and collects the responsed by the
313378
batch triggered _get_single_records function.
314379
@@ -325,12 +390,13 @@ def get_query(self, product: str=None, bbox: list=None, start: str=None, end: st
325390
Returns:
326391
list -- The records data
327392
"""
328-
393+
series = False
329394
# Parse the XML request by injecting the query data into the XML templates
330395
output_schema="http://www.opengis.net/cat/csw/2.0.2" if series is True else "http://www.isotc211.org/2005/gmd"
331396

332397
xml_filters=[]
333398

399+
334400
if series:
335401
xml_filters.append(xml_series)
336402

@@ -351,9 +417,14 @@ def get_query(self, product: str=None, bbox: list=None, start: str=None, end: st
351417
if bbox and not series:
352418
xml_filters.append(xml_bbox.format(bbox=bbox))
353419

420+
if timestamp and not series:
421+
xml_filters.append(xml_timestamp.format(timestamp=str(timestamp)))
422+
354423
if len(xml_filters) == 0:
355424
return CWSError("Please provide fiters on the data (bounding box, start, end)")
356425

426+
427+
357428
filter_parsed=""
358429
if len(xml_filters) == 1:
359430
filter_parsed=xml_filters[0]

services/data/data/dependencies/xml_templates.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,3 +72,9 @@
7272
"<gml:upperCorner>{bbox.x2} {bbox.y2}</gml:upperCorner>"
7373
"</gml:Envelope>"
7474
"</ogc:BBOX>")
75+
76+
xml_timestamp = (
77+
"<ogc:PropertyIsLessThanOrEqualTo>"
78+
"<ogc:PropertyName>apiso:Modified</ogc:PropertyName>"
79+
"<ogc:Literal>{timestamp}</ogc:Literal>"
80+
"</ogc:PropertyIsLessThanOrEqualTo>")

0 commit comments

Comments
 (0)