-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Added study distribution * Split validation from queue, PR feedback * ruff uprev * decorator cleanup * Submodule, urlparse * coverage * security slash
- Loading branch information
1 parent
512074e
commit 57b87c7
Showing
29 changed files
with
513 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
[submodule "tests/test_data/mock_payloads/cumulus-aggregator-test-study"] | ||
path = tests/test_data/mock_payloads/cumulus-aggregator-test-study | ||
url = https://github.com/smart-on-fhir/cumulus-aggregator-test-study |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,6 +2,7 @@ | |
|
||
import boto3 | ||
import botocore | ||
|
||
from shared import decorators, enums, functions | ||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,6 +3,7 @@ | |
import os | ||
|
||
import boto3 | ||
|
||
from shared import decorators, enums, functions | ||
|
||
|
||
|
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
"""Handler for validating the payload contents and submitting to queue""" | ||
|
||
import json | ||
import os | ||
import urllib | ||
|
||
import boto3 | ||
import requests | ||
|
||
from shared import decorators, functions | ||
|
||
sns_client = boto3.client("sns", os.environ.get("AWS_REGION")) | ||
valid_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~:/?#[]@!$&'()*+," | ||
|
||
|
||
def validate_github_url(config): | ||
parsed_url = urllib.parse.urlparse(config["url"]) | ||
if ( | ||
not parsed_url.netloc == "github.com" | ||
or not parsed_url.path.startswith("/smart-on-fhir/") | ||
or any(c not in valid_chars for c in config["url"]) | ||
): | ||
raise ValueError(f"{config['url']} is not an official Cumulus study.") | ||
res = requests.get(config["url"], timeout=10) | ||
if res.status_code != 200: | ||
raise ValueError(f"{config['url']} is not a valid git repository") | ||
if "tag" in config and config["tag"] is not None: | ||
res = requests.get(config["url"] + f'/tree/{config["tag"]}', timeout=10) | ||
if res.status_code != 200: | ||
raise ValueError(f"{config['tag']} is not a valid tag") | ||
|
||
|
||
def validate_body(body: dict): | ||
"""Selects the appropriate handler for processing study requests""" | ||
for key in body.keys(): | ||
match key: | ||
case "study_name": | ||
pass | ||
case "github": | ||
validate_github_url(body[key]) | ||
case _: | ||
raise ValueError(f"Invalid key {body[key]} received.") | ||
|
||
|
||
@decorators.generic_error_handler(msg="Error generating distributed request") | ||
def distribute_handler(event: dict, context): | ||
"""Creates a distribution packages and queues for delivery""" | ||
del context | ||
body = json.loads(event["body"]) | ||
validate_body(body) | ||
topic_sns_arn = os.environ.get("TOPIC_QUEUE_API_ARN") | ||
sns_client.publish(TopicArn=topic_sns_arn, Message=event["body"], Subject=body["study_name"]) | ||
# TODO: should we create an ID/API for the dashboard to track request status? | ||
res = functions.http_response(200, f'Preparing to queue {body["study_name"]}.') | ||
return res |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
requests |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
../../shared |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
"""Handler for submitting studies to an SNS queue for distribution to remote sites. | ||
In the long term, this module (or a submodule imported by this module) will be responsible | ||
for parsing the output of a dashboard guided workflow/query builder generated payload, | ||
and converting it to a cumulus library compatible study. | ||
It also enables distribution of a smart-on-fhir owned study directly from github, | ||
which is the mode it operates in today. | ||
Due to needing cumulus library, this handler is different from all the other lambda | ||
handlers, in that it is packaged in a docker image and loaded from an elastic container | ||
registry. This has a few architectural implications not present in other lambdas - notably, | ||
the home directory is static and we have to write any data to disk inside of /tmp as the | ||
only writable location. | ||
""" | ||
|
||
import json | ||
import os | ||
import pathlib | ||
import subprocess | ||
|
||
import boto3 | ||
from cumulus_library import cli | ||
|
||
from shared import decorators, functions | ||
|
||
# lambda performance tuning - moving these two variables to be global in the module | ||
# means that their initialization happens during build, rather than invocation. | ||
# This helps reduce the spinup time, especially for the boto client, and since | ||
# there are some hefty bits in here already with the docker spinup, shaving a second | ||
# or two off here is helpful to keep us under the ten second timeout. | ||
# | ||
# https://docs.aws.amazon.com/lambda/latest/dg/best-practices.html#function-code | ||
|
||
sns_client = boto3.client("sns", os.environ.get("AWS_REGION")) | ||
BASE_DIR = "/tmp" # noqa: S108 | ||
|
||
|
||
def get_study_from_github(config): | ||
try: | ||
args = ["--depth", "1", config["url"], f"{BASE_DIR}/studies"] | ||
if config["tag"]: | ||
args = ["--branch", config["tag"], *args] | ||
subprocess.run(["/usr/bin/git", "clone", *args], check=True) # noqa: S603 | ||
|
||
except subprocess.CalledProcessError: | ||
# TODO: retry/backoff logic? or do we just have a user queue again? | ||
raise ValueError(f"{config['url']} is unavailable") | ||
|
||
|
||
def prepare_study(body: dict): | ||
write_path = pathlib.Path(f"{BASE_DIR}/prepared") | ||
write_path.mkdir(parents=True, exist_ok=True) | ||
cli.main( | ||
cli_args=[ | ||
"build", | ||
"-t", | ||
body["study_name"], | ||
"-s", | ||
f"{BASE_DIR}/studies", | ||
"--prepare", | ||
f"{write_path}", | ||
], | ||
) | ||
return pathlib.Path(f"{write_path}") / f"{body['study_name']}.zip" | ||
|
||
|
||
def process_body(body: dict): | ||
"""Selects the appropriate handler for processing study requests""" | ||
for key in body.keys(): | ||
match key: | ||
case "github": | ||
get_study_from_github(body[key]) | ||
|
||
|
||
@decorators.generic_error_handler(msg="Error generating distributed request") | ||
def queue_handler(event: dict, context): | ||
"""Creates a distribution packages and queues for delivery""" | ||
del context | ||
body = event["Records"][0]["Sns"]["Message"] | ||
body = json.loads(body) | ||
process_body(body) | ||
payload = prepare_study(body) | ||
topic_sns_arn = os.environ.get("TOPIC_STUDY_PAYLOAD_ARN") | ||
with open(payload, "rb") as f: | ||
file = f.read() | ||
sns_client.publish( | ||
TopicArn=topic_sns_arn, | ||
Message=json.dumps({"study": body["study_name"]}), | ||
MessageGroupId=body["study_name"], | ||
Subject=body["study_name"], | ||
MessageAttributes={"study": {"DataType": "Binary", "BinaryValue": file}}, | ||
) | ||
res = functions.http_response(200, f'Study {body["study_name"]} queued.') | ||
return res |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
cumulus-library >= 4.1.3 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
../../shared |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
FROM public.ecr.aws/lambda/python:3.11 | ||
|
||
RUN yum update git -y | ||
RUN yum install git -y | ||
|
||
WORKDIR ${LAMBDA_TASK_ROOT} | ||
COPY dashboard/queue_distribute/requirements.txt . | ||
RUN pip install -r requirements.txt | ||
COPY dashboard/queue_distribute/queue_distribute.py . | ||
COPY shared shared | ||
|
||
# Force setup of some initial matplotlib configuration artifacts | ||
RUN mkdir /tmp/matlplotlib | ||
ENV MPLCONFIGDIR=/tmp/matlplotlib | ||
RUN cumulus-library version | ||
|
||
CMD ["queue_distribute.queue_handler"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,6 +5,7 @@ | |
|
||
import awswrangler | ||
import boto3 | ||
|
||
from shared import decorators, enums, functions | ||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.