コード例 #1
0
        /// <summary>
        /// The method to get a DB connection string from the Vault using options from appsettings.json
        /// </summary>
        /// <param name="vaultClient">The instance of the Vault client </param>
        /// <param name="pathToConnectionOptions">The path to connection options in appsettings.json</param>
        /// <param name="pathToConnectionString">The path to the connection string template in appsettings.json</param>
        /// <param name="configuration">Represents the application configuration</param>
        /// <returns></returns>
        public static string GetDbConnectionString(VaultClient.VaultClient vaultClient, string pathToConnectionOptions,
                                                   string pathToConnectionString, IConfiguration configuration)
        {
            var connectionOptions = vaultClient.Get(configuration[pathToConnectionOptions]).Result;

            return(string.Format($"{configuration[pathToConnectionString]}", connectionOptions["host"],
                                 connectionOptions["port"], connectionOptions["database"], connectionOptions["userId"],
                                 connectionOptions["password"]));
        }
コード例 #2
0
        public static string GetDbConnectionString(VaultClient.VaultClient vaultClient, IConfiguration configuration)
        {
            var connectionOptions = vaultClient.Get(configuration["Database:ConnectionOptions"]).Result;

            return(string.Format(configuration["Database:ConnectionString"],
                                 connectionOptions["host"],
                                 connectionOptions["port"],
                                 connectionOptions["userId"],
                                 connectionOptions["password"]));
        }
コード例 #3
0
        public void ConfigureServices(IServiceCollection services)
        {
            using var vaultClient = new VaultClient.VaultClient(new VaultOptions
            {
                BaseUrl = new Uri(EnvironmentVariableHelper.Get("Vault:Endpoint", Configuration)),
                Engine  = Configuration["Vault:Engine"],
                Role    = Configuration["Vault:Role"]
            });
            vaultClient.Login(EnvironmentVariableHelper.Get("Vault:Token", Configuration)).GetAwaiter().GetResult();

            var authorityOptions = vaultClient.Get(Configuration["Authority:Options"]).GetAwaiter().GetResult();

            services.AddHealthChecks()
            .AddDbContextCheck <EdoContext>()
            .AddRedis(EnvironmentVariableHelper.Get("Redis:Endpoint", Configuration));

            services.ConfigureAuthentication(authorityOptions);
            services.AddControllers()
            .AddNewtonsoftJson(opts => opts.SerializerSettings.Converters.Add(new Newtonsoft.Json.Converters.StringEnumConverter()))
            .AddJsonOptions(opts => opts.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter()))
            .AddFluentValidation(fv =>
            {
                fv.DisableDataAnnotationsValidation         = true;
                fv.ImplicitlyValidateRootCollectionElements = true;
                fv.ImplicitlyValidateChildProperties        = true;
                fv.RegisterValidatorsFromAssembly(Assembly.GetExecutingAssembly());
            });
            services.AddResponseCompression();
            services.ConfigureTracing(Configuration, HostEnvironment);
            services.AddProblemDetailsErrorHandling();
            services.ConfigureApiVersioning();
            services.ConfigureSwagger();
            services.ConfigureCache(Configuration);
            services.ConfigureHttpClients(Configuration, HostEnvironment, vaultClient, authorityOptions["authorityUrl"]);
            services.ConfigureServiceOptions(Configuration, HostEnvironment, vaultClient);
            services.ConfigureUserEventLogging(Configuration, vaultClient);
            services.AddServices(HostEnvironment, Configuration, vaultClient);
            services.AddSignalR().AddStackExchangeRedis(EnvironmentVariableHelper.Get("Redis:Endpoint", Configuration));

            // override services
            services.AddTransient <AccommodationAvailabilitiesService>();
            services.AddTransient <AccommodationService>();
            services.AddTransient <IAgentContextService, AgentContextService>();
            services.AddTransient <BookingCancellationService>();
            services.AddTransient <IBookingEvaluationService, DirectApiBookingEvaluationService>();
            services.AddTransient <INotificationService, EdoDummyNotificationService>();
            services.AddTransient <ValuationService>();
            services.AddTransient <WideAvailabilitySearchService>();
            services.AddTransient <BookingInfoService>();
            services.AddTransient <BookingCreationService>();
            services.AddTransient <IBookingRegistrationService, DirectApiBookingRegistrationService>();
            services.AddTransient <ClientReferenceCodeValidationService>();
            services.ConfigureWideAvailabilityStorage(HostEnvironment, Configuration, vaultClient);
        }
コード例 #4
0
        private static Dictionary <string, string> GetDbOptions(IConfiguration configuration)
        {
            using var vaultClient = new VaultClient.VaultClient(new VaultOptions
            {
                BaseUrl = new Uri(Environment.GetEnvironmentVariable(configuration["Vault:Endpoint"]), UriKind.Absolute),
                Engine  = configuration["Vault:Engine"],
                Role    = configuration["Vault:Role"]
            });
            vaultClient.Login(Environment.GetEnvironmentVariable(configuration["Vault:Token"])).Wait();

            return(vaultClient.Get(configuration["EDO:Database:Options"]).Result);
        }
コード例 #5
0
        public void ConfigureServices(IServiceCollection services)
        {
            var serializationSettings = new JsonSerializerSettings
            {
                ContractResolver = new CamelCasePropertyNamesContractResolver(),
                Formatting       = Formatting.None
            };

            JsonConvert.DefaultSettings = () => serializationSettings;

            using var vaultClient = new VaultClient.VaultClient(new VaultOptions
            {
                BaseUrl = new Uri(EnvironmentVariableHelper.Get("Vault:Endpoint", Configuration)),
                Engine  = Configuration["Vault:Engine"],
                Role    = Configuration["Vault:Role"]
            });
            vaultClient.Login(EnvironmentVariableHelper.Get("Vault:Token", Configuration)).GetAwaiter().GetResult();

            services.AddHealthChecks();

            services.ConfigureServiceOptions(Configuration, vaultClient)
            .AddServices()
            .AddMemoryCache();

            services.AddStaticDataPublicationServices(vaultClient, Configuration, _environment);
            services.AddHostedService <DataUpdateHostedService>();

            services.AddTracing(Configuration, options =>
            {
                options.ServiceName = $"{_environment.ApplicationName}-{_environment.EnvironmentName}";
                options.JaegerHost  = _environment.IsLocal()
                    ? Configuration.GetValue <string>("Jaeger:AgentHost")
                    : Configuration.GetValue <string>(Configuration.GetValue <string>("Jaeger:AgentHost"));
                options.JaegerPort = _environment.IsLocal()
                    ? Configuration.GetValue <int>("Jaeger:AgentPort")
                    : Configuration.GetValue <int>(Configuration.GetValue <string>("Jaeger:AgentPort"));
                options.RedisEndpoint = Configuration.GetValue <string>(Configuration.GetValue <string>("Redis:Endpoint"));
            });
        }
コード例 #6
0
        public static IServiceCollection ConfigureServiceOptions(this IServiceCollection services,
                                                                 IConfiguration configuration, VaultClient.VaultClient vaultClient)
        {
            var databaseOptions = vaultClient.Get(configuration["Nakijin:Database:Options"]).GetAwaiter().GetResult();

            services.AddEntityFrameworkNpgsql().AddDbContextPool <NakijinContext>(options =>
            {
                var host     = databaseOptions["host"];
                var port     = databaseOptions["port"];
                var password = databaseOptions["password"];
                var userId   = databaseOptions["userId"];

                var connectionString = configuration.GetConnectionString("Nakijin");
                options.UseNpgsql(string.Format(connectionString, host, port, userId, password), builder =>
                {
                    builder.UseNetTopologySuite();
                    builder.EnableRetryOnFailure();
                });
                options.EnableSensitiveDataLogging(false);
                options.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking);
            }, 16);

            services.Configure <RequestLocalizationOptions>(o =>
            {
                o.DefaultRequestCulture = new RequestCulture("en");
                o.SupportedCultures     = new[]
                {
                    new CultureInfo("en"),
                    new CultureInfo("ar"),
                    new CultureInfo("ru")
                    //TODO: add others if needed
                };

                o.RequestCultureProviders.Insert(0, new RouteDataRequestCultureProvider {
                    Options = o
                });
            });

            var authorityOptions = vaultClient.Get(configuration["Nakijin:Authority:Options"]).GetAwaiter().GetResult();
            var authorityUrl     = authorityOptions["authorityUrl"];

            services.AddAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme)
            .AddJwtBearer(o =>
            {
                o.Authority            = authorityUrl;
                o.Audience             = authorityOptions["apiName"];
                o.RequireHttpsMetadata = true;
            });


            var clientOptions = vaultClient.Get(configuration["Nakijin:Client:Options"]).GetAwaiter().GetResult();

            services.AddAccessTokenManagement(options =>
            {
                options.Client.Clients.Add(HttpClientNames.Identity, new ClientCredentialsTokenRequest
                {
                    Address      = new Uri(new Uri(authorityUrl), "/connect/token").ToString(),
                    ClientId     = clientOptions["clientId"],
                    ClientSecret = clientOptions["clientSecret"],
                });
            });

            var suppliersEndpoint = configuration.GetValue <string>("Suppliers:Endpoint");

            services.AddSupplierOptionsProvider(options =>
            {
                options.IdentityClientName = HttpClientNames.Identity;
                options.BaseEndpoint       = suppliersEndpoint;
                options.StorageTimeout     = TimeSpan.FromSeconds(60);
                options.UpdaterInterval    = TimeSpan.FromSeconds(60);
            });

            return(services);
        }
