Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lambda Function to be invoked or triggered by S3(csv file upload) #723

Closed
rahul-JFL opened this issue Aug 25, 2020 · 5 comments
Closed
Assignees
Labels
guidance Question that needs advice or information. module/lambda-client-lib

Comments

@rahul-JFL
Copy link

The Question

Lambda Function to be invoked or triggered by S3(csv file upload). My question is here , how do i get csv file data in function, because i tried with 'String input' parameter.but it is not working.

Environment

SDK Version: AWSSDK.Core 3.3.107.39
Package Version: 1.1.0
OS Info: Windows 10
Build Environment: Visual Studio
Targeted .NET Platform: VS2019(.net core 3.1)-->


Thanks,
Rahul
This is a ❓ general question

@ashishdhingra ashishdhingra self-assigned this Aug 25, 2020
@ashishdhingra ashishdhingra transferred this issue from aws/aws-sdk-net Aug 25, 2020
@ashishdhingra ashishdhingra added guidance Question that needs advice or information. module/lambda-client-lib needs-triage This issue or PR still needs to be triaged. labels Aug 25, 2020
@ashishdhingra
Copy link
Contributor

aws/aws-sdk-net#1681

@ashishdhingra
Copy link
Contributor

Hi @rahul-JFL,

Please refer the Amazon.Lambda.S3Events for the Lambda function signature for retrieving events from an S3 bucket.

Below is the default function handler class generated by Visual Studio Lambda AWS Tools template for a Simple S3 Function:
Follow the path New Project -> AWS Lambda Project (.NET Core - C#) -> Configure your new project -> Select Blueprint [Simple S3 Function]

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

using Amazon.Lambda.Core;
using Amazon.Lambda.S3Events;
using Amazon.S3;
using Amazon.S3.Util;

// Assembly attribute to enable the Lambda function's JSON input to be converted into a .NET class.
[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))]

namespace AWSLambda2
{
    public class Function
    {
        IAmazonS3 S3Client { get; set; }

        /// <summary>
        /// Default constructor. This constructor is used by Lambda to construct the instance. When invoked in a Lambda environment
        /// the AWS credentials will come from the IAM role associated with the function and the AWS region will be set to the
        /// region the Lambda function is executed in.
        /// </summary>
        public Function()
        {
            S3Client = new AmazonS3Client();
        }

        /// <summary>
        /// Constructs an instance with a preconfigured S3 client. This can be used for testing the outside of the Lambda environment.
        /// </summary>
        /// <param name="s3Client"></param>
        public Function(IAmazonS3 s3Client)
        {
            this.S3Client = s3Client;
        }
        
        /// <summary>
        /// This method is called for every Lambda invocation. This method takes in an S3 event object and can be used 
        /// to respond to S3 notifications.
        /// </summary>
        /// <param name="evnt"></param>
        /// <param name="context"></param>
        /// <returns></returns>
        public async Task<string> FunctionHandler(S3Event evnt, ILambdaContext context)
        {
            var s3Event = evnt.Records?[0].S3;
            if(s3Event == null)
            {
                return null;
            }

            try
            {
                var response = await this.S3Client.GetObjectMetadataAsync(s3Event.Bucket.Name, s3Event.Object.Key);
                return response.Headers.ContentType;
            }
            catch(Exception e)
            {
                context.Logger.LogLine($"Error getting object {s3Event.Object.Key} from bucket {s3Event.Bucket.Name}. Make sure they exist and your bucket is in the same region as this function.");
                context.Logger.LogLine(e.Message);
                context.Logger.LogLine(e.StackTrace);
                throw;
            }
        }
    }
}

As shown in the article Tutorial: Using AWS Lambda with Amazon S3, following JSON (as an example) is sent to Lambda function when an event is triggered based on file operation (e.g. PUT) on S3 bucket:

