Beispiel #1
0
        private async Task CreateFunctionAsync()
        {
            var tryCount = 3;

            while (true)
            {
                try
                {
                    await _lambdaClient.CreateFunctionAsync(new CreateFunctionRequest
                    {
                        FunctionName = _functionName,
                        Code         = new FunctionCode
                        {
                            ImageUri = _imageUri
                        },
                        MemorySize  = 512,
                        Role        = _executionRoleArn,
                        PackageType = PackageType.Image
                    });

                    break;
                }
                catch (InvalidParameterValueException)
                {
                    tryCount--;
                    if (tryCount == 0)
                    {
                        throw;
                    }

                    // Wait another 5 seconds to let execution role propagate
                    await Task.Delay(5000);
                }
            }

            var endTime  = DateTime.Now.AddSeconds(30);
            var isActive = false;

            while (DateTime.Now < endTime)
            {
                var response = await _lambdaClient.GetFunctionConfigurationAsync(new GetFunctionConfigurationRequest
                {
                    FunctionName = _functionName
                });

                if (response.State == State.Active)
                {
                    isActive = true;
                    break;
                }

                await Task.Delay(2000);
            }

            if (!isActive)
            {
                throw new Exception($"Timed out trying to create Lambda function {_functionName}");
            }
        }
        /// <summary>
        /// Create a Lambda Function or return the ARN of the existing Lambda Function with the same name.
        /// </summary>
        /// <param name="client"></param>
        /// <param name="functionName">Name of lambda function.</param>
        /// <param name="functionHandlerName">The name of the .js file that contains the Lambda handler.
        /// e.g helloworld.js has functionHandlerName "helloworld". </param>
        /// <param name="code">The Base64-encoded zip file of the code to be used. The name of the file
        /// in the zip file that contains the Lambda functio handler should match functionHandlerName.
        /// .Net 2.0 does not support System.IO.Compression.ZipArchive so the process of creating the
        /// Base64-encoded zip file should be done outside of the test framework in the following way:
        /// private static string CreateScriptBytesBase64(string name, string script)
        /// {
        ///     using (var stream = new MemoryStream())
        ///     {
        ///         using (var archive = new ZipArchive(stream, ZipArchiveMode.Create, true))
        ///         {
        ///             var entry = archive.CreateEntry(name + ".js");
        ///             using (var entryStream = entry.Open())
        ///             using (var writer = new StreamWriter(entryStream))
        ///             {
        ///                 writer.Write(script);
        ///             }
        ///         }
        ///         var bytes = stream.ToArray();
        ///         var base64 = Convert.ToBase64String(bytes);
        ///         return base64;
        ///     }
        /// }
        /// </param>
        /// <param name="iamRoleArn"></param>
        /// <returns></returns>
        public static string CreateFunctionIfNotExists(AmazonLambdaClient client, string functionName, string functionHandlerName, string code, string iamRoleArn)
        {
            AutoResetEvent ars = new AutoResetEvent(false);
            Exception      responseException = new Exception();

            string functionArn = UtilityMethods.GetFunctionArnIfExists(client, functionName);

            if (functionArn == null)
            {
                int  retries  = 3;
                long codeSize = -1;
                while (retries > 0)
                {
                    client.CreateFunctionAsync(new CreateFunctionRequest
                    {
                        FunctionName = functionName,
                        Code         = new FunctionCode
                        {
                            ZipFile = GetScriptStream(code)
                        },
                        Handler     = functionHandlerName + ".handler",
                        Runtime     = Runtime.Nodejs43,
                        Description = "Feel free to delete this function. The tests will recreate it when needed.",
                        Role        = iamRoleArn
                    }, (response) =>
                    {
                        responseException = response.Exception;
                        if (responseException == null)
                        {
                            functionArn = response.Response.FunctionArn;
                            codeSize    = response.Response.CodeSize;
                        }
                        ars.Set();
                    }, new AsyncOptions {
                        ExecuteCallbackOnMainThread = false
                    });
                    ars.WaitOne();
                    if (responseException == null)
                    {
                        break;
                    }
                    else
                    {
                        Utils.AssertTrue(responseException is InvalidParameterValueException);
                        // Need to wait longer for eventual consistency of role
                        retries--;
                        Thread.Sleep(TimeSpan.FromSeconds(10));
                    }
                }
                Assert.IsNotNull(functionArn);
                Utils.AssertTrue(codeSize > 0);
            }
            return(functionArn);
        }
        internal static async Task <CreateFunctionResponse> CreateFunctionAsync
        (
            this AmazonLambdaClient client,
            AppPackage package,

            ASPNetServerLessPublishAWSLambdaConfigSection lambdaConfig,
            Runtime lambdaRuntime,

            CancellationToken cancellationToken = default(CancellationToken)
        )
        {
            var environmentVariables = new Dictionary <string, string>(lambdaConfig.EnvironmentVAriables);
            var functionTags         = new Dictionary <string, string> {
                { "Name", lambdaConfig.FunctionName }
            };
            var response = (CreateFunctionResponse)null;

            using (var packageStream = new MemoryStream(package.PackageBytes))
            {
                var createFunctionRequest = new CreateFunctionRequest()
                {
                    Code = new FunctionCode()
                    {
                        ZipFile = packageStream
                    },
                    Environment = new Environment()
                    {
                        Variables = environmentVariables
                    },

                    FunctionName = lambdaConfig.FunctionName,
                    Handler      = lambdaConfig.FunctionHandler,

                    MemorySize = lambdaConfig.FunctionMemory.Value,
                    Role       = lambdaConfig.FunctionRole,

                    Tags    = functionTags,
                    Timeout = lambdaConfig.FunctionTimeoutSeconds.Value,

                    Runtime = lambdaRuntime
                };

                response = await client.CreateFunctionAsync(createFunctionRequest, cancellationToken).ConfigureAwait(false);

                createFunctionRequest = null;
            }

            functionTags         = null;
            environmentVariables = null;

            return(response);
        }
