【问题标题】:why my lambda .net api doesnt work with dynamoDb?为什么我的 lambda .net api 不适用于 dynamoDb?
【发布时间】:2021-09-12 23:41:04
【问题描述】:

我有一个问题,当我在本地运行 api 时工作正常并在 Dynamo db 中完成所有操作,但是当我发布到我的 AWS lambda 时它不起作用我缺少什么(api 返回状态 500) ?

事实是代码在我的前提下工作正常,数据插入正确,但是当我在 aws lambda 中发布它时,crud 不起作用,它什么也不做(返回状态 500),会有任何权限缺失?

代码冻结在这一行:

        Table table = Table.LoadTable(client_, "TblUsers_");

代码在这里:

using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Threading.Tasks;
using System.Linq;
using System.Transactions;
using UserCrudApiChallenge.Infraestructure.Interface;
using UserCrudApiChallenge.CrossCutting.User;
using UserCrudApiChallenge.Domain.Entity;
using Amazon.DynamoDBv2;
using Amazon.DynamoDBv2.DataModel;
using Amazon.DynamoDBv2.DocumentModel;
using Amazon.DynamoDBv2.Model;
using Amazon.Runtime;
using Amazon;
using Amazon.S3;

namespace UserCrudApiChallenge.Infraestructure.Repository
{
    public class UserRepository : IUserRepository
    {
        private readonly BasicAWSCredentials _connection;

        public UserRepository()
        {
            _connection =  new  BasicAWSCredentials(Environment.GetEnvironmentVariable("DYNAMODB_ACCESS_KEY"),
                Environment.GetEnvironmentVariable("DYNAMODB_SECRET_KEY"));    
        }

        public async Task<User> AddUserAsync(User user)
        {
            try
            {
                AmazonDynamoDBClient client_ = new AmazonDynamoDBClient(_connection, RegionEndpoint.USEast2);
                Table table = Table.LoadTable(client_, "TblUsers_");
                DynamoDBContext context = new DynamoDBContext(client_);
                Document result = await table.PutItemAsync(context.ToDocument(user));

                return user;
            }
            catch (Exception ex)
            {
                Console.WriteLine("FAILED to write the new user, because:\n       {0}.", ex.Message);
                throw;
            }            
        }

        public async Task<bool> UpdateUserAsync(User user)
        {
            try
            {
                AmazonDynamoDBClient client = new AmazonDynamoDBClient(_connection, RegionEndpoint.USEast2);
                UpdateItemRequest updateRequest = new UpdateItemRequest()
                {
                    TableName = "TblUsers_",
                    Key = new Dictionary<string, AttributeValue>
                {
                    {"Id", new AttributeValue {S = user.Id } }
                },
                    AttributeUpdates = new Dictionary<string, AttributeValueUpdate>
                {
                        {"Name", new AttributeValueUpdate
                        {
                            Value = new AttributeValue{ S =  user.Name },
                            Action = AttributeAction.PUT
                        }
                    },
                    {"Email", new AttributeValueUpdate
                        {
                            Value = new AttributeValue{ S =  user.Email },
                            Action = AttributeAction.PUT
                        }
                    },
                     {"Password", new AttributeValueUpdate
                        {
                            Value = new AttributeValue{ S =  user.Password },
                            Action = AttributeAction.PUT
                        }
                    }
                }
                };
                await client.UpdateItemAsync(updateRequest);

                return true;
            }
            catch (Exception ex)
            {  
                throw;
            }         
        }

        public async Task<User> FindUserByIdAsync(string userId)
        {    
            try
            {
                AmazonDynamoDBClient client = new AmazonDynamoDBClient(_connection, RegionEndpoint.USEast2);
                Table table = Table.LoadTable(client, "TblUsers_");
                Document result = await table.GetItemAsync(userId);
                return MapUserWithPassword(result);
            }
            catch (Exception ex)
            {  
                throw;
            }
        }

