Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions src/main/java/org/sagebionetworks/template/Constants.java
Original file line number Diff line number Diff line change
Expand Up @@ -123,10 +123,14 @@ public class Constants {

public static final String PROPERTY_KEY_RDS_REPO_SNAPSHOT_IDENTIFIER = "org.sagebionetworks.repo.snapshot.identifier";
public static final String PROPERTY_KEY_RDS_TABLES_SNAPSHOT_IDENTIFIERS = "org.sagebionetworks.tables.snapshot.identifiers";
public static final String NOSNAPSHOT = "NOSNAPSHOT"; // value to indicate a snapshot is not used to init a stack

public static final String PROPERTY_KEY_LAMBDA_ARTIFACT_BUCKET = "org.sagebionetworks.lambda.artifact.bucket";
public static final String PROPERTY_KEY_LAMBDA_VIRUS_SCANNER_ARTIFACT_URL = "org.sagebionetworks.lambda.virusscanner.artifactUrl";
public static final String PROPERTY_KEY_LAMBDA_MARKDOWNIT_ARTIFACT_URL = "org.sagebionetworks.lambda.markdownit.artifactUrl";
public static final String PROPERTY_KEY_LAMBDA_ARTIFACT_BUCKET = "org.sagebionetworks.lambda.artifact.bucket";
public static final String NOSNAPSHOT = "NOSNAPSHOT"; // value to indicate a snapshot is not used to init a stack
public static final String PROPERTY_KEY_LAMBDA_MARKDOWNIT_ARTIFACT_VERSION = "org.sagebionetworks.lambda.markdownit.artifact.version";
public static final String PROPERTY_KEY_LAMBDA_MARKDOWNIT_VPC = "org.sagebionetworks.lambda.markdownit.vpc";
public static final String PROPERTY_KEY_LAMBDA_MARKDOWNIT_SUBNETS = "org.sagebionetworks.lambda.markdownit.vpc.subnets";

public static final String PROPERTY_KEY_ENABLE_RDS_ENHANCED_MONITORING = "org.sagebionetworks.enable.rds.enhanced.monitoring";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@
import static org.sagebionetworks.template.Constants.CAPABILITY_NAMED_IAM;
import static org.sagebionetworks.template.Constants.PROPERTY_KEY_LAMBDA_ARTIFACT_BUCKET;
import static org.sagebionetworks.template.Constants.PROPERTY_KEY_LAMBDA_MARKDOWNIT_ARTIFACT_URL;
import static org.sagebionetworks.template.Constants.PROPERTY_KEY_LAMBDA_MARKDOWNIT_ARTIFACT_VERSION;
import static org.sagebionetworks.template.Constants.PROPERTY_KEY_LAMBDA_MARKDOWNIT_SUBNETS;
import static org.sagebionetworks.template.Constants.PROPERTY_KEY_LAMBDA_MARKDOWNIT_VPC;
import static org.sagebionetworks.template.Constants.PROPERTY_KEY_STACK;

public class MarkDownItLambdaBuilderImpl implements MarkDownItLambdaBuilder {
Expand Down Expand Up @@ -61,10 +64,11 @@ public void buildMarkDownItLambda() {

String stack = config.getProperty(PROPERTY_KEY_STACK);
String artifactBucket = config.getProperty(PROPERTY_KEY_LAMBDA_ARTIFACT_BUCKET);
String lambdaSourceArtifactUrl = config.getProperty(PROPERTY_KEY_LAMBDA_MARKDOWNIT_ARTIFACT_URL);
String lambdaArtifactKey = String.format("artifacts/markdown-it/%s", FilenameUtils.getName(lambdaSourceArtifactUrl));
String version = config.getProperty(PROPERTY_KEY_LAMBDA_MARKDOWNIT_ARTIFACT_VERSION);
String lambdaSourceArtifactUrl = getSourceArtifactUrl(version);
String lambdaArtifactKey = String.format("artifacts/markdown-it/%s/markdown-it.zip", version);

// Download from jfrog and upload to S3
// Download from Github and upload to S3
File artifact = downloader.downloadFile(lambdaSourceArtifactUrl);
try {
s3Client.putObject(artifactBucket, lambdaArtifactKey, artifact);
Expand All @@ -76,14 +80,26 @@ public void buildMarkDownItLambda() {

}

private String getSourceArtifactUrl(String version) {
final String LAMBDA_SOURCE_ARTIFACT_URL_FORMAT = "https://github.com/Sage-Bionetworks/synapse-markdown-it-lambda/releases/download/%s/markdown-it.zip";
String lambdaSourceArtifactUrl = String.format(LAMBDA_SOURCE_ARTIFACT_URL_FORMAT, version);
return lambdaSourceArtifactUrl;
}

private Optional<Stack> buildMarkDownItLambdaStack(String stack, String artifactBucket, String artifactKey) {

String stackName = String.format("%s-markdown-it-function", stack);
String stackName = String.format("%s-markdown-it-function-direct", stack);

String vpcId = config.getProperty(PROPERTY_KEY_LAMBDA_MARKDOWNIT_VPC);
String[] subnetIds = config.getCommaSeparatedProperty(PROPERTY_KEY_LAMBDA_MARKDOWNIT_SUBNETS);

// Setup context
VelocityContext context = new VelocityContext();
context.put("stack", stack);
context.put("lambdaArtifactBucket", artifactBucket);
context.put("lambdaArtifactKey", artifactKey);
context.put("vpcId", vpcId);
context.put("subnetIds", subnetIds);

// Generate template
Template template = velocityEngine.getTemplate(Constants.TEMPLATE_MARKDOWNIT_API_VTP);
Expand Down
61 changes: 42 additions & 19 deletions src/main/resources/templates/markdownit/markdown-it-api.json.vtp
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
{
"Resources": {
"mdlambdaSecurityGroup": {
"Type": "AWS::EC2::SecurityGroup",
"Properties": {
"GroupDescription": "Security group for markdown lambda",
"VpcId": "${vpcId}",
"SecurityGroupIngress": [],
"SecurityGroupEgress": [],
"Tags": [
{
"Key": "Name",
"Value": "markdown-lambda-sg"
}
]
}
},
"mdlambdaServiceRole": {
"Type": "AWS::IAM::Role",
"Properties": {
Expand All @@ -16,7 +31,8 @@
"Version": "2012-10-17"
},
"ManagedPolicyArns": [
#[[{ "Fn::Sub": "arn:${AWS::Partition}:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" }]]#
#[[{ "Fn::Sub": "arn:${AWS::Partition}:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" }]]#,
#[[{ "Fn::Sub": "arn:${AWS::Partition}:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole" }]]#
]
}
},
Expand All @@ -27,38 +43,45 @@
"S3Bucket": "${lambdaArtifactBucket}",
"S3Key": "${lambdaArtifactKey}"
},
"FunctionName": "${stack}-markdownit",
"Handler": "index.handler",
"Role": { "Fn::GetAtt": [ "mdlambdaServiceRole", "Arn" ] },
"Runtime": "nodejs20.x",
"Timeout": 10
"Timeout": 10,
"MemorySize": 256,
"VpcConfig": {
"SecurityGroupIds": [{ "Ref": "mdlambdaSecurityGroup" }],
"SubnetIds": [
#foreach($subnetId in $subnetIds)
"${subnetId}"#if($foreach.hasNext),#end
#end
]
}
}
},
"mdlambdaFunctionUrl": {
"Type": "AWS::Lambda::Url",
"mdlambdaVersion": {
"Type": "AWS::Lambda::Version",
"Properties": {
"AuthType": "NONE",
"TargetFunctionArn": { "Ref": "mdlambda" },
"Cors": {
"AllowOrigins": ["*"],
"AllowMethods": ["GET", "POST"]
}
"FunctionName": { "Ref": "mdlambda" }
}
},
"mdlambdaFunctionUrlPermission": {
"Type": "AWS::Lambda::Permission",
"mdlambdaAliasProd": {
"Type": "AWS::Lambda::Alias",
"Properties": {
"Action": "lambda:InvokeFunctionUrl",
"Name": "prod",
"FunctionName": { "Ref": "mdlambda" },
"Principal": "*",
"FunctionUrlAuthType": "NONE"
"FunctionVersion": { "Fn::GetAtt": [ "mdlambdaVersion", "Version" ] }
}
}
},
"Outputs": {
"LambdaFunctionUrl": {
"Value": { "Ref": "mdlambdaFunctionUrl" },
"Description": "The URL endpoint for the Lambda function"
"LambdaFunctionArn": {
"Value": { "Fn::GetAtt": ["mdlambda", "Arn"] },
"Description": "The ARN of the Lambda function"
},
"LambdaAliasArn": {
"Value": { "Ref": "mdlambdaAliasProd" },
"Description": "Stable ARN for invoking the prod alias"
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import java.util.Optional;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.any;
Expand All @@ -32,6 +33,9 @@
import static org.sagebionetworks.template.Constants.CAPABILITY_NAMED_IAM;
import static org.sagebionetworks.template.Constants.PROPERTY_KEY_LAMBDA_ARTIFACT_BUCKET;
import static org.sagebionetworks.template.Constants.PROPERTY_KEY_LAMBDA_MARKDOWNIT_ARTIFACT_URL;
import static org.sagebionetworks.template.Constants.PROPERTY_KEY_LAMBDA_MARKDOWNIT_ARTIFACT_VERSION;
import static org.sagebionetworks.template.Constants.PROPERTY_KEY_LAMBDA_MARKDOWNIT_SUBNETS;
import static org.sagebionetworks.template.Constants.PROPERTY_KEY_LAMBDA_MARKDOWNIT_VPC;
import static org.sagebionetworks.template.Constants.PROPERTY_KEY_STACK;

@ExtendWith(MockitoExtension.class)
Expand Down Expand Up @@ -64,7 +68,9 @@ public void before() {
stack = "dev";
when(mockConfig.getProperty(PROPERTY_KEY_STACK)).thenReturn(stack);
when(mockConfig.getProperty(PROPERTY_KEY_LAMBDA_ARTIFACT_BUCKET)).thenReturn("lambda.sagebase.org");
when(mockConfig.getProperty(PROPERTY_KEY_LAMBDA_MARKDOWNIT_ARTIFACT_URL)).thenReturn("https://sagebionetworks.jfrog.io/lambda/org/sagebase/markdownit/markdownit.zip");
when(mockConfig.getProperty(PROPERTY_KEY_LAMBDA_MARKDOWNIT_ARTIFACT_VERSION)).thenReturn("v1.0.0");
when(mockConfig.getProperty(PROPERTY_KEY_LAMBDA_MARKDOWNIT_VPC)).thenReturn("vpc-12345");
when(mockConfig.getCommaSeparatedProperty(PROPERTY_KEY_LAMBDA_MARKDOWNIT_SUBNETS)).thenReturn(new String[]{"subnet-12345", "subnet-12346"});
}

@Test
Expand All @@ -90,12 +96,12 @@ public void testBuildMarkDownItLambda() throws Exception {
when(mockCloudFormationClientWrapper.describeStack(any())).thenReturn(Optional.of(markdownItLambdaStack));

String expectedBucket = "lambda.sagebase.org";
String expectedKey = "artifacts/markdown-it/markdownit.zip";
String expectedKey = "artifacts/markdown-it/v1.0.0/markdown-it.zip";

// call under test
builder.buildMarkDownItLambda();

verify(mockDownloader).downloadFile("https://sagebionetworks.jfrog.io/lambda/org/sagebase/markdownit/markdownit.zip");
verify(mockDownloader).downloadFile("https://github.com/Sage-Bionetwors/synapse-markdown-it-lambda/releases/download/v1.0.0/markdown-it.zip");
verify(mockS3Client).putObject(expectedBucket, expectedKey, mockFile);

verify(mockFile).delete();
Expand All @@ -109,7 +115,7 @@ public void testBuildMarkDownItLambda() throws Exception {
verify(mockCloudFormationClientWrapper, times(1)).describeStack(argCaptorDescribeStack.capture());

CreateOrUpdateStackRequest request = argCaptorCreateOrUpdateStack.getValue();
assertEquals("dev-markdown-it-function", request.getStackName());
assertEquals("dev-markdown-it-function-direct", request.getStackName());
assertTrue(request.getTags().isEmpty());
assertEquals(1, request.getCapabilities().length);
assertEquals(Capability.CAPABILITY_NAMED_IAM, request.getCapabilities()[0]);
Expand All @@ -122,8 +128,7 @@ public void testBuildMarkDownItLambda() throws Exception {
assertTrue(resources.has("mdlambda"));
assertTrue(resources.has("mdlambdaFunctionUrl"));

assertEquals("dev-markdown-it-function", argCaptorWaitForStack.getValue());
assertEquals("dev-markdown-it-function", argCaptorDescribeStack.getValue());
assertEquals("dev-markdown-it-function-direct", argCaptorWaitForStack.getValue());

}

Expand Down
Loading