public RedirectResult Form_POST()
        {
            if (!_cart.CanPlaceOrder)
            {
                _cart.CannotPlaceOrderReasons.ForEach(s => TempData.ErrorMessages().Add(s));
                return(_uniquePageService.RedirectTo <PaymentDetails>());
            }

            var response = _payPalExpressService.DoExpressCheckout(_cart);

            if (response.RedirectToPayPal)
            {
                return(Redirect(_payPalUrlService.GetExpressCheckoutRedirectUrl(_cart.PayPalExpressToken)));
            }
            if (response.Success)
            {
                var order = _orderPlacementService.PlaceOrder(_cart, response.UpdateOrder);
                return(_uniquePageService.RedirectTo <OrderPlaced>(new { id = order.Guid }));
            }

            TempData["error-details"] = new FailureDetails
            {
                Message =
                    "An error occurred processing your PayPal Express order, please contact the merchant"
            };
            return(_uniquePageService.RedirectTo <PaymentDetails>());
        }
Esempio n. 2
0
 private void ResetSessionInfo(CartModel cart, FailureDetails failureDetails)
 {
     if (cart != null)
     {
         _sagePayService.ResetSessionInfo(cart.UserGuid);
         _sagePayService.SetFailureDetails(cart.UserGuid, failureDetails);
     }
 }
        public List <FailedMessage.FailureGroup> GetGroups(string messageType, FailureDetails failureDetails)
        {
            var groups = new List <FailedMessage.FailureGroup>();

            foreach (var enricher in failedEnrichers)
            {
                groups.AddRange(enricher.Enrich(messageType, failureDetails));
            }
            return(groups);
        }
        public FailureDetails ParseFailureDetails(IReadOnlyDictionary <string, string> headers)
        {
            var result = new FailureDetails();

            DictionaryExtensions.CheckIfKeyExists("NServiceBus.TimeOfFailure", headers, s => result.TimeOfFailure = DateTimeExtensions.ToUtcDateTime(s));

            result.Exception = GetException(headers);

            result.AddressOfFailingEndpoint = headers[FaultsHeaderKeys.FailedQ];

            return(result);
        }
Esempio n. 5
0
        static ClassifiableMessageDetails CreateFailureDetailsWithStackTrace(string stackTrace)
        {
            var failureWithEmptyStackTrace = new FailureDetails
            {
                Exception = new ExceptionDetails
                {
                    StackTrace    = stackTrace,
                    ExceptionType = "exceptionType"
                }
            };

            return(new ClassifiableMessageDetails(null, failureWithEmptyStackTrace, null));
        }
        public async Task CatchInvalidOperationException(ErrorPropagationMode mode)
        {
            // The error propagation mode must be set before the worker is started
            this.worker.ErrorPropagationMode = mode;

            await this.worker
            .AddTaskOrchestrations(typeof(ExceptionHandlingOrchestration))
            .AddTaskActivities(typeof(ThrowInvalidOperationException))
            .StartAsync();

            // This is required for exceptions to be serialized
            this.worker.TaskActivityDispatcher.IncludeDetails = true;

            OrchestrationInstance instance = await this.client.CreateOrchestrationInstanceAsync(typeof(ExceptionHandlingOrchestration), null);

            OrchestrationState state = await this.client.WaitForOrchestrationAsync(instance, DefaultTimeout);

            Assert.IsNotNull(state);
            Assert.AreEqual(OrchestrationStatus.Completed, state.OrchestrationStatus);
            Assert.IsNotNull(state.Output, "The expected error information wasn't found!");

            if (mode == ErrorPropagationMode.SerializeExceptions)
            {
                // The exception should be deserializable
                InvalidOperationException e = JsonConvert.DeserializeObject <InvalidOperationException>(state.Output);
                Assert.IsNotNull(e);
                Assert.AreEqual("This is a test exception", e.Message);
            }
            else if (mode == ErrorPropagationMode.UseFailureDetails)
            {
                // The failure details should contain the relevant exception metadata
                FailureDetails details = JsonConvert.DeserializeObject <FailureDetails>(state.Output);
                Assert.IsNotNull(details);
                Assert.AreEqual(typeof(InvalidOperationException).FullName, details.ErrorType);
                Assert.IsTrue(details.IsCausedBy <InvalidOperationException>());
                Assert.IsTrue(details.IsCausedBy <Exception>()); // check that base types work too
                Assert.AreEqual("This is a test exception", details.ErrorMessage);
                Assert.IsNotNull(details.StackTrace);

                // The callstack should be in the error details
                string expectedCallstackSubstring = typeof(ThrowInvalidOperationException).FullName !.Replace('+', '.');
                Assert.IsTrue(
                    details.StackTrace !.IndexOf(expectedCallstackSubstring) > 0,
                    $"Expected to find {expectedCallstackSubstring} in the exception details. Actual: {details.StackTrace}");
            }
            else
            {
                Assert.Fail($"Unexpected {nameof(ErrorPropagationMode)} value: {mode}");
            }
        }
        static ClassifiableMessageDetails CreateFailureDetailsWithMessage(string message)
        {
            var failure = new FailureDetails
            {
                Exception = new ExceptionDetails
                {
                    StackTrace    = "Stack trace",
                    ExceptionType = "exceptionType",
                    Message       = message
                }
            };

            return(new ClassifiableMessageDetails(null, failure, null));
        }
        public FailureDetails ParseFailureDetails(IReadOnlyDictionary <string, string> headers)
        {
            var result = new FailureDetails();

            DictionaryExtensions.CheckIfKeyExists("NServiceBus.TimeOfFailure", headers, s => result.TimeOfFailure = DateTimeExtensions.ToUtcDateTime(s));

            result.Exception = GetException(headers);

            if (!headers.ContainsKey(FaultsHeaderKeys.FailedQ))
            {
                throw new Exception($"Missing '{FaultsHeaderKeys.FailedQ}' header. Message is poison message or incorrectly send to (error) queue.");
            }
            result.AddressOfFailingEndpoint = headers[FaultsHeaderKeys.FailedQ];

            return(result);
        }
