diff --git a/examples/Logging/src/HelloWorld/Function.cs b/examples/Logging/src/HelloWorld/Function.cs
index 4ef91a25a..79c835149 100644
--- a/examples/Logging/src/HelloWorld/Function.cs
+++ b/examples/Logging/src/HelloWorld/Function.cs
@@ -21,7 +21,10 @@ public class Function
private static HttpClient? _httpClient;
private static IDynamoDBContext? _dynamoDbContext;
- public Function()
+ ///
+ /// Function constructor
+ ///
+ public Function()
{
_httpClient = new HttpClient();
@@ -36,6 +39,15 @@ public Function()
var config = new DynamoDBContextConfig { Conversion = DynamoDBEntryConversion.V2 };
_dynamoDbContext = new DynamoDBContext(new AmazonDynamoDBClient(), config);
}
+
+ ///
+ /// Test constructor
+ ///
+ public Function(IDynamoDBContext dynamoDbContext, HttpClient httpClient)
+ {
+ _httpClient = httpClient;
+ _dynamoDbContext = dynamoDbContext;
+ }
[Logging(LogEvent = true)]
public async Task FunctionHandler(APIGatewayProxyRequest apigwProxyEvent,
@@ -108,17 +120,16 @@ public async Task FunctionHandler(APIGatewayProxyReques
}
///
- /// Saves the loopup record in DynamoDB
+ /// Saves the lookup record in DynamoDB
///
///
- ///
- private static Task SaveRecordInDynamo(LookupRecord lookupRecord)
+ /// A Task that can be used to poll or wait for results, or both.
+ private static async Task SaveRecordInDynamo(LookupRecord lookupRecord)
{
try
{
Logger.LogInformation($"Saving record with id {lookupRecord.LookupId}");
- _dynamoDbContext?.SaveAsync(lookupRecord).Wait();
- return Task.FromResult(lookupRecord);
+ await _dynamoDbContext?.SaveAsync(lookupRecord)!;
}
catch (AmazonDynamoDBException e)
{
diff --git a/examples/Logging/test/HelloWorld.Test/FunctionTest.cs b/examples/Logging/test/HelloWorld.Test/FunctionTest.cs
index dabd5dfdb..c57b14e17 100644
--- a/examples/Logging/test/HelloWorld.Test/FunctionTest.cs
+++ b/examples/Logging/test/HelloWorld.Test/FunctionTest.cs
@@ -1,11 +1,16 @@
using System;
using System.Collections.Generic;
+using System.Net;
using System.Net.Http;
using System.Text.Json;
+using System.Threading;
using System.Threading.Tasks;
+using Amazon.DynamoDBv2.DataModel;
using Xunit;
using Amazon.Lambda.APIGatewayEvents;
using Amazon.Lambda.TestUtilities;
+using Moq;
+using Moq.Protected;
using Xunit.Abstractions;
namespace HelloWorld.Tests
@@ -13,40 +18,54 @@ namespace HelloWorld.Tests
public class FunctionTest
{
private readonly ITestOutputHelper _testOutputHelper;
- private static readonly HttpClient Client = new HttpClient();
public FunctionTest(ITestOutputHelper testOutputHelper)
{
_testOutputHelper = testOutputHelper;
}
- private static async Task GetCallingIP()
- {
- Client.DefaultRequestHeaders.Accept.Clear();
- Client.DefaultRequestHeaders.Add("User-Agent", "AWS Lambda .Net Client");
-
- var stringTask = Client.GetStringAsync("http://checkip.amazonaws.com/")
- .ConfigureAwait(continueOnCapturedContext: false);
-
- var msg = await stringTask;
- return msg.Replace("\n", "");
- }
-
[Fact]
public async Task TestHelloWorldFunctionHandler()
{
+ // Arrange
var requestId = Guid.NewGuid().ToString("D");
- var request = new APIGatewayProxyRequest()
- { RequestContext = new APIGatewayProxyRequest.ProxyRequestContext() { RequestId = requestId } };
- var context = new TestLambdaContext()
+ var accountId = Guid.NewGuid().ToString("D");
+ var location = "192.158. 1.38";
+
+ var dynamoDbContext = new Mock();
+ var handlerMock = new Mock();
+ handlerMock
+ .Protected()
+ .Setup>(
+ "SendAsync",
+ ItExpr.IsAny(),
+ ItExpr.IsAny()
+ )
+ .ReturnsAsync(new HttpResponseMessage
+ {
+ StatusCode = HttpStatusCode.OK,
+ Content = new StringContent(location)
+ })
+ .Verifiable();
+
+ var request = new APIGatewayProxyRequest
+ {
+ RequestContext = new APIGatewayProxyRequest.ProxyRequestContext
+ {
+ RequestId = requestId,
+ AccountId = accountId
+ }
+ };
+
+ var context = new TestLambdaContext
{
FunctionName = "PowertoolsLoggingSample-HelloWorldFunction-Gg8rhPwO7Wa1",
FunctionVersion = "1",
MemoryLimitInMB = 215,
AwsRequestId = Guid.NewGuid().ToString("D")
};
- string location = GetCallingIP().Result;
- Dictionary body = new Dictionary
+
+ var body = new Dictionary
{
{ "LookupId", requestId },
{ "Greeting", "Hello AWS Lambda Powertools for .NET" },
@@ -60,7 +79,7 @@ public async Task TestHelloWorldFunctionHandler()
Headers = new Dictionary { { "Content-Type", "application/json" } }
};
- var function = new Function();
+ var function = new Function(dynamoDbContext.Object, new HttpClient(handlerMock.Object));
var response = await function.FunctionHandler(request, context);
_testOutputHelper.WriteLine("Lambda Response: \n" + response.Body);
diff --git a/examples/Logging/test/HelloWorld.Test/HelloWorld.Tests.csproj b/examples/Logging/test/HelloWorld.Test/HelloWorld.Tests.csproj
index 512a14d91..be3f49fd8 100644
--- a/examples/Logging/test/HelloWorld.Test/HelloWorld.Tests.csproj
+++ b/examples/Logging/test/HelloWorld.Test/HelloWorld.Tests.csproj
@@ -6,7 +6,9 @@
+
+
diff --git a/examples/Metrics/src/HelloWorld/Function.cs b/examples/Metrics/src/HelloWorld/Function.cs
index bb6b128b4..ef288f58b 100644
--- a/examples/Metrics/src/HelloWorld/Function.cs
+++ b/examples/Metrics/src/HelloWorld/Function.cs
@@ -41,6 +41,15 @@ public Function()
var config = new DynamoDBContextConfig { Conversion = DynamoDBEntryConversion.V2 };
_dynamoDbContext = new DynamoDBContext(new AmazonDynamoDBClient(), config);
}
+
+ ///
+ /// Test constructor
+ ///
+ public Function(IDynamoDBContext dynamoDbContext, HttpClient httpClient)
+ {
+ _httpClient = httpClient;
+ _dynamoDbContext = dynamoDbContext;
+ }
///
/// Lambda Handler
@@ -141,17 +150,16 @@ public async Task FunctionHandler(APIGatewayProxyReques
}
///
- /// Saves the LookupRecord record in DynamoDB
+ /// Saves the lookup record in DynamoDB
///
/// Instance of LookupRecord
- /// LookupRecord
- private static Task SaveRecordInDynamo(LookupRecord lookupRecord)
+ /// A Task that can be used to poll or wait for results, or both.
+ private static async Task SaveRecordInDynamo(LookupRecord lookupRecord)
{
try
{
Logger.LogInformation($"Saving record with id {lookupRecord.LookupId}");
- _dynamoDbContext?.SaveAsync(lookupRecord).Wait();
- return Task.FromResult(lookupRecord);
+ await _dynamoDbContext?.SaveAsync(lookupRecord)!;
}
catch (AmazonDynamoDBException e)
{
diff --git a/examples/Metrics/test/HelloWorld.Test/FunctionTest.cs b/examples/Metrics/test/HelloWorld.Test/FunctionTest.cs
index dabd5dfdb..1eafc0338 100644
--- a/examples/Metrics/test/HelloWorld.Test/FunctionTest.cs
+++ b/examples/Metrics/test/HelloWorld.Test/FunctionTest.cs
@@ -1,11 +1,16 @@
using System;
using System.Collections.Generic;
+using System.Net;
using System.Net.Http;
using System.Text.Json;
+using System.Threading;
using System.Threading.Tasks;
+using Amazon.DynamoDBv2.DataModel;
using Xunit;
using Amazon.Lambda.APIGatewayEvents;
using Amazon.Lambda.TestUtilities;
+using Moq;
+using Moq.Protected;
using Xunit.Abstractions;
namespace HelloWorld.Tests
@@ -13,31 +18,45 @@ namespace HelloWorld.Tests
public class FunctionTest
{
private readonly ITestOutputHelper _testOutputHelper;
- private static readonly HttpClient Client = new HttpClient();
public FunctionTest(ITestOutputHelper testOutputHelper)
{
_testOutputHelper = testOutputHelper;
}
- private static async Task GetCallingIP()
- {
- Client.DefaultRequestHeaders.Accept.Clear();
- Client.DefaultRequestHeaders.Add("User-Agent", "AWS Lambda .Net Client");
-
- var stringTask = Client.GetStringAsync("http://checkip.amazonaws.com/")
- .ConfigureAwait(continueOnCapturedContext: false);
-
- var msg = await stringTask;
- return msg.Replace("\n", "");
- }
-
[Fact]
public async Task TestHelloWorldFunctionHandler()
{
var requestId = Guid.NewGuid().ToString("D");
- var request = new APIGatewayProxyRequest()
- { RequestContext = new APIGatewayProxyRequest.ProxyRequestContext() { RequestId = requestId } };
+ var accountId = Guid.NewGuid().ToString("D");
+ var location = "192.158. 1.38";
+ Environment.SetEnvironmentVariable("POWERTOOLS_METRICS_NAMESPACE","AWSLambdaPowertools");
+
+ var dynamoDbContext = new Mock();
+ var handlerMock = new Mock();
+ handlerMock
+ .Protected()
+ .Setup>(
+ "SendAsync",
+ ItExpr.IsAny(),
+ ItExpr.IsAny()
+ )
+ .ReturnsAsync(new HttpResponseMessage
+ {
+ StatusCode = HttpStatusCode.OK,
+ Content = new StringContent(location)
+ })
+ .Verifiable();
+
+ var request = new APIGatewayProxyRequest
+ {
+ RequestContext = new APIGatewayProxyRequest.ProxyRequestContext
+ {
+ RequestId = requestId,
+ AccountId = accountId
+ }
+ };
+
var context = new TestLambdaContext()
{
FunctionName = "PowertoolsLoggingSample-HelloWorldFunction-Gg8rhPwO7Wa1",
@@ -45,8 +64,8 @@ public async Task TestHelloWorldFunctionHandler()
MemoryLimitInMB = 215,
AwsRequestId = Guid.NewGuid().ToString("D")
};
- string location = GetCallingIP().Result;
- Dictionary body = new Dictionary
+
+ var body = new Dictionary
{
{ "LookupId", requestId },
{ "Greeting", "Hello AWS Lambda Powertools for .NET" },
@@ -60,7 +79,7 @@ public async Task TestHelloWorldFunctionHandler()
Headers = new Dictionary { { "Content-Type", "application/json" } }
};
- var function = new Function();
+ var function = new Function(dynamoDbContext.Object, new HttpClient(handlerMock.Object));
var response = await function.FunctionHandler(request, context);
_testOutputHelper.WriteLine("Lambda Response: \n" + response.Body);
diff --git a/examples/Metrics/test/HelloWorld.Test/HelloWorld.Tests.csproj b/examples/Metrics/test/HelloWorld.Test/HelloWorld.Tests.csproj
index 512a14d91..be3f49fd8 100644
--- a/examples/Metrics/test/HelloWorld.Test/HelloWorld.Tests.csproj
+++ b/examples/Metrics/test/HelloWorld.Test/HelloWorld.Tests.csproj
@@ -6,7 +6,9 @@
+
+
diff --git a/examples/Tracing/src/HelloWorld/Function.cs b/examples/Tracing/src/HelloWorld/Function.cs
index 342e3e29d..4f5b2ea23 100644
--- a/examples/Tracing/src/HelloWorld/Function.cs
+++ b/examples/Tracing/src/HelloWorld/Function.cs
@@ -42,6 +42,15 @@ public Function()
var config = new DynamoDBContextConfig { Conversion = DynamoDBEntryConversion.V2 };
_dynamoDbContext = new DynamoDBContext(new AmazonDynamoDBClient(), config);
}
+
+ ///
+ /// Test constructor
+ ///
+ public Function(IDynamoDBContext dynamoDbContext, HttpClient httpClient)
+ {
+ _httpClient = httpClient;
+ _dynamoDbContext = dynamoDbContext;
+ }
///
/// Lambda Handler
@@ -58,8 +67,7 @@ public async Task FunctionHandler(APIGatewayProxyReques
Logger.LogInformation("Getting ip address from external service");
-
- var location = await GetCallingIp();
+ var location = await GetCallingIp().ConfigureAwait(false);
var lookupRecord = new LookupRecord(lookupId: requestContextRequestId,
greeting: "Hello AWS Lambda Powertools for .NET", ipAddress: location);
@@ -124,18 +132,17 @@ public async Task FunctionHandler(APIGatewayProxyReques
}
///
- /// Saves the LookupRecord record in DynamoDB
+ /// Saves the lookup record in DynamoDB
///
/// Instance of LookupRecord
- /// LookupRecord
+ /// A Task that can be used to poll or wait for results, or both.
[Tracing(SegmentName = "DynamoDB")]
- private static Task SaveRecordInDynamo(LookupRecord lookupRecord)
+ private static async Task SaveRecordInDynamo(LookupRecord lookupRecord)
{
try
{
Logger.LogInformation($"Saving record with id {lookupRecord.LookupId}");
- _dynamoDbContext?.SaveAsync(lookupRecord).Wait();
- return Task.FromResult(lookupRecord);
+ await _dynamoDbContext?.SaveAsync(lookupRecord)!;
}
catch (AmazonDynamoDBException e)
{
diff --git a/examples/Tracing/test/HelloWorld.Test/FunctionTest.cs b/examples/Tracing/test/HelloWorld.Test/FunctionTest.cs
index dabd5dfdb..ea1dab4cb 100644
--- a/examples/Tracing/test/HelloWorld.Test/FunctionTest.cs
+++ b/examples/Tracing/test/HelloWorld.Test/FunctionTest.cs
@@ -1,11 +1,16 @@
using System;
using System.Collections.Generic;
+using System.Net;
using System.Net.Http;
using System.Text.Json;
+using System.Threading;
using System.Threading.Tasks;
+using Amazon.DynamoDBv2.DataModel;
using Xunit;
using Amazon.Lambda.APIGatewayEvents;
using Amazon.Lambda.TestUtilities;
+using Moq;
+using Moq.Protected;
using Xunit.Abstractions;
namespace HelloWorld.Tests
@@ -13,31 +18,45 @@ namespace HelloWorld.Tests
public class FunctionTest
{
private readonly ITestOutputHelper _testOutputHelper;
- private static readonly HttpClient Client = new HttpClient();
-
+
public FunctionTest(ITestOutputHelper testOutputHelper)
{
_testOutputHelper = testOutputHelper;
}
- private static async Task GetCallingIP()
- {
- Client.DefaultRequestHeaders.Accept.Clear();
- Client.DefaultRequestHeaders.Add("User-Agent", "AWS Lambda .Net Client");
-
- var stringTask = Client.GetStringAsync("http://checkip.amazonaws.com/")
- .ConfigureAwait(continueOnCapturedContext: false);
-
- var msg = await stringTask;
- return msg.Replace("\n", "");
- }
-
[Fact]
public async Task TestHelloWorldFunctionHandler()
{
var requestId = Guid.NewGuid().ToString("D");
- var request = new APIGatewayProxyRequest()
- { RequestContext = new APIGatewayProxyRequest.ProxyRequestContext() { RequestId = requestId } };
+ var accountId = Guid.NewGuid().ToString("D");
+ var location = "192.158. 1.38";
+ Environment.SetEnvironmentVariable("POWERTOOLS_SERVICE_NAME","powertools-dotnet-sample");
+
+ var dynamoDbContext = new Mock();
+ var handlerMock = new Mock();
+ handlerMock
+ .Protected()
+ .Setup>(
+ "SendAsync",
+ ItExpr.IsAny(),
+ ItExpr.IsAny()
+ )
+ .ReturnsAsync(new HttpResponseMessage
+ {
+ StatusCode = HttpStatusCode.OK,
+ Content = new StringContent(location)
+ })
+ .Verifiable();
+
+ var request = new APIGatewayProxyRequest
+ {
+ RequestContext = new APIGatewayProxyRequest.ProxyRequestContext
+ {
+ RequestId = requestId,
+ AccountId = accountId
+ }
+ };
+
var context = new TestLambdaContext()
{
FunctionName = "PowertoolsLoggingSample-HelloWorldFunction-Gg8rhPwO7Wa1",
@@ -45,8 +64,8 @@ public async Task TestHelloWorldFunctionHandler()
MemoryLimitInMB = 215,
AwsRequestId = Guid.NewGuid().ToString("D")
};
- string location = GetCallingIP().Result;
- Dictionary body = new Dictionary
+
+ var body = new Dictionary
{
{ "LookupId", requestId },
{ "Greeting", "Hello AWS Lambda Powertools for .NET" },
@@ -60,7 +79,7 @@ public async Task TestHelloWorldFunctionHandler()
Headers = new Dictionary { { "Content-Type", "application/json" } }
};
- var function = new Function();
+ var function = new Function(dynamoDbContext.Object, new HttpClient(handlerMock.Object));
var response = await function.FunctionHandler(request, context);
_testOutputHelper.WriteLine("Lambda Response: \n" + response.Body);
diff --git a/examples/Tracing/test/HelloWorld.Test/HelloWorld.Tests.csproj b/examples/Tracing/test/HelloWorld.Test/HelloWorld.Tests.csproj
index 512a14d91..be3f49fd8 100644
--- a/examples/Tracing/test/HelloWorld.Test/HelloWorld.Tests.csproj
+++ b/examples/Tracing/test/HelloWorld.Test/HelloWorld.Tests.csproj
@@ -6,7 +6,9 @@
+
+
diff --git a/libraries/src/AWS.Lambda.Powertools.Tracing/Internal/XRayRecorder.cs b/libraries/src/AWS.Lambda.Powertools.Tracing/Internal/XRayRecorder.cs
index 144da9cdd..51d511a1d 100644
--- a/libraries/src/AWS.Lambda.Powertools.Tracing/Internal/XRayRecorder.cs
+++ b/libraries/src/AWS.Lambda.Powertools.Tracing/Internal/XRayRecorder.cs
@@ -39,17 +39,23 @@ internal class XRayRecorder : IXRayRecorder
/// The instance.
public static IXRayRecorder Instance => _instance ??= new XRayRecorder();
+ ///
+ /// Checks whether current execution is in AWS Lambda.
+ ///
+ /// Returns true if current execution is in AWS Lambda.
+ private static readonly bool _isLambda = AWSXRayRecorder.IsLambda();
+
///
/// Gets the emitter.
///
/// The emitter.
- public ISegmentEmitter Emitter => AWSXRayRecorder.Instance.Emitter;
+ public ISegmentEmitter Emitter => _isLambda ? AWSXRayRecorder.Instance.Emitter : null;
///
/// Gets the streaming strategy.
///
/// The streaming strategy.
- public IStreamingStrategy StreamingStrategy => AWSXRayRecorder.Instance.StreamingStrategy;
+ public IStreamingStrategy StreamingStrategy => _isLambda ? AWSXRayRecorder.Instance.StreamingStrategy : null;
///
/// Begins the subsegment.
@@ -57,7 +63,8 @@ internal class XRayRecorder : IXRayRecorder
/// The name.
public void BeginSubsegment(string name)
{
- AWSXRayRecorder.Instance.BeginSubsegment(name);
+ if (_isLambda)
+ AWSXRayRecorder.Instance.BeginSubsegment(name);
}
///
@@ -66,7 +73,8 @@ public void BeginSubsegment(string name)
/// The value.
public void SetNamespace(string value)
{
- AWSXRayRecorder.Instance.SetNamespace(value);
+ if (_isLambda)
+ AWSXRayRecorder.Instance.SetNamespace(value);
}
///
@@ -76,7 +84,8 @@ public void SetNamespace(string value)
/// The value.
public void AddAnnotation(string key, object value)
{
- AWSXRayRecorder.Instance.AddAnnotation(key, value);
+ if (_isLambda)
+ AWSXRayRecorder.Instance.AddAnnotation(key, value);
}
///
@@ -87,7 +96,8 @@ public void AddAnnotation(string key, object value)
/// The value.
public void AddMetadata(string nameSpace, string key, object value)
{
- AWSXRayRecorder.Instance.AddMetadata(nameSpace, key, value);
+ if (_isLambda)
+ AWSXRayRecorder.Instance.AddMetadata(nameSpace, key, value);
}
///
@@ -95,7 +105,8 @@ public void AddMetadata(string nameSpace, string key, object value)
///
public void EndSubsegment()
{
- AWSXRayRecorder.Instance.EndSubsegment();
+ if (_isLambda)
+ AWSXRayRecorder.Instance.EndSubsegment();
}
///
@@ -104,7 +115,9 @@ public void EndSubsegment()
/// Entity.
public Entity GetEntity()
{
- return AWSXRayRecorder.Instance.GetEntity();
+ return _isLambda
+ ? AWSXRayRecorder.Instance.GetEntity()
+ : new Segment("Root");
}
///
@@ -113,7 +126,8 @@ public Entity GetEntity()
/// The entity.
public void SetEntity(Entity entity)
{
- AWSXRayRecorder.Instance.SetEntity(entity);
+ if (_isLambda)
+ AWSXRayRecorder.Instance.SetEntity(entity);
}
///
@@ -122,7 +136,8 @@ public void SetEntity(Entity entity)
/// The exception.
public void AddException(Exception exception)
{
- AWSXRayRecorder.Instance.AddException(exception);
+ if (_isLambda)
+ AWSXRayRecorder.Instance.AddException(exception);
}
///
@@ -132,6 +147,7 @@ public void AddException(Exception exception)
/// The value.
public void AddHttpInformation(string key, object value)
{
- AWSXRayRecorder.Instance.AddHttpInformation(key, value);
+ if (_isLambda)
+ AWSXRayRecorder.Instance.AddHttpInformation(key, value);
}
}
\ No newline at end of file
diff --git a/libraries/src/AWS.Lambda.Powertools.Tracing/Tracing.cs b/libraries/src/AWS.Lambda.Powertools.Tracing/Tracing.cs
index 2987047d5..357987b01 100644
--- a/libraries/src/AWS.Lambda.Powertools.Tracing/Tracing.cs
+++ b/libraries/src/AWS.Lambda.Powertools.Tracing/Tracing.cs
@@ -212,11 +212,14 @@ public static void WithSubsegment(string nameSpace, string name, Entity entity,
childSubsegment.IsInProgress = false;
childSubsegment.Release();
childSubsegment.SetEndTimeToNow();
- if (childSubsegment.IsEmittable())
- XRayRecorder.Instance.Emitter.Send(childSubsegment.RootSegment);
- else if (XRayRecorder.Instance.StreamingStrategy.ShouldStream(childSubsegment))
- XRayRecorder.Instance.StreamingStrategy.Stream(childSubsegment.RootSegment,
- XRayRecorder.Instance.Emitter);
+ if (PowertoolsConfigurations.Instance.IsLambdaEnvironment)
+ {
+ if (childSubsegment.IsEmittable())
+ XRayRecorder.Instance.Emitter.Send(childSubsegment.RootSegment);
+ else if (XRayRecorder.Instance.StreamingStrategy.ShouldStream(childSubsegment))
+ XRayRecorder.Instance.StreamingStrategy.Stream(childSubsegment.RootSegment,
+ XRayRecorder.Instance.Emitter);
+ }
}
}