Skip to content

Commit 6c4fcc1

Browse files
authored
Update nails stack to collect project id from library orcabus id (#1039)
1 parent 50c40aa commit 6c4fcc1

File tree

3 files changed

+147
-17
lines changed

3 files changed

+147
-17
lines changed

lib/workload/stateless/stacks/stacky-mcstackface/glue-constructs/nails/part_1/initialise-library-db/index.ts

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,16 @@ import path from 'path';
2121
import * as sfn from 'aws-cdk-lib/aws-stepfunctions';
2222
import * as events from 'aws-cdk-lib/aws-events';
2323
import * as eventsTargets from 'aws-cdk-lib/aws-events-targets';
24+
import * as ssm from 'aws-cdk-lib/aws-ssm';
25+
import * as secretsmanager from 'aws-cdk-lib/aws-secretsmanager';
26+
import * as lambda from 'aws-cdk-lib/aws-lambda';
27+
import { MetadataToolsPythonLambdaLayer } from '../../../../../../../components/python-metadata-tools-layer';
28+
import {
29+
hostedZoneNameParameterPath,
30+
jwtSecretName,
31+
} from '../../../../../../../../../config/constants';
32+
import { PythonFunction } from '@aws-cdk/aws-lambda-python-alpha';
33+
import { Duration } from 'aws-cdk-lib';
2434

2535
export interface PieriandxInitialiseLibraryConstructProps {
2636
tableObj: dynamodb.ITableV2;
@@ -45,6 +55,51 @@ export class PieriandxInitialiseLibraryConstruct extends Construct {
4555
constructor(scope: Construct, id: string, props: PieriandxInitialiseLibraryConstructProps) {
4656
super(scope, id);
4757

58+
/*
59+
Part 0: Get the metadata layer
60+
*/
61+
// Get the metadata layer object
62+
const metadataLayerObj = new MetadataToolsPythonLambdaLayer(this, 'metadata-tools-layer', {
63+
layerPrefix: 'nails-get-library',
64+
});
65+
66+
/*
67+
Collect the required secret and ssm parameters for getting metadata
68+
*/
69+
const hostnameSsmParameterObj = ssm.StringParameter.fromStringParameterName(
70+
this,
71+
'hostname_ssm_parameter',
72+
hostedZoneNameParameterPath
73+
);
74+
const orcabusTokenSecretObj = secretsmanager.Secret.fromSecretNameV2(
75+
this,
76+
'orcabus_token_secret',
77+
jwtSecretName
78+
);
79+
80+
// Get library objects
81+
const lambdaObj = new PythonFunction(this, 'get_project_id_from_library_id_py', {
82+
entry: path.join(__dirname, 'lambdas', 'get_project_id_from_library_id_py'),
83+
runtime: lambda.Runtime.PYTHON_3_12,
84+
architecture: lambda.Architecture.ARM_64,
85+
index: 'get_project_id_from_library_id.py',
86+
handler: 'handler',
87+
memorySize: 1024,
88+
layers: [metadataLayerObj.lambdaLayerVersionObj],
89+
environment: {
90+
HOSTNAME_SSM_PARAMETER: hostnameSsmParameterObj.parameterName,
91+
ORCABUS_TOKEN_SECRET_ID: orcabusTokenSecretObj.secretName,
92+
},
93+
// We dont know how big the database will get so will may need a longer timeout
94+
timeout: Duration.seconds(120),
95+
});
96+
97+
// Allow the lambda to read the secret
98+
orcabusTokenSecretObj.grantRead(lambdaObj.currentVersion);
99+
100+
// Allow the lambda to read the ssm parameter
101+
hostnameSsmParameterObj.grantRead(lambdaObj.currentVersion);
102+
48103
/*
49104
Part 1: Build the internal sfn
50105
*/
@@ -61,6 +116,10 @@ export class PieriandxInitialiseLibraryConstruct extends Construct {
61116
/* General */
62117
__table_name__: props.tableObj.tableName,
63118

119+
/* Lambdas */
120+
__get_project_id_from_library_id_lambda_function_arn__:
121+
lambdaObj.currentVersion.functionArn,
122+
64123
/* Table Partitions */
65124
__library_partition_name__: this.PieriandxInitialiseLibrary.tablePartition.library,
66125
},
@@ -70,7 +129,9 @@ export class PieriandxInitialiseLibraryConstruct extends Construct {
70129
Part 2: Grant the sfn permissions
71130
*/
72131
// access the dynamodb table
73-
props.tableObj.grantReadWriteData(inputMakerSfn.role);
132+
props.tableObj.grantReadWriteData(inputMakerSfn);
133+
// invoke the lambda
134+
lambdaObj.currentVersion.grantInvoke(inputMakerSfn);
74135

75136
/*
76137
Part 3: Subscribe to the library events from the event bus where the library assay type
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#!/usr/bin/env python3
2+
3+
"""
4+
Given the following
5+
6+
* libraryOrcabusId
7+
8+
Get the library object, and return the projectId
9+
10+
* projectId
11+
"""
12+
13+
import boto3
14+
import typing
15+
16+
from metadata_tools import get_library_from_library_orcabus_id
17+
18+
if typing.TYPE_CHECKING:
19+
from mypy_boto3_ssm import SSMClient
20+
from mypy_boto3_secretsmanager import SecretsManagerClient
21+
22+
23+
def handler(event, context):
24+
"""
25+
26+
:param event:
27+
:param context:
28+
:return:
29+
"""
30+
31+
# Inputs
32+
library_orcabus_id = event.get("libraryOrcabusId")
33+
34+
# Get the library object
35+
library_obj = get_library_from_library_orcabus_id(library_orcabus_id)
36+
37+
# Return the projectId
38+
return {
39+
"projectId": library_obj['projectSet'][0]['projectId']
40+
}
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,77 @@
11
{
22
"Comment": "A description of my state machine",
3-
"StartAt": "Move Inputs",
3+
"StartAt": "Save input vars",
44
"States": {
5-
"Move Inputs": {
5+
"Save input vars": {
66
"Type": "Pass",
7-
"Next": "Initialise Library ID",
8-
"Parameters": {
9-
"inputs.$": "$",
10-
"input_payload_data.$": "$.payload.data"
7+
"Next": "Get project id from library id",
8+
"Assign": {
9+
"inputPayloadData": "{% $states.input.payload.data %}"
1110
}
1211
},
13-
"Initialise Library ID": {
12+
"Get project id from library id": {
13+
"Type": "Task",
14+
"Resource": "arn:aws:states:::lambda:invoke",
15+
"Output": "{% $states.result.Payload %}",
16+
"Arguments": {
17+
"FunctionName": "${__get_project_id_from_library_id_lambda_function_arn__}",
18+
"Payload": {
19+
"libraryOrcabusId": "{% $inputPayloadData.library.orcabusId %}"
20+
}
21+
},
22+
"Retry": [
23+
{
24+
"ErrorEquals": [
25+
"Lambda.ServiceException",
26+
"Lambda.AWSLambdaException",
27+
"Lambda.SdkClientException",
28+
"Lambda.TooManyRequestsException"
29+
],
30+
"IntervalSeconds": 1,
31+
"MaxAttempts": 3,
32+
"BackoffRate": 2,
33+
"JitterStrategy": "FULL"
34+
}
35+
],
36+
"Next": "Initialise Library Id",
37+
"Assign": {
38+
"projectId": "{% $states.result.Payload.projectId %}"
39+
}
40+
},
41+
"Initialise Library Id": {
1442
"Type": "Task",
1543
"Resource": "arn:aws:states:::dynamodb:putItem",
16-
"Parameters": {
44+
"Arguments": {
1745
"TableName": "${__table_name__}",
1846
"Item": {
1947
"id": {
20-
"S.$": "$.input_payload_data.library.orcabusId"
48+
"S": "{% $inputPayloadData.library.orcabusId %}"
2149
},
2250
"id_type": {
2351
"S": "${__library_partition_name__}"
2452
},
2553
"library_id": {
26-
"S.$": "$.input_payload_data.library.libraryId"
54+
"S": "{% $inputPayloadData.library.libraryId %}"
2755
},
2856
"library_obj": {
29-
"S.$": "States.JsonToString($.input_payload_data.library)"
57+
"S": "{% $string($inputPayloadData.library) %}"
3058
},
3159
"project_id": {
32-
"S.$": "$.input_payload_data.projectSet[0].projectId"
60+
"S": "{% $projectId %}"
3361
},
3462
"external_sample_id": {
35-
"S.$": "$.input_payload_data.sample.externalSampleId"
63+
"S": "{% $inputPayloadData.sample.externalSampleId %}"
3664
},
3765
"external_subject_id": {
38-
"S.$": "$.input_payload_data.subject.subjectId"
66+
"S": "{% $inputPayloadData.subject.subjectId %}"
3967
},
4068
"instrument_run_id": {
41-
"S.$": "$.input_payload_data.instrumentRunId"
69+
"S": "{% $inputPayloadData.instrumentRunId %}"
4270
}
4371
}
4472
},
4573
"End": true
4674
}
47-
}
75+
},
76+
"QueryLanguage": "JSONata"
4877
}

0 commit comments

Comments
 (0)