Esempio n. 9
0
 private bool CanPlaceOrder(out RedirectResult redirectResult)
 {
     redirectResult = null;
     if (!_cartModel.CanPlaceOrder)
     {
         TempData["error-details"] = new FailureDetails
         {
             Message =
                 "We were unable to process your order with the specified cart. Please check your details and try again"
         };
         {
             redirectResult = _uniquePageService.RedirectTo <PaymentDetails>();
             return(false);
         }
     }
     return(true);
 }
        /// <summary>
        /// Common Exception Functionality
        /// </summary>
        /// <param name="client">Client to access codepipeline</param>
        /// <param name="ex">Exception thrown by the lambdas</param>
        /// <param name="jobId">ID of the job that failed</param>
        /// <param name="context">Lambda context for logging</param>
        /// <returns><see cref="PutJobFailureResultRequest"/> to send back to codepipeline</returns>
        private async Task <PutJobFailureResultResponse> DoException(
            IAmazonCodePipeline client,
            Exception ex,
            string jobId,
            ILambdaContext context
            )
        {
            // Send the failure response and log
            context.Logger.LogLine("Exception encountered");
            context.Logger.LogLine(ex.Message);
            var failureDetails = new FailureDetails
            {
                Message = ex.Message,
                Type    = FailureType.JobFailed
            };

            return(await client.PutJobFailureResultAsync(jobId, failureDetails));
        }
        public ActionResult Response3DSecure(FormCollection formCollection)
        {
            if (!_cartModel.CanPlaceOrder)
            {
                TempData["error-details"] = new FailureDetails
                {
                    Message =
                        "We were unable to process your order with the specified cart. Please check your details and try again"
                };
                return(_uniquePageService.RedirectTo <PaymentDetails>());
            }
            if (_cartModel.CartGuid != _paypoint3DSecureHelper.GetCartGuid() ||
                _cartModel.TotalToPay != _paypoint3DSecureHelper.GetOrderAmount())
            {
                TempData["error-details"] = new FailureDetails
                {
                    Message = "Your order was changed after going off to PayPoint for 3D secure validation. No payment has been taken, but you will need to re-submit your details."
                };
                return(_uniquePageService.RedirectTo <PaymentDetails>());
            }

            var response = _paypointPaymentService.Handle3DSecureResponse(formCollection);

            if (response.Requires3DSecure)
            {
                TempData["redirect-details"] = response.RedirectDetails;
                return(RedirectToAction("Redirect3DSecure"));
            }

            if (response.PaymentSucceeded)
            {
                var order = _orderPlacementService.PlaceOrder(_cartModel, o =>
                {
                    o.PaymentStatus      = PaymentStatus.Paid;
                    o.PaidDate           = CurrentRequestData.Now;
                    o.ShippingStatus     = ShippingStatus.Unshipped;
                    o.AuthorisationToken = response.PaypointPaymentDetails.AuthCode;
                });
                return(_uniquePageService.RedirectTo <OrderPlaced>(new { id = order.Guid }));
            }

            TempData["error-details"] = response.FailureDetails;
            return(_uniquePageService.RedirectTo <PaymentDetails>());
        }
Esempio n. 12
0
        /// <summary>
        ///
        /// </summary>
        public void OnStateElection(ElectStateContext context)
        {
            // the way Hangfire works is retrying a job X times (10 by default),
            //so this won't be called directly with a failed state sometimes.
            // To solve this we should look into TraversedStates for a failed state

            var failed = context.CandidateState as FailedState ??
                         context.TraversedStates.FirstOrDefault(x => x is FailedState) as FailedState;

            if (failed == null)
            {
                return;
            }

            //GracefulWebRequest gets a HttpWebResponse containing the ServiceException and formats it as the message of a System.Exception
            //e.g. "BadRequest {"Code":2002,"Message":"Failed to get requested export data with error: No data for export"}"

            var message                    = failed.Exception.Message;
            var httpStatusCode             = HttpStatusCode.InternalServerError;
            ContractExecutionResult result = null;

            try
            {
                //Extract the HttpStatusCode
                httpStatusCode = (HttpStatusCode)Enum.Parse(typeof(HttpStatusCode), message.Split(' ')[0]);
                message        = message.Substring(httpStatusCode.ToString().Length + 1);
                //See if it's a service exception
                result = JsonConvert.DeserializeObject <ContractExecutionResult>(message);
            }
            catch (Exception)
            {
                //Not a service exception therefore just use original exception message
                result = new ContractExecutionResult(ContractExecutionStatesEnum.InternalProcessingError, message);
            }

            var failedDetails = new FailureDetails {
                Code = httpStatusCode, Result = result
            };
            var additionalData = JsonConvert.SerializeObject(failedDetails);

            context.SetJobParameter <FailureDetails>(ExportFailedState.EXPORT_DETAILS_KEY, failedDetails);
            context.CandidateState = new ExportFailedState(failed.Exception, additionalData);
        }
Esempio n. 13
0
        public IEnumerable <FailedMessage.FailureGroup> Enrich(string messageType, FailureDetails failureDetails, FailedMessage.ProcessingAttempt processingAttempt)
        {
            var details = new ClassifiableMessageDetails(messageType, failureDetails, processingAttempt);

            foreach (var classifier in classifiers)
            {
                var classification = classifier.ClassifyFailure(details);

                if (classification == null)
                {
                    continue;
                }

                yield return(new FailedMessage.FailureGroup
                {
                    Id = DeterministicGuid.MakeId(classifier.Name, classification).ToString(),
                    Title = classification,
                    Type = classifier.Name
                });
            }
        }
        public Task Announce(IReadOnlyDictionary <string, string> headers, FailureDetails failureDetails)
        {
            var failingEndpointId = headers.ProcessingEndpointName();

            if (headers.TryGetValue("ServiceControl.Retry.UniqueMessageId", out var failedMessageId))
            {
                return(domainEvents.Raise(new MessageFailed
                {
                    FailureDetails = failureDetails,
                    EndpointId = failingEndpointId,
                    FailedMessageId = failedMessageId,
                    RepeatedFailure = true
                }));
            }

            return(domainEvents.Raise(new MessageFailed
            {
                FailureDetails = failureDetails,
                EndpointId = failingEndpointId,
                FailedMessageId = headers.UniqueId()
            }));
        }
Esempio n. 15
0
        public JobStatusResult GetMockExportJobStatus(string jobId)
        {
            string         downloadLink = null;
            FailureDetails details      = null;

            var status = IN_PROGRESS_STATUS;

            if (jobId == SUCCESS_JOB_ID)
            {
                status       = SUCCESS_STATUS;
                downloadLink = "some download link";
            }
            else if (jobId == FAILURE_JOB_ID)
            {
                status  = FAILURE_STATUS;
                details = new FailureDetails {
                    Code = HttpStatusCode.BadRequest, Result = new ContractExecutionResult(2005, "Export limit reached")
                };
            }

            return(new JobStatusResult {
                Key = GetS3Key(jobId, "dummy file"), Status = status, DownloadLink = downloadLink, FailureDetails = details
            });
        }
Esempio n. 16
0
        public ClassifiableMessageDetails(string messageType, FailureDetails failureDetails)
        {
            Details = failureDetails;

            MessageType = messageType;
        }
Esempio n. 17
0
 internal TaskFailureException WithFailureDetails(FailureDetails failureDetails)
 {
     FailureDetails = failureDetails;
     return(this);
 }
Esempio n. 18
0
        public JobStatusResult GetJobStatus(string jobId)
        {
            log.LogInformation($"GetJobStatus: jobId={jobId}");

            var jobData = JobStorage.Current.GetConnection()?.GetJobData(jobId);
            var status  = jobData?.State;

            if (string.IsNullOrEmpty(status))
            {
                throw new ServiceException(HttpStatusCode.BadRequest,
                                           new ContractExecutionResult(ContractExecutionStatesEnum.ValidationError,
                                                                       $"Missing job details for {jobId}"));
            }

            log.LogInformation($"GetJobStatus: {jobId} status={status}");
            string         key          = null;
            string         downloadLink = null;
            FailureDetails details      = null;

            if (status.Equals(Hangfire.States.SucceededState.StateName, StringComparison.OrdinalIgnoreCase))
            {
                if (Request.Path.Value.Contains("export"))
                {
                    // Attempt to get the download link that should have been set in the job
                    key          = JobStorage.Current.GetConnection().GetJobParameter(jobId, ExportJob.S3_KEY_STATE_KEY);
                    downloadLink = JobStorage.Current.GetConnection().GetJobParameter(jobId, ExportJob.DOWNLOAD_LINK_STATE_KEY);
                    log.LogInformation($"Getting export job {jobId} downloadLink={downloadLink}");

                    if (string.IsNullOrEmpty(key) || string.IsNullOrEmpty(downloadLink))
                    {
                        log.LogWarning("S3Key or Downloadlink not set in background job, attempting to find it via the original request");
                        var filename = (jobData?.Job.Args[0] as ScheduleJobRequest).Filename ?? jobId;
                        key          = ExportJob.GetS3Key(jobId, filename);
                        downloadLink = exportJob.GetDownloadLink(jobId, filename);
                    }
                }
            }
            else if (status.Equals(Hangfire.States.DeletedState.StateName, StringComparison.OrdinalIgnoreCase))
            {
                var detailsJson = JobStorage.Current.GetConnection().GetJobParameter(jobId, ExportFailedState.EXPORT_DETAILS_KEY);
                log.LogDebug($"GetJobStatus: detailsJson={detailsJson}");
                if (!string.IsNullOrEmpty(detailsJson))
                {
                    details = JsonConvert.DeserializeObject <FailureDetails>(detailsJson);
                }
            }

            // Change behavior so it's not a breaking change for the UI.

            if (details != null &&
                status.Equals(Hangfire.States.DeletedState.StateName, StringComparison.OrdinalIgnoreCase) &&
                details.Result.Code != ContractExecutionStatesEnum.ExecutedSuccessfully)
            {
                status = Hangfire.States.FailedState.StateName;
            }

            var result = new JobStatusResult {
                Key = key, Status = status, DownloadLink = downloadLink, FailureDetails = details
            };

            log.LogInformation($"GetJobStatus: result={JsonConvert.SerializeObject(result)}");
            return(result);
        }
