Skip to content

Commit 5e2e379

Browse files
authored
Merge 2fc497f into fce033b
2 parents fce033b + 2fc497f commit 5e2e379

File tree

4 files changed

+183
-1
lines changed

4 files changed

+183
-1
lines changed

cumulus_lambda_functions/cumulus_wrapper/query_collections.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,39 @@ def query_rules(self, private_api_prefix: str):
158158
return {'server_error': f'error while invoking:{str(e)}'}
159159
return {'results': query_result}
160160

161+
def delete_sqs_rules(self, new_collection: dict, private_api_prefix: str):
162+
# $ curl --request DELETE https://example.com/rules/repeat_test --header 'Authorization: Bearer ReplaceWithTheToken'
163+
underscore_collection_name = re.sub(r'[^a-zA-Z0-9_]', '___', new_collection["name"]) # replace any character that's not alphanumeric or underscore with 3 underscores
164+
rule_name = f'{underscore_collection_name}___{new_collection["version"]}___rules_sqs'
165+
payload = {
166+
'httpMethod': 'DELETE',
167+
'resource': '/{proxy+}',
168+
'path': f'/{self.__rules_key}/{rule_name}',
169+
'headers': {
170+
'Content-Type': 'application/json',
171+
},
172+
}
173+
LOGGER.debug(f'payload: {payload}')
174+
try:
175+
query_result = self._invoke_api(payload, private_api_prefix)
176+
"""
177+
{'statusCode': 500, 'body': '', 'headers': {}}
178+
"""
179+
if query_result['statusCode'] >= 500:
180+
LOGGER.error(f'server error status code: {query_result["statusCode"]}. details: {query_result}')
181+
return {'server_error': query_result}
182+
if query_result['statusCode'] >= 400:
183+
LOGGER.error(f'client error status code: {query_result["statusCode"]}. details: {query_result}')
184+
return {'client_error': query_result}
185+
query_result = json.loads(query_result['body'])
186+
LOGGER.debug(f'json query_result: {query_result}')
187+
if 'message' not in query_result:
188+
return {'server_error': f'invalid response: {query_result}'}
189+
except Exception as e:
190+
LOGGER.exception('error while invoking')
191+
return {'server_error': f'error while invoking:{str(e)}'}
192+
return {'status': query_result['message']}
193+
161194
def create_sqs_rules(self, new_collection: dict, private_api_prefix: str, sqs_url: str, provider_name: str = '', workflow_name: str = 'CatalogGranule', visibility_timeout: int = 1800):
162195
"""
163196
curl --request POST "$CUMULUS_BASEURL/rules" --header "Authorization: Bearer $cumulus_token" --header 'Content-Type: application/json' --data '{

cumulus_lambda_functions/lib/uds_db/granules_db_index.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,17 @@ def add_entry(self, tenant: str, tenant_venue: str, json_body: dict, doc_id: str
305305
# TODO validate custom metadata vs the latest index to filter extra items
306306
return
307307

308+
def get_size(self, tenant: str, tenant_venue: str, collection_id: str):
309+
read_alias_name = f'{DBConstants.granules_read_alias_prefix}_{tenant}_{tenant_venue}'.lower().strip()
310+
search_dsl = {
311+
'query': {'bool': {'must': [{
312+
'term': {'collection': collection_id}
313+
}]}},
314+
'size': 0
315+
}
316+
search_result = self.__es.query(search_dsl, querying_index=read_alias_name)
317+
return self.__es.get_result_size(search_result)
318+
308319
def dsl_search(self, tenant: str, tenant_venue: str, search_dsl: dict):
309320
read_alias_name = f'{DBConstants.granules_read_alias_prefix}_{tenant}_{tenant_venue}'.lower().strip()
310321
if 'sort' not in search_dsl: # We cannot paginate w/o sort. So, max is 10k items:

cumulus_lambda_functions/uds_api/collections_api.py

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
import json
22
import os
3+
from datetime import datetime
34
from typing import Union
45

5-
from pystac import Catalog, Link
6+
from pystac import Catalog, Link, Collection, Extent, SpatialExtent, TemporalExtent, Summaries, Provider
67

78
from cumulus_lambda_functions.lib.uds_db.db_constants import DBConstants
9+
from cumulus_lambda_functions.lib.uds_db.granules_db_index import GranulesDbIndex
810

911
from cumulus_lambda_functions.lib.uds_db.uds_collections import UdsCollections
1012

@@ -276,3 +278,60 @@ async def query_collections(request: Request, collection_id: Union[str, None] =
276278
if collections_result['statusCode'] == 200:
277279
return collections_result['body']
278280
raise HTTPException(status_code=collections_result['statusCode'], detail=collections_result['body'])
281+
282+
@router.delete("/{collection_id}")
283+
@router.delete("/{collection_id}/")
284+
async def delete_single_collection(request: Request, collection_id: str):
285+
LOGGER.debug(f'starting delete_single_collection: {collection_id}')
286+
LOGGER.debug(f'starting delete_single_collection request: {request}')
287+
288+
authorizer: UDSAuthorizorAbstract = UDSAuthorizerFactory() \
289+
.get_instance(UDSAuthorizerFactory.cognito,
290+
es_url=os.getenv('ES_URL'),
291+
es_port=int(os.getenv('ES_PORT', '443'))
292+
)
293+
auth_info = FastApiUtils.get_authorization_info(request)
294+
uds_collections = UdsCollections(es_url=os.getenv('ES_URL'),
295+
es_port=int(os.getenv('ES_PORT', '443')), es_type=os.getenv('ES_TYPE', 'AWS'))
296+
if collection_id is None or collection_id == '':
297+
raise HTTPException(status_code=500, detail=f'missing or invalid collection_id: {collection_id}')
298+
collection_identifier = uds_collections.decode_identifier(collection_id)
299+
if not authorizer.is_authorized_for_collection(DBConstants.delete, collection_id,
300+
auth_info['ldap_groups'],
301+
collection_identifier.tenant,
302+
collection_identifier.venue):
303+
LOGGER.debug(f'user: {auth_info["username"]} is not authorized for {collection_id}')
304+
raise HTTPException(status_code=403, detail=json.dumps({
305+
'message': 'not authorized to execute this action'
306+
}))
307+
308+
granules_count = GranulesDbIndex().get_size(collection_identifier.tenant, collection_identifier.venue,
309+
collection_id)
310+
LOGGER.debug(f'granules_count: {granules_count} for {collection_id}')
311+
if granules_count > 0:
312+
LOGGER.debug(f'NOT deleting {collection_id} as it is not empty')
313+
raise HTTPException(status_code=409, detail=f'NOT deleting {collection_id} as it is not empty')
314+
315+
try:
316+
new_collection = Collection(
317+
id=collection_id,
318+
description='TODO',
319+
extent = Extent(
320+
SpatialExtent([[0.0, 0.0, 0.0, 0.0]]),
321+
TemporalExtent([[datetime.utcnow(), datetime.utcnow()]])
322+
),
323+
license = "proprietary",
324+
providers = [],
325+
# title=input_collection['LongName'],
326+
# keywords=[input_collection['SpatialKeywords']['Keyword']],
327+
summaries = Summaries({
328+
"totalGranules": [-1],
329+
}),
330+
)
331+
creation_result = CollectionDapaCreation(new_collection).delete()
332+
except Exception as e:
333+
LOGGER.exception('failed during ingest_cnm_dapa')
334+
raise HTTPException(status_code=500, detail=str(e))
335+
if creation_result['statusCode'] < 300:
336+
return creation_result['body'], creation_result['statusCode']
337+
raise HTTPException(status_code=creation_result['statusCode'], detail=creation_result['body'])

cumulus_lambda_functions/uds_api/dapa/collections_dapa_creation.py

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,18 @@ def __init__(self, request_body):
8181
self.__uds_collection = UdsCollections(es_url=os.getenv('ES_URL'), es_port=int(os.getenv('ES_PORT', '443')), es_type=os.getenv('ES_TYPE', 'AWS'), use_ssl=os.getenv('ES_USE_SSL', 'TRUE').strip() is True)
8282
self.__cumulus_collection_query = CollectionsQuery('', '')
8383

84+
def __delete_collection_cumulus(self, cumulus_collection_doc):
85+
delete_result = self.__cumulus_collection_query.delete_collection(self.__cumulus_lambda_prefix, cumulus_collection_doc['name'], cumulus_collection_doc['version'])
86+
if 'status' not in delete_result:
87+
LOGGER.error(f'status not in creation_result: {delete_result}')
88+
return {
89+
'statusCode': 500,
90+
'body': {
91+
'message': delete_result
92+
}
93+
}, None
94+
return None, delete_result
95+
8496
def __create_collection_cumulus(self, cumulus_collection_doc):
8597
creation_result = self.__cumulus_collection_query.create_collection(cumulus_collection_doc, self.__cumulus_lambda_prefix)
8698
if 'status' not in creation_result:
@@ -116,6 +128,37 @@ def __create_rules_cumulus(self, cumulus_collection_doc):
116128
}
117129
return None
118130

131+
def __delete_rules_cumulus(self, cumulus_collection_doc):
132+
rule_deletion_result = self.__cumulus_collection_query.delete_sqs_rules(
133+
cumulus_collection_doc,
134+
self.__cumulus_lambda_prefix
135+
)
136+
if 'status' not in rule_deletion_result:
137+
LOGGER.error(f'status not in rule_creation_result. deleting collection: {rule_deletion_result}')
138+
return {
139+
'statusCode': 500,
140+
'body': {
141+
'message': rule_deletion_result,
142+
'details': f'collection deletion result: {rule_deletion_result}'
143+
}
144+
}
145+
return None
146+
147+
def __delete_collection_uds(self):
148+
try:
149+
delete_collection_result = self.__uds_collection.delete_collection(
150+
collection_id=self.__collection_transformer.get_collection_id()
151+
)
152+
except Exception as e:
153+
LOGGER.exception(f'failed to add collection to Elasticsearch')
154+
return {
155+
'statusCode': 500,
156+
'body': {
157+
'message': f'unable to delete collection to Elasticsearch: {str(e)}',
158+
}
159+
}
160+
return None
161+
119162
def __create_collection_uds(self, cumulus_collection_doc):
120163

121164
try:
@@ -143,6 +186,42 @@ def __create_collection_uds(self, cumulus_collection_doc):
143186
}
144187
return None
145188

189+
def delete(self):
190+
deletion_result = {}
191+
try:
192+
cumulus_collection_doc = self.__collection_transformer.from_stac(self.__request_body)
193+
self.__provider_id = self.__provider_id if self.__collection_transformer.output_provider is None else self.__collection_transformer.output_provider
194+
LOGGER.debug(f'__provider_id: {self.__provider_id}')
195+
creation_result = 'NA'
196+
197+
if self.__include_cumulus:
198+
rules_deletion_result = self.__delete_rules_cumulus(cumulus_collection_doc)
199+
deletion_result['cumulus_rule_deletion'] = rules_deletion_result if rules_deletion_result is not None else 'succeeded'
200+
delete_err, delete_result = self.__delete_collection_cumulus(cumulus_collection_doc)
201+
deletion_result['cumulus_collection_deletion'] = delete_err if delete_err is not None else delete_result
202+
else:
203+
deletion_result['cumulus_rule_deletion'] = 'NA'
204+
deletion_result['cumulus_collection_deletion'] = 'NA'
205+
206+
uds_deletion_result = self.__delete_collection_uds()
207+
deletion_result['uds_collection_deletion'] = uds_deletion_result if uds_deletion_result is not None else 'succeeded'
208+
except Exception as e:
209+
LOGGER.exception('error while creating new collection in Cumulus')
210+
return {
211+
'statusCode': 500,
212+
'body': {
213+
'message': f'error while creating new collection in Cumulus. check details',
214+
'details': str(e)
215+
}
216+
}
217+
LOGGER.info(f'creation_result: {creation_result}')
218+
return {
219+
'statusCode': 200,
220+
'body': {
221+
'message': deletion_result
222+
}
223+
}
224+
146225
def create(self):
147226
try:
148227
cumulus_collection_doc = self.__collection_transformer.from_stac(self.__request_body)

0 commit comments

Comments
 (0)