コード例 #7
0
ファイル: Startup.cs プロジェクト: happy-travel/kanazawa
        public void ConfigureServices(IServiceCollection services)
        {
            var serializationSettings = new JsonSerializerSettings
            {
                ContractResolver = new CamelCasePropertyNamesContractResolver(),
                Formatting       = Formatting.None
            };

            JsonConvert.DefaultSettings = () => serializationSettings;

            using var vaultClient = new VaultClient.VaultClient(new VaultOptions
            {
                Engine  = Configuration["Vault:Engine"],
                Role    = Configuration["Vault:Role"],
                BaseUrl = new Uri(EnvironmentVariableHelper.Get("Vault:Endpoint", Configuration))
            });

            vaultClient.Login(EnvironmentVariableHelper.Get("Vault:Token", Configuration)).Wait();

            var jobsSettings = vaultClient.Get(Configuration["Identity:JobsOptions"]).GetAwaiter().GetResult();
            var clientSecret = jobsSettings[Configuration["Identity:Secret"]];

            var edoSettings  = vaultClient.Get(Configuration["Edo:EdoOptions"]).GetAwaiter().GetResult();
            var authorityUrl = edoSettings[Configuration["Identity:Authority"]];
            var edoApiUrl    = edoSettings[Configuration["Edo:Api"]];

            services.AddAccessTokenManagement(options =>
            {
                options.User.RefreshBeforeExpiration = TimeSpan.FromMinutes(2);
                options.Client.Clients.Add(HttpClientNames.Identity, new ClientCredentialsTokenRequest
                {
                    Address      = $"{authorityUrl}connect/token",
                    ClientId     = Configuration["Identity:ClientId"],
                    ClientSecret = clientSecret
                });
            });

            services.AddTracing(Configuration, options =>
            {
                options.ServiceName = $"{_environment.ApplicationName}-{_environment.EnvironmentName}";
                options.JaegerHost  = _environment.IsLocal()
                    ? Configuration.GetValue <string>("Jaeger:AgentHost")
                    : Configuration.GetValue <string>(Configuration.GetValue <string>("Jaeger:AgentHost"));
                options.JaegerPort = _environment.IsLocal()
                    ? Configuration.GetValue <int>("Jaeger:AgentPort")
                    : Configuration.GetValue <int>(Configuration.GetValue <string>("Jaeger:AgentPort"));
            });

            services
            .Configure <CompletionOptions>(Configuration.GetSection("Completion"))
            .Configure <ChargeOptions>(Configuration.GetSection("Charge"))
            .Configure <CancellationOptions>(Configuration.GetSection("Cancellation"))
            .Configure <NotificationOptions>(Configuration.GetSection("Notification"))
            .Configure <MarkupBonusMaterializationOptions>(Configuration.GetSection("MarkupBonusMaterialization"))
            .Configure <RefundOptions>(Configuration.GetSection("Refund"));

            services.AddHttpClient(HttpClientNames.EdoApi, client =>
            {
                client.BaseAddress = new Uri(edoApiUrl);
                client.Timeout     = TimeSpan.FromHours(1);
            })
            .AddPolicyHandler((sp, _) => Policy(sp))
            .AddClientAccessTokenHandler(HttpClientNames.Identity);

            services.AddHealthChecks();

            services.AddHostedService <UpdaterService>();
        }
コード例 #8
0
ファイル: Startup.cs プロジェクト: QuinntyneBrown/edo
        public void ConfigureServices(IServiceCollection services)
        {
            var serializationSettings = new JsonSerializerSettings
            {
                ContractResolver = new CamelCasePropertyNamesContractResolver(),
                Formatting       = Formatting.None
            };

            JsonConvert.DefaultSettings = () => serializationSettings;

            using var vaultClient = new VaultClient.VaultClient(new VaultOptions
            {
                BaseUrl = new Uri(EnvironmentVariableHelper.Get("Vault:Endpoint", Configuration)),
                Engine  = Configuration["Vault:Engine"],
                Role    = Configuration["Vault:Role"]
            });
            vaultClient.Login(EnvironmentVariableHelper.Get("Vault:Token", Configuration)).GetAwaiter().GetResult();

            services.AddResponseCompression()
            .AddCors()
            .AddLocalization()
            .AddMemoryCache()
            .AddMemoryFlow()
            .AddStackExchangeRedisCache(options => { options.Configuration = EnvironmentVariableHelper.Get("Redis:Endpoint", Configuration); })
            .AddDoubleFlow()
            .AddCacheFlowJsonSerialization()
            .AddTracing(HostingEnvironment, Configuration);

            services.ConfigureServiceOptions(Configuration, HostingEnvironment, vaultClient)
            .ConfigureHttpClients(Configuration, HostingEnvironment, vaultClient)
            .ConfigureAuthentication(Configuration, HostingEnvironment, vaultClient)
            .AddServices();

            services.AddHealthChecks()
            .AddDbContextCheck <EdoContext>()
            .AddRedis(EnvironmentVariableHelper.Get("Redis:Endpoint", Configuration))
            .AddCheck <ControllerResolveHealthCheck>(nameof(ControllerResolveHealthCheck));

            services.AddApiVersioning(options =>
            {
                options.AssumeDefaultVersionWhenUnspecified = false;
                options.DefaultApiVersion = new ApiVersion(1, 0);
                options.ReportApiVersions = true;
            });

            services.AddSwaggerGen(options =>
            {
                options.SwaggerDoc("v1.0", new OpenApiInfo {
                    Title = "HappyTravel.com Edo API", Version = "v1.0"
                });

                var xmlCommentsFileName = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
                var xmlCommentsFilePath = Path.Combine(AppContext.BaseDirectory, xmlCommentsFileName);
                options.IncludeXmlComments(xmlCommentsFilePath);
                options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
                {
                    Description = "JWT Authorization header using the Bearer scheme. Example: \"Authorization: Bearer {token}\"",
                    Name        = "Authorization",
                    In          = ParameterLocation.Header,
                    Type        = SecuritySchemeType.ApiKey
                });
                options.AddSecurityRequirement(new OpenApiSecurityRequirement()
                {
                    {
                        new OpenApiSecurityScheme
                        {
                            Reference = new OpenApiReference
                            {
                                Type = ReferenceType.SecurityScheme,
                                Id   = "Bearer"
                            },
                            Scheme = "oauth2",
                            Name   = "Bearer",
                            In     = ParameterLocation.Header,
                        },
                        Array.Empty <string>()
                    }
                });
            });
            services.AddSwaggerGenNewtonsoftSupport();

            services.AddOData();

            services.AddMvcCore(options =>
            {
                options.Conventions.Insert(0, new LocalizationConvention());
                options.Conventions.Add(new AuthorizeControllerModelConvention());
                options.Filters.Add(new MiddlewareFilterAttribute(typeof(LocalizationPipelineFilter)));
                options.Filters.Add(typeof(ModelValidationFilter));

                AddODataMediaTypes(options);
            })
            .AddAuthorization()
            .AddControllersAsServices()
            .AddMvcOptions(m => m.EnableEndpointRouting = true)
            .AddFormatterMappings()
            .AddNewtonsoftJson(options => options.SerializerSettings.Converters.Add(new StringEnumConverter()))
            .AddApiExplorer()
            .AddCacheTagHelper()
            .AddDataAnnotations();
        }
コード例 #9
0
        public void ConfigureServices(IServiceCollection services)
        {
            var serializationSettings = new JsonSerializerSettings
            {
                ContractResolver = new CamelCasePropertyNamesContractResolver(),
                Formatting       = Formatting.None
            };

            JsonConvert.DefaultSettings = () => serializationSettings;

            using var vaultClient = new VaultClient.VaultClient(new VaultOptions
            {
                BaseUrl = new Uri(EnvironmentVariableHelper.Get("Vault:Endpoint", Configuration)),
                Engine  = Configuration["Vault:Engine"],
                Role    = Configuration["Vault:Role"]
            });
            vaultClient.Login(EnvironmentVariableHelper.Get("Vault:Token", Configuration)).GetAwaiter().GetResult();

            services.AddMemoryCache()
            .AddStackExchangeRedisCache(options =>
            {
                options.Configuration = EnvironmentVariableHelper.Get("Redis:Endpoint", Configuration);
            })
            .AddDoubleFlow();

            services.ConfigureServiceOptions(Configuration, vaultClient)
            .AddServices();

            services.AddHealthChecks()
            .AddCheck <ControllerResolveHealthCheck>(nameof(ControllerResolveHealthCheck))
            .AddRedis(EnvironmentVariableHelper.Get("Redis:Endpoint", Configuration));

            services.AddResponseCompression()
            .AddHttpContextAccessor()
            .AddCors()
            .AddLocalization()
            .AddMemoryCache()
            .AddTracing(Configuration, options =>
            {
                options.ServiceName = $"{_environment.ApplicationName}-{_environment.EnvironmentName}";
                options.JaegerHost  = _environment.IsLocal()
                        ? Configuration.GetValue <string>("Jaeger:AgentHost")
                        : Configuration.GetValue <string>(Configuration.GetValue <string>("Jaeger:AgentHost"));
                options.JaegerPort = _environment.IsLocal()
                        ? Configuration.GetValue <int>("Jaeger:AgentPort")
                        : Configuration.GetValue <int>(Configuration.GetValue <string>("Jaeger:AgentPort"));
                options.RedisEndpoint = Configuration.GetValue <string>(Configuration.GetValue <string>("Redis:Endpoint"));
            });

            services.AddApiVersioning(options =>
            {
                options.AssumeDefaultVersionWhenUnspecified = false;
                options.DefaultApiVersion = new ApiVersion(1, 0);
                options.ReportApiVersions = true;
            });

            services.AddSwaggerGen(options =>
            {
                options.SwaggerDoc("v1.0",
                                   new OpenApiInfo {
                    Title = "HappyTravel.com Property Management System API", Version = "v1.0"
                });

                var apiXmlCommentsFilePath = Path.Combine(AppContext.BaseDirectory,
                                                          $"{Assembly.GetExecutingAssembly().GetName().Name}.xml");
                options.IncludeXmlComments(apiXmlCommentsFilePath);

                foreach (var assembly in Assembly.GetExecutingAssembly().GetReferencedAssemblies())
                {
                    var path = Path.Combine(AppContext.BaseDirectory, $"{assembly.Name}.xml");
                    if (File.Exists(path))
                    {
                        options.IncludeXmlComments(path);
                    }
                }

                options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
                {
                    Description = "JWT Authorization header using the Bearer scheme. Example: \"Authorization: Bearer {token}\"",
                    Name        = "Authorization",
                    In          = ParameterLocation.Header,
                    Type        = SecuritySchemeType.ApiKey
                });
                options.AddSecurityRequirement(new OpenApiSecurityRequirement
                {
                    {
                        new OpenApiSecurityScheme
                        {
                            Reference = new OpenApiReference
                            {
                                Type = ReferenceType.SecurityScheme,
                                Id   = "Bearer"
                            },
                            Scheme = "oauth2",
                            Name   = "Bearer",
                            In     = ParameterLocation.Header,
                        },
                        Array.Empty <string>()
                    }
                });
                options.CustomSchemaIds(t => t.ToString());
            });
            //  services.AddSwaggerGenNewtonsoftSupport();

            services.AddMvcCore()
            .AddFormatterMappings()
            .AddNewtonsoftJson()
            .AddApiExplorer()
            .AddCacheTagHelper()
            .AddControllersAsServices()
            .AddAuthorization(options =>
            {
                options.FallbackPolicy = new AuthorizationPolicyBuilder().RequireAuthenticatedUser().Build();
                options.AddPolicy("CanEdit", policy =>
                {
                    policy.RequireClaim("scope", "mapper.edit");
                });
            });

            services.AddTransient <ILocationMappingInfoService, LocationMappingInfoService>();
            services.AddTransient <ILocationMappingFactory, LocationMappingFactory>();
            services.AddTransient <CountryHtIdMappingService>();
            services.AddStaticDataPublicationServices(vaultClient, Configuration, _environment);
            services.AddProblemDetailsErrorHandling();
        }