Esempio n. 19
0
 /// <summary>
 /// There are no comments for FailureDetails in the schema.
 /// </summary>
 public void AddToFailureDetails(FailureDetails failureDetails)
 {
     base.AddObject("FailureDetails", failureDetails);
 }
        /// <summary>
        /// A Lambda function to respond to HTTP Get methods from API Gateway
        /// </summary>
        /// <param name="request"></param>
        /// <returns>The list of blogs</returns>
        public async Task <AmazonWebServiceResponse> FixCloudFormationOutput(CodePipelineJobEvent jobEvent, ILambdaContext context)
        {
            var jobId = jobEvent.CodePipelineJob.Id;

            context.Logger.LogLine($"JobId: {jobId}");

            // Setup Clients
            var codePipelineClient = new AmazonCodePipelineClient();
            var stsClient          = new AmazonSecurityTokenServiceClient();

            try
            {
                var jobData = jobEvent.CodePipelineJob.Data;

                // Assume the role in the cloudformation account that screwed up the bucket permissions
                // for the output object
                var userParameters = jobData.ActionConfiguration.Configuration["UserParameters"];
                var paramDict      = JsonConvert.DeserializeObject <Dictionary <string, string> >(userParameters);
                var roleArn        = paramDict["RoleArn"];

                var assumeRoleRequest = new AssumeRoleRequest {
                    RoleArn         = roleArn,
                    RoleSessionName = "codepipeline",
                    DurationSeconds = 900
                };
                var assumeRoleResponse = await stsClient.AssumeRoleAsync(assumeRoleRequest);

                // Setup an S3 Client with the sts creds
                var s3Client = new AmazonS3Client(assumeRoleResponse.Credentials);

                // Update the ACLs of the input artifacts
                foreach (var inputArtifact in jobData.InputArtifacts)
                {
                    var bucketName = inputArtifact.Location.S3Location.BucketName;
                    var bucketKey  = inputArtifact.Location.S3Location.ObjectKey;
                    context.Logger.LogLine($"Fixing {bucketName}/{bucketKey}");

                    var putObjectAclRequest = new PutACLRequest
                    {
                        BucketName = bucketName,
                        CannedACL  = S3CannedACL.BucketOwnerFullControl,
                        Key        = bucketKey
                    };
                    await s3Client.PutACLAsync(putObjectAclRequest);
                }

                // Send the success response
                var successResultRequest = new PutJobSuccessResultRequest
                {
                    JobId = jobId
                };
                return(await codePipelineClient.PutJobSuccessResultAsync(successResultRequest));
            }
            catch (Exception ex)
            {
                // Send the failure response and log
                context.Logger.LogLine("FixCloudFormationOutput Exception");
                context.Logger.LogLine(ex.Message);
                var failureDetails = new FailureDetails {
                    Message = ex.Message,
                    Type    = FailureType.JobFailed
                };
                return(await codePipelineClient.PutJobFailureResultAsync(jobId, failureDetails));
            }
        }
Esempio n. 21
0
 public ClassifiableMessageDetails(string messageType, FailureDetails failureDetails, ProcessingAttempt processingAttempt)
 {
     Details           = failureDetails;
     ProcessingAttempt = processingAttempt;
     MessageType       = messageType;
 }
Esempio n. 22
0
 public void SetFailureDetails(Guid userGuid, FailureDetails failureDetails)
 {
     _cartSessionManager.SetSessionValue(SagePayFailureDetailsKey, userGuid, failureDetails, SessionDataTimeoutDefaults.PaymentInfo);
 }
Esempio n. 23
0
        public JobRequest ExecuteCallback(object parameter, object context)
        {
            var parentJob      = (string)parameter;
            var currentContext = (PerformContext)context;

            var jobData = JobStorage.Current.GetConnection()?.GetJobData(parentJob);
            var status  = jobData?.State;

            if (status == null)
            {
                throw new NullReferenceException("JobData.State cannot be null");
            }

            var details = new FailureDetails {
                Code = System.Net.HttpStatusCode.OK, Result = new ContractExecutionResult()
            };

            if (status.Equals(Hangfire.States.DeletedState.StateName, StringComparison.OrdinalIgnoreCase))
            {
                var detailsJson = JobStorage.Current.GetConnection().GetJobParameter(parentJob, ExportFailedState.EXPORT_DETAILS_KEY);

                log.LogDebug($"ExportEmailGenerator.ExecuteCallback: detailsJson={detailsJson}");

                if (!string.IsNullOrEmpty(detailsJson))
                {
                    details = JsonConvert.DeserializeObject <FailureDetails>(detailsJson);
                }
            }

            try
            {
                var key          = "";
                var downloadLink = "";

                if (details.Result.Code == ContractExecutionStatesEnum.ExecutedSuccessfully)
                {
                    key          = JobStorage.Current.GetConnection().GetJobParameter(parentJob, ExportJob.ExportJob.S3_KEY_STATE_KEY);
                    downloadLink = JobStorage.Current.GetConnection().GetJobParameter(parentJob, ExportJob.ExportJob.DOWNLOAD_LINK_STATE_KEY);
                }

                var projectName = currentContext.GetJobParameter <string>(Tags.PROJECTNAME_TAG);
                var recipients  = currentContext.GetJobParameter <string[]>(Tags.RECIPIENTS_TAG);

                var result = new JobStatusResult {
                    Key = key, Status = status, DownloadLink = downloadLink, FailureDetails = details
                };
                var emailParameters = new EmailModel {
                    FromName = "*****@*****.**", To = recipients, Subject = $"Roller Report {projectName} {DateTime.UtcNow:yyyy-MM-ddTHH-mm}"
                };

                if (string.IsNullOrEmpty(downloadLink))
                {
                    result.Status = Hangfire.States.FailedState.StateName;
                }

                emailParameters.SetContent(JsonConvert.SerializeObject(result));

                log.LogDebug($"Getting ready to send email { JsonConvert.SerializeObject(emailParameters) }");

                return(new JobRequest {
                    JobUid = Guid.Parse("7c2fc23d-ca84-490d-9240-8e2e622c2470"), SetupParameters = null, RunParameters = emailParameters
                });
            }
            catch (Exception ex)
            {
                log.LogError(ex, "Failed to prepare email message");
                throw;
            }
        }