        public async Task<User> FindUserById(string id)
        {
            try
            {
                AmazonDynamoDBClient client = new AmazonDynamoDBClient(_connection, RegionEndpoint.USEast2);

                QueryRequest qry = new QueryRequest
                {
                    TableName = "TblUsers_",
                    ExpressionAttributeNames = new Dictionary<string, string>
                    {
                      { "#Id", "Id" }
                    },
                    ExpressionAttributeValues = new Dictionary<string, AttributeValue> { { ":id", new AttributeValue { S = id } } },
                    KeyConditionExpression = "#Id = :id",
                };

                var result = await client.QueryAsync(qry);

                if (result.Count == 0 || result is null)
                {
                    throw new Exception("No user");
                }
    
                return UsersMapper(result.Items.FirstOrDefault());
            }
            catch (Exception ex)
            {    
                throw;
            }   
        }

        public async Task<List<User>> GetUsers()
        {
            try
            {
                AmazonDynamoDBClient client = new AmazonDynamoDBClient(_connection, RegionEndpoint.USEast2);

                DynamoDBContext context = new DynamoDBContext(client);
                Table table = Table.LoadTable(client, "TblUsers_");

                //get all records
                var conditions = new List<ScanCondition>();
                // you can add scan conditions, or leave empty
                List<User> allUsers = await context.ScanAsync<User>(conditions).GetRemainingAsync();
                return allUsers;
            }
            catch (Exception ex)
            {    
                throw;
            }    
        }

        public async Task<bool> DeleteUserAsync(string id)
        {
            try
            {
                AmazonDynamoDBClient client = new AmazonDynamoDBClient(_connection, RegionEndpoint.USEast2);

                DeleteItemRequest request = new DeleteItemRequest
                {
                    TableName = "TblUsers_",
                    Key = new Dictionary<string, AttributeValue> { { "Id", new AttributeValue { S = id } } }
                };

                await client.DeleteItemAsync(request);

                return true;
            }
            catch (Exception ex)
            {    
                throw;
            }           
        }    

        private User MapUserWithPassword(Document document)
        {
            User user = new User(document["Id"], document["Name"], string.Empty, document["Email"]);
            return user;
        }

        private User UsersMapper(Dictionary<string, AttributeValue> item)
        {    
            try
            {
                User user = new User(item["Id"].S, item["Name"].S, item["Password"].S, item["Email"].S);

                return user;
            }
            catch (Exception ex)
            {   
                throw;
            }
        }
    }
}

【问题讨论】:

  • 您的 AWS Lambda 函数是否连接了 VPC?如果是这样,是否有特定原因为什么它连接到 VPC? DynamoDB 是通过 Internet 访问的服务,但连接到 VPC 的 AWS Lambda 函数只有在还配置了 NAT 网关的情况下才能访问 Internet。如果不需要 VPC 访问,则断开 Lambda 函数与 VPC 的连接,看看它是否有效。
  • 与问题无关,但您所有的 try { ... } catch(Exception ex) { throw; } 包装都是毫无意义的。此处的行为与您忽略它们的行为相同。这些包装只会让您的代码更难阅读和维护。
  • @PeterCsala 我只是想看看它是否陷入异常,但它甚至没有达到目标,实际上它坚持到了特定的行(更新帖子)
  • @JohnRotenstein 最后问题出在vpc上,显然在代码级别它没有到达数据库,这解决了我的问题,非常感谢!!!!!!

标签: .net amazon-web-services .net-core aws-lambda amazon-dynamodb


【解决方案1】:

DynamoDB 是一项通过 Internet 访问的服务。因此,如果您的 AWS Lambda 函数无法访问 Internet,它可能无法访问 DynamoDB。

当 AWS Lambda 函数配置为使用 VPC 时,它只能在以下情况下访问 DynamoDB:

  • Lambda 函数连接到一个私有子网,并且公共子网中有一个NAT 网关
  • VPC 已经配置了一个用于 DynamoDB 的 VPC 终端节点,它将 VPC 直接连接到 DynamoDB

如果 Lambda 函数不需要 VPC 访问,则断开 Lambda 函数与 VPC 的连接。这将自动提供 Internet 访问。

【讨论】:

    猜你喜欢
    • 2015-04-21
    • 2015-12-10
    • 1970-01-01
    • 1970-01-01
    • 2016-12-07
    • 1970-01-01
    • 2016-11-16
    • 1970-01-01
    • 2019-01-17
    相关资源
    最近更新 更多