【发布时间】: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