Skip to content

Commit 38fb800

Browse files
authored
Merge pull request #2924 from ASFHyP3/develop
Release v10.11.9
2 parents e2dd83b + 0c0bc16 commit 38fb800

13 files changed

+110
-35
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@ All notable changes to this project will be documented in this file.
44
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
55
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

7+
## [10.11.9]
8+
9+
### Fixed
10+
- CMR outages no longer block jobs from being submitted, except for the `OPERA_RTC_S1` and `OPERA_RTC_S1_SLC` job types. Fixes https://github.com/ASFHyP3/hyp3/issues/2761
11+
712
## [10.11.8]
813

914
### Changed

apps/api/src/hyp3_api/handlers.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
from http.client import responses
22

3-
import requests
43
from flask import Response, abort, jsonify, request
54

65
import dynamo
@@ -13,7 +12,7 @@
1312
)
1413
from hyp3_api import util
1514
from hyp3_api.multi_burst_validation import MultiBurstValidationError
16-
from hyp3_api.validation import ValidationError, validate_jobs
15+
from hyp3_api.validation import CmrError, ValidationError, validate_jobs
1716

1817

1918
def problem_format(status: int, message: str) -> Response:
@@ -28,9 +27,8 @@ def post_jobs(body: dict, user: str) -> dict:
2827

2928
try:
3029
validate_jobs(body['jobs'])
31-
except requests.HTTPError as e:
32-
print(f'CMR search failed: {e}')
33-
abort(problem_format(503, 'Could not submit jobs due to a CMR error. Please try again later.'))
30+
except CmrError as e:
31+
abort(problem_format(503, str(e)))
3432
except (ValidationError, MultiBurstValidationError) as e:
3533
abort(problem_format(400, str(e)))
3634

apps/api/src/hyp3_api/validation.py

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,12 @@ class ValidationError(Exception):
2626
pass
2727

2828

29+
class CmrError(Exception):
30+
"""Raised when the CMR query has failed and is required for the current job type."""
31+
32+
pass
33+
34+
2935
with (Path(__file__).parent / 'job_validation_map.yml').open() as job_validation_map_file:
3036
JOB_VALIDATION_MAP = yaml.safe_load(job_validation_map_file.read())
3137

@@ -39,6 +45,9 @@ def _has_sufficient_coverage(granule: Polygon) -> bool:
3945

4046

4147
def _get_cmr_metadata(granules: Iterable[str]) -> list[dict]:
48+
if not granules:
49+
return []
50+
4251
cmr_parameters = {
4352
'granule_ur': [f'{granule}*' for granule in granules],
4453
'options[granule_ur][pattern]': 'true',
@@ -61,15 +70,25 @@ def _get_cmr_metadata(granules: Iterable[str]) -> list[dict]:
6170
'page_size': 2000,
6271
}
6372
response = requests.post(CMR_URL, data=cmr_parameters)
64-
response.raise_for_status()
65-
return [
73+
74+
try:
75+
response.raise_for_status()
76+
except requests.HTTPError as e:
77+
print(f'CMR search failed: {e}')
78+
return []
79+
80+
granule_metadata = [
6681
{
6782
'name': entry.get('producer_granule_id', entry.get('title')),
6883
'polygon': Polygon(_format_points(entry['polygons'][0][0])),
6984
}
7085
for entry in response.json()['feed']['entry']
7186
]
7287

88+
_make_sure_granules_exist(granules, granule_metadata)
89+
90+
return granule_metadata
91+
7392

7493
def _is_third_party_granule(granule: str) -> bool:
7594
return granule.startswith('S2') or granule.startswith('L')
@@ -83,6 +102,13 @@ def _make_sure_granules_exist(granules: Iterable[str], granule_metadata: list[di
83102
raise ValidationError(f'Some requested scenes could not be found: {", ".join(not_found_granules)}')
84103

85104

105+
def check_cmr_query_succeeded(job: dict, granule_metadata: list[dict]) -> None:
106+
if not granule_metadata:
107+
raise CmrError(
108+
f'Cannot validate job(s) of type {job["job_type"]} because CMR query failed. Please try again later.'
109+
)
110+
111+
86112
def check_dem_coverage(_, granule_metadata: list[dict]) -> None:
87113
bad_granules = [g['name'] for g in granule_metadata if not _has_sufficient_coverage(g['polygon'])]
88114
if bad_granules:
@@ -279,12 +305,7 @@ def check_opera_rtc_s1_date(job: dict, _) -> None:
279305

280306
def validate_jobs(jobs: list[dict]) -> None:
281307
granules = get_granules(jobs)
282-
283-
if granules:
284-
granule_metadata = _get_cmr_metadata(granules)
285-
_make_sure_granules_exist(granules, granule_metadata)
286-
else:
287-
granule_metadata = []
308+
granule_metadata = _get_cmr_metadata(granules)
288309

289310
for job in jobs:
290311
for validator_name in JOB_VALIDATION_MAP[job['job_type']]:

job_spec/OPERA_RTC_S1.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ OPERA_RTC_S1:
2424
cost: 1.0
2525
validators:
2626
- check_opera_rtc_s1_date
27+
- check_cmr_query_succeeded
2728
- check_opera_rtc_s1_bounds
2829
steps:
2930
- name: ''

job_spec/OPERA_RTC_S1_SLC.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ OPERA_RTC_S1_SLC:
2323
DEFAULT:
2424
cost: 1.0
2525
validators:
26+
- check_cmr_query_succeeded
2627
- check_opera_rtc_s1_bounds
2728
steps:
2829
- name: ''

requirements-all.txt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,15 @@
55
-r requirements-apps-disable-private-dns.txt
66
-r requirements-apps-search-archive.txt
77
-r requirements-apps-update-db.txt
8-
boto3==1.40.35
8+
boto3==1.40.40
99
jinja2==3.1.6
1010
moto[dynamodb]==5.1.13
1111
pytest==8.4.2
12-
PyYAML==6.0.2
12+
PyYAML==6.0.3
1313
responses==0.25.8
14-
ruff==0.13.1
14+
ruff==0.13.2
1515
mypy==1.18.2
1616
setuptools==80.9.0
1717
setuptools_scm==9.2.0
1818
openapi-spec-validator==0.7.2
19-
cfn-lint==1.39.1
19+
cfn-lint==1.40.0

requirements-apps-api.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,6 @@ prance==25.4.8.0
66
PyJWT==2.10.1
77
requests==2.32.5
88
serverless_wsgi==3.1.0
9-
shapely==2.1.1
9+
shapely==2.1.2
1010
strict-rfc3339==0.7
1111
./lib/dynamo/
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
boto3==1.40.35
1+
boto3==1.40.40

requirements-apps-get-files.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
boto3==1.40.35
1+
boto3==1.40.40
22
./lib/dynamo/
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
boto3==1.40.35
1+
boto3==1.40.40
22
./lib/dynamo/
33
./lib/lambda_logging/

0 commit comments

Comments
 (0)