コード例 #10
0
        public static IServiceCollection ConfigureServiceOptions(this IServiceCollection services,
                                                                 IConfiguration configuration, VaultClient.VaultClient vaultClient)
        {
            var databaseOptions = vaultClient.Get(configuration["Nakijin:Database:Options"]).GetAwaiter().GetResult();

            services.AddDbContext <NakijinContext>(options =>
            {
                var host     = databaseOptions["host"];
                var port     = databaseOptions["port"];
                var password = databaseOptions["password"];
                var userId   = databaseOptions["userId"];

                var connectionString = configuration.GetConnectionString("Nakijin");
                options.UseNpgsql(string.Format(connectionString, host, port, userId, password), builder =>
                {
                    builder.CommandTimeout(120);
                    builder.UseNetTopologySuite();
                    builder.EnableRetryOnFailure();
                });
                options.EnableSensitiveDataLogging(false);
                options.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking);
            }, ServiceLifetime.Singleton, ServiceLifetime.Singleton);

            services.Configure <StaticDataLoadingOptions>(o =>
            {
                var preloadingBatchSize =
                    EnvironmentVariableHelper.Get("Workers:StaticDataLoadingOptions:PreloadingBatchSize", configuration);
                var mappingBatchSize =
                    EnvironmentVariableHelper.Get("Workers:StaticDataLoadingOptions:MappingBatchSize", configuration);
                var dataCorrectionBatchSize =
                    EnvironmentVariableHelper.Get("Workers:StaticDataLoadingOptions:DataCorrectionBatchSize", configuration);
                var dbCommandTimeOut =
                    EnvironmentVariableHelper.Get("Workers:StaticDataLoadingOptions:DbCommandTimeOut", configuration);

                o.PreloadingBatchSize = string.IsNullOrWhiteSpace(preloadingBatchSize)
                    ? Models.Constants.DefaultPreloadingBatchSize
                    : int.Parse(preloadingBatchSize);
                o.MappingBatchSize = string.IsNullOrWhiteSpace(mappingBatchSize)
                    ? Models.Constants.DefaultMappingBatchSize
                    : int.Parse(mappingBatchSize);
                o.DataCorrectionBatchSize = string.IsNullOrWhiteSpace(dataCorrectionBatchSize)
                    ? Models.Constants.DefaultDataCorrectionBatchSize
                    : int.Parse(dataCorrectionBatchSize);
                o.DbCommandTimeOut = string.IsNullOrWhiteSpace(dbCommandTimeOut)
                    ? Models.Constants.DefaultDbCommandTimeOut
                    : int.Parse(dbCommandTimeOut);
            });

            services.Configure <UpdateOptions>(o =>
            {
                var workersToRun  = EnvironmentVariableHelper.Get("Workers:WorkersToRun", configuration);
                var supplierCodes = EnvironmentVariableHelper.Get("Workers:Suppliers", configuration);

                o.WorkersToRun = string.IsNullOrWhiteSpace(workersToRun)
                    ? Enum.GetValues(typeof(WorkerTypes))
                                 .Cast <WorkerTypes>()
                                 .Except(new WorkerTypes[] { WorkerTypes.None }).ToList()
                    : workersToRun.Split(';').Select(s => s.Trim()).Select(Enum.Parse <WorkerTypes>).ToList();

                o.Suppliers = string.IsNullOrWhiteSpace(supplierCodes)
                    ? null
                    : supplierCodes.Split(';').Select(s => s.Trim()).ToList();
            });

            services.Configure <MappingOptions>(o =>
            {
                var mappingMode = EnvironmentVariableHelper.Get("Workers:MappingOptions:MappingMode", configuration);
                o.Mode          = string.IsNullOrWhiteSpace(mappingMode)
                    ? MappingModes.Full
                    : Enum.Parse <MappingModes>(mappingMode);
            });

            services.Configure <DataCorrectionOptions>(o =>
            {
                var dataCorrectionMode = EnvironmentVariableHelper.Get("Workers:DataCorrectionOptions:DataCorrectionMode", configuration);
                o.Mode = string.IsNullOrWhiteSpace(dataCorrectionMode)
                    ? DataCorrectionModes.Full
                    : Enum.Parse <DataCorrectionModes>(dataCorrectionMode);
            });

            services.Configure <LocalityCollectionOptions>(o =>
            {
                var collectionMode = EnvironmentVariableHelper.Get("Workers:LocalityCollectionOptions:CollectionMode", configuration);
                o.CollectionMode   = string.IsNullOrWhiteSpace(collectionMode)
                    ? LocalityCollectionModes.Full
                    : Enum.Parse <LocalityCollectionModes>(collectionMode);
            });

            var clientOptions    = vaultClient.Get(configuration["Nakijin:Client:Options"]).GetAwaiter().GetResult();
            var authorityOptions = vaultClient.Get(configuration["Nakijin:Authority:Options"]).GetAwaiter().GetResult();
            var authorityUrl     = authorityOptions["authorityUrl"];

            services.AddAccessTokenManagement(options =>
            {
                options.Client.Clients.Add(HttpClientNames.Identity, new ClientCredentialsTokenRequest
                {
                    Address      = new Uri(new Uri(authorityUrl), "/connect/token").ToString(),
                    ClientId     = clientOptions["clientId"],
                    ClientSecret = clientOptions["clientSecret"],
                });
            });

            services.AddClientAccessTokenHttpClient(HttpClientNames.Connectors, configureClient: (Action <HttpClient>)null !);

            var suppliersEndpoint = configuration.GetValue <string>("Suppliers:Endpoint");

            services.AddSupplierOptionsClient(o
                                              => o.BaseEndpoint = suppliersEndpoint,
                                              HttpClientNames.Identity);

            return(services);
        }
