// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: MIT-0
using Amazon;
using Amazon.DynamoDBv2;
using Amazon.DynamoDBv2.DataModel;
using Amazon.Lambda.CloudWatchEvents;
using Amazon.Lambda.Core;
using Amazon.Util;
using Amazon.XRay.Recorder.Handlers.AwsSdk;
using AWS.Lambda.Powertools.Logging;
using AWS.Lambda.Powertools.Metrics;
using AWS.Lambda.Powertools.Tracing;
using Unicorn.Web.Common;
using DynamoDBContextConfig = Amazon.DynamoDBv2.DataModel.DynamoDBContextConfig;
namespace Unicorn.Web.ApprovalService;
public class PublicationApprovedEventHandler
{
private readonly IDynamoDBContext _dynamoDbContext;
///
/// Default constructor. Initialises global variables for function.
///
/// Init exception
public PublicationApprovedEventHandler()
{
// Instrument all AWS SDK calls
AWSSDKHandler.RegisterXRayForAllServices();
var dynamodbTable = Environment.GetEnvironmentVariable("DYNAMODB_TABLE") ?? "";
if (string.IsNullOrEmpty(dynamodbTable))
throw new Exception("Environment variable DYNAMODB_TABLE is not defined.");
AWSConfigsDynamoDB.Context.TypeMappings[typeof(PropertyRecord)] =
new TypeMapping(typeof(PropertyRecord), dynamodbTable);
var config = new DynamoDBContextConfig { Conversion = DynamoDBEntryConversion.V2 };
_dynamoDbContext = new DynamoDBContext(new AmazonDynamoDBClient(), config);
}
///
/// Event handler for PublicationApprovedEvent
///
/// EventBridge event that triggers this function
/// Lambda Context runtime methods and attributes
[Logging(LogEvent = true)]
[Metrics(CaptureColdStart = true)]
[Tracing(CaptureMode = TracingCaptureMode.ResponseAndError)]
public async Task FunctionHandler(CloudWatchEvent publicationApprovedEvent, ILambdaContext context)
{
try
{
await PublicationApproved(publicationApprovedEvent.Detail);
}
catch (Exception e)
{
Logger.LogError(e);
throw new PublicationApprovedEventHandlerException(e.Message);
}
}
[Tracing(SegmentName = "Publication Approved")]
private async Task PublicationApproved(PublicationApprovedEvent publicationApproved)
{
Logger.LogInformation($"Updating publication status for Property ID: {publicationApproved.PropertyId}");
var splitString = publicationApproved.PropertyId.Split('/');
var country = splitString[0];
var city = splitString[1];
var street = splitString[2];
var number = splitString[3];
var pk = PropertyRecordHelper.GetPartitionKey(country, city);
var sk = PropertyRecordHelper.GetSortKey(street, number);
Logger.LogInformation($"Loading the property from DynamoDB with PK {pk} and SK {sk}");
var existingProperty = await _dynamoDbContext.LoadAsync(pk, sk);
if (string.Equals(publicationApproved.EvaluationResult, PropertyStatus.Approved, StringComparison.CurrentCultureIgnoreCase))
{
existingProperty.Status = PropertyStatus.Approved;
}
else if (string.Equals(publicationApproved.EvaluationResult, PropertyStatus.Declined, StringComparison.CurrentCultureIgnoreCase))
{
existingProperty.Status = PropertyStatus.Declined;
}
else
{
Logger.LogInformation($"evaluation_result: {publicationApproved.EvaluationResult} is not valid");
return;
}
Logger.LogInformation($"Storing the evaluation result {existingProperty.Status} for property in DynamoDB with PK {pk} and SK {sk}");
await _dynamoDbContext.SaveAsync(existingProperty);
Metrics.AddMetric("PropertiesApproved", 1, MetricUnit.Count);
}
}