Notes – April 22- April 26

Hello world lambda in Go

package main

import (
    "context"

    "github.com/aws/aws-lambda-go/lambda"
)

type MyEvent struct {
    Name string `json:"name"`
}

type Pet struct {
    Name string `json:"name"`
}

type Response struct {
    Status string `json:"status"`
    Pets   []Pet  `json:"pets"`
}

func HandleRequest(ctx context.Context, name MyEvent) (Response, error) {
    var pets []Pet
    pets = append(pets, Pet{Name: "Lucky"})
    pets = append(pets, Pet{Name: "Bethoven"})
    response := Response{
        Status: "OK",
        Pets:   pets,
    }
    return response, nil
}

func main() {
    lambda.Start(HandleRequest)
}

This is how you define a lambda function with Cloudformation

  MyLambdaFunction:
    Type: AWS::Serverless::Function
    Properties:
      Handler: "main"
      Runtime: go1.x
      CodeUri: s3://path/to/your/lambda.zip
      Description: "Your own description"
      Timeout: 5 # In seconds
      Role:
        Fn::GetAtt:
          - "SomeRole"
          - "Arn"

How do I reference a resource in another Cloudformation stack during template creation?

https://aws.amazon.com/premiumsupport/knowledge-center/cloudformation-reference-resource/

Connecting a lambda function to an SQS queue

  EventSourceMapping:
    Type: AWS::Lambda::EventSourceMapping
    Properties:
      BatchSize: 10 # Default 10. Max 10
      Enabled: true
      EventSourceArn:
        Fn::ImportValue:
          Ref: ExternalQueueArn # The queue was defined in another Cloudformation stack
      FunctionName:
         Fn::GetAtt:
          - "MyLambdaFunction" asdfasd   
          - "Arn"

What is the easiest to define a policy to connect to an AWS resource?

Simply define your policy within the role:

MyRole:
Properties:
  ManagedPolicyArns:
  - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
  AssumeRolePolicyDocument:
    Statement:
    - Action: ["sts:AssumeRole"]
      Effect: Allow
      Principal:
        Service: [lambda.amazonaws.com]
    Version: "2012-10-17"
  Policies:
    -
      PolicyName: "QueuePermissions"
      PolicyDocument:
        Version: "2012-10-17"
        Statement:
          -
            Effect: "Allow"
            Resource: "*"
            Action:
              - "sqs:DeleteMessage"

Cloudformation template parameters

When defining parameters, make sure you set a default value. For example:

ExternalQueueArn:
  Type: String
  Default: "ExternalQueueArn"

Instead of:

ExternalQueueArn:
  Type: String

Working with SQS

  1. Create a brand new project on IntelliJ with Maven(make sure the Maven plugins are enabled)
  2. Add a dependency for AWS SQS library
    <dependencies>
        <!-- https://mvnrepository.com/artifact/com.amazonaws/aws-java-sdk-sqs -->
        <dependency>
            <groupId>com.amazonaws</groupId>
            <artifactId>aws-java-sdk-sqs</artifactId>
            <version>1.11.538</version>
        </dependency>
    </dependencies>

Credentials

Put your AWS credentials in your ~/.aws/credentials file.

Send message request

import com.amazonaws.services.sqs.AmazonSQS;
import com.amazonaws.services.sqs.AmazonSQSClientBuilder;
import com.amazonaws.services.sqs.model.SendMessageRequest;

public class SqsClient {
    private static final String QUEUE_NAME = "MyQueue";

    public static void main(String[] args)
    {
        AmazonSQS sqs = AmazonSQSClientBuilder.defaultClient();

        // Get the URL for a queue
        String queueUrl = sqs.getQueueUrl(QUEUE_NAME).getQueueUrl();
        System.out.println("Queue URL: " + queueUrl);


        SendMessageRequest sendMessageResult = new SendMessageRequest()
                .withQueueUrl(queueUrl)
                .withMessageBody("hello world")
                .withDelaySeconds(5);
        sqs.sendMessage(sendMessageResult);
    }
}

Parse a request’s payload in a Java lambda

ObjectMapper mapper = new ObjectMapper();
Payload payload = mapper.readValue(inputStream, Payload.class);

Where Payload is a class that models your data, for example, given the following payload:

{
    "Records": [
        {
            "attributes": {
                "ApproximateFirstReceiveTimestamp": "1556142295605",
                "ApproximateReceiveCount": "1",
                "SenderId": "AIAAIAA1AA1P11AACN1O1",
                "SentTimestamp": "1556142290605"
            },
            "awsRegion": "us-west-2",
            "body": "{\"message\": \"Hello!\"}",
            "eventSource": "aws:sqs",
            "eventSourceARN": "arn:aws:sqs:us-west-2:111111111111:ExternalQueue",
            "md5OfBody": "c5fd3360e55117d8467fadfef40f8631",
            "messageAttributes": {},
            "messageId": "111bc111-9256-4bb4-bbcb-bbbc111cbeb1",
            "receiptHandle": "AAAAAAAA..."
        }
    ]
}

Your classes would look like:

@JsonIgnoreProperties(ignoreUnknown = true)
public class Payload {
    private List<Record> records;

    @JsonProperty("Records")
    public List<Record> getRecords() {
        return records;
    }

    public void setRecords(List<Record> records) {
        this.records = records;
    }
}

@JsonIgnoreProperties(ignoreUnknown = true)
public class Record {
    private String messageId;
    private String body;
    private String eventSource;
    private String eventSourceARN;
    private String awsRegion;

    // Getters & Setters
}

How to create (Input|Output)Stream implementations in Java

Java provides two implementations out of the box, they work with bytes though:

ByteArrayInputStream inputStream = new ByteArrayInputStream("{}".getBytes());
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();

How to read InputStream as a string

Use the BufferedReader class

BufferedReader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
reader.readLine();

Reference: https://stackoverflow.com/questions/5200187

Reading a file in Java(a quick reminder)

InputStreamReader isr = new InputStreamReader(new FileInputStream(fileName), StandardCharsets.UTF_8);
BufferedReader bufferedReader = new BufferedReader(isr);
StringBuilder builder = new StringBuilder();
String line;
while ((line = bufferedReader.readLine()) != null) {
    builder.append(line);
}
return builder.toString();

Posted

in

by

Tags: