Skip to content

Commit 9fb03f3

Browse files
author
Drew Meyers
committed
Merge branch 'main' into 413-submit-ogc
2 parents d5d0275 + 2f04b33 commit 9fb03f3

File tree

21 files changed

+725
-52
lines changed

21 files changed

+725
-52
lines changed

README.md

Lines changed: 87 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ Trigger events by themselves don't automatically mean that SDS processing is rea
4949
As described by [Hua et al. [2022]](#1):
5050
> A fundamental capability of an SDS is to systematically process science data through a series of data transformations from raw instrument data to geophysical measurements. Data are first made available to the SDS from GDS to be processed to higher level data products. The data transformation steps may utilize ancillary and auxiliary files as well as production rules that stipulate conditions for when each step should be executed.
5151
52+
In an SDS, evaluators are functions (irrespective of how they are deployed and called) that perform adaptation-specific evaluation to determine if the next step in the processing pipeline is ready for execution.
5253
In an SDS, evaluators are functions (irrespective of how they are deployed and called) that perform adaptation-specific evaluation to determine if the next step in the processing pipeline is ready for execution.
5354

5455
As an example, the following shows the input-output diagram for the NISAR L-SAR L0B PGE (a.k.a. science algorithm):
@@ -176,26 +177,28 @@ In this case, the router sees that the action is `submit_dag_by_id` and thus mak
176177

177178
## Contents
178179

179-
* [Features](#features)
180-
* [Contents](#contents)
181-
* [Quick Start](#quick-start)
182-
* [Requirements](#requirements)
183-
* [Setting Up the End-to-End Demo](#setting-up-the-end-to-end-demo)
184-
* [Deploying the Initiator](#deploying-the-initiator)
185-
* [Deploying an Example Evaluator (SNS topic-\>SQS queue-\>Lambda)](#deploying-an-example-evaluator-sns-topic-sqs-queue-lambda)
186-
* [Deploying an S3 Event Notification Trigger](#deploying-an-s3-event-notification-trigger)
187-
* [Verify End-to-End Functionality (part 1)](#verify-end-to-end-functionality-part-1)
188-
* [Deploying an EventBridge Scheduler Trigger](#deploying-an-eventbridge-scheduler-trigger)
189-
* [Verify End-to-End Functionality (part 2)](#verify-end-to-end-functionality-part-2)
190-
* [Tear Down](#tear-down)
191-
* [Setup Instructions for Development](#setup-instructions-for-development)
192-
* [Build Instructions](#build-instructions)
193-
* [Test Instructions](#test-instructions)
194-
* [Changelog](#changelog)
195-
* [Frequently Asked Questions (FAQ)](#frequently-asked-questions-faq)
196-
* [Contributing](#contributing)
197-
* [License](#license)
198-
* [References](#references)
180+
- [Features](#features)
181+
- [Contents](#contents)
182+
- [Quick Start](#quick-start)
183+
- [Requirements](#requirements)
184+
- [Setting Up the End-to-End Demo](#setting-up-the-end-to-end-demo)
185+
- [Deploying the Initiator](#deploying-the-initiator)
186+
- [Deploying an Example Evaluator (SNS topic-\>SQS queue-\>Lambda)](#deploying-an-example-evaluator-sns-topic-sqs-queue-lambda)
187+
- [Deploying an S3 Event Notification Trigger](#deploying-an-s3-event-notification-trigger)
188+
- [Verify End-to-End Functionality (part 1)](#verify-end-to-end-functionality-part-1)
189+
- [Deploying an EventBridge Scheduler Trigger](#deploying-an-eventbridge-scheduler-trigger)
190+
- [Verify End-to-End Functionality (part 2)](#verify-end-to-end-functionality-part-2)
191+
- [Deploying an EventBridge Scheduler Trigger for Periodic CMR Queries](#deploying-an-eventbridge-scheduler-trigger-for-periodic-cmr-queries)
192+
- [Verify End-to-End Functionality (part 3)](#verify-end-to-end-functionality-part-3)
193+
- [Tear Down](#tear-down)
194+
- [Setup Instructions for Development](#setup-instructions-for-development)
195+
- [Build Instructions](#build-instructions)
196+
- [Test Instructions](#test-instructions)
197+
- [Changelog](#changelog)
198+
- [Frequently Asked Questions (FAQ)](#frequently-asked-questions-faq)
199+
- [Contributing](#contributing)
200+
- [License](#license)
201+
- [References](#references)
199202

200203
## Quick Start
201204

@@ -235,6 +238,7 @@ This guide provides a quick way to get started with our project. Please see our
235238
export AWS_REGION=$(aws configure get region)
236239
sed -i "s/hilo-hawaii-1/${AWS_REGION}/g" test_router.yaml
237240
sed -i "s/123456789012:eval_nisar_ingest/${AWS_ACCOUNT_ID}:uod-dev-eval_nisar_ingest-evaluator_topic/g" test_router.yaml
241+
sed -i "s/123456789012:eval_airs_ingest/${AWS_ACCOUNT_ID}:uod-dev-eval_airs_ingest-evaluator_topic/g" test_router.yaml
238242
```
239243

240244
1. You will need an S3 bucket for terraform to stage the router Lambda zip file during deployment. Create one or reuse an existing one and set an environment variable for it:
@@ -279,7 +283,13 @@ This guide provides a quick way to get started with our project. Please see our
279283
1. Change directory to the location of the sns_sqs_lambda evaluator terraform:
280284

281285
```
282-
cd ../evaluators/sns_sqs_lambda/
286+
cp -rp sns_sqs_lambda sns_sqs_lambda-nisar_tlm
287+
```
288+
289+
1. Change directory into the NISAR TLM evaluator terraform:
290+
291+
```
292+
cd sns_sqs_lambda-nisar_tlm/
283293
```
284294

285295
1. Set the name of the evaluator to our NISAR example:
@@ -404,6 +414,62 @@ This guide provides a quick way to get started with our project. Please see our
404414
1. The deployed EventBridge scheduler runs the trigger Lambda function with schedule expression of `rate(1 minute)`. After a minute, verify that the `eval_nisar_ingest` evaluator Lambda function was called successfully for each of those scheduled invocations by looking at its CloudWatch logs for entries similar to this:
405415
![eval_log_2](https://github.com/unity-sds/unity-initiator/assets/387300/cae82e10-a736-43b7-8957-790fc29b5fea)
406416

417+
#### Deploying an EventBridge Scheduler Trigger for Periodic CMR Queries
418+
419+
1. Change directory to the location of the s3_bucket_notification trigger terraform:
420+
421+
```
422+
cd ../cmr_query/
423+
```
424+
425+
1. Note the implementation of the trigger lambda code. It will query CMR for granules for a particular collection within a timeframe, query its dynamodb table if they already exist, and if not, submit them as payload URLs to the initiator SNS topic and save them into the dynamodb table:
426+
427+
```
428+
cat lambda_handler.py
429+
```
430+
431+
1. Set the CMR provider ID for the AIRS RetStd collection:
432+
433+
```
434+
export PROVIDER_ID=GES_DISC
435+
```
436+
437+
1. Set the CMR concept ID for the AIRS RetStd collection:
438+
439+
```
440+
export CONCEPT_ID=C1701805619-GES_DISC
441+
```
442+
443+
1. Set the amount of seconds to look back from the current epoch for granules in the collection. For example, we will set this value to 2 days (172800 seconds) so that when the CMR query lambda kicks off, it will query for all AIRS RetStd granules using a temporal search of `now - 172800 seconds` to `now`:
444+
445+
```
446+
export SECONDS_BACK=172800
447+
```
448+
449+
1. Initialize terraform:
450+
451+
```
452+
terraform init
453+
```
454+
455+
1. Run terraform apply. Note the DEPLOYMENT_NAME, CODE_BUCKET and INITIATOR_TOPIC_ARN environment variables should have been set in the previous steps. If not set them again:
456+
457+
```
458+
terraform apply \
459+
--var deployment_name=${DEPLOYMENT_NAME} \
460+
--var code_bucket=${CODE_BUCKET} \
461+
--var initiator_topic_arn=${INITIATOR_TOPIC_ARN} \
462+
--var provider_id=${PROVIDER_ID} \
463+
--var concept_id=${CONCEPT_ID} \
464+
--var seconds_back=${SECONDS_BACK} \
465+
-auto-approve
466+
```
467+
468+
#### Verify End-to-End Functionality (part 3)
469+
470+
1. The deployed EventBridge scheduler runs the trigger CMR query Lambda function with schedule expression of `rate(1 minute)`. After a minute, verify that the `eval_airs_ingest` evaluator Lambda function was called successfully for each of those scheduled invocations by looking at its CloudWatch logs for entries similar to this:
471+
![eval_log_3](https://github.com/user-attachments/assets/54b26349-91b2-4958-9082-47613da6c675)
472+
407473
#### Tear Down
408474

409475
1. Simply go back into each of the terraform directories for which `terraform apply` was run and run `terraform destroy`.
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#!/bin/bash
2+
BASE_PATH=$(dirname "${BASH_SOURCE}")
3+
BASE_PATH=$(cd "${BASE_PATH}/.."; pwd)
4+
DIST_DIR=${BASE_PATH}/dist
5+
PKG_DIR=${DIST_DIR}/lambda_packages
6+
CMR_QUERY_DIR=${BASE_PATH}/terraform-unity/triggers/cmr_query
7+
8+
set -ex
9+
10+
rm -rf $DIST_DIR
11+
pip install hatch
12+
hatch clean
13+
hatch build
14+
VERSION=$(hatch run python -c 'from importlib.metadata import version; print(version("unity_initiator"))')
15+
echo "{\"version\": \"$VERSION\"}" > ${DIST_DIR}/version.json
16+
mkdir -p $PKG_DIR
17+
pip install -t $PKG_DIR ${DIST_DIR}/unity_initiator-*.whl
18+
pip install -t $PKG_DIR python_cmr
19+
cp ${CMR_QUERY_DIR}/lambda_handler.py $PKG_DIR/
20+
cd $PKG_DIR
21+
zip -rq ${DIST_DIR}/cmr_query-${VERSION}-lambda.zip .

scripts/build_lambda_package.sh

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ BASE_PATH=$(dirname "${BASH_SOURCE}")
33
BASE_PATH=$(cd "${BASE_PATH}/.."; pwd)
44
DIST_DIR=${BASE_PATH}/dist
55
PKG_DIR=${DIST_DIR}/lambda_packages
6-
TEST_DIR=${BASE_PATH}/tests
76

87
set -ex
98

src/unity_initiator/cloud/lambda_handler.py

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -57,25 +57,25 @@ def lambda_handler_initiator(event, context):
5757
# TODO: Find cleaner way of parsing payloads from a variety of sources (S3 event notification, EventBridge->Lambda).
5858
# For now we use brittle assumptions on the payload structure for each of the supported sources.
5959

60-
# skip S3 test event
61-
if message.get("Event", None) == "s3:TestEvent":
62-
logger.info("Skipped s3:TestEvent")
63-
continue
64-
65-
# payload comes from S3 notification
66-
if "Records" in message:
67-
for rec in message["Records"]:
68-
s3_info = rec["s3"]
69-
payloads.append(
70-
{
71-
"payload": f"s3://{s3_info['bucket']['name']}/{s3_info['object']['key']}"
72-
}
73-
)
74-
# payload comes from EventBridge scheduled task
60+
if isinstance(message, dict):
61+
# skip S3 test event
62+
if message.get("Event", None) == "s3:TestEvent":
63+
logger.info("Skipped s3:TestEvent")
64+
continue
65+
66+
# payload comes from S3 notification
67+
if "Records" in message:
68+
for rec in message["Records"]:
69+
s3_info = rec["s3"]
70+
payloads.append(
71+
{
72+
"payload": f"s3://{s3_info['bucket']['name']}/{s3_info['object']['key']}"
73+
}
74+
)
75+
elif isinstance(message, list):
76+
# payload comes from EventBridge scheduled task
77+
payloads.extend(message)
7578
else:
76-
if isinstance(message, list):
77-
payloads.extend(message)
78-
else:
79-
payloads.append(message)
79+
payloads.append(message)
8080

8181
return lambda_handler_multiple_payloads(payloads, context)

terraform-unity/evaluators/sns-sqs-lambda/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ No modules.
2626

2727
| Name | Type |
2828
|------|------|
29+
| [aws_cloudwatch_log_group.evaluator_lambda_log_group](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_log_group) | resource |
2930
| [aws_iam_policy.evaluator_lambda_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource |
3031
| [aws_iam_role.evaluator_lambda_iam_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource |
3132
| [aws_iam_role_policy_attachment.lambda_base_policy_attachment](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |

terraform-unity/evaluators/sns-sqs-lambda/locals.tf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
locals {
2+
function_name = "${var.project}-${var.venue}-${var.evaluator_name}-evaluator"
23
tags = {
34
Venue = "dev"
45
ServiceArea = "cs"

terraform-unity/evaluators/sns-sqs-lambda/main.tf

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ resource "aws_lambda_function" "evaluator_lambda" {
88
]
99
}
1010

11-
function_name = "${var.project}-${var.venue}-${var.evaluator_name}-evaluator"
11+
function_name = local.function_name
1212
role = aws_iam_role.evaluator_lambda_iam_role.arn
1313
handler = "lambda_function.lambda_handler"
1414
runtime = "python3.11"
@@ -18,8 +18,13 @@ resource "aws_lambda_function" "evaluator_lambda" {
1818
tags = local.tags
1919
}
2020

21+
resource "aws_cloudwatch_log_group" "evaluator_lambda_log_group" {
22+
name = "/aws/lambda/${local.function_name}"
23+
retention_in_days = 14
24+
}
25+
2126
resource "aws_iam_role" "evaluator_lambda_iam_role" {
22-
name = "${var.project}-${var.venue}-${var.evaluator_name}-evaluator_lambda_iam_role"
27+
name = "${local.function_name}_lambda_iam_role"
2328

2429
assume_role_policy = jsonencode({
2530
Version = "2012-10-17",
@@ -38,7 +43,7 @@ resource "aws_iam_role" "evaluator_lambda_iam_role" {
3843
}
3944

4045
resource "aws_iam_policy" "evaluator_lambda_policy" {
41-
name = "${var.project}-${var.venue}-${var.evaluator_name}-evaluator_lambda_policy"
46+
name = "${local.function_name}_lambda_policy"
4247
description = "A policy for the evaluator lambda function to access S3 and SQS"
4348

4449
policy = jsonencode({
@@ -89,7 +94,7 @@ resource "aws_ssm_parameter" "evaluator_lambda_function_name" {
8994

9095

9196
resource "aws_sqs_queue" "evaluator_dead_letter_queue" {
92-
name = "${var.project}-${var.venue}-${var.evaluator_name}-evaluator_dead_letter_queue"
97+
name = "${local.function_name}_dead_letter_queue"
9398
delay_seconds = 0
9499
max_message_size = 2048
95100
message_retention_seconds = 1209600
@@ -99,7 +104,7 @@ resource "aws_sqs_queue" "evaluator_dead_letter_queue" {
99104
}
100105

101106
resource "aws_sqs_queue" "evaluator_queue" {
102-
name = "${var.project}-${var.venue}-${var.evaluator_name}-evaluator_queue"
107+
name = "${local.function_name}_queue"
103108
delay_seconds = 0
104109
max_message_size = 2048
105110
message_retention_seconds = 1209600
@@ -113,7 +118,7 @@ resource "aws_sqs_queue" "evaluator_queue" {
113118
}
114119

115120
resource "aws_sns_topic" "evaluator_topic" {
116-
name = "${var.project}-${var.venue}-${var.evaluator_name}-evaluator_topic"
121+
name = "${local.function_name}_topic"
117122
}
118123

119124
resource "aws_sns_topic_policy" "evaluator_topic_policy" {

terraform-unity/initiator/locals.tf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
locals {
2+
function_name = "${var.project}-${var.venue}-${var.deployment_name}-inititator"
23
tags = {
34
Venue = "dev"
45
ServiceArea = "cs"

terraform-unity/initiator/main.tf

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ resource "aws_ssm_parameter" "initiator_lambda_function_name" {
118118

119119

120120
resource "aws_sqs_queue" "initiator_dead_letter_queue" {
121-
name = "${var.project}-${var.venue}-${var.deployment_name}-inititator_dead_letter_queue"
121+
name = "${local.function_name}_dead_letter_queue"
122122
delay_seconds = 0
123123
max_message_size = 2048
124124
message_retention_seconds = 1209600
@@ -127,7 +127,7 @@ resource "aws_sqs_queue" "initiator_dead_letter_queue" {
127127
}
128128

129129
resource "aws_sqs_queue" "initiator_queue" {
130-
name = "${var.project}-${var.venue}-${var.deployment_name}-inititator_queue"
130+
name = "${local.function_name}_queue"
131131
delay_seconds = 0
132132
max_message_size = 2048
133133
message_retention_seconds = 1209600
@@ -141,7 +141,7 @@ resource "aws_sqs_queue" "initiator_queue" {
141141
}
142142

143143
resource "aws_sns_topic" "initiator_topic" {
144-
name = "${var.project}-${var.venue}-${var.deployment_name}-inititator_topic"
144+
name = "${local.function_name}_topic"
145145
tags = local.tags
146146
}
147147

0 commit comments

Comments
 (0)