// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: MIT-0 using System.Text.Json; using Amazon; using Amazon.DynamoDBv2; using Amazon.DynamoDBv2.DataModel; 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 DynamoDBContextConfig = Amazon.DynamoDBv2.DataModel.DynamoDBContextConfig; // 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 Unicorn.Properties.PropertiesService; /// /// Represents the AWS Lambda function that checks the existence of a contract in the Properties Service /// contract Status table /// public class ContractExistsCheckerFunction { private readonly IDynamoDBContext _dynamoDbContext; /// /// Default constructor. Initialises global variables for function. /// /// Init exception public ContractExistsCheckerFunction() { // Instrument all AWS SDK calls AWSSDKHandler.RegisterXRayForAllServices(); var dynamodbTable = Environment.GetEnvironmentVariable("CONTRACT_STATUS_TABLE"); if (string.IsNullOrEmpty(dynamodbTable)) { throw new Exception("Environment variable CONTRACT_STATUS_TABLE is not defined."); } AWSConfigsDynamoDB.Context.TypeMappings[typeof(ContractStatusItem)] = new TypeMapping(typeof(ContractStatusItem), dynamodbTable); var config = new DynamoDBContextConfig { Conversion = DynamoDBEntryConversion.V2 }; _dynamoDbContext = new DynamoDBContext(new AmazonDynamoDBClient(), config); } /// /// Event handler for ContractStatusChangedEvent /// /// The input payload /// Lambda Context runtime methods and attributes /// [Logging(LogEvent = true)] [Metrics(CaptureColdStart = true)] [Tracing(CaptureMode = TracingCaptureMode.ResponseAndError)] public async Task FunctionHandler(object input, ILambdaContext context) { var document = JsonSerializer.SerializeToDocument(input); var propertyId = document.RootElement.GetProperty("Input").GetProperty("PropertyId").GetString(); var item = await GetContractStatus(propertyId ?? "").ConfigureAwait(false); if (item == null) { throw new ContractStatusNotFoundException($"Could not find property with ID: {propertyId}"); } } /// /// Retrieves the contract status for a specifies property /// /// Property ID /// Instance of [Tracing] private async Task GetContractStatus(string propertyId) { try { Logger.LogInformation($"Getting Contract Status for {propertyId}"); var item = await _dynamoDbContext.LoadAsync(propertyId).ConfigureAwait(false); Logger.LogInformation($"Found contact: {item != null}"); return item; } catch (Exception e) { Logger.LogInformation($"Error loading contract {propertyId}: {e.Message}"); return null; } } }