Esempio n. 24
0
        private void AnnounceFailedMessage(IReadOnlyDictionary <string, string> headers, FailureDetails failureDetails)
        {
            var failingEndpointId = Address.Parse(failureDetails.AddressOfFailingEndpoint).Queue;

            string failedMessageId;

            if (headers.TryGetValue("ServiceControl.Retry.UniqueMessageId", out failedMessageId))
            {
                domainEvents.Raise(new MessageFailed
                {
                    FailureDetails  = failureDetails,
                    EndpointId      = failingEndpointId,
                    FailedMessageId = failedMessageId,
                    RepeatedFailure = true
                });
            }
            else
            {
                domainEvents.Raise(new MessageFailed
                {
                    FailureDetails  = failureDetails,
                    EndpointId      = failingEndpointId,
                    FailedMessageId = headers.UniqueId(),
                });
            }
        }
        public void ConfigureServices(IServiceCollection container)
        {
            container.Configure <AwsSettings>(Configuration.GetSection("Aws"));
            container.Configure <AppSettings>(Configuration.GetSection(nameof(AppSettings)));
            container.Configure <Dependencies>(Configuration.GetSection(nameof(Dependencies)));

            var mvcBuilder = container
                             .AddControllers()
                             .AddNewtonsoftJson(options =>
            {
                options.SerializerSettings.Converters.Add(new StringEnumConverter());
                options.SerializerSettings.Converters.Add(new VersionConverter());
                options.SerializerSettings.Converters.Add(new DateTimeOffsetConvertor());
                options.SerializerSettings.Converters.Add(new DateTimeOffsetNullableConvertor());
                options.SerializerSettings.Converters.Add(new TimeSpanConverter());
                options.SerializerSettings.Converters.Add(new TimeSpanNullableConvertor());
                options.SerializerSettings.DateTimeZoneHandling  = DateTimeZoneHandling.Utc;
                options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
                options.SerializerSettings.NullValueHandling     = NullValueHandling.Ignore;
                options.SerializerSettings.Formatting            = Formatting.Indented;
            })
                             .AddApplicationPart(Assembly.GetExecutingAssembly())
                             .ConfigureApiBehaviorOptions(options =>
            {
                options.InvalidModelStateResponseFactory = context =>
                {
                    var problems = new FailureDetails(context.HttpContext.TraceIdentifier);

                    return(new BadRequestObjectResult(problems));
                };
            });

            container.AddSingleton <IEnvironmentNameAccessor, EnvironmentNameAccessor>();
            container.AddScoped <IExceptionHandler, ExceptionHandler>();

            container
            .AddScoped <ScopedCorrelation>()
            .AddTransient <IScopedCorrelation>(sp => sp.GetRequiredService <ScopedCorrelation>());

            container
            .AddScoped <ScopedCancellationToken>()
            .AddTransient <IScopedCancellationToken>(sp => sp.GetRequiredService <ScopedCancellationToken>());

            container.AddScoped <KestralResponseBodyMiddleware>();
            container.AddScoped <ScopedCancellationTokenMiddleware>();
            container.AddScoped <ScopedCorrelationIdMiddleware>();
            container.AddScoped <StaticFilesMiddleware>();
            container.AddScoped <ResponseHeadersMiddleware>();
            container.AddScoped <RequestExceptionMiddleware>();

            container.Configure <RouteOptions>(options =>
            {
                options.LowercaseUrls = true;
            });

            container.AddHttpContextAccessor();

            var appSettings = Configuration.GetSection(nameof(AppSettings)).Get <AppSettings>();
            var jwtKey      = Encoding.ASCII.GetBytes(appSettings.JwtSecret);

            container
            .AddAuthentication(auth =>
            {
                auth.DefaultScheme          = PolicyName;
                auth.DefaultChallengeScheme = PolicyName;
            })
            .AddPolicyScheme(PolicyName, "API-Key or Authorization Bearer", options =>
            {
                options.ForwardDefaultSelector = context =>
                {
                    if (context.Request.Headers.ContainsKey(Headers.ApiKey))
                    {
                        return(Headers.ApiKey);
                    }
                    else
                    {
                        return(JwtBearerDefaults.AuthenticationScheme);
                    }
                };
            })
            .AddScheme <AuthenticationSchemeOptions, ApiKeyHandler>(Headers.ApiKey, options => options.ClaimsIssuer = appSettings.JwtIssuer)
            .AddJwtBearer(x =>
            {
                x.RequireHttpsMetadata      = false;
                x.SaveToken                 = true;
                x.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuerSigningKey = true,
                    IssuerSigningKey         = new SymmetricSecurityKey(jwtKey),
                    ValidateIssuer           = true,
                    ValidIssuer      = appSettings.JwtIssuer,
                    ValidAudience    = appSettings.JwtAudience,
                    ValidateAudience = true,
                    ValidateLifetime = true
                };
            });

            container.AddAuthorization(options =>
            {
                options.AddPolicy(Headers.ApiKey, policy => policy
                                  .AddAuthenticationSchemes(Headers.ApiKey)
                                  .RequireAuthenticatedUser());

                options.AddPolicy(JwtBearerDefaults.AuthenticationScheme, policy => policy
                                  .AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme)
                                  .RequireAuthenticatedUser());
            });

            container.AddResponseCompression(options =>
            {
                options.EnableForHttps = true;
                options.MimeTypes      = new List <string>()
                {
                    "application/javascript",
                    "application/json",
                    "application/xml",
                    "application/pdf",
                    "text/css",
                    "text/html",
                    "text/json",
                    "text/plain",
                    "text/xml"
                };
                options.Providers.Add <BrotliCompressionProvider>();
                options.Providers.Add <GzipCompressionProvider>();
            });

            container
            .AddSwaggerGen(options =>
            {
                options.SwaggerDoc(
                    "v1",
                    new OpenApiInfo()
                {
                    Title   = "Invictus Funds API",
                    Version = "v1",
                    Contact = new OpenApiContact()
                    {
                        Name  = "Pseudonym",
                        Url   = new Uri("https://www.pseudonym.org.uk"),
                        Email = "*****@*****.**",
                    }
                });

                options.EnableAnnotations();
                options.AddSecurityDefinition(Headers.ApiKey, new OpenApiSecurityScheme
                {
                    Description = "Api Key used to interact with the system.",
                    Name        = Headers.ApiKey,
                    In          = ParameterLocation.Header,
                    Type        = SecuritySchemeType.ApiKey
                });
                options.AddSecurityDefinition(JwtConstants.TokenType, new OpenApiSecurityScheme
                {
                    Description  = "JWT token used to interact with the system.",
                    Name         = Headers.Authorization,
                    In           = ParameterLocation.Header,
                    Type         = SecuritySchemeType.Http,
                    Scheme       = JwtBearerDefaults.AuthenticationScheme.ToLower(),
                    BearerFormat = JwtConstants.TokenType
                });
                options.AddSecurityRequirement(new OpenApiSecurityRequirement
                {
                    {
                        new OpenApiSecurityScheme
                        {
                            Reference = new OpenApiReference
                            {
                                Id   = JwtConstants.TokenType,
                                Type = ReferenceType.SecurityScheme,
                            }
                        },
                        new List <string>()
                    },
                    {
                        new OpenApiSecurityScheme
                        {
                            Reference = new OpenApiReference
                            {
                                Id   = Headers.ApiKey,
                                Type = ReferenceType.SecurityScheme,
                            }
                        },
                        new List <string>()
                    }
                });
            })
            .AddSwaggerGenNewtonsoftSupport();

            // Clients
            container
            .AddBloxyClient()
            .AddCoinGeckoClient()
            .AddEthplorerClient()
            .AddInfuraClient()
            .AddTheGraphClient()
            .AddLightstreamClient()
            .AddPolygonClient()
            .AddInvictusClient()
            .AddExchangeRateClient();

            container.AddTransient <IAuthService, AuthService>();
            container.AddTransient <IStakeService, StakeService>();
            container.AddTransient <IInvestmentService, InvestmentService>();
            container.AddTransient <IFundService, FundService>();

            container.AddSingleton <IDataKeyProvider, DataKeyProvider>();
            container.AddScoped <ITransactionRepository, TransactionRepository>();
            container.AddScoped <IOperationRepository, OperationRepository>();
            container.AddScoped <IFundPerformanceRepository, FundPerformanceRepository>();
            container.AddScoped <IStakingPowerRepository, StakingPowerRepository>();

            container
            .AddScoped <IQuantityProviderFactory, QuantityProviderFactory>()
            .AddScoped <IQuantityProvider, NoiaQuantityProvider>()
            .AddScoped <IQuantityProvider, LightstreamsQuantityProvider>()
            .AddScoped <IQuantityProvider>(sp => InvictusQuantityProvider <IPolygonClient> .Create(sp, Symbol.C10))
            .AddScoped <IQuantityProvider>(sp => InvictusQuantityProvider <IPolygonClient> .Create(sp, Symbol.C20))
            .AddScoped <IQuantityProvider>(sp => InvictusQuantityProvider <IPolygonClient> .Create(sp, Symbol.IBA))
            .AddScoped <IQuantityProvider>(sp => InvictusQuantityProvider <IEtherClient> .Create(sp, Symbol.IHF))
            .AddScoped <IQuantityProvider>(sp => InvictusQuantityProvider <IPolygonClient> .Create(sp, Symbol.IML));

            container.AddDefaultAWSOptions(Configuration.GetAWSOptions());
            container.AddScoped <IAmazonDynamoDB>(sp =>
            {
                var awsSettings = sp.GetRequiredService <IOptions <AwsSettings> >();
                if (awsSettings.Value.UseConfiguredSecurity())
                {
                    return(new AmazonDynamoDBClient(
                               awsSettings.Value.AccessKey,
                               awsSettings.Value.SecretAccessKey,
                               RegionEndpoint.GetBySystemName(awsSettings.Value.Region)));
                }
                else
                {
                    return(new AmazonDynamoDBClient(RegionEndpoint.GetBySystemName(awsSettings.Value.Region)));
                }
            });

            container
            .AddHostedService <CurrencyUpdaterService>()
            .AddSingleton <CurrencyConverter>()
            .AddTransient <ICurrencyConverter>(sp => sp.GetRequiredService <CurrencyConverter>());

            if (appSettings.CacheTransactions)
            {
                container.AddHostedService <TransactionCachingService>();
            }

            if (appSettings.CacheStakePower)
            {
                container.AddHostedService <FundStakingPowerCachingService>();
            }

            if (appSettings.CacheFundPerformance)
            {
                container.AddHostedService <FundPerformanceCachingService>();
            }
        }
        public void ConfigureServices(IServiceCollection container)
        {
            container.Configure <AppSettings>(Configuration.GetSection(nameof(AppSettings)));

            container.AddControllersWithViews()
            .AddNewtonsoftJson(options =>
            {
                options.SerializerSettings.Converters.Add(new StringEnumConverter());
                options.SerializerSettings.Converters.Add(new VersionConverter());
                options.SerializerSettings.DateFormatString      = "yyyy-MM-ddTHH:mm:ss";
                options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
                options.SerializerSettings.NullValueHandling     = NullValueHandling.Ignore;
                options.SerializerSettings.Formatting            = Formatting.Indented;
            })
            .AddApplicationPart(Assembly.GetExecutingAssembly())
            .ConfigureApiBehaviorOptions(options =>
            {
                options.InvalidModelStateResponseFactory = context =>
                {
                    var problems = new FailureDetails(context.HttpContext.TraceIdentifier);

                    return(new BadRequestObjectResult(problems));
                };
            });

            container.AddRazorPages();

            container.AddSingleton <IEnvironmentNameAccessor, EnvironmentNameAccessor>();
            container.AddScoped <IExceptionHandler, ExceptionHandler>();

            container
            .AddScoped <ScopedCorrelation>()
            .AddTransient <IScopedCorrelation>(sp => sp.GetRequiredService <ScopedCorrelation>());

            container
            .AddScoped <ScopedCancellationToken>()
            .AddTransient <IScopedCancellationToken>(sp => sp.GetRequiredService <ScopedCancellationToken>());

            container.AddScoped <KestralResponseBodyMiddleware>();
            container.AddScoped <ScopedCancellationTokenMiddleware>();
            container.AddScoped <ScopedCorrelationIdMiddleware>();
            container.AddScoped <RequestExceptionMiddleware>();

            container.Configure <RouteOptions>(options =>
            {
                options.LowercaseUrls = true;
            });

            container.AddHttpContextAccessor();

            container.AddResponseCompression(options =>
            {
                options.EnableForHttps = true;
                options.MimeTypes      = new List <string>()
                {
                    "application/javascript",
                    "application/json",
                    "application/xml",
                    "application/pdf",
                    "text/css",
                    "text/html",
                    "text/json",
                    "text/plain",
                    "text/xml"
                };
                options.Providers.Add <BrotliCompressionProvider>();
                options.Providers.Add <GzipCompressionProvider>();
            });

            container.AddScoped <IAuthService, AuthService>();
        }
