Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue #61: Add option to register XRay manifest from embedded resource #63

Merged
merged 2 commits into from
Mar 27, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 14 additions & 3 deletions sdk/src/Handlers/AwsSdk/AWSSDKHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
using Amazon.Runtime.Internal;
using Amazon.XRay.Recorder.Handlers.AwsSdk.Internal;
using System;
using System.IO;

namespace Amazon.XRay.Recorder.Handlers.AwsSdk
{
Expand Down Expand Up @@ -44,7 +45,7 @@ public static void RegisterXRayForAllServices(String path)
{
_customizer = GetCustomizer();
_customizer.RegisterAll = true;
_customizer.Path = path;
_customizer.XRayPipelineHandler = new XRayPipelineHandler(path);
}

/// <summary>
Expand All @@ -59,11 +60,21 @@ public static void RegisterXRay<T>()
/// <summary>
/// Registers file path of AWS Service Manifest file. This file would be used for all the registered <see cref="Runtime.AmazonServiceClient"/> instances.
/// </summary>
/// <param name="path"> Absolute path to the file which contains the operation parameter whitelist configuration.</param>
/// <param name="path"> Absolute path to the file which contains the operation parameter whitelist configuration.</param>
public static void RegisterXRayManifest(String path)
{
_customizer = GetCustomizer();
_customizer.Path = path;
_customizer.XRayPipelineHandler = new XRayPipelineHandler(path);
}

/// <summary>
/// Registers AWS Service Manifest resource stream. This stream would be used for all the registered <see cref="Runtime.AmazonServiceClient"/> instances.
/// </summary>
/// <param name="stream"> stream for manifest which contains the operation parameter whitelist configuration.</param>
public static void RegisterXRayManifest(Stream stream)
{
_customizer = GetCustomizer();
_customizer.XRayPipelineHandler = new XRayPipelineHandler(stream);
}

private static XRayPipelineCustomizer GetCustomizer()
Expand Down
35 changes: 30 additions & 5 deletions sdk/src/Handlers/AwsSdk/Internal/XRayPipelineHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,31 @@ public XRayPipelineHandler(string path)
Init(_recorder, stream);
}
}
}

/// <summary>
/// Initializes a new instance of the <see cref="XRayPipelineHandler" /> class.
/// </summary>
/// <param name="stream"> stream for manifest which contains the operation parameter whitelist configuration.</param>
/// <exception cref="System.ArgumentNullException">Thrown when recorder is null.</exception>
public XRayPipelineHandler(Stream stream)
{
_recorder = AWSXRayRecorder.Instance;

if (_recorder == null)
{
throw new ArgumentNullException("recorder");
}

if (stream == null)
{
_logger.DebugFormat("The provided stream is null, initializing with default AWS whitelist.");
InitWithDefaultAWSWhitelist(_recorder);
}
else
{
Init(_recorder, stream);
}
}

private static bool TryReadPropertyValue(object obj, string propertyName, out object value)
Expand Down Expand Up @@ -623,11 +648,11 @@ public class XRayPipelineCustomizer : IRuntimePipelineCustomizer
public string UniqueName { get { return "X-Ray Registration Customization"; } }
private Boolean registerAll;
private List<Type> types = new List<Type>();
private String path;
private ReaderWriterLockSlim rwLock = new ReaderWriterLockSlim();

public bool RegisterAll { get => registerAll; set => registerAll = value; }
public string Path { get => path; set => path = value; }
public string Path { get; set; }
public XRayPipelineHandler XRayPipelineHandler { get; set; } = null;

public void Customize(Type serviceClientType, RuntimePipeline pipeline)
{
Expand All @@ -641,13 +666,13 @@ public void Customize(Type serviceClientType, RuntimePipeline pipeline)
addCustomization = ProcessType(serviceClientType, addCustomization);
}

if (addCustomization && string.IsNullOrEmpty(Path))
if (addCustomization && XRayPipelineHandler == null)
{
pipeline.AddHandlerAfter<EndpointResolver>(new XRayPipelineHandler());
}
else if (addCustomization && !string.IsNullOrEmpty(Path))
else if (addCustomization && XRayPipelineHandler != null)
{
pipeline.AddHandlerAfter<EndpointResolver>(new XRayPipelineHandler(Path)); // Custom AWS Manifest file path provided
pipeline.AddHandlerAfter<EndpointResolver>(XRayPipelineHandler); // Custom AWS Manifest file path provided
}
}

Expand Down
46 changes: 46 additions & 0 deletions sdk/test/UnitTests/AWSSDKHandlerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,24 @@ public void TestLoadServiceHandlerManifestWithDefaultConfigurationForAWSSDKHandl
Assert.IsNotNull(handler.AWSServiceHandlerManifest);
}

[TestMethod]
public void TestLoadServiceHandlerManifestWithDefaultConfigurationForAWSSDKHandlerNullStream()
{
Stream stream = null;
var handler = new XRayPipelineHandler(stream);
Assert.IsNotNull(handler.AWSServiceHandlerManifest);
}

[TestMethod]
public void TestLoadServiceHandlerManifestWithDefaultConfigurationForAWSSDKHandlerAsStream()
{
using (Stream stream = new FileStream(_path, FileMode.Open, FileAccess.Read))
{
var handler = new XRayPipelineHandler(stream);
sergedomk marked this conversation as resolved.
Show resolved Hide resolved
Assert.IsNotNull(handler.AWSServiceHandlerManifest);
}
}

[TestMethod]
[ExpectedException(typeof(FileNotFoundException))]
public void TestLoadServiceInfoManifestInvalidPathForAWSSDKHandler()
Expand Down Expand Up @@ -274,5 +292,33 @@ public void TestLambdaInvokeSubsegmentContainsFunctionNameForAWSSDKHandler()
Assert.AreEqual("Invoke", segment.Subsegments[0].Aws["operation"]);
Assert.AreEqual("testFunction", segment.Subsegments[0].Aws["function_name"]);
}

[TestMethod]
public void TestRegisterXRayManifestWithStreamLambdaForAWSSDKHandler()
{
String temp_path = $"JSONs{Path.DirectorySeparatorChar}AWSRequestInfoWithLambda.json"; //registering manifest file with Lambda
using (Stream stream = new FileStream(temp_path, FileMode.Open, FileAccess.Read))
{
AWSSDKHandler.RegisterXRayManifest(stream);
}
var lambda = new AmazonLambdaClient(new AnonymousAWSCredentials(), RegionEndpoint.USEast1);
CustomResponses.SetResponse(lambda, null, null, true);
_recorder.BeginSegment("lambda", TraceId);
#if NET45
lambda.Invoke(new InvokeRequest
{
FunctionName = "testFunction"
});
#else
lambda.InvokeAsync(new InvokeRequest
{
FunctionName = "testFunction"
}).Wait();
#endif
var segment = AWSXRayRecorder.Instance.TraceContext.GetEntity();
_recorder.EndSegment();

Assert.AreEqual("Invoke", segment.Subsegments[0].Aws["operation"]);
}
}
}