Beispiel #4
0
        private static async Task CreateFunctionAsync(AmazonLambdaClient lambdaClient, string bucketName)
        {
            await DeleteFunctionIfExistsAsync(lambdaClient);

            var createRequest = new CreateFunctionRequest
            {
                FunctionName = FunctionName,
                Code         = new FunctionCode
                {
                    S3Bucket = bucketName,
                    S3Key    = DeploymentZipKey
                },
                Handler    = "PingAsync",
                MemorySize = 512,
                Runtime    = Runtime.Provided,
                Role       = ExecutionRoleArn
            };

            var startTime = DateTime.Now;
            var created   = false;

            while (DateTime.Now < startTime.AddSeconds(30))
            {
                try
                {
                    await lambdaClient.CreateFunctionAsync(createRequest);

                    created = true;
                    break;
                }
                catch (InvalidParameterValueException ipve)
                {
                    // Wait for the role to be fully propagated through AWS
                    if (ipve.Message == "The role defined for the function cannot be assumed by Lambda.")
                    {
                        await Task.Delay(2000);
                    }
                    else
                    {
                        throw;
                    }
                }
            }

            if (!created)
            {
                throw new Exception($"Timed out trying to create Lambda function {FunctionName}");
            }
        }
        /// <summary>
        /// Updates the AWS Lambda functions code.
        /// </summary>
        /// <param name="functionName">The name of an AWS Lambda function.</param>
        /// <param name="settings">The <see cref="UpdateFunctionCodeSettings"/> used during the request to AWS.</param>
        /// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
        public async Task <string> CreateFunction(string functionName, CreateFunctionSettings settings, CancellationToken cancellationToken = default(CancellationToken))
        {
            if (String.IsNullOrEmpty(functionName))
            {
                throw new ArgumentNullException(nameof(functionName));
            }



            // Create Request
            AmazonLambdaClient client = this.CreateClient(settings);

            CreateFunctionRequest request = new CreateFunctionRequest()
            {
                FunctionName = functionName,
                Handler      = settings.Handler,

                Runtime     = Runtime.FindValue(settings.Runtime),
                Role        = settings.Role,
                Environment = new Amazon.Lambda.Model.Environment()
                {
                    Variables = settings.Environment
                },

                Timeout    = settings.Timeout,
                MemorySize = settings.MemorySize,
                Publish    = settings.Publish,
                KMSKeyArn  = settings.KMSKeyArn,

                Tags        = settings.Tags,
                Description = settings.Description,

                Code = new FunctionCode()
                {
                    S3Bucket        = settings.S3Bucket,
                    S3Key           = settings.S3Key,
                    S3ObjectVersion = settings.S3Version,
                }
            };



            if (!String.IsNullOrEmpty(settings.DeadLetterConfig))
            {
                request.DeadLetterConfig.TargetArn = settings.DeadLetterConfig;
            }

            if (settings.ZipPath != null)
            {
                request.Code.ZipFile = this.GetFileStream(settings.ZipPath, settings);
            }



            if (settings.VpcSecurityGroupIds.Count > 0)
            {
                request.VpcConfig.SecurityGroupIds = settings.VpcSecurityGroupIds;
            }

            if (settings.VpcSubnetIds.Count > 0)
            {
                request.VpcConfig.SubnetIds = settings.VpcSubnetIds;
            }



            // Check Response
            CreateFunctionResponse response = await client.CreateFunctionAsync(request, cancellationToken);

            if (response.HttpStatusCode == HttpStatusCode.OK)
            {
                _Log.Verbose("Successfully updated function '{0}'", functionName);
                return(response.Version);
            }
            else
            {
                _Log.Error("Failed to update function '{0}'", functionName);
                return("");
            }
        }