Skip to content

Commit ee46ce9

Browse files
committed
PR-7502 Refactored to grab SQS from lambda
1 parent d723e04 commit ee46ce9

4 files changed

Lines changed: 77 additions & 22 deletions

File tree

ctorm/ctorm/cnm_sender.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,11 @@ def __init__(
1919
self.provider = provider
2020
self.cnm_s_generator = CtormCnmSGenerator()
2121

22-
def send_all(self):
22+
def send_all(self) -> bool:
2323
for granule in self.granules:
2424
cnms = self.cnm_s_generator(granule, self.provider)
2525
log.debug("Sending %s", cnms)
26+
# TODO: actually send
27+
28+
# TODO: determine successfulllness
29+
return True

ctorm/ctorm/lambda_run.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
import json
66
import logging
77

8+
from aws_lambda_typing import context as context_
9+
810
from ctorm.load_tester import lambda_handler
911

1012
log = logging.getLogger()
@@ -19,14 +21,15 @@
1921

2022

2123
# mock event data
22-
with open("../../data/lambda_event.json", "r") as f:
24+
with open("../../data/lambda-event-eventbridge.json", "r") as f:
2325
mock_event = json.load(f)
2426

2527

2628
# Mock context object
27-
class MockContext:
29+
class MockContext(context_.Context):
2830
function_name = "local_test"
2931
memory_limit_in_mb = 128
32+
aws_request_id = "LOLOCAL"
3033

3134

3235
# Run it

ctorm/ctorm/load_tester.py

Lines changed: 53 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,29 @@
11
import json
22
import logging
33
import os
4+
from functools import cache
45
from typing import List
56

7+
import boto3
68
from aws_lambda_typing import context as context_
79
from aws_lambda_typing import events
810
from cnm_sender import CnmSender
911

1012
from ctorm.config import (
13+
AWS_REGION,
1114
CtormConfig,
1215
CtormPreparedGranule,
1316
)
1417

1518
log = logging.getLogger(__name__)
1619

1720

21+
@cache
22+
def get_sqs_client():
23+
return boto3.client("sqs", region_name=AWS_REGION)
24+
25+
26+
@cache
1827
def configure_cfg():
1928
cfg = CtormConfig.from_file(
2029
cfg_file=os.getenv("CFG_FILE", "./ctorm.cfg"),
@@ -43,9 +52,46 @@ def configure_logging() -> None:
4352
)
4453

4554

46-
def load_test(cfg: CtormConfig, granule_list: List[CtormPreparedGranule]):
47-
c_sender = CnmSender(cfg, granule_list)
48-
c_sender.send_all()
55+
def get_granule_list(event: events.EventBridgeEvent) -> List[CtormPreparedGranule]:
56+
# TODO: Implement
57+
return []
58+
59+
60+
def load_test(
61+
cfg: CtormConfig,
62+
gr_queue_url: str,
63+
):
64+
# fetch 10 messages from SQS
65+
messages = []
66+
while len(messages) < 10:
67+
# Since we're trying to send x granules per invocation, we will do what we can
68+
# to get a full load of 10 messages.
69+
sqs_resp = get_sqs_client().receive_message(
70+
QueueUrl=gr_queue_url,
71+
MaxNumberOfMessages=min(10 - len(messages), 10),
72+
WaitTimeSeconds=5,
73+
VisibilityTimeout=3600,
74+
)
75+
76+
batch = sqs_resp.get("Messages", [])
77+
if not batch:
78+
break
79+
80+
messages.extend(batch)
81+
82+
for message in sqs_resp.get("Messages", []):
83+
body = json.loads(message["Body"])
84+
receipt_handle = message["ReceiptHandle"]
85+
granule_list = body.get("granules", [])
86+
87+
c_sender = CnmSender(cfg, granule_list)
88+
success = c_sender.send_all()
89+
if success:
90+
log.debug("Deleting message %s", receipt_handle)
91+
# TODO: uncomment after some dev'ing
92+
# get_sqs_client().delete_message(
93+
# QueueUrl=gr_queue_url, ReceiptHandle=receipt_handle
94+
# )
4995

5096

5197
def lambda_handler(event: events.EventBridgeEvent, context: context_.Context):
@@ -61,9 +107,10 @@ def lambda_handler(event: events.EventBridgeEvent, context: context_.Context):
61107

62108
try:
63109
log.debug("Received event: %s", event)
64-
g_list = event["Records"].pop().get("body")
65-
g_list = json.loads(g_list).get("granules")
66-
load_test(cfg, g_list)
110+
# g_list = event["Records"].pop().get("body")
111+
# g_list = json.loads(g_list).get("granules")
112+
113+
load_test(cfg, event["granules_queue_url"])
67114

68115
log.info("CNM sender invocation completed")
69116
return {"ok": True}

ctorm/ctorm/prepare.py

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
from botocore.exceptions import ClientError
1111
from mypy_boto3_s3.type_defs import ListObjectsV2OutputTypeDef
1212

13-
from ctorm.config import AWS_REGION, CtormConfig, CtormPipeline
13+
from ctorm.config import AWS_REGION, MD5_CHECKSUM_PATTERN, CtormConfig, CtormPipeline
1414

1515
log = getLogger(__name__)
1616

@@ -164,8 +164,9 @@ def process_ummg(self, ummg: dict, ct_bkt: CtormPipeline) -> dict:
164164
]:
165165
if r_urls["URL"].endswith(distr_file["Name"]):
166166
# We handily have the md5 and size in the ummg
167-
filedict[K.MD5] = distr_file["Checksum"]["Value"]
167+
# TODO: double-check this test is correct and we're not unnecessarily HEADing too many files.
168168
filedict[K.SIZE] = distr_file["SizeInBytes"]
169+
filedict[K.MD5] = distr_file["Checksum"]["Value"]
169170
break
170171
else:
171172
# We must look to S3 for the size and md5
@@ -176,17 +177,17 @@ def process_ummg(self, ummg: dict, ct_bkt: CtormPipeline) -> dict:
176177
)
177178
log.debug("head_object: %s", headobj)
178179
filedict[K.SIZE] = headobj["ContentLength"]
179-
filedict[K.MD5] = headobj["ETag"].replace('"', "")
180-
if filedict[K.MD5].endswith("-1"):
181-
# This was a multipart upload. We'll have to do something clever to get the MD5 of it.
182-
183-
if self.cfg.calc_md5:
184-
log.debug(
185-
"multipart upload detected for %s", objloc
186-
)
187-
filedict[K.MD5] = self.get_real_md5(
188-
ct_bkt, bucket, objloc
189-
)
180+
181+
md5 = headobj["ETag"].replace('"', "")
182+
if MD5_CHECKSUM_PATTERN.fullmatch(md5):
183+
filedict[K.MD5] = md5
184+
elif self.cfg.calc_md5:
185+
log.debug("multipart upload detected for %s", objloc)
186+
filedict[K.MD5] = self.get_real_md5(
187+
ct_bkt, bucket, objloc
188+
)
189+
else:
190+
log.debug("no need to calculate md5 for %s", objloc)
190191
except ClientError as e:
191192
log.error("head_object failed: %s", e)
192193
# TODO: trash entire message for this granule?

0 commit comments

Comments
 (0)