{
  "Records":[
    {
      "eventVersion":"2.0",
      "eventSource":"aws:s3",
      "awsRegion":"us-west-2",
      "eventTime":"1970-01-01T00:00:00.000Z",
      "eventName":"ObjectCreated:Put",
      "userIdentity":{
        "principalId":"AIDAJDPLRKLG7UEXAMPLE"
      },
      "requestParameters":{
        "sourceIPAddress":"127.0.0.1"
      },
      "responseElements":{
        "x-amz-request-id":"C3D13FE58DE4C810",
        "x-amz-id-2":"FMyUVURIY8/IgAtTv8xRjskZQpcIZ9KG4V5Wp6S7S/JRWeUWerMUE5JgHvANOjpD"
      },
      "s3":{
        "s3SchemaVersion":"1.0",
        "configurationId":"testConfigRule",
        "bucket":{
          "name":"sourcebucket",
          "ownerIdentity":{
            "principalId":"A3NL1KOZZKExample"
          },
          "arn":"arn:aws:s3:::sourcebucket"
        },
        "object":{
          "key":"HappyFace.jpg",
          "size":1024,
          "eTag":"d41d8cd98f00b204e9800998ecf8427e",
          "versionId":"096fKKXTRTtl3on89fVO.nfljtsv6qko"
        }
      }
    }
  ]
}

The S3Event class object which is passed as parameter to Lambda function handler simply represents S3 event in an object oriented way.

You can use the logic in above handler to get bucket name and object key inside the Lambda function handler, and then use S3 API to get the object and do the processing (in your case process CSV content).

You can configure event on S3 bucket to trigger Lambda function when CSV file is uploaded (PUT) into S3 bucket.

Hope this guidance helps and let me know if this issue could be closed.

Thanks,
Ashish

@ashishdhingra ashishdhingra added response-requested Waiting on additional info and feedback. Will move to close soon in 7 days. and removed needs-triage This issue or PR still needs to be triaged. labels Aug 25, 2020
@rahul-JFL
Copy link
Author

Hi Ashish,

I have upload lambda function zip and upload a csv file. But i am unable to see my logs and not identifying execution.

Please find attachment of my lambda function class.

JFLGetSTN.txt

I want to implement following functionality in my lambda function

  1. read uploaded csv file (with delimiter ^ )
  2. save data in RDS.
  3. create a xml file (with the same data) and upload in S3 Bucket.

thanks
Rahul Gupta

@rahul-JFL
Copy link
Author

screenshot of my lambda function with trigger S3

LambdaFuncton

@ashishdhingra
Copy link
Contributor

ashishdhingra commented Aug 27, 2020

Hi @rahul-JFL,

I'm not sure on why you are using S3Client.GetObjectMetadataAsync() to retrieve file content. As per API documentation https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/S3/MS3GetObjectMetadataAsyncStringStringCancellationToken.html, this method returns the metadata of object without returning the object itself. Also, you are passing object's key to your JFLSTNData() method, not the object content.

You need to:

  • Use S3Client.GetObject() to retrieve your CSV file content.
  • Use context.Logger.LogLine() to log to CloudWatch stream.
  • Your Lambda should have proper access to write to CloudWatch stream
  • Similarly your Lambda should have permissions to GET and PUT objects to S3 bucket.
  • Proper access to Amazon RDS.

Please revisit you code to make necessary corrections. For any sample code, please search the S3 documentation and/or using internet search engines. There are many examples out there similar to your scenario, which could be helpful. Kindly refer the post Convert CSV to JSON files with AWS Lambda and S3 Events as an example, even though the lambda function handler code is in Python, it can be easily replicated to C# (use this post only as reference, all production implementation should be tested thoroughly).

Closing this issue as above provides necessary guidance for your scenario.

Thanks,
Ashish

@aws aws locked as resolved and limited conversation to collaborators Aug 27, 2020
@ashishdhingra ashishdhingra removed the response-requested Waiting on additional info and feedback. Will move to close soon in 7 days. label Aug 27, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
guidance Question that needs advice or information. module/lambda-client-lib
Projects
None yet
Development

No branches or pull requests

2 participants