Esempio n. 27
0
        private void AnnounceFailedMessage(IReadOnlyDictionary <string, string> headers, FailureDetails failureDetails)
        {
            var failingEndpointId = Address.Parse(failureDetails.AddressOfFailingEndpoint).Queue;

            string failedMessageId;

            if (headers.TryGetValue("ServiceControl.Retry.UniqueMessageId", out failedMessageId))
            {
                bus.Publish <MessageFailedRepeatedly>(m =>
                {
                    m.FailureDetails  = failureDetails;
                    m.EndpointId      = failingEndpointId;
                    m.FailedMessageId = failedMessageId;
                });
            }
            else
            {
                bus.Publish <MessageFailed>(m =>
                {
                    m.FailureDetails  = failureDetails;
                    m.EndpointId      = failingEndpointId;
                    m.FailedMessageId = headers.UniqueId();
                });
            }
        }
        /// <summary>
        /// Used to modify recordset with value from api gateway code deploy in another account.
        /// </summary>
        /// <param name="jobEvent">CodePipeline event.</param>
        /// <param name="context">Lambda Context</param>
        /// <returns>Job success of the Lambda</returns>
        public async Task <AmazonWebServiceResponse> UpdateApiGatewayAliasRecordSet(CodePipelineJobEvent jobEvent, ILambdaContext context)
        {
            var jobId = jobEvent.CodePipelineJob.Id;

            context.Logger.LogLine($"JobId: {jobId}");

            using (var codePipelineClient = new AmazonCodePipelineClient())
                using (var s3Client = new AmazonS3Client())
                    using (var dnsClient = new AmazonRoute53Client())
                    {
                        // Prep the user parameters
                        var userParameters = jobEvent.CodePipelineJob.Data.ActionConfiguration.Configuration["UserParameters"];
                        context.Logger.LogLine("UserParameters:");
                        context.Logger.LogLine(userParameters);
                        var paramDict = JsonConvert.DeserializeObject <Dictionary <string, string> >(userParameters);

                        try
                        {
                            DnsSettings dnsSettings = null;

                            // Get the first (only) input artifact
                            var artifact           = jobEvent.CodePipelineJob.Data.InputArtifacts.First();
                            var artifactBucketName = artifact.Location.S3Location.BucketName;
                            var artifactBucketKey  = artifact.Location.S3Location.ObjectKey;

                            // Unzip and get json
                            using (var getResponse = await s3Client.GetObjectAsync(artifactBucketName, artifactBucketKey))
                            {
                                var memoryStream = new MemoryStream();
                                using (var objectStream = getResponse.ResponseStream)
                                {
                                    objectStream.CopyTo(memoryStream);
                                }


                                var searchFile = paramDict["DnsJson"];
                                context.Logger.LogLine("Unziping artifact");
                                context.Logger.LogLine($"Searching for {searchFile}");
                                using (var archive = new ZipArchive(memoryStream, ZipArchiveMode.Read))
                                {
                                    foreach (var entry in archive.Entries)
                                    {
                                        var fileName = entry.Name;
                                        context.Logger.LogLine("Checking File: " + entry.Name);

                                        if (searchFile == fileName)
                                        {
                                            using (var fileStream = entry.Open())
                                                using (var streamReader = new StreamReader(fileStream))
                                                {
                                                    var dnsJson = await streamReader.ReadToEndAsync();

                                                    dnsSettings = JsonConvert.DeserializeObject <DnsSettings>(dnsJson);
                                                }

                                            break;
                                        }
                                    }
                                }
                            }

                            // Get the hosted zones in the tools region
                            context.Logger.LogLine($"Searching for {dnsSettings.HostedZoneLookupDomainName}");
                            var hostedZones = await dnsClient.ListHostedZonesAsync();

                            var myHostedZone = hostedZones.HostedZones.FirstOrDefault(z => z.Name == dnsSettings.HostedZoneLookupDomainName);
                            if (myHostedZone == null)
                            {
                                var noZoneMessage = $"Hosted Zone {dnsSettings.HostedZoneLookupDomainName} could not be found";
                                context.Logger.LogLine(noZoneMessage);
                                var failureDetails = new FailureDetails
                                {
                                    Message = noZoneMessage,
                                    Type    = FailureType.ConfigurationError
                                };
                                return(await codePipelineClient.PutJobFailureResultAsync(jobId, failureDetails));
                            }

                            // The record set we need to create
                            var recordSet = new ResourceRecordSet
                            {
                                Name            = dnsSettings.WebApiDnsDomain,
                                Type            = RRType.A,
                                ResourceRecords = new List <ResourceRecord> {
                                    new ResourceRecord {
                                        Value = $"ALIAS {dnsSettings.RegionalDomainName}"
                                    }
                                }
                            };
                            var rsChange = new Change
                            {
                                Action            = ChangeAction.UPSERT,
                                ResourceRecordSet = recordSet
                            };
                            var rsChangeBatch = new ChangeBatch
                            {
                                Changes = new List <Change> {
                                    rsChange
                                }
                            };


                            // Create/Update the recordset
                            var changeDnsRequest = new ChangeResourceRecordSetsRequest
                            {
                                ChangeBatch  = rsChangeBatch,
                                HostedZoneId = myHostedZone.Id
                            };
                            var changeResponse = await dnsClient.ChangeResourceRecordSetsAsync(changeDnsRequest);

                            // Log and send the success response
                            context.Logger.LogLine($"Request Id {changeResponse.ChangeInfo.Id} submitted");
                            context.Logger.LogLine($"{dnsSettings.WebApiDnsDomain} => A ALIAS {dnsSettings.RegionalDomainName}");
                            var successResultRequest = new PutJobSuccessResultRequest
                            {
                                JobId = jobId
                            };
                            return(await codePipelineClient.PutJobSuccessResultAsync(successResultRequest));
                        }
                        catch (Exception ex)
                        {
                            // Send the failure response and log
                            return(await DoException(codePipelineClient, ex, jobId, context));
                        }
                    }
        }
