Create a Simple Scheduler from EventBridge
Create a Lambda Function and let the Schedule Triggers it
Our execution flow involves the following steps:
- Scheduler triggers a lambda function in
js
written in the aws console. - This
js
lamdba invoke our springboot lambda viaclient-lambda
sdk. - Springboot lambda handles the task.
Remark 1. This springboot lamdba can be sheerly internal, meaning that this is simply a function and not exposed to the public via api-gateway nor via load-balancer.
Remark 2. Unless our springboot lambda is also exposed to the public, we can add signature to the payload sent from js
lambda to springboot
lamdba (by using the same secret in both ends). For simplicity in this article we simply send a GET
request to an endpoint.
import { InvokeCommand, LambdaClient, ListLayersCommand, } from "@aws-sdk/client-lambda"; export const handler = async (event) => { const client = new LambdaClient({ region: process.env.AWS_REGION }); const apiGatewayEvent = { httpMethod: "GET", path: "/scheduling/package-deadline/check", headers: { "Content-Type": "application/json", }, requestContext: { identity: { sourceIp: "127.0.0.1", }, }, }; const command = new InvokeCommand({ FunctionName: "alice-timetable-kotlin-dev-api", Payload: JSON.stringify(apiGatewayEvent), InvocationType: "RequestResponse", }); const response = await client.send(command); console.log(JSON.stringify(response, null, 4)); const res = { statusCode: 200, body: "Response: " + JSON.stringify(response), }; return res; };
Now this lambda function will invoke our springboot application (alice-timetable-kotlin-dev-api
) by calling our endpoint /scheduling/package-deadline/check
regularly (depends on how long you scheduled repeatedly).
The Endpoint to be Invoked Regularly: /scheduling/package-deadline/check
/scheduling/package-deadline/check
In our springboot application we have defined
package dev.james.alicetimetable.controller import dev.james.alicetimetable.commons.models.APIResponse import org.springframework.web.bind.annotation.GetMapping import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RestController @RestController @RequestMapping("/scheduling") class ScehduleController { @GetMapping("/package-deadline/check") fun checkPackagesDeadline(): APIResponse<String> { println("I am checking deadline") return APIResponse("This is the trigger route for deadline-checking.") } }
The Policy
In order for schedule's lambda function to invoke our springboot lambda, let's create an inline-policy:
{ "Version": "2012-10-17", "Statement": [ { "Action": ["lambda:InvokeFunction"], "Resource": [ "arn:aws:lambda:ap-northeast-1:562976154517:function:alice-timetable-kotlin-dev-api" ], "Effect": "Allow" } ] }
Ideally for relatively serious project we should manage this policy in terraform code. For small project it is fine to simply create it manually (be sure to do the same thing in all environments).