コード例 #11
0
ファイル: Startup.cs プロジェクト: happy-travel/edo
        public void ConfigureServices(IServiceCollection services)
        {
            var serializationSettings = new JsonSerializerSettings
            {
                ContractResolver = new CamelCasePropertyNamesContractResolver(),
                Formatting       = Formatting.None
            };

            JsonConvert.DefaultSettings = () => serializationSettings;

            using var vaultClient = new VaultClient.VaultClient(new VaultOptions
            {
                BaseUrl = new Uri(EnvironmentVariableHelper.Get("Vault:Endpoint", Configuration)),
                Engine  = Configuration["Vault:Engine"],
                Role    = Configuration["Vault:Role"]
            });
            vaultClient.Login(EnvironmentVariableHelper.Get("Vault:Token", Configuration)).GetAwaiter().GetResult();

            services.AddResponseCompression()
            .AddCors()
            .AddLocalization()
            .AddMemoryCache()
            .AddMemoryFlow()
            .AddStackExchangeRedisCache(options =>
            {
                var host = EnvironmentVariableHelper.Get("Redis:Endpoint", Configuration);
                options.ConfigurationOptions = new ConfigurationOptions
                {
                    EndPoints    = { new DnsEndPoint(host, 6379) },
                    AsyncTimeout = 15000,     // set to 15 seconds before we stop storing large objects in Redis
                };
            })
            .AddDoubleFlow()
            .AddCacheFlowJsonSerialization()
            .AddTracing(Configuration, options =>
            {
                options.ServiceName = $"{HostingEnvironment.ApplicationName}-{HostingEnvironment.EnvironmentName}";
                options.JaegerHost  = HostingEnvironment.IsLocal()
                        ? Configuration.GetValue <string>("Jaeger:AgentHost")
                        : Configuration.GetValue <string>(Configuration.GetValue <string>("Jaeger:AgentHost"));
                options.JaegerPort = HostingEnvironment.IsLocal()
                        ? Configuration.GetValue <int>("Jaeger:AgentPort")
                        : Configuration.GetValue <int>(Configuration.GetValue <string>("Jaeger:AgentPort"));
                options.RedisEndpoint = Configuration.GetValue <string>(Configuration.GetValue <string>("Redis:Endpoint"));
            })
            .AddUserEventLogging(Configuration, vaultClient);

            var(apiName, authorityUrl) = GetApiNameAndAuthority(Configuration, HostingEnvironment, vaultClient);

            services.ConfigureServiceOptions(Configuration, HostingEnvironment, vaultClient)
            .ConfigureHttpClients(Configuration, HostingEnvironment, vaultClient, authorityUrl)
            .ConfigureAuthentication(Configuration, HostingEnvironment, apiName, authorityUrl)
            .AddServices(HostingEnvironment, Configuration, vaultClient);

            services.AddHealthChecks()
            .AddDbContextCheck <EdoContext>()
            .AddRedis(EnvironmentVariableHelper.Get("Redis:Endpoint", Configuration))
            .AddCheck <ControllerResolveHealthCheck>(nameof(ControllerResolveHealthCheck));

            services.AddProblemDetailsErrorHandling();

            services.AddApiVersioning(options =>
            {
                options.AssumeDefaultVersionWhenUnspecified = false;
                options.DefaultApiVersion = new ApiVersion(1, 0);
                options.ReportApiVersions = true;
            });

            services.AddSwaggerGen(options =>
            {
                options.SwaggerDoc("agent", new OpenApiInfo {
                    Title = "Happytravel.com Edo API for an agent app", Version = "v1.0"
                });
                options.SwaggerDoc("admin", new OpenApiInfo {
                    Title = "Happytravel.com Edo API for an admin app", Version = "v1.0"
                });
                options.SwaggerDoc("property-owner", new OpenApiInfo {
                    Title = "Happytravel.com Edo API for property owners", Version = "v1.0"
                });
                options.SwaggerDoc("service", new OpenApiInfo {
                    Title = "Happytravel.com service Edo API", Version = "v1.0"
                });

                var xmlCommentsFileName = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
                var xmlCommentsFilePath = Path.Combine(AppContext.BaseDirectory, xmlCommentsFileName);
                options.IncludeXmlComments(xmlCommentsFilePath);
                options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
                {
                    Description = "JWT Authorization header using the Bearer scheme. Example: \"Authorization: Bearer {token}\"",
                    Name        = "Authorization",
                    In          = ParameterLocation.Header,
                    Type        = SecuritySchemeType.ApiKey
                });
                options.AddSecurityRequirement(new OpenApiSecurityRequirement()
                {
                    {
                        new OpenApiSecurityScheme
                        {
                            Reference = new OpenApiReference
                            {
                                Type = ReferenceType.SecurityScheme,
                                Id   = "Bearer"
                            },
                            Scheme = "oauth2",
                            Name   = "Bearer",
                            In     = ParameterLocation.Header,
                        },
                        Array.Empty <string>()
                    }
                });
                // Use fully qualified object names
                options.CustomSchemaIds(x => x.FullName);
            });
            services.AddSwaggerGenNewtonsoftSupport();

            services.AddNotificationCenter(EnvironmentVariableHelper.Get("Redis:Endpoint", Configuration));

            services.AddMvcCore(options =>
            {
                options.Conventions.Insert(0, new LocalizationConvention());
                options.Conventions.Add(new AuthorizeControllerModelConvention());
                options.Conventions.Add(new ApiExplorerGroupPerVersionConvention());
                options.Filters.Add(new MiddlewareFilterAttribute(typeof(LocalizationPipelineFilter)));
                options.Filters.Add(typeof(ModelValidationFilter));

                AddODataMediaTypes(options);
            })
            .AddAuthorization()
            .AddControllersAsServices()
            .AddMvcOptions(m => m.EnableEndpointRouting = true)
            .AddFormatterMappings()
            .AddNewtonsoftJson(options => options.SerializerSettings.Converters.Add(new StringEnumConverter()))
            .AddApiExplorer()
            .AddCacheTagHelper()
            .AddDataAnnotations()
            .AddOData(opt => opt.Filter().Select().OrderBy().SetMaxTop(100));
        }
