static async Task ProcessWebRequestAsync(string uri, string method, string load, string onSuccess, string onFailure, string tracking, string contentType, Variable headers, int timeout, bool justFire = false) { try { WebRequest request = WebRequest.CreateHttp(uri); request.Method = method; request.ContentType = contentType; if (!string.IsNullOrWhiteSpace(load)) { var bytes = Encoding.UTF8.GetBytes(load); request.ContentLength = bytes.Length; using (var requestStream = request.GetRequestStream()) { requestStream.Write(bytes, 0, bytes.Length); } } if (headers != null && headers.Tuple != null) { var keys = headers.GetKeys(); foreach (var header in keys) { var headerValue = headers.GetVariable(header).AsString(); request.Headers.Add(header, headerValue); } } Task <WebResponse> task = request.GetResponseAsync(); Task finishTask = FinishRequest(onSuccess, onFailure, tracking, task, timeout); if (justFire) { return; } await finishTask; } catch (Exception exc) { await CustomFunction.RunAsync(onFailure, new Variable(tracking), new Variable(""), new Variable(exc.Message)); } }
static async Task FinishRequest(string onSuccess, string onFailure, string tracking, Task <WebResponse> responseTask, int timeoutMs) { string result = ""; string method = onSuccess; HttpWebResponse response = null; Task timeoutTask = Task.Delay(timeoutMs); try { Task first = await Task.WhenAny(timeoutTask, responseTask); if (first == timeoutTask) { await timeoutTask; throw new Exception("Timeout waiting for response."); } response = await responseTask as HttpWebResponse; if ((int)response.StatusCode >= 400) { throw new Exception(response.StatusDescription); } using (StreamReader sr = new StreamReader(response.GetResponseStream())) { result = sr.ReadToEnd(); } } catch (Exception exc) { result = exc.Message; method = onFailure; } string responseCode = response == null ? "" : response.StatusCode.ToString(); await CustomFunction.RunAsync(method, new Variable(tracking), new Variable(responseCode), new Variable(result)); }
public async Task Can_Use_Custom_Function_Variables() { // Arrange LambdaTestServer.ClearLambdaEnvironmentVariables(); var options = new LambdaTestServerOptions() { FunctionArn = "my-custom-arn", FunctionHandler = "my-custom-handler", FunctionMemorySize = 1024, FunctionName = "my-function-name", FunctionTimeout = TimeSpan.FromSeconds(119), FunctionVersion = 42, LogGroupName = "my-log-group", LogStreamName = "my-log-stream", }; using var server = new LambdaTestServer(options); using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(2)); await server.StartAsync(cts.Token); var request = new LambdaTestRequest(Array.Empty <byte>(), "my-request-id") { ClientContext = @"{""client"":{""app_title"":""my-app""}}", CognitoIdentity = @"{""cognitoIdentityId"":""my-identity""}", }; var context = await server.EnqueueAsync(request); _ = Task.Run(async() => { await context.Response.WaitToReadAsync(cts.Token); if (!cts.IsCancellationRequested) { cts.Cancel(); } }); using var httpClient = server.CreateClient(); // Act await CustomFunction.RunAsync(httpClient, cts.Token); // Assert context.Response.TryRead(out var response).ShouldBeTrue(); response.ShouldNotBeNull(); response !.IsSuccessful.ShouldBeTrue(); response.Content.ShouldNotBeNull(); var lambdaContext = response.ReadAs <IDictionary <string, string> >(); lambdaContext.ShouldContainKeyAndValue("AwsRequestId", request.AwsRequestId); lambdaContext.ShouldContainKeyAndValue("ClientContext", "my-app"); lambdaContext.ShouldContainKeyAndValue("FunctionName", options.FunctionName); lambdaContext.ShouldContainKeyAndValue("FunctionVersion", "42"); lambdaContext.ShouldContainKeyAndValue("IdentityId", "my-identity"); lambdaContext.ShouldContainKeyAndValue("InvokedFunctionArn", options.FunctionArn); lambdaContext.ShouldContainKeyAndValue("LogGroupName", options.LogGroupName); lambdaContext.ShouldContainKeyAndValue("LogStreamName", options.LogStreamName); lambdaContext.ShouldContainKeyAndValue("MemoryLimitInMB", "1024"); lambdaContext.ShouldContainKey("RemainingTime"); string remainingTimeString = lambdaContext["RemainingTime"]; TimeSpan.TryParse(remainingTimeString, out var remainingTime).ShouldBeTrue(); remainingTime.Minutes.ShouldBe(options.FunctionTimeout.Minutes); }