0

I have sam app that declares S3 bucket, lambda function and DynamoDB table, when a CSV file is uploaded to the S3 bucket, it triggers the lambda function that parses and stores the records into the DynamoDB table, after I'm uploading the CSV file to the S3 bucket the lambda function is triggered but I have an exception that says :

One or more errors occurred. (Access Denied): AggregateException at System.Threading.Tasks.Task.Wait(Int32 millisecondsTimeout, CancellationToken cancellationToken) at lambda_method(Closure , Stream , Stream , LambdaContextInternal ) at Amazon.Runtime.Internal.HttpErrorResponseExceptionHandler.HandleException(IExecutionContext executionContext, HttpErrorResponseException exception) at Amazon.Runtime.Internal.ErrorHandler.ProcessException(IExecutionContext executionContext, Exception exception) at Amazon.Runtime.Internal.ErrorHandler.InvokeAsync[T](IExecutionContext executionContext) at Amazon.Runtime.Internal.CallbackHandler.InvokeAsync[T](IExecutionContext executionContext) at Amazon.Runtime.Internal.EndpointDiscoveryHandler.InvokeAsync[T](IExecutionContext executionContext) at Amazon.Runtime.Internal.EndpointDiscoveryHandler.InvokeAsync[T](IExecutionContext executionContext) at Amazon.Runtime.Internal.CredentialsRetriever.InvokeAsync[T](IExecutionContext executionContext) at Amazon.Runtime.Internal.RetryHandler.InvokeAsync[T](IExecutionContext executionContext) at Amazon.Runtime.Internal.RetryHandler.InvokeAsync[T](IExecutionContext executionContext) at Amazon.Runtime.Internal.CallbackHandler.InvokeAsync[T](IExecutionContext executionContext) at Amazon.Runtime.Internal.CallbackHandler.InvokeAsync[T](IExecutionContext executionContext) at Amazon.S3.Internal.AmazonS3ExceptionHandler.InvokeAsync[T](IExecutionContext executionContext) at Amazon.Runtime.Internal.ErrorCallbackHandler.InvokeAsync[T](IExecutionContext executionContext) at Amazon.Runtime.Internal.MetricsHandler.InvokeAsync[T](IExecutionContext executionContext) at Localgov.MunicipalityBusiness.ProcessMunicipalityBusinessUpload.Handler(S3EventNotification s3Event) in E:\Azavar Repositories\Lata 3\LATA\Code\Microservices\MunicipalityBusinesses\src\MunicipalityBusiness\ProcessMunicipalityBusinessUpload.cs:line 39 Exception of type 'Amazon.Runtime.Internal.HttpErrorResponseException' was thrown.: HttpErrorResponseException at Amazon.Runtime.HttpWebRequestMessage.GetResponseAsync(CancellationToken cancellationToken) at Amazon.Runtime.Internal.HttpHandler`1.InvokeAsync[T](IExecutionContext executionContext) at Amazon.Runtime.Internal.RedirectHandler.InvokeAsync[T](IExecutionContext executionContext) at Amazon.Runtime.Internal.Unmarshaller.InvokeAsync[T](IExecutionContext executionContext) at Amazon.S3.Internal.AmazonS3ResponseHandler.InvokeAsync[T](IExecutionContext executionContext) at Amazon.Runtime.Internal.ErrorHandler.InvokeAsync[T](IExecutionContext executionContext)

my sam code is

AWSTemplateFormatVersion: "2010-09-09"
Transform: AWS::Serverless-2016-10-31
Description: Sample SAM Template for serverless-lata
Globals:
  Function:
    Timeout: 10
Resources:
  ResultsTable:
    Type: AWS::Serverless::SimpleTable
  ProcessMunicipalityBusinessUpload:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: ./src/MunicipalityBusiness/
      Handler: Localgov.MunicipalityBusiness::Localgov.MunicipalityBusiness.ProcessMunicipalityBusinessUpload::Handler
      Runtime: dotnetcore2.1
      Description: Parse CSV text and insert it into DynamoDB
      MemorySize: 512
      Timeout: 30
      Policies:
        - Version: "2012-10-17"
          Statement:
            - Effect: Allow
              Action:
                - "s3:GetObject"
              Resource: "arn:aws:s3:::*"
            - Effect: Allow
              Action:
                - "dynamodb:GetItem"
                - "dynamodb:PutItem"
                - "dynamodb:DeleteItem"
                - "dynamodb:UpdateItem"
                - "dynamodb:Scan"
                - "dynamodb:Query"
                - "dynamodb:BatchWriteItem"
                - "dynamodb:BatchGetItem"
                - "dynamodb:DescribeTable"
                - "dynamodb:ConditionCheckItem"
              Resource:
                "Fn::Join":
                  - ""
                  - - "arn:aws:dynamodb:"
                    - Ref: "AWS::Region"
                    - ":"
                    - Ref: "AWS::AccountId"
                    - ":table/"
                    - Ref: ResultsTable
      Events:
        BucketEvent1:
          Type: S3
          Properties:
            Bucket:
              Ref: SourceCSVBucket
            Events:
              - "s3:ObjectCreated:*"
  SourceCSVBucket:
    Type: "AWS::S3::Bucket"
  DynamoDBTable:
    Type: AWS::DynamoDB::Table
    Properties:
      AttributeDefinitions:
        - AttributeName: "municipalityId"
          AttributeType: "S"
        - AttributeName: "bId"
          AttributeType: "S"
      KeySchema:
        - AttributeName: "municipalityId"
          KeyType: "HASH"
        - AttributeName: "bId"
          KeyType: "RANGE"
      BillingMode: PAY_PER_REQUEST
      GlobalSecondaryIndexes:
        - IndexName: GetMunicipalityBusinessGSI
          KeySchema:
            - AttributeName: bId
              KeyType: HASH
            - AttributeName: municipalityId
              KeyType: RANGE
          Projection:
            ProjectionType: ALL

and my DotNet file is :

using System.Threading.Tasks;
using Amazon.Lambda.Core;
using System.IO;
using CsvHelper;
using System.Globalization;
using Amazon.S3.Util;
using Amazon.S3.Model;
using Amazon;
using Amazon.S3;
using Amazon.DynamoDBv2;
using Amazon.DynamoDBv2.Model;
using System.Collections.Generic;


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

namespace Localgov.MunicipalityBusiness
{

    public class ProcessMunicipalityBusinessUpload
    {

        public async Task Handler(S3EventNotification s3Event)
        {
            //The region should be dynamic, I will fix it
            RegionEndpoint bucketRegion = RegionEndpoint.USEast1;
            IAmazonS3 client = new AmazonS3Client(bucketRegion);

            var bucketName = s3Event.Records[0].S3.Bucket.Name;
            var keyName = s3Event.Records[0].S3.Object.Key;
            string responseBody = "";

            GetObjectRequest request = new GetObjectRequest
            {
                BucketName = bucketName,
                Key = keyName,
            };

            using (GetObjectResponse response = await client.GetObjectAsync(request))
            using (Stream responseStream = response.ResponseStream)
            using (StreamReader reader = new StreamReader(responseStream))
            {

                responseBody = reader.ReadToEnd(); // Now you process the response body.
                LambdaLogger.Log(responseBody.ToString());
                using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
                {
                    var records = csv.GetRecords<Business>();
                    foreach (var item in records)
                    {
                        Business business = (Business)item;

                        var request1 = new PutItemRequest
                        {
                            //this should be dynamic name, nut I didn't know how to import it
                            TableName = "sam-app2-DynamoDBTable-1JC98R13C6X31",
                            Item = new Dictionary<string, AttributeValue>
                        {
                            { "municipalityId", new AttributeValue { N = "1" }},
                            { "bId", new AttributeValue { S = business.Fein_ss }},
                            { "dba", new AttributeValue { S = business.Dba }},
                            { "businessName", new AttributeValue { S = business.BusinessName }},
                            { "businessAddress", new AttributeValue { S = business.BusinessAddress }},
                            { "stateTaxId", new AttributeValue { S = business.StateTaxId }},
                            { "fein_ss", new AttributeValue { S = business.Fein_ss }},
                            { "licesne", new AttributeValue { S = business.Licesne }},
                            { "mailingAddress", new AttributeValue { S = business.MailingAddress }},
                            { "dateClosed", new AttributeValue { S = business.DateClosed }},
                            { "businessCity", new AttributeValue { S = business.BusinessCity }},
                            { "businessState", new AttributeValue { S = business.BusinessState }},
                            { "businessZip", new AttributeValue { S = business.BusinessZip }},
                        }
                    };
                    var client2 = new AmazonDynamoDBClient();
                    await client2.PutItemAsync(request1);                    
                    }
                }
            }
        }
    }
}
Tarik Ziyad
  • 115
  • 1
  • 10

0 Answers0