コード例 #12
0
        public static IServiceCollection ConfigureServiceOptions(this IServiceCollection services, IConfiguration configuration,
                                                                 IWebHostEnvironment environment, VaultClient.VaultClient vaultClient)
        {
            #region mailing setting

            var mailSettings = vaultClient.Get(configuration["Edo:Email:Options"]).GetAwaiter().GetResult();
            var edoPublicUrl = mailSettings[configuration["Edo:Email:EdoPublicUrl"]];

            var sendGridApiKey = mailSettings[configuration["Edo:Email:ApiKey"]];
            var senderAddress  = mailSettings[configuration["Edo:Email:SenderAddress"]];
            services.Configure <SenderOptions>(options =>
            {
                options.ApiKey        = sendGridApiKey;
                options.BaseUrl       = new Uri(edoPublicUrl);
                options.SenderAddress = new EmailAddress(senderAddress);
            });

            var agentInvitationTemplateId = mailSettings[configuration["Edo:Email:AgentInvitationTemplateId"]];
            services.Configure <AgentInvitationOptions>(options =>
            {
                options.MailTemplateId = agentInvitationTemplateId;
                options.EdoPublicUrl   = edoPublicUrl;
            });

            var administratorInvitationTemplateId = mailSettings[configuration["Edo:Email:AdministratorInvitationTemplateId"]];
            services.Configure <AdministratorInvitationOptions>(options =>
            {
                options.MailTemplateId = administratorInvitationTemplateId;
                options.EdoPublicUrl   = edoPublicUrl;
            });
            services.Configure <UserInvitationOptions>(options =>
                                                       options.InvitationExpirationPeriod = TimeSpan.FromDays(7));

            var administrators = JsonConvert.DeserializeObject <List <string> >(mailSettings[configuration["Edo:Email:Administrators"]]);
            var masterAgentRegistrationMailTemplateId  = mailSettings[configuration["Edo:Email:MasterAgentRegistrationTemplateId"]];
            var regularAgentRegistrationMailTemplateId = mailSettings[configuration["Edo:Email:RegularAgentRegistrationTemplateId"]];
            services.Configure <AgentRegistrationNotificationOptions>(options =>
            {
                options.AdministratorsEmails       = administrators;
                options.MasterAgentMailTemplateId  = masterAgentRegistrationMailTemplateId;
                options.RegularAgentMailTemplateId = regularAgentRegistrationMailTemplateId;
            });

            var bookingVoucherTemplateId               = mailSettings[configuration["Edo:Email:BookingVoucherTemplateId"]];
            var bookingInvoiceTemplateId               = mailSettings[configuration["Edo:Email:BookingInvoiceTemplateId"]];
            var bookingCancelledTemplateId             = mailSettings[configuration["Edo:Email:BookingCancelledTemplateId"]];
            var bookingFinalizedTemplateId             = mailSettings[configuration["Edo:Email:BookingFinalizedTemplateId"]];
            var bookingDeadlineNotificationTemplateId  = mailSettings[configuration["Edo:Email:BookingDeadlineNotificationTemplateId"]];
            var reservationsBookingFinalizedTemplateId = mailSettings[configuration["Edo:Email:ReservationsBookingFinalizedTemplateId"]];
            var reservationsBookingCancelledTemplateId = mailSettings[configuration["Edo:Email:ReservationsBookingCancelledTemplateId"]];
            var bookingSummaryTemplateId               = mailSettings[configuration["Edo:Email:BookingSummaryTemplateId"]];
            var bookingAdministratorSummaryTemplateId  = mailSettings[configuration["Edo:Email:BookingAdministratorSummaryTemplateId"]];
            var bookingPaymentsSummaryTemplateId       = mailSettings[configuration["Edo:Email:BookingAdministratorPaymentsSummaryTemplateId"]];
            var ccNotificationAddresses = JsonConvert.DeserializeObject <List <string> >(mailSettings[configuration["Edo:Email:CcNotificationAddresses"]]);
            var adminCreditCardPaymentConfirmationTemplateId = mailSettings[configuration["Edo:Email:AdminCreditCardPaymentConfirmationTemplateId"]];
            var agentCreditCardPaymentConfirmationTemplateId = mailSettings[configuration["Edo:Email:AgentCreditCardPaymentConfirmationTemplateId"]];
            services.Configure <BookingMailingOptions>(options =>
            {
                options.VoucherTemplateId                             = bookingVoucherTemplateId;
                options.InvoiceTemplateId                             = bookingInvoiceTemplateId;
                options.BookingCancelledTemplateId                    = bookingCancelledTemplateId;
                options.BookingFinalizedTemplateId                    = bookingFinalizedTemplateId;
                options.DeadlineNotificationTemplateId                = bookingDeadlineNotificationTemplateId;
                options.ReservationsBookingFinalizedTemplateId        = reservationsBookingFinalizedTemplateId;
                options.ReservationsBookingCancelledTemplateId        = reservationsBookingCancelledTemplateId;
                options.CcNotificationAddresses                       = ccNotificationAddresses;
                options.BookingSummaryTemplateId                      = bookingSummaryTemplateId;
                options.BookingAdministratorPaymentsSummaryTemplateId = bookingPaymentsSummaryTemplateId;
                options.BookingAdministratorSummaryTemplateId         = bookingAdministratorSummaryTemplateId;
                options.AdminCreditCardPaymentConfirmationTemplateId  = adminCreditCardPaymentConfirmationTemplateId;
                options.AgentCreditCardPaymentConfirmationTemplateId  = agentCreditCardPaymentConfirmationTemplateId;
            });

            var receiptTemplateId = mailSettings[configuration["Edo:Email:KnownCustomerReceiptTemplateId"]];
            services.Configure <PaymentNotificationOptions>(po => { po.ReceiptTemplateId = receiptTemplateId; });

            #endregion

            var databaseOptions = vaultClient.Get(configuration["Edo:Database:Options"]).GetAwaiter().GetResult();
            services.AddEntityFrameworkNpgsql().AddDbContextPool <EdoContext>(options =>
            {
                var host     = databaseOptions["host"];
                var port     = databaseOptions["port"];
                var password = databaseOptions["password"];
                var userId   = databaseOptions["userId"];

                var connectionString = configuration.GetConnectionString("Edo");
                options.UseNpgsql(string.Format(connectionString, host, port, userId, password), builder =>
                {
                    builder.UseNetTopologySuite();
                    builder.EnableRetryOnFailure();
                });
                options.EnableSensitiveDataLogging(false);
                options.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking);
            }, 16);

            var currencyConverterOptions = vaultClient.Get(configuration["CurrencyConverter:Options"]).GetAwaiter().GetResult();
            services.Configure <CurrencyRateServiceOptions>(o =>
            {
                var url = environment.IsLocal()
                    ? configuration["CurrencyConverter:Url"]
                    : currencyConverterOptions["url"];

                o.ServiceUrl = new Uri(url);

                var cacheLifeTimeMinutes = environment.IsLocal()
                    ? configuration["CurrencyConverter:CacheLifetimeInMinutes"]
                    : currencyConverterOptions["cacheLifetimeMinutes"];

                o.CacheLifeTime = TimeSpan.FromMinutes(int.Parse(cacheLifeTimeMinutes));
            });

            var supplierOptions = vaultClient.Get(configuration["Suppliers:Options"]).GetAwaiter().GetResult();
            services.Configure <SupplierOptions>(options =>
            {
                options.Netstorming = environment.IsLocal()
                    ? configuration["Suppliers:Netstorming"]
                    : supplierOptions["netstormingConnector"];

                options.Illusions = environment.IsLocal()
                    ? configuration["Suppliers:Illusions"]
                    : supplierOptions["illusions"];

                options.Etg = environment.IsLocal()
                    ? configuration["Suppliers:Etg"]
                    : supplierOptions["etg"];

                options.DirectContracts = environment.IsLocal()
                    ? configuration["Suppliers:DirectContracts"]
                    : supplierOptions["directContracts"];

                options.Rakuten = environment.IsLocal()
                    ? configuration["Suppliers:Rakuten"]
                    : supplierOptions["rakuten"];

                var enabledConnectors = environment.IsLocal()
                    ? configuration["Suppliers:EnabledConnectors"]
                    : supplierOptions["enabledConnectors"];

                options.EnabledSuppliers = enabledConnectors
                                           .Split(';')
                                           .Select(c => c.Trim())
                                           .Where(c => !string.IsNullOrWhiteSpace(c))
                                           .Select(Enum.Parse <Suppliers>)
                                           .ToList();
            });

            var googleOptions = vaultClient.Get(configuration["Edo:Google:Options"]).GetAwaiter().GetResult();
            services.Configure <GoogleOptions>(options => { options.ApiKey = googleOptions["apiKey"]; })
            .Configure <FlowOptions>(options =>
            {
                options.CacheKeyDelimiter = "::";
                options.CacheKeyPrefix    = "HappyTravel::Edo::Api";
            })
            .Configure <RequestLocalizationOptions>(options =>
            {
                options.DefaultRequestCulture = new RequestCulture("en");
                options.SupportedCultures     = new[]
                {
                    new CultureInfo("en"),
                    new CultureInfo("ar"),
                    new CultureInfo("ru")
                };

                options.RequestCultureProviders.Insert(0, new RouteDataRequestCultureProvider {
                    Options = options
                });
            });

            services.Configure <LocationServiceOptions>(o =>
            {
                o.IsGoogleGeoCoderDisabled = bool.TryParse(googleOptions["disabled"], out var disabled) && disabled;
            });

            var paymentLinksOptions = vaultClient.Get(configuration["PaymentLinks:Options"]).GetAwaiter().GetResult();
            var externalPaymentLinksMailTemplateId             = mailSettings[configuration["Edo:Email:ExternalPaymentsTemplateId"]];
            var externalPaymentLinksConfirmationMailTemplateId = mailSettings[configuration["Edo:Email:PaymentLinkPaymentConfirmation"]];
            services.Configure <PaymentLinkOptions>(options =>
            {
                options.ClientSettings = new ClientSettings
                {
                    Currencies = configuration.GetSection("PaymentLinks:Currencies")
                                 .Get <List <Currencies> >(),
                    ServiceTypes = configuration.GetSection("PaymentLinks:ServiceTypes")
                                   .Get <Dictionary <ServiceTypes, string> >()
                };
                options.LinkMailTemplateId = externalPaymentLinksMailTemplateId;
                options.PaymentConfirmationMailTemplateId = externalPaymentLinksConfirmationMailTemplateId;
                options.SupportedVersions = new List <Version> {
                    new Version(0, 2)
                };
                options.PaymentUrlPrefix = new Uri(paymentLinksOptions["endpoint"]);
            });

            var payfortOptions     = vaultClient.Get(configuration["Edo:Payfort:Options"]).GetAwaiter().GetResult();
            var payfortUrlsOptions = vaultClient.Get(configuration["Edo:Payfort:Urls"]).GetAwaiter().GetResult();
            services.Configure <PayfortOptions>(options =>
            {
                options.AccessCode        = payfortOptions["access-code"];
                options.Identifier        = payfortOptions["merchant-identifier"];
                options.ShaRequestPhrase  = payfortOptions["request-phrase"];
                options.ShaResponsePhrase = payfortOptions["response-phrase"];
                options.PaymentUrl        = payfortUrlsOptions["payment"];
                options.TokenizationUrl   = payfortUrlsOptions["tokenization"];
                options.ReturnUrl         = payfortUrlsOptions["return"];
                options.ResultUrl         = payfortUrlsOptions["result"];
            });

            var clientOptions = vaultClient.Get(configuration["Edo:Client:Options"]).GetAwaiter().GetResult();
            var(_, authorityUrl) = GetApiNameAndAuthority(configuration, environment, vaultClient);

            services.Configure <TokenRequestOptions>(options =>
            {
                var uri              = new Uri(new Uri(authorityUrl), "/connect/token");
                options.Address      = uri.ToString();
                options.ClientId     = clientOptions["clientId"];
                options.ClientSecret = clientOptions["clientSecret"];
                options.Scope        = clientOptions["scope"];
                options.GrantType    = OidcConstants.GrantTypes.ClientCredentials;
            });

            var commonBankDetails = vaultClient.Get(configuration["Edo:BankDetails:Options"]).GetAwaiter().GetResult();
            var aedAccountDetails = vaultClient.Get(configuration["Edo:BankDetails:AccountDetails:AED"]).GetAwaiter().GetResult();
            var eurAccountDetails = vaultClient.Get(configuration["Edo:BankDetails:AccountDetails:EUR"]).GetAwaiter().GetResult();
            var usdAccountDetails = vaultClient.Get(configuration["Edo:BankDetails:AccountDetails:USD"]).GetAwaiter().GetResult();

            services.Configure <BankDetails>(options =>
            {
                options.BankAddress = commonBankDetails["bankAddress"];
                options.BankName    = commonBankDetails["bankName"];
                options.CompanyName = commonBankDetails["companyName"];
                options.RoutingCode = commonBankDetails["routingCode"];
                options.SwiftCode   = commonBankDetails["swiftCode"];

                options.AccountDetails = new Dictionary <Currencies, BankDetails.CurrencySpecificData>
                {
                    {
                        Currencies.AED, new BankDetails.CurrencySpecificData
                        {
                            Iban          = aedAccountDetails["iban"],
                            AccountNumber = aedAccountDetails["accountNumber"]
                        }
                    },
                    {
                        Currencies.EUR, new BankDetails.CurrencySpecificData
                        {
                            Iban          = eurAccountDetails["iban"],
                            AccountNumber = eurAccountDetails["accountNumber"]
                        }
                    },
                    {
                        Currencies.USD, new BankDetails.CurrencySpecificData
                        {
                            Iban          = usdAccountDetails["iban"],
                            AccountNumber = usdAccountDetails["accountNumber"]
                        }
                    },
                };
            });

            var amazonS3DocumentsOptions = vaultClient.Get(configuration["AmazonS3:Options"]).GetAwaiter().GetResult();
            var contractsS3FolderName    = configuration["AmazonS3:ContractsS3FolderName"];
            var imagesS3FolderName       = configuration["AmazonS3:ImagesS3FolderName"];

            services.AddAmazonS3Client(options =>
            {
                options.AccessKeyId    = amazonS3DocumentsOptions["accessKeyId"];
                options.AccessKey      = amazonS3DocumentsOptions["accessKey"];
                options.AmazonS3Config = new AmazonS3Config
                {
                    RegionEndpoint = RegionEndpoint.GetBySystemName(amazonS3DocumentsOptions["regionEndpoint"])
                };
            });

            services.Configure <ContractFileServiceOptions>(options =>
            {
                options.Bucket       = amazonS3DocumentsOptions["bucket"];
                options.S3FolderName = contractsS3FolderName;
            });

            services.Configure <ImageFileServiceOptions>(options =>
            {
                options.Bucket       = amazonS3DocumentsOptions["bucket"];
                options.S3FolderName = imagesS3FolderName;
            });

            return(services);
        }
コード例 #13
0
        public static IServiceCollection AddStaticDataPublicationServices(this IServiceCollection services, VaultClient.VaultClient vaultClient, IConfiguration configuration, IWebHostEnvironment environment)
        {
            string endpoint;
            string port;
            string syncTimeout;

            if (environment.IsLocal())
            {
                endpoint    = configuration["StaticDataPublication:Redis:Endpoint"];
                port        = configuration["StaticDataPublication:Redis:Port"];
                syncTimeout = configuration["StaticDataPublication:Redis:SyncTimeout"];
            }
            else
            {
                var redisOptions = vaultClient.Get(configuration["StaticDataPublication:Redis"]).GetAwaiter().GetResult();
                endpoint    = redisOptions["endpoint"];
                port        = redisOptions["port"];
                syncTimeout = redisOptions["syncTimeout"];
            }

            var streamNames              = vaultClient.Get(configuration["StaticDataPublication:RedisStreams"]).GetAwaiter().GetResult();
            var countriesStreamName      = streamNames["CountriesStreamName"];
            var localitiesStreamName     = streamNames["LocalitiesStreamName"];
            var localityZonesStreamName  = streamNames["LocalityZonesStreamName"];
            var accommodationsStreamName = streamNames["AccommodationsStreamName"];

            services.AddStackExchangeRedisExtensions <StackExchangeRedisDefaultSerializer>(new RedisConfiguration
            {
                Hosts = new []
                {
                    new RedisHost
                    {
                        Host = endpoint,
                        Port = int.Parse(port)
                    }
                },
                SyncTimeout = int.Parse(syncTimeout)
            });

            services.Configure <StaticDataPublicationOptions>(o =>
            {
                o.CountriesStreamName      = countriesStreamName;
                o.LocalitiesStreamName     = localitiesStreamName;
                o.LocalityZonesStreamName  = localityZonesStreamName;
                o.AccommodationsStreamName = accommodationsStreamName;
            });

            services.AddSingleton <IStaticDataPublicationService, StaticDataPublicationService>();

            services.AddTransient <CountryChangePublisher>();
            services.AddTransient <LocalityChangePublisher>();
            services.AddTransient <LocalityZoneChangePublisher>();
            services.AddTransient <AccommodationChangePublisher>();

            return(services);
        }
