コード例 #1
0
        private async Task WriteResponse(
            CloudFormationResourceRequest <TProperties> rawRequest,
            CloudFormationResourceResponse <TAttributes> rawResponse
            )
        {
            Exception exception = null;
            var       backoff   = TimeSpan.FromMilliseconds(100);

            // write response to pre-signed S3 URL
            for (var i = 0; i < MAX_SEND_ATTEMPTS; ++i)
            {
                try {
                    if (rawRequest.ResponseURL == null)
                    {
                        throw new InvalidOperationException("ResponseURL is missing");
                    }
                    var httpResponse = await HttpClient.SendAsync(new HttpRequestMessage {
                        RequestUri = new Uri(rawRequest.ResponseURL),
                        Method     = HttpMethod.Put,
                        Content    = new ByteArrayContent(Encoding.UTF8.GetBytes(LambdaSerializer.Serialize(rawResponse)))
                    });

                    if (httpResponse.StatusCode != HttpStatusCode.OK)
                    {
                        throw new LambdaCustomResourceException(
                                  "PUT operation to pre-signed S3 URL failed with status code: {0} [{1} {2}] = {3}",
                                  httpResponse.StatusCode,
                                  rawRequest.RequestType,
                                  rawRequest.ResourceType ?? "<MISSING>",
                                  await httpResponse.Content.ReadAsStringAsync()
                                  );
                    }
                    return;
                } catch (InvalidOperationException e) {
                    exception = e;
                    break;
                } catch (Exception e) {
                    exception = e;
                    LogErrorAsWarning(e, "writing response to pre-signed S3 URL failed");
                    await Task.Delay(backoff);

                    backoff = TimeSpan.FromSeconds(backoff.TotalSeconds * 2);
                }
            }
            if (exception == null)
            {
                exception = new ShouldNeverHappenException($"ALambdaCustomResourceFunction.WriteResponse failed w/o an explicit");
            }

            // max attempts have been reached; fail permanently and record the failed request for playback
            LogError(exception);
            await RecordFailedMessageAsync(LambdaLogLevel.ERROR, FailedMessageOrigin.CloudFormation, LambdaSerializer.Serialize(rawRequest), exception);
        }
コード例 #2
0
        private async Task WriteResponse(
            CloudFormationResourceRequest <TProperties> rawRequest,
            CloudFormationResourceResponse <TAttributes> rawResponse
            )
        {
            Exception exception = null;

            // write response to pre-signed S3 URL
            for (var i = 0; i < MAX_SEND_ATTEMPTS; ++i)
            {
                try {
                    var httpResponse = await HttpClient.SendAsync(new HttpRequestMessage {
                        RequestUri = new Uri(rawRequest.ResponseURL),
                        Method     = HttpMethod.Put,
                        Content    = new ByteArrayContent(Encoding.UTF8.GetBytes(SerializeJson(rawResponse)))
                    });

                    if (httpResponse.StatusCode != HttpStatusCode.OK)
                    {
                        throw new LambdaCustomResourceException(
                                  "PUT operation to pre-signed S3 URL failed with status code: {0} [{1} {2}] = {3}",
                                  httpResponse.StatusCode,
                                  rawRequest.RequestType,
                                  rawRequest.ResourceType,
                                  await httpResponse.Content.ReadAsStringAsync()
                                  );
                    }
                    return;
                } catch (Exception e) {
                    exception = e;
                    LogErrorAsWarning(e, "writing response to pre-signed S3 URL failed");
                    await Task.Delay(TimeSpan.FromMilliseconds(100));
                }
            }

            // max attempts have been reached; fail permanently and record the failed request for playback
            LogError(exception);
            await RecordFailedMessageAsync(LambdaLogLevel.ERROR, FailedMessageOrigin.CloudFormation, SerializeJson(rawRequest), exception);
        }
コード例 #3
0
        //--- Methods ---
        public override async Task ProcessMessageAsync(CloudFormationResourceRequest <TRequestProperties> rawRequest, ILambdaContext context)
        {
            LogInfo(JsonConvert.SerializeObject(rawRequest, Formatting.Indented));
            CloudFormationResourceResponse <TResponseProperties> rawResponse;

            LogInfo($"{rawRequest.ResourceType}: {rawRequest.RequestType.ToString().ToUpperInvariant()} operation received");
            try {
                var request = new Request <TRequestProperties> {
                    RequestType           = rawRequest.RequestType,
                    ResourceType          = rawRequest.ResourceType,
                    LogicalResourceId     = rawRequest.LogicalResourceId,
                    PhysicalResourceId    = rawRequest.PhysicalResourceId,
                    ResourceProperties    = rawRequest.ResourceProperties,
                    OldResourceProperties = rawRequest.OldResourceProperties
                };

                // handle slack request
                Response <TResponseProperties> response;
                switch (request.RequestType)
                {
                case RequestType.Create:
                    response = await HandleCreateResourceAsync(request);

                    break;

                case RequestType.Update:
                    response = await HandleUpdateResourceAsync(request);

                    break;

                case RequestType.Delete:
                    response = await HandleDeleteResourceAsync(request);

                    break;

                default:
                    throw new ArgumentOutOfRangeException(nameof(request.RequestType), request.RequestType, "unexpected request value");
                }
                rawResponse = new CloudFormationResourceResponse <TResponseProperties> {
                    Status             = CloudFormationResourceResponseStatus.SUCCESS,
                    Reason             = "",
                    StackId            = rawRequest.StackId,
                    RequestId          = rawRequest.RequestId,
                    LogicalResourceId  = rawRequest.LogicalResourceId,
                    PhysicalResourceId = response.PhysicalResourceId ?? rawRequest.PhysicalResourceId,
                    NoEcho             = response.NoEcho,
                    Data = response.Properties
                };
                LogInfo($"{rawRequest.ResourceType}: {rawRequest.RequestType.ToString().ToUpperInvariant()} operation was successful");
            } catch (Exception e) {
                LogError(e, $"{rawRequest.ResourceType}: {rawRequest.RequestType.ToString().ToUpperInvariant()} operation FAILED [{{0}}]", e.Message);
                rawResponse = new CloudFormationResourceResponse <TResponseProperties> {
                    Status            = CloudFormationResourceResponseStatus.FAILED,
                    Reason            = e.Message,
                    StackId           = rawRequest.StackId,
                    RequestId         = rawRequest.RequestId,
                    LogicalResourceId = rawRequest.LogicalResourceId
                };
            }

            // write response to pre-signed S3 URL
            try {
                var httpResponse = await HttpClient.SendAsync(new HttpRequestMessage {
                    RequestUri = new Uri(rawRequest.ResponseURL),
                    Method     = HttpMethod.Put,
                    Content    = new ByteArrayContent(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(rawResponse)))
                });

                if (httpResponse.StatusCode != HttpStatusCode.OK)
                {
                    throw new CustomResourceException(
                              "PUT operation to pre-signed S3 URL failed with status code: {0} [{1} {2}] = {3}",
                              httpResponse.StatusCode,
                              rawRequest.RequestType,
                              rawRequest.ResourceType,
                              await httpResponse.Content.ReadAsStringAsync()
                              );
                }
            } catch (Exception e) {
                LogError(e, "writing response to pre-signed S3 URL failed");

                // TODO (2018-06-14, bjorg): how should we handle this? we may want the handler to re-attempt the
                // resource creation since the request was SNS based
                throw;
            }
        }