Esempio n. 29
0
 /// <summary>
 /// Create a new FailureDetails object.
 /// </summary>
 /// <param name="failureId">Initial value of FailureId.</param>
 public static FailureDetails CreateFailureDetails(int failureId)
 {
     FailureDetails failureDetails = new FailureDetails();
     failureDetails.FailureId = failureId;
     return failureDetails;
 }
 public FailedMessage.ProcessingAttempt CreateProcessingAttempt(Dictionary <string, string> headers, Dictionary <string, object> metadata, FailureDetails failureDetails, MessageIntentEnum intent, bool recoverable, string correlationId, string replyToAddress)
 {
     return(new FailedMessage.ProcessingAttempt
     {
         AttemptedAt = failureDetails.TimeOfFailure,
         FailureDetails = failureDetails,
         MessageMetadata = metadata,
         MessageId = headers[Headers.MessageId],
         Headers = headers,
         ReplyToAddress = replyToAddress,
         Recoverable = recoverable,
         CorrelationId = correlationId,
         MessageIntent = intent
     });
 }
Esempio n. 31
0
 public FailedMessage.ProcessingAttempt CreateProcessingAttempt(Dictionary <string, string> headers, Dictionary <string, object> metadata, FailureDetails failureDetails)
 {
     return(new FailedMessage.ProcessingAttempt
     {
         AttemptedAt = failureDetails.TimeOfFailure,
         FailureDetails = failureDetails,
         MessageMetadata = metadata,
         MessageId = headers[Headers.MessageId],
         Headers = headers
     });
 }