コード例 #14
0
        public static IServiceCollection AddServices(this IServiceCollection services, IHostEnvironment environment, IConfiguration configuration, VaultClient.VaultClient vaultClient)
        {
            services.AddScoped <IdempotentFunctionExecutor>();
            services.AddScoped <IdempotentBookingExecutor>();

            services.AddSingleton(NtsGeometryServices.Instance.CreateGeometryFactory(GeoConstants.SpatialReferenceId));
            services.AddSingleton <IConnectionMultiplexer>(ConnectionMultiplexer.Connect(EnvironmentVariableHelper.Get("Redis:Endpoint", configuration)));
            services.AddSingleton <IDistributedLocker, RedisDistributedLocker>();

            services.AddTransient <IConnectorClient, ConnectorClient>();
            services.AddSingleton <IConnectorSecurityTokenManager, ConnectorSecurityTokenManager>();
            services.AddTransient <ICountryService, CountryService>();
            services.AddTransient <IGeoCoder, GoogleGeoCoder>();

            services.AddSingleton <IVersionService, VersionService>();

            services.AddTransient <ILocationService, LocationService>();
            services.AddTransient <IAgencyVerificationService, AgencyVerificationService>();

            services.AddTransient <Services.Agents.IAgentService, Services.Agents.AgentService>();
            services.AddTransient <IAgentRolesService, AgentRolesService>();
            services.AddTransient <IAgentRegistrationService, AgentRegistrationService>();
            services.AddTransient <IAccountPaymentService, AccountPaymentService>();
            services.AddTransient <IAgencyAccountService, AgencyAccountService>();
            services.AddTransient <IPaymentSettingsService, PaymentSettingsService>();
            services.AddTransient <IBookingOfflinePaymentService, BookingOfflinePaymentService>();
            services.AddTransient <IBookingCreditCardPaymentService, BookingCreditCardPaymentService>();
            services.AddTransient <IBookingAccountPaymentService, BookingAccountPaymentService>();
            services.AddTransient <IBookingPaymentCallbackService, BookingPaymentCallbackService>();

            services.AddScoped <IAgentContextService, HttpBasedAgentContextService>();
            services.AddScoped <IAgentContextInternal, HttpBasedAgentContextService>();
            services.AddHttpContextAccessor();
            services.AddSingleton <IDateTimeProvider, DefaultDateTimeProvider>();
            services.AddTransient <IBookingRecordManager, BookingRecordManager>();
            services.AddTransient <ITagProcessor, TagProcessor>();

            services.AddSingleton <IMailSender, SendGridMailSender>();
            services.AddSingleton <ITokenInfoAccessor, TokenInfoAccessor>();
            services.AddSingleton <IIdentityUserInfoService, IdentityUserInfoService>();
            services.AddTransient <IAccountBalanceAuditService, AccountBalanceAuditService>();
            services.AddTransient <ICreditCardAuditService, CreditCardAuditService>();
            services.AddTransient <IOfflinePaymentAuditService, OfflinePaymentAuditService>();

            services.AddTransient <IAccountManagementService, AccountManagementService>();
            services.AddTransient <IAdministratorService, AdministratorService>();
            services.AddTransient <IAdministratorRolesManagementService, AdministratorRolesManagementService>();
            services.AddTransient <IAdministratorManagementService, AdministratorManagementService>();
            services.AddTransient <IAgentRolesManagementService, AgentRolesManagementService>();
            services.AddScoped <IAdministratorContext, HttpBasedAdministratorContext>();
            services.AddScoped <IServiceAccountContext, HttpBasedServiceAccountContext>();

            services.AddTransient <IInvitationRecordService, InvitationRecordService>();
            services.AddTransient <IAgentInvitationRecordListService, AgentInvitationRecordListService>();
            services.AddTransient <IAgentInvitationAcceptService, AgentInvitationAcceptService>();
            services.AddTransient <IAdminInvitationAcceptService, AdminInvitationAcceptService>();
            services.AddTransient <IAgentInvitationCreateService, AgentInvitationCreateService>();
            services.AddTransient <IAdminInvitationCreateService, AdminInvitationCreateService>();

            services.AddTransient <IExternalAdminContext, ExternalAdminContext>();

            services.AddScoped <IManagementAuditService, ManagementAuditService>();

            services.AddScoped <IEntityLocker, EntityLocker>();
            services.AddTransient <IAccountPaymentProcessingService, AccountPaymentProcessingService>();

            services.AddTransient <IPayfortService, PayfortService>();
            services.AddTransient <ICreditCardsManagementService, CreditCardsManagementService>();
            services.AddTransient <IPayfortSignatureService, PayfortSignatureService>();

            services.AddTransient <IMarkupPolicyService, MarkupPolicyService>();
            services.AddTransient <IMarkupService, MarkupService>();
            services.AddTransient <IDiscountFunctionService, DiscountFunctionService>();

            services.AddTransient <IDisplayedMarkupFormulaService, DisplayedMarkupFormulaService>();
            services.AddTransient <IMarkupBonusMaterializationService, MarkupBonusMaterializationService>();
            services.AddTransient <IMarkupBonusDisplayService, MarkupBonusDisplayService>();

            services.AddSingleton <IMarkupPolicyTemplateService, MarkupPolicyTemplateService>();
            services.AddScoped <IAgentMarkupPolicyManager, AgentMarkupPolicyManager>();
            services.AddScoped <IAgencyMarkupPolicyManager, AgencyMarkupPolicyManager>();
            services.AddTransient <IMarkupPolicyAuditService, MarkupPolicyAuditService>();
            services.AddScoped <IAdminMarkupPolicyManager, AdminMarkupPolicyManager>();

            services.AddTransient <IAgencyDiscountManagementService, AgencyDiscountManagementService>();

            services.AddScoped <ICurrencyRateService, CurrencyRateService>();
            services.AddScoped <ICurrencyConverterService, CurrencyConverterService>();

            services.AddTransient <ISupplierOrderService, SupplierOrderService>();

            services.AddSingleton <IJsonSerializer, NewtonsoftJsonSerializer>();
            services.AddTransient <IAgentSettingsManager, AgentSettingsManager>();
            services.AddTransient <IAgentStatusManagementService, AgentStatusManagementService>();

            services.AddTransient <IPaymentLinkService, PaymentLinkService>();
            services.AddTransient <IPaymentLinksProcessingService, PaymentLinksProcessingService>();
            services.AddTransient <IPaymentLinksStorage, PaymentLinksStorage>();
            services.AddTransient <IPaymentCallbackDispatcher, PaymentCallbackDispatcher>();
            services.AddTransient <IAgentRolesAssignmentService, AgentRolesAssignmentService>();
            services.AddTransient <IPermissionChecker, PermissionChecker>();

            services.AddTransient <IBookingNotificationService, BookingNotificationService>();
            services.AddTransient <IBookingDocumentsMailingService, BookingDocumentsMailingService>();
            services.AddTransient <IBookingReportsService, BookingReportsService>();

            services.AddTransient <IPaymentHistoryService, PaymentHistoryService>();
            services.AddTransient <IBookingDocumentsService, BookingDocumentsService>();
            services.AddTransient <IBookingAuditLogService, BookingAuditLogService>();
            services.AddSingleton <ISupplierConnectorManager, SupplierConnectorManager>();
            services.AddTransient <IWideAvailabilitySearchService, WideAvailabilitySearchService>();
            services.AddTransient <IWideAvailabilityPriceProcessor, WideAvailabilityPriceProcessor>();
            services.AddTransient <IWideAvailabilityAccommodationsStorage, WideAvailabilityAccommodationsStorage>();

            services.AddTransient <IRoomSelectionService, RoomSelectionService>();
            services.AddTransient <IRoomSelectionPriceProcessor, RoomSelectionPriceProcessor>();

            services.AddTransient <IBookingEvaluationService, BookingEvaluationService>();
            services.AddTransient <IBookingEvaluationPriceProcessor, BookingEvaluationPriceProcessor>();

            services.AddTransient <ISupplierBookingManagementService, SupplierBookingManagementService>();
            services.AddTransient <IFinancialAccountBookingFlow, FinancialAccountBookingFlow>();
            services.AddTransient <IBankCreditCardBookingFlow, BankCreditCardBookingFlow>();
            services.AddTransient <IOfflinePaymentBookingFlow, OfflinePaymentBookingFlow>();
            services.AddTransient <IBookingInfoService, BookingInfoService>();
            services.AddTransient <IBookingRequestExecutor, BookingRequestExecutor>();
            services.AddTransient <IBookingRequestStorage, BookingRequestStorage>();
            services.AddTransient <IBookingResponseProcessor, BookingResponseProcessor>();

            services.AddTransient <IBookingRecordsUpdater, BookingRecordsUpdater>();
            services.AddTransient <IBookingRegistrationService, BookingRegistrationService>();
            services.AddTransient <IBookingChangeLogService, BookingChangeLogService>();

            services.AddTransient <IBookingMoneyReturnService, BookingMoneyReturnService>();
            services.AddTransient <IBookingsProcessingService, BookingsProcessingService>();
            services.AddTransient <IDeadlineService, DeadlineService>();
            services.AddTransient <IAppliedBookingMarkupRecordsManager, AppliedBookingMarkupRecordsManager>();

            services.AddTransient <IAgentBookingDocumentsService, AgentBookingDocumentsService>();

            services.AddSingleton <IAuthorizationPolicyProvider, CustomAuthorizationPolicyProvider>();
            services.AddTransient <IAuthorizationHandler, InAgencyPermissionAuthorizationHandler>();
            services.AddTransient <IAuthorizationHandler, MinAgencyVerificationStateAuthorizationHandler>();
            services.AddTransient <IAuthorizationHandler, AdministratorPermissionsAuthorizationHandler>();
            services.AddTransient <IAuthorizationHandler, AgentRequiredAuthorizationHandler>();
            services.AddTransient <IAuthorizationHandler, ServiceAccountRequiredAuthorizationHandler>();

            services.AddTransient <ICreditCardPaymentProcessingService, CreditCardPaymentProcessingService>();
            services.AddTransient <ICreditCardMoneyAuthorizationService, CreditCardMoneyAuthorizationService>();
            services.AddTransient <ICreditCardMoneyCaptureService, CreditCardMoneyCaptureService>();
            services.AddTransient <ICreditCardMoneyRefundService, CreditCardMoneyRefundService>();
            services.AddTransient <IPayfortResponseParser, PayfortResponseParser>();
            services.AddTransient <ICreditCardPaymentConfirmationService, CreditCardPaymentConfirmationService>();

            services.AddTransient <ICompanyService, CompanyService>();
            services.AddTransient <MailSenderWithCompanyInfo>();

            // Default behaviour allows not authenticated requests to be checked by authorization policies.
            // Special wrapper returns Forbid result for them.
            // More information: https://github.com/dotnet/aspnetcore/issues/4656
            services.AddTransient <IPolicyEvaluator, ForbidUnauthenticatedPolicyEvaluator>();
            // Default policy evaluator needs to be registered as dependency of ForbidUnauthenticatedPolicyEvaluator.
            services.AddTransient <PolicyEvaluator>();

            services.AddTransient <NetstormingResponseService>();
            services.AddTransient <WebhookResponseService>();

            services.AddNameNormalizationServices();

            services.AddTransient <IMultiProviderAvailabilityStorage, MultiProviderAvailabilityStorage>();
            services.AddTransient <IWideAvailabilitySearchStateStorage, WideAvailabilitySearchStateStorage>();
            services.AddTransient <IRoomSelectionStorage, RoomSelectionStorage>();

            var isUseMongoDbStorage = configuration.GetValue <bool>("WideAvailabilityStorage:UseMongoDbStorage");

            if (isUseMongoDbStorage)
            {
                services.AddMongoDbStorage(environment, configuration, vaultClient);
                services.AddTransient <IWideAvailabilityStorage, MongoDbWideAvailabilityStorage>();
            }
            else
            {
                services.AddTransient <IWideAvailabilityStorage, RedisWideAvailabilityStorage>();
            }

            services.AddTransient <IBookingEvaluationStorage, BookingEvaluationStorage>();

            services.AddTransient <IRootAgencySystemSettingsService, RootAgencySystemSettingsService>();

            services.AddTransient <IPriceProcessor, PriceProcessor>();

            services.AddTransient <IInvoiceService, InvoiceService>();
            services.AddTransient <IReceiptService, ReceiptService>();
            services.AddTransient <IPaymentDocumentsStorage, PaymentDocumentsStorage>();
            services.AddTransient <IPaymentLinkNotificationService, PaymentLinkNotificationService>();

            services.AddTransient <AdministratorServices.IAgentService, AdministratorServices.AgentService>();
            services.AddTransient <IAgentSystemSettingsService, AgentSystemSettingsService>();
            services.AddTransient <IAgencySystemSettingsService, AgencySystemSettingsService>();

            services.AddTransient <IAgentSystemSettingsManagementService, AgentSystemSettingsManagementService>();
            services.AddTransient <IAgencySystemSettingsManagementService, AgencySystemSettingsManagementService>();

            services.AddTransient <IBookingService, BookingService>();
            services.AddTransient <IAccommodationBookingSettingsService, AccommodationBookingSettingsService>();

            services.AddTransient <IContractFileManagementService, ContractFileManagementService>();
            services.AddTransient <IContractFileService, ContractFileService>();
            services.AddTransient <IImageFileService, ImageFileService>();

            services.AddTransient <IAnalyticsService, ElasticAnalyticsService>();
            services.AddTransient <IBookingAnalyticsService, BookingAnalyticsService>();
            services.AddTransient <IAgentMovementService, AgentMovementService>();

            services.AddTransient <IAgentBookingManagementService, AgentBookingManagementService>();
            services.AddTransient <IAdministratorBookingManagementService, AdministratorBookingManagementService>();
            services.AddTransient <IBookingStatusRefreshService, BookingStatusRefreshService>();

            services.AddTransient <IApiClientManagementService, ApiClientManagementService>();
            services.AddTransient <IAccommodationMapperClient, AccommodationMapperClient>();
            services.AddTransient <IMapperManagementClient, MapperManagementClient>();
            services.AddTransient <IAvailabilitySearchAreaService, AvailabilitySearchAreaService>();

            services.AddTransient <IAdminAgencyManagementService, AdminAgencyManagementService>();
            services.AddTransient <IAgencyManagementService, AgencyManagementService>();
            services.AddTransient <IChildAgencyService, ChildAgencyService>();
            services.AddTransient <IAgencyService, AgencyService>();

            services.AddTransient <IAgencyRemovalService, AgencyRemovalService>();
            services.AddTransient <IAgentRemovalService, AgentRemovalService>();

            services.AddTransient <IApiClientService, ApiClientService>();
            services.AddTransient <IReportService, ReportService>();

            services.AddTransient <IAdministratorRolesAssignmentService, AdministratorRolesAssignmentService>();

            services.AddTransient <IConverter <AgencyWiseRecordData, AgencyWiseReportRow>, AgencyWiseRecordDataConverter>();
            services.AddTransient <IConverter <PayableToSupplierRecordData, PayableToSupplierReportRow>, PayableToSupplierRecordDataConverter>();
            services.AddTransient <IConverter <FullBookingsReportData, FullBookingsReportRow>, FullBookingsReportDataConverter>();
            services.AddTransient <IConverter <FinalizedBookingsReportData, FinalizedBookingsReportRow>, FinalizedBookingsReportDataConverter>();
            services.AddTransient <IConverter <HotelWiseData, HotelWiseRow>, HotelWiseBookingReportDataConverter>();
            services.AddTransient <IRecordManager <AgencyWiseRecordData>, AgencyWiseRecordManager>();
            services.AddTransient <IRecordManager <PayableToSupplierRecordData>, PayableToSupplierRecordsManager>();
            services.AddTransient <IRecordManager <FullBookingsReportData>, FullBookingsRecordManager>();
            services.AddTransient <IRecordManager <FinalizedBookingsReportData>, FinalizedBookingsRecordManager>();
            services.AddTransient <IConverter <AgencyWiseRecordData, AgencyWiseReportRow>, AgencyWiseRecordDataConverter>();
            services.AddTransient <IConverter <PayableToSupplierRecordData, PayableToSupplierReportRow>, PayableToSupplierRecordDataConverter>();
            services.AddTransient <IConverter <FullBookingsReportData, FullBookingsReportRow>, FullBookingsReportDataConverter>();
            services.AddTransient <IConverter <PendingSupplierReferenceData, PendingSupplierReferenceRow>, PendingSupplierReferenceProjectionConverter>();
            services.AddTransient <IConverter <ConfirmedBookingsData, ConfirmedBookingsRow>, ConfirmedBookingsConverter>();
            services.AddTransient <IConverter <VccBookingData, VccBookingRow>, VccBookingDataConverter>();
            services.AddTransient <IConverter <AgentWiseReportData, AgentWiseReportRow>, AgentWiseRecordDataConverter>();
            services.AddTransient <IRecordManager <AgencyWiseRecordData>, AgencyWiseRecordManager>();
            services.AddTransient <IRecordManager <PayableToSupplierRecordData>, PayableToSupplierRecordsManager>();
            services.AddTransient <IRecordManager <FullBookingsReportData>, FullBookingsRecordManager>();
            services.AddTransient <IRecordManager <PendingSupplierReferenceData>, PendingSupplierReferenceRecordManager>();
            services.AddTransient <IRecordManager <ConfirmedBookingsData>, ConfirmedBookingsRecordManager>();
            services.AddTransient <IRecordManager <AgencyProductivity>, AgenciesProductivityRecordManager>();
            services.AddTransient <IRecordManager <HotelWiseData>, HotelWiseRecordManager>();
            services.AddTransient <IRecordManager <CancellationDeadlineData>, CancellationDeadlineReportManager>();
            services.AddTransient <IRecordManager <ThirdPartySupplierData>, ThirdPartySuppliersReportManager>();
            services.AddTransient <IRecordManager <VccBookingData>, VccBookingRecordManager>();
            services.AddTransient <IRecordManager <AgentWiseReportData>, AgentWiseRecordManager>();
            services.AddTransient <IRecordManager <HotelProductivityData>, HotelProductivityRecordManager>();
            services.AddTransient <IRecordManager <CancelledBookingsReportData>, CancelledBookingsReportRecordManager>();
            services.AddTransient <IFixHtIdService, FixHtIdService>();

            services.AddTransient <IBookingConfirmationService, BookingConfirmationService>();
            services.AddTransient <IPropertyOwnerConfirmationUrlGenerator, PropertyOwnerConfirmationUrlGenerator>();
            services.AddTransient <INGeniusClient, NGeniusClient>();
            services.AddTransient <INGeniusPaymentService, NGeniusPaymentService>();
            services.AddTransient <NGeniusWebhookProcessingService>();
            services.AddTransient <INGeniusRefundService, NGeniusRefundService>();
            services.AddTransient <ICreditCardPaymentManagementService, CreditCardPaymentManagementService>();
            services.AddTransient <IBalanceNotificationsManagementService, BalanceNotificationsManagementService>();
            services.AddTransient <IBalanceManagementNotificationsService, BalanceManagementNotificationsService>();
            services.AddHostedService <MarkupPolicyStorageUpdater>();
            services.AddHostedService <DiscountStorageUpdater>();
            services.AddSingleton <IMarkupPolicyStorage, MarkupPolicyStorage>();
            services.AddSingleton <IDiscountStorage, DiscountStorage>();
            services.AddTransient <ILocalityInfoService, LocalityInfoService>();
            services.AddTransient <IDirectApiClientManagementService, DirectApiClientManagementService>();
            services.AddTransient <IAvailabilityRequestStorage, AvailabilityRequestStorage>();

            services.AddCreditCardProvider(configuration, vaultClient);

            //TODO: move to Consul when it will be ready
            services.AddCurrencyConversionFactory(new List <BufferPair>
            {
                new()
                {
                    BufferValue    = decimal.Zero,
                    SourceCurrency = Currencies.AED,
                    TargetCurrency = Currencies.USD
                },
                new()
                {
                    BufferValue    = decimal.Zero,
                    SourceCurrency = Currencies.USD,
                    TargetCurrency = Currencies.AED
                }
            });
コード例 #15
0
        public static IServiceCollection ConfigureServiceOptions(this IServiceCollection services, IConfiguration configuration,
                                                                 IHostEnvironment environment, VaultClient.VaultClient vaultClient)
        {
            #region mailing setting

            var mailSettings           = vaultClient.Get(configuration["Edo:Email:Options"]).GetAwaiter().GetResult();
            var edoAgentAppFrontendUrl = mailSettings[configuration["Edo:Email:EdoAgentAppFrontendUrl"]];

            var sendGridApiKey = mailSettings[configuration["Edo:Email:ApiKey"]];
            var senderAddress  = mailSettings[configuration["Edo:Email:SenderAddress"]];
            services.Configure <SenderOptions>(options =>
            {
                options.ApiKey        = sendGridApiKey;
                options.BaseUrl       = new Uri(edoAgentAppFrontendUrl);
                options.SenderAddress = new EmailAddress(senderAddress);
            });

            var edoManagementFrontendUrl = mailSettings[configuration["Edo:Email:EdoManagementFrontendUrl"]];
            services.Configure <AdminInvitationMailOptions>(options =>
            {
                options.FrontendBaseUrl = edoManagementFrontendUrl;
            });

            var administrators = JsonConvert.DeserializeObject <List <string> >(mailSettings[configuration["Edo:Email:Administrators"]]);
            services.Configure <AgentRegistrationNotificationOptions>(options =>
            {
                options.AdministratorsEmails = administrators;
            });

            var ccNotificationAddresses = JsonConvert.DeserializeObject <List <string> >(mailSettings[configuration["Edo:Email:CcNotificationAddresses"]]);
            services.Configure <BookingMailingOptions>(options =>
            {
                options.CcNotificationAddresses = ccNotificationAddresses;
            });

            var reservationsOfficeBackupEmail = mailSettings[configuration["Edo:Email:ReservationsOfficeBackupEmail"]];
            services.Configure <PropertyOwnerMailingOptions>(options =>
            {
                options.ReservationsOfficeBackupEmail = reservationsOfficeBackupEmail;
            });

            var happyTravelAccountsEmail = mailSettings[configuration["Edo:Email:HappyTravelAccountsEmail"]];
            services.Configure <BalanceManagementNotificationsOptions>(options =>
            {
                options.AccountsEmail = happyTravelAccountsEmail;
            });
            #endregion

            #region tag processing options

            services.Configure <TagProcessingOptions>(configuration.GetSection("TagProcessing"));

            #endregion

            services.Configure <BookingStatusUpdateOptions>(configuration.GetSection("BookingStatusUpdate"));

            var databaseOptions = vaultClient.Get(configuration["Edo:Database:Options"]).GetAwaiter().GetResult();
            services.AddEntityFrameworkNpgsql().AddDbContextPool <EdoContext>(options =>
            {
                var host     = databaseOptions["host"];
                var port     = databaseOptions["port"];
                var password = databaseOptions["password"];
                var userId   = databaseOptions["userId"];

                var connectionString = configuration.GetConnectionString("Edo");
                options.UseNpgsql(string.Format(connectionString, host, port, userId, password), builder =>
                {
                    builder.UseNetTopologySuite();
                    builder.EnableRetryOnFailure();
                });
                options.EnableSensitiveDataLogging(false);
                options.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking);
            }, 16);

            services.Configure <CurrencyRateServiceOptions>(configuration.GetSection("CurrencyConverter"));

            services.Configure <SupplierOptions>(configuration.GetSection("Suppliers"));

            var googleOptions = vaultClient.Get(configuration["Edo:Google:Options"]).GetAwaiter().GetResult();
            services.Configure <GoogleOptions>(options => { options.ApiKey = googleOptions["apiKey"]; })
            .Configure <FlowOptions>(options =>
            {
                options.CacheKeyDelimiter = "::";
                options.CacheKeyPrefix    = "HappyTravel::Edo::Api";
            })
            .Configure <RequestLocalizationOptions>(options =>
            {
                options.DefaultRequestCulture = new RequestCulture("en");
                options.SupportedCultures     = new[]
                {
                    new CultureInfo("en"),
                    new CultureInfo("ar"),
                    new CultureInfo("ru")
                };

                options.RequestCultureProviders.Insert(0, new RouteDataRequestCultureProvider {
                    Options = options
                });
            });

            services.Configure <LocationServiceOptions>(o =>
            {
                o.IsGoogleGeoCoderDisabled = bool.TryParse(googleOptions["disabled"], out var disabled) && disabled;
            });

            var paymentLinksOptions = vaultClient.Get(configuration["PaymentLinks:Options"]).GetAwaiter().GetResult();
            services.Configure <PaymentLinkOptions>(options =>
            {
                options.ClientSettings = new ClientSettings
                {
                    Currencies = configuration.GetSection("PaymentLinks:Currencies")
                                 .Get <List <Currencies> >(),
                    ServiceTypes = configuration.GetSection("PaymentLinks:ServiceTypes")
                                   .Get <Dictionary <ServiceTypes, string> >()
                };
                options.SupportedVersions = new List <Version> {
                    new Version(0, 2)
                };
                options.PaymentUrlPrefix = new Uri(paymentLinksOptions["endpoint"]);
            });

            var payfortOptions     = vaultClient.Get(configuration["Edo:Payfort:Options"]).GetAwaiter().GetResult();
            var payfortUrlsOptions = vaultClient.Get(configuration["Edo:Payfort:Urls"]).GetAwaiter().GetResult();
            services.Configure <PayfortOptions>(options =>
            {
                options.AccessCode        = payfortOptions["access-code"];
                options.Identifier        = payfortOptions["merchant-identifier"];
                options.ShaRequestPhrase  = payfortOptions["request-phrase"];
                options.ShaResponsePhrase = payfortOptions["response-phrase"];
                options.PaymentUrl        = payfortUrlsOptions["payment"];
                options.TokenizationUrl   = payfortUrlsOptions["tokenization"];
                options.ReturnUrl         = payfortUrlsOptions["return"];
                options.ResultUrl         = payfortUrlsOptions["result"];
            });

            services.Configure <BankDetails>(configuration.GetSection("BankDetails"));

            var amazonS3DocumentsOptions = vaultClient.Get(configuration["AmazonS3:Options"]).GetAwaiter().GetResult();
            var contractsS3FolderName    = configuration["AmazonS3:ContractsS3FolderName"];
            var imagesS3FolderName       = configuration["AmazonS3:ImagesS3FolderName"];

            services.AddAmazonS3Client(options =>
            {
                options.AccessKeyId    = amazonS3DocumentsOptions["accessKeyId"];
                options.SecretKey      = amazonS3DocumentsOptions["accessKey"];
                options.AmazonS3Config = new AmazonS3Config
                {
                    RegionEndpoint = RegionEndpoint.GetBySystemName(amazonS3DocumentsOptions["regionEndpoint"])
                };
            });

            services.Configure <ContractFileServiceOptions>(options =>
            {
                options.Bucket       = amazonS3DocumentsOptions["bucket"];
                options.S3FolderName = contractsS3FolderName;
            });

            services.Configure <ImageFileServiceOptions>(options =>
            {
                options.Bucket       = amazonS3DocumentsOptions["bucket"];
                options.S3FolderName = imagesS3FolderName;
            });

            var urlGenerationOptions = vaultClient.Get(configuration["UrlGeneration:Options"]).GetAwaiter().GetResult();
            services.Configure <UrlGenerationOptions>(options =>
            {
                options.ConfirmationPageUrl = urlGenerationOptions["confirmationPageUrl"];
                options.AesKey = Convert.FromBase64String(urlGenerationOptions["aesKey"]);
                options.AesIV  = Convert.FromBase64String(urlGenerationOptions["aesIV"]);
            });

            services.Configure <PaymentProcessorOption>(configuration.GetSection("PaymentProcessor"));
            services.Configure <MarkupPolicyStorageOptions>(configuration.GetSection("MarkupPolicyStorageOptions"));
            services.Configure <DiscountStorageOptions>(configuration.GetSection("DiscountStorageOptions"));

            #region Configure NGenius

            var nGeniusOptions = vaultClient.Get(configuration["Edo:NGenius"]).GetAwaiter().GetResult();
            services.Configure <NGeniusOptions>(options =>
            {
                options.ApiKey  = nGeniusOptions["apiKey"];
                options.Host    = nGeniusOptions["host"];
                options.Outlets = new Dictionary <Currencies, string>
                {
                    { Currencies.USD, nGeniusOptions["usd"] },
                    { Currencies.AED, nGeniusOptions["aed"] }
                };
            });

            services.AddHttpClient(HttpClientNames.NGenius, c => { c.BaseAddress = new Uri(nGeniusOptions["host"]); })
            .SetHandlerLifetime(TimeSpan.FromMinutes(5))
            .AddPolicyHandler(GetDefaultRetryPolicy());

            #endregion

            return(services);
        }