Esempio n. 1
0
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies());
            services.AddMediatR(Assembly.GetExecutingAssembly());

            services.AddApplicationServices(Configuration, _env, _logger);

            string ApiEndpointAuth = Configuration.GetValue <string>(ConstatCsro.EndPoints.ApiEndpointAuth);

            services.AddHttpClient(Core.ConstatCsro.EndPoints.ApiEndpointAuth, (client) =>
            {
                client.Timeout     = TimeSpan.FromMinutes(ConstatCsro.ClientNames.API_TimeOut_Mins);
                client.BaseAddress = new Uri(ApiEndpointAuth);
                client.DefaultRequestHeaders.Add("Accept", "application/json");
            }).ConfigurePrimaryHttpMessageHandler(() =>
            {
                return(new HttpClientHandler()
                {
                    AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip | DecompressionMethods.Brotli,
                    UseCookies = false
                });
            })
            .SetHandlerLifetime(TimeSpan.FromMinutes(5))
            .AddPolicyHandler(PollyHelper.GetRetryPolicy())
            .AddPolicyHandler(PollyHelper.GetRetryPolicy());
            ;

            #region Auth

            services.AddAuthorization(options =>
            {
                // By default, all incoming requests will be authorized according to the default policy
                //Will automatical sign in user
                //options.FallbackPolicy = options.DefaultPolicy;

                options.AddPolicy(PoliciesCsro.CanApproveAdoRequestPolicy, policy => policy.RequireClaim(ClaimTypesCsro.CanApproveAdoRequestClaim, true.ToString()));
            });

            //TODO replace with rest or GRPC service
            services.AddScoped <IRestUserService, RestUserService>();
            services.AddScoped <IClaimsTransformation, ClaimsTransformation>();

            #endregion

            services.AddApplicationInsightsTelemetry();
            services.AddControllers();
            services.AddMvc(options =>
            {
                options.Filters.Add(new CsroValidationFilter());
            })
            .AddFluentValidation(options =>
            {
                //options.RegisterValidatorsFromAssemblyContaining<Startup>();
                options.RegisterValidatorsFromAssemblyContaining <Validation.BaseAdoAbstractValidator>();
            });


            services.AddScoped <IApiIdentity, ApiIdentity>();
            services.AddScoped <IEmailService, EmailService>();
            services.AddSingleton <IMessageBus, AzServiceBusMessageBus>();

            services.AddTransient <IProjectAdoServices, ProjectAdoServices>();
            services.AddTransient <IProcessAdoServices, ProcessAdoServices>();
            services.AddSingleton <ICacheProvider, CacheProvider>(); //testing
            services.AddTransient <IPropertyMappingService, AdoPropertyMappingService>();

            //services.AddSingleton<IServiceBusConsumer, AzServiceBusConsumer>();

            services.AddScoped <IAdoProjectApproverService, AdoProjectApproverService>();
            services.AddScoped <IGenerateEmailForApprovalService, GenerateEmailForApprovalService>();
            services.AddScoped <IAdoProjectAccessRepository, AdoProjectAccessRepository>();

            //services.AddControllers(options => options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute()));
            services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc("v1", new OpenApiInfo {
                    Title = _namespace, Version = "v1"
                });
            });

            #region DbContext

            DbTypeEnum DbTypeEnum = DbTypeEnum.Unknown;
            try
            {
                DbTypeEnum = Configuration.GetValue <DbTypeEnum>(nameof(DbTypeEnum));
            }
            catch { }

            services.AddDbContext <AdoContext>(options =>
            {
                if (DbTypeEnum == DbTypeEnum.SqlLite)
                {
                    options.UseSqlite(Configuration.GetConnectionString(KeyVaultConfig.ConnectionStrings.AdoDb), x => x.MigrationsAssembly(_namespace));
                }
                else if (DbTypeEnum == DbTypeEnum.InMemory)
                {
                    options.UseInMemoryDatabase(databaseName: KeyVaultConfig.ConnectionStrings.AdoDb);
                }
                else
                {
                    options.UseSqlServer(Configuration.GetConnectionString(KeyVaultConfig.ConnectionStrings.AdoDb), x => x.MigrationsAssembly(_namespace));
                }
            });

            //services.AddDbContext<TokenCacheContext>(options =>
            //{
            //    if (UseSqlLiteDb)
            //        options.UseSqlite(Configuration.GetConnectionString(KeyVaultConfig.ConnectionStrings.TokenCacheDb));
            //    else
            //        options.UseSqlServer(Configuration.GetConnectionString(KeyVaultConfig.ConnectionStrings.TokenCacheDb));

            //});

            #endregion

            #region Repositories

            services.AddScoped(typeof(IRepository <>), typeof(AdoRepository <>));
            services.AddScoped <IAdoProjectHistoryRepository, AdoProjectHistoryRepository>();
            services.AddScoped <IAdoProjectRepository, AdoProjectRepository>();

            #endregion

            var busConfig = Configuration.GetSection(nameof(BusConfig)).Get <BusConfig>();
            if (busConfig == null)
            {
                _logger.LogWarning($"No {nameof(BusConfig)} found.");
            }
            else
            {
                _logger.LogInformation($"{nameof(BusConfig)} is {busConfig} ", busConfig);
                //_logger.LogInformation("BusConfig is {busConfig} ", busConfig);
                if (busConfig.IsBusEnabled && busConfig.BusTypeEnum == BusTypeEnum.AzureServiceBus)
                {
                    //should be last to hav all dependencies
                    services.AddHostedService <ProjectApprovalHostedService>(sp =>
                    {
                        var serviceProvider          = services.BuildServiceProvider();
                        var apiIdentity              = serviceProvider.GetService <IApiIdentity>();
                        var ctx                      = serviceProvider.GetService <AdoContext>();
                        IRepository <AdoProject> obj = new Repository <AdoProject>(ctx, apiIdentity);
                        var logger                   = sp.GetService <ILogger <ProjectApprovalHostedService> >();
                        IGenerateEmailForApprovalService generateEmailForApprovalService = serviceProvider.GetService <IGenerateEmailForApprovalService>();
                        return(new ProjectApprovalHostedService(generateEmailForApprovalService, logger));
                    });

                    services.AddHostedService <AzServiceBusConsumer>(sp =>
                    {
                        var serviceProvider = services.BuildServiceProvider();
                        //var serviceProvider = sp;
                        var apiIdentity = serviceProvider.GetService <IApiIdentity>();
                        var ctx         = serviceProvider.GetService <AdoContext>();
                        IRepository <AdoProject> obj = new Repository <AdoProject>(ctx, apiIdentity);

                        IConfiguration configuration               = serviceProvider.GetService <IConfiguration>();
                        IMessageBus messageBus                     = serviceProvider.GetService <IMessageBus>();
                        IMediator mediator                         = serviceProvider.GetService <IMediator>();
                        IProjectAdoServices projectAdoServices     = serviceProvider.GetService <IProjectAdoServices>();
                        IAdoProjectRepository adoProjectRepository = serviceProvider.GetService <IAdoProjectRepository>();
                        IAdoProjectHistoryRepository adoProjectHistoryRepository = serviceProvider.GetService <IAdoProjectHistoryRepository>();
                        IMapper mapper = serviceProvider.GetService <IMapper>();
                        ILogger <AzServiceBusConsumer> logger = serviceProvider.GetService <ILogger <AzServiceBusConsumer> >();
                        return(new AzServiceBusConsumer(configuration, messageBus, mediator, projectAdoServices, adoProjectRepository, adoProjectHistoryRepository, mapper, logger));
                    });
                }
            }
        }
Esempio n. 2
0
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            if (_env.IsDevelopment())
            {
                ;
            }
            else if (_env.IsStaging())
            {
                ;
            }

            services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies());
            services.AddMediatR(Assembly.GetExecutingAssembly());

            services.AddApplicationServices(Configuration, _env, _logger);

            #region Add HttpClient

            services.AddHttpClient(Core.ConstatCsro.ClientNames.MANAGEMENT_AZURE_EndPoint, (client) =>
            {
                client.Timeout     = TimeSpan.FromMinutes(Core.ConstatCsro.ClientNames.MANAGEMENT_TimeOut_Mins);
                client.BaseAddress = new Uri(Core.ConstatCsro.ClientNames.MANAGEMENT_AZURE_EndPoint);
                client.DefaultRequestHeaders.Add("Accept", "application/json");
            }).ConfigurePrimaryHttpMessageHandler(() =>
            {
                return(new HttpClientHandler()
                {
                    AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip | DecompressionMethods.Brotli,
                    UseCookies = false
                });
            })
            .SetHandlerLifetime(TimeSpan.FromMinutes(5))
            .AddPolicyHandler(PollyHelper.GetRetryPolicy())
            .AddPolicyHandler(PollyHelper.GetRetryPolicy());
            ;

            string ApiEndpointAuth = Configuration.GetValue <string>(ConstatCsro.EndPoints.ApiEndpointAuth);
            services.AddHttpClient(Core.ConstatCsro.EndPoints.ApiEndpointAuth, (client) =>
            {
                client.Timeout     = TimeSpan.FromMinutes(ConstatCsro.ClientNames.API_TimeOut_Mins);
                client.BaseAddress = new Uri(ApiEndpointAuth);
                client.DefaultRequestHeaders.Add("Accept", "application/json");
            }).ConfigurePrimaryHttpMessageHandler(() =>
            {
                return(new HttpClientHandler()
                {
                    AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip | DecompressionMethods.Brotli,
                    UseCookies = false
                });
            })
            .SetHandlerLifetime(TimeSpan.FromMinutes(5))
            .AddPolicyHandler(PollyHelper.GetRetryPolicy())
            .AddPolicyHandler(PollyHelper.GetRetryPolicy());
            ;

            #endregion

            //services.Configure<MicrosoftIdentityOptions>(options =>
            //{
            //    options.ResponseType = OpenIdConnectResponseType.Code;
            //    if (UseKeyVault && !string.IsNullOrWhiteSpace(azureAdOptions.ClientSecret))
            //        options.ClientSecret = azureAdOptions.ClientSecret;
            //    if (UseKeyVault)
            //        LogSecretVariableValueStartValue(ClientSecretVaultName, azureAdOptions.ClientSecret);
            //});

            #region Auth

            services.AddAuthorization(options =>
            {
                // By default, all incoming requests will be authorized according to the default policy
                //Will automatical sign in user
                //options.FallbackPolicy = options.DefaultPolicy;

                options.AddPolicy(PoliciesCsro.IsAdminPolicy, policy => policy.RequireClaim(ClaimTypes.Role, RolesCsro.Admin));
            });

            //TODO replace with rest or GRPC service
            services.AddScoped <IRestUserService, RestUserService>();
            services.AddScoped <IClaimsTransformation, ClaimsTransformation>();

            #endregion

            services.AddApplicationInsightsTelemetry();
            services.AddControllers();
            services.AddMvc(options =>
            {
                options.Filters.Add(new CsroValidationFilter());
            })
            .AddFluentValidation(options =>
            {
                //options.RegisterValidatorsFromAssemblyContaining<Startup>();
                options.RegisterValidatorsFromAssemblyContaining <Server.Services.Validation.BaseAbstractValidator>();
            });

            services.AddScoped <IApiIdentity, ApiIdentity>();
            services.AddScoped <IEmailService, EmailService>();
            services.AddSingleton <IMessageBus, AzServiceBusMessageBus>();

            services.AddTransient <IAzureVmManagementService, AzureVmManagementService>();
            services.AddTransient <ISubcriptionService, SubcriptionService>();
            services.AddTransient <ISubcriptionSPNService, SubcriptionSPNService>();
            services.AddTransient <IResourceGroupervice, ResourceGroupervice>();
            services.AddTransient <ISubcriptionRepository, SubcriptionRepository>();

            services.AddSingleton <ICacheProvider, CacheProvider>(); //testing

            //services.AddApplicationInsightsTelemetry(Configuration["APPINSIGHTS_CONNECTIONSTRING"]);

            //services.AddControllers(options => options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute()));
            services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc("v1", new OpenApiInfo {
                    Title = _namespace, Version = "v1"
                });
            });

            #region SDK services

            services.AddTransient <IVmSdkService, VmSdkService>();
            services.AddTransient <ISubscriptionSdkService, SubscriptionSdkService>();
            services.AddTransient <IAdService, AdService>();
            services.AddTransient <IGsnowService, FakeGsnowService>();

            bool UseChainTokenCredential = Configuration.GetValue <bool>("UseChainTokenCredential");
            if (UseChainTokenCredential)
            {
                services.AddTransient <ICsroTokenCredentialProvider, ChainnedCsroTokenCredentialProvider>(); //for personal
                //services.AddTransient<ICsroTokenCredentialProvider, ChainnedCsroTokenCredentialProvider>((op) =>
                //{
                //    var pr = new ChainnedCsroTokenCredentialProvider(azureAdOptions);
                //    return pr;
                //}); //for personal
            }
            else
            {
                services.AddTransient <ICsroTokenCredentialProvider, CsroTokenCredentialProvider>(); //for work
            }
            #endregion

            #region DbContext

            DbTypeEnum DbTypeEnum = DbTypeEnum.Unknown;
            try
            {
                DbTypeEnum = Configuration.GetValue <DbTypeEnum>(nameof(DbTypeEnum));
            }
            catch { }

            if (DbTypeEnum == DbTypeEnum.Unknown)
            {
                throw new Exception($"Unable to read {nameof(DbTypeEnum)} from config. Please set value to SqlServer, InMemory for testing or.....");
            }

            services.AddDbContext <AppVersionContext>(options =>
            {
                if (DbTypeEnum == DbTypeEnum.SqlLite)
                {
                    options.UseSqlite(Configuration.GetConnectionString(KeyVaultConfig.ConnectionStrings.ApiDb), x => x.MigrationsAssembly(_namespace));
                }
                else if (DbTypeEnum == DbTypeEnum.InMemory)
                {
                    options.UseInMemoryDatabase(databaseName: KeyVaultConfig.ConnectionStrings.ApiDb);
                }
                else
                {
                    options.UseSqlServer(Configuration.GetConnectionString(KeyVaultConfig.ConnectionStrings.ApiDb), x => x.MigrationsAssembly(_namespace));
                }
            });

            services.AddDbContext <CustomersDbContext>(options =>
            {
                var cs = Configuration.GetConnectionString(KeyVaultConfig.ConnectionStrings.CustomerDb);
                if (DbTypeEnum == DbTypeEnum.SqlLite)
                {
                    options.UseSqlite(Configuration.GetConnectionString(KeyVaultConfig.ConnectionStrings.CustomerDb), x => x.MigrationsAssembly(_namespace));
                }
                else if (DbTypeEnum == DbTypeEnum.InMemory)
                {
                    options.UseInMemoryDatabase(databaseName: KeyVaultConfig.ConnectionStrings.CustomerDb);
                }
                else //SqlServer
                {
                    options.UseSqlServer(Configuration.GetConnectionString(KeyVaultConfig.ConnectionStrings.CustomerDb), x => x.MigrationsAssembly(_namespace));
                }
            });

            //services.AddDbContext<TokenCacheContext>(options =>
            //{
            //    if (DbTypeEnum == DbTypeEnum.SqlLite)
            //        options.UseSqlite(Configuration.GetConnectionString(KeyVaultConfig.ConnectionStrings.TokenCacheDb));
            //    else
            //        options.UseSqlServer(Configuration.GetConnectionString(KeyVaultConfig.ConnectionStrings.TokenCacheDb));

            //});

            #endregion

            #region Repositories
            services.AddScoped(typeof(IRepository <>), typeof(AppRepository <>));

            services.AddScoped <ITicketRepository, TicketRepository>();
            services.AddScoped <IVersionRepository, VersionRepository>();
            services.AddScoped <IVmTicketRepository, VmTicketRepository>();
            services.AddScoped <ICustomerRepository, CustomerRepository>();
            services.AddScoped <IVmTicketHistoryRepository, VmTicketHistoryRepository>();

            #endregion

            var busConfig = Configuration.GetSection(nameof(BusConfig)).Get <BusConfig>();
            if (busConfig == null)
            {
                _logger.LogWarning($"No {nameof(BusConfig)} found.");
            }
            else
            {
                _logger.LogInformation($"{nameof(BusConfig)} is {busConfig} ", busConfig);
                if (busConfig.IsBusEnabled && busConfig.BusTypeEnum == BusTypeEnum.AzureServiceBus)
                {
                    services.AddHostedService <AzServiceBusConsumer>(sp =>
                    {
                        //var serviceProvider = sp;
                        var serviceProvider = _serviceProvider;
                        //var apiIdentity = serviceProvider.GetService<IApiIdentity>();
                        //var ctx = serviceProvider.GetService<AdoContext>();
                        //IRepository<AdoProject> obj = new Repository<AdoProject>(ctx, apiIdentity);

                        IConfiguration configuration = serviceProvider.GetService <IConfiguration>();
                        IMessageBus messageBus       = serviceProvider.GetService <IMessageBus>();
                        IMediator mediator           = serviceProvider.GetService <IMediator>();
                        IMapper mapper = serviceProvider.GetService <IMapper>();
                        ILogger <AzServiceBusConsumer> logger = serviceProvider.GetService <ILogger <AzServiceBusConsumer> >();
                        return(new AzServiceBusConsumer(configuration, messageBus, mediator, mapper, logger));
                    });
                }
            }

            services.AddHealthChecks().AddDbContextCheck <CustomersDbContext>("Customers DB");
            services.AddHealthChecks().AddDbContextCheck <AppVersionContext>("Api DB");
            if (busConfig != null && busConfig.IsBusEnabled && busConfig.BusTypeEnum == BusTypeEnum.AzureServiceBus)
            {
                services.AddHealthChecks()
                .AddAzureServiceBusTopicHealthCheck(Configuration["ConnectionStrings:AzureServiceBus"],
                                                    Configuration["ServiceBusConfig:VmOperationRequesTopic"], "ServiceBus: Vm Operation Topic", HealthStatus.Unhealthy);
            }
            _serviceProvider = services.BuildServiceProvider();
        }
Esempio n. 3
0
        // This method gets called by the runtime. Use this method to add services to the container.
        // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
        public void ConfigureServices(IServiceCollection services)
        {
            var azureAdOptions = Configuration.GetSection(nameof(AzureAd)).Get <AzureAd>();
            var keyVaultConfig = Configuration.GetSection(nameof(KeyVaultConfig)).Get <KeyVaultConfig>();
            var adoConfig      = Configuration.GetSection(nameof(AdoConfig)).Get <AdoConfig>();

            _logger.LogInformation($"{nameof(KeyVaultConfig.UseKeyVault)} = {keyVaultConfig.UseKeyVault}");

            if (keyVaultConfig.UseKeyVault)
            {
                try
                {
                    //_logger.LogInformation($"Delay to wait for AUTH api to start");
                    //Task.Delay(10 * 1000).Wait();

                    _logger.LogInformation($"{nameof(KeyVaultConfig.KeyVaultName)} = {keyVaultConfig.KeyVaultName}");
                    var azureServiceTokenProvider = new AzureServiceTokenProvider();
                    var keyVaultClient            = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(azureServiceTokenProvider.KeyVaultTokenCallback));

                    //clien secret
                    if (keyVaultConfig.ClientSecretVaultKey != null)
                    {
                        azureAdOptions.ClientSecret = keyVaultClient.GetSecretAsync(keyVaultConfig.KeyVaultName, keyVaultConfig.ClientSecretVaultKey).Result.Value;
                        Configuration[KeyVaultConfig.Constants.AzureAdClientSecret] = azureAdOptions.ClientSecret;
                    }
                    _logger.LogSecretVariableValueStartValue(KeyVaultConfig.Constants.AzureAdClientSecret, azureAdOptions.ClientSecret);

                    //SPN clien secret
                    var spnAd = Configuration.GetSection(nameof(SpnAd)).Get <SpnAd>();
                    if (keyVaultConfig.SpnClientSecretVaultKey != null)
                    {
                        spnAd.ClientSecret = keyVaultClient.GetSecretAsync(keyVaultConfig.KeyVaultName, keyVaultConfig.SpnClientSecretVaultKey).Result.Value;
                        Configuration[KeyVaultConfig.Constants.SpnClientSecret] = spnAd.ClientSecret;
                    }
                    _logger?.LogSecretVariableValueStartValue(KeyVaultConfig.Constants.SpnClientSecret, spnAd.ClientSecret);

                    //ConnectionStrings
                    if (keyVaultConfig.TokenCacheDbCsVaultKey != null)
                    {
                        if (!keyVaultConfig.UseLocalDb)
                        {
                            Configuration["ConnectionStrings:" + KeyVaultConfig.ConnectionStrings.TokenCacheDb] = keyVaultClient.GetSecretAsync(keyVaultConfig.KeyVaultName, keyVaultConfig.TokenCacheDbCsVaultKey).Result.Value;
                        }
                    }
                    _logger.LogSecretVariableValueStartValue(KeyVaultConfig.ConnectionStrings.TokenCacheDb, Configuration["ConnectionStrings:" + KeyVaultConfig.ConnectionStrings.TokenCacheDb]);

                    //ado
                    if (keyVaultConfig.AdoPersonalAccessTokenVaultKey != null)
                    {
                        adoConfig.AdoPersonalAccessToken = keyVaultClient.GetSecretAsync(keyVaultConfig.KeyVaultName, keyVaultConfig.AdoPersonalAccessTokenVaultKey).Result.Value;
                        Configuration["AdoConfig:" + nameof(adoConfig.AdoPersonalAccessToken)] = adoConfig.AdoPersonalAccessToken;
                    }
                    _logger.LogSecretVariableValueStartValue(nameof(adoConfig.AdoPersonalAccessToken), adoConfig.AdoPersonalAccessToken);
                }
                catch (Exception ex)
                {
                    _logger?.LogError("Error reading Keyvalut", ex);
                }
            }

            services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies());
            services.AddTransient <ITimeZoneService, TimeZoneService>();
            //services.AddAutoMapperBuilder(builder =>
            //{
            //    builder.Profiles.Add(new VersionProfile(services.BuildServiceProvider().GetRequiredService<ITimeZoneService>()));
            //});

            #region Add HttpClient

            string ApiEndpoint = Configuration.GetValue <string>(ConstatCsro.EndPoints.ApiEndpoint);
            services.AddHttpClient(ConstatCsro.EndPoints.ApiEndpoint, (client) =>
            {
                client.Timeout     = TimeSpan.FromMinutes(ConstatCsro.ClientNames.API_TimeOut_Mins);
                client.BaseAddress = new Uri(ApiEndpoint);
                client.DefaultRequestHeaders.Add("Accept", "application/json");
            }).ConfigurePrimaryHttpMessageHandler(() =>
            {
                return(new HttpClientHandler()
                {
                    AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip | DecompressionMethods.Brotli,
                    UseCookies = false
                });
            })
            .SetHandlerLifetime(TimeSpan.FromMinutes(5))
            .AddPolicyHandler(PollyHelper.GetRetryPolicy())
            .AddPolicyHandler(PollyHelper.GetRetryPolicy());
            ;

            string ApiEndpointAdo = Configuration.GetValue <string>(ConstatCsro.EndPoints.ApiEndpointAdo);
            services.AddHttpClient(ConstatCsro.EndPoints.ApiEndpointAdo, (client) =>
            {
                client.Timeout     = TimeSpan.FromMinutes(ConstatCsro.ClientNames.API_TimeOut_Mins);
                client.BaseAddress = new Uri(ApiEndpointAdo);
                client.DefaultRequestHeaders.Add("Accept", "application/json");
            }).ConfigurePrimaryHttpMessageHandler(() =>
            {
                return(new HttpClientHandler()
                {
                    AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip | DecompressionMethods.Brotli,
                    UseCookies = false
                });
            })
            .SetHandlerLifetime(TimeSpan.FromMinutes(5))
            .AddPolicyHandler(PollyHelper.GetRetryPolicy())
            .AddPolicyHandler(PollyHelper.GetRetryPolicy());
            ;

            const int REPORT_TIME_OUT   = 55;
            string    ApiEndpointReport = Configuration.GetValue <string>(ConstatCsro.EndPoints.ApiEndpointReport);
            services.AddHttpClient(ConstatCsro.EndPoints.ApiEndpointReport, (client) =>
            {
                client.Timeout     = TimeSpan.FromMinutes(REPORT_TIME_OUT);
                client.BaseAddress = new Uri(ApiEndpointReport);
                client.DefaultRequestHeaders.Add("Accept", "application/json");
            }).ConfigurePrimaryHttpMessageHandler(() =>
            {
                return(new HttpClientHandler()
                {
                    AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip | DecompressionMethods.Brotli,
                    UseCookies = false
                });
            })
            .SetHandlerLifetime(TimeSpan.FromMinutes(REPORT_TIME_OUT))
            .AddPolicyHandler(PollyHelper.GetRetryPolicy())
            .AddPolicyHandler(PollyHelper.GetRetryPolicy());
            ;

            string ApiEndpointAuth = Configuration.GetValue <string>(ConstatCsro.EndPoints.ApiEndpointAuth);
            services.AddHttpClient(ConstatCsro.EndPoints.ApiEndpointAuth, (client) =>
            {
                client.Timeout     = TimeSpan.FromMinutes(ConstatCsro.ClientNames.API_TimeOut_Mins);
                client.BaseAddress = new Uri(ApiEndpointAuth);
                client.DefaultRequestHeaders.Add("Accept", "application/json");
            }).ConfigurePrimaryHttpMessageHandler(() =>
            {
                return(new HttpClientHandler()
                {
                    AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip | DecompressionMethods.Brotli,
                    UseCookies = false
                });
            })
            .SetHandlerLifetime(TimeSpan.FromMinutes(5))
            .AddPolicyHandler(PollyHelper.GetRetryPolicy())
            .AddPolicyHandler(PollyHelper.GetRetryPolicy());
            ;

            services.AddHttpClient(ConstatCsro.ClientNames.MANAGEMENT_AZURE_EndPoint, (client) =>
            {
                client.Timeout     = TimeSpan.FromMinutes(ConstatCsro.ClientNames.MANAGEMENT_TimeOut_Mins);
                client.BaseAddress = new Uri(ConstatCsro.ClientNames.MANAGEMENT_AZURE_EndPoint);
                client.DefaultRequestHeaders.Add("Accept", "application/json");
            }).ConfigurePrimaryHttpMessageHandler(() =>
            {
                return(new HttpClientHandler()
                {
                    AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip | DecompressionMethods.Brotli,
                    UseCookies = false
                });
            })
            .SetHandlerLifetime(TimeSpan.FromMinutes(5))
            .AddPolicyHandler(PollyHelper.GetRetryPolicy())
            .AddPolicyHandler(PollyHelper.GetRetryPolicy());
            ;

            services.AddHttpClient(ConstatAdo.ClientNames.DEVOPS_EndPoint, (client) =>
            {
                client.Timeout     = TimeSpan.FromMinutes(ConstatAdo.ClientNames.MANAGEMENT_TimeOut_Mins);
                client.BaseAddress = new Uri(ConstatAdo.ClientNames.DEVOPS_EndPoint);
                client.DefaultRequestHeaders.Add("Accept", "application/json");
            }).ConfigurePrimaryHttpMessageHandler(() =>
            {
                return(new HttpClientHandler()
                {
                    AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip | DecompressionMethods.Brotli,
                    UseCookies = false
                });
            })
            .SetHandlerLifetime(TimeSpan.FromMinutes(5))
            .AddPolicyHandler(PollyHelper.GetRetryPolicy())
            .AddPolicyHandler(PollyHelper.GetRetryPolicy());
            ;

            #endregion

            var distributedTokenCachesConfig = Configuration.GetSection(nameof(DistributedTokenCachesConfig)).Get <DistributedTokenCachesConfig>();
            if (distributedTokenCachesConfig != null && distributedTokenCachesConfig.IsEnabled)
            {
                services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
                .AddMicrosoftIdentityWebApp(Configuration.GetSection("AzureAd"))
                //.EnableTokenAcquisitionToCallDownstreamApi()    //v1
                .EnableTokenAcquisitionToCallDownstreamApi(new List <string> {
                    "user.read", "openid", "email", "profile", "offline_access", Configuration.GetValue <string>(Core.ConstatCsro.Scopes.Scope_Auth_Api)
                })
                .AddDistributedTokenCaches();
            }
            else
            {
                services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
                .AddMicrosoftIdentityWebApp(Configuration.GetSection("AzureAd"))
                //.EnableTokenAcquisitionToCallDownstreamApi()    //v1
                .EnableTokenAcquisitionToCallDownstreamApi(new List <string> {
                    "user.read", "openid", "email", "profile", "offline_access", Configuration.GetValue <string>(Core.ConstatCsro.Scopes.Scope_Auth_Api)
                })
                .AddInMemoryTokenCaches();
            }

            #region Distributed Token Caches

            //services.AddDistributedSqlServerCache(options =>
            //{
            //    options.ConnectionString = Configuration.GetConnectionString(KeyVaultConfig.ConnectionStrings.TokenCacheDb);
            //    options.SchemaName = "dbo";
            //    options.TableName = "TokenCache";

            //    //def is 20 minutes
            //    if (distributedTokenCachesConfig?.DefaultSlidingExpirationMinutes > 0)
            //        options.DefaultSlidingExpiration = TimeSpan.FromMinutes(distributedTokenCachesConfig.DefaultSlidingExpirationMinutes);
            //});

            #endregion

            services.Configure <MicrosoftIdentityOptions>(options =>
            {
                options.ResponseType = OpenIdConnectResponseType.Code;
                if (keyVaultConfig.UseKeyVault && !string.IsNullOrWhiteSpace(azureAdOptions.ClientSecret))
                {
                    options.ClientSecret = azureAdOptions.ClientSecret;
                }
                if (keyVaultConfig.UseKeyVault)
                {
                    _logger.LogSecretVariableValueStartValue(keyVaultConfig.ClientSecretVaultKey, azureAdOptions.ClientSecret);
                }
            });

            services.AddControllersWithViews()
            .AddMicrosoftIdentityUI()
            .AddFluentValidation(fv =>
            {
                fv.ImplicitlyValidateChildProperties = true;
                fv.RegisterValidatorsFromAssemblyContaining <Services.Validation.BaseAbstractValidator>();
            });

            services.AddAuthorization(options =>
            {
                // By default, all incoming requests will be authorized according to the default policy
                //Will automatical sign in user
                options.FallbackPolicy = options.DefaultPolicy;

                //options.AddPolicy(PoliciesCsro.CanApproveAdoRequest, policy => policy.RequireClaim(ClaimTypesCsro.CanApproveAdoRequest, true.ToString()));
                foreach (var pol in PoliciesCsro.PolicyClaimsDictionary)
                {
                    options.AddPolicy(pol.Key, policy => policy.RequireClaim(pol.Value.Type, pol.Value.Value));
                }
            });

            services.AddRazorPages();
            services.AddServerSideBlazor()
            .AddMicrosoftIdentityConsentHandler();

            services.AddTransient <IGraphClientService, GraphClientService>();
            services.AddTransient <IAuthCsroService, AuthCsroService>();
            services.AddTransient <IUserDataService, UserDataService>();
            services.AddTransient <IUserClaimDataService, UserClaimDataService>();
            services.AddTransient <ICsvExporter, CsvExporter>();

            services.AddTransient <IVersionService, VersionService>();
            services.AddTransient <IBaseDataService <Ticket>, TicketDataService>();
            services.AddTransient <IBaseDataService <VmTicketHistory>, VmTicketHistoryDataService>();
            services.AddTransient <IAdoProjectHistoryDataService, AdoProjectHistoryDataService>();
            services.AddTransient <IVmTicketDataService, VmTicketDataService>();
            services.AddTransient <ISubcriptionDataService, SubcriptionDataService>();
            services.AddTransient <ICustomerDataService, CustomerDataService>();
            services.AddTransient <IServiceIssueDataService, ServiceIssueDataService>();
            services.AddTransient <ISupportAzureService, SupportAzureService>();
            services.AddTransient <IRefundSupportTicketDataService, RefundSupportTicketDataService>();
            services.AddTransient <IServiceOutageDataService, ServiceOutageDataService>();
            services.AddTransient <IServiceOutageSummaryDataService, ServiceOutageSummaryDataService>();
            services.AddTransient <IEmailDataService, EmailDataService>();

            services.AddTransient <IVmService, VmService>();
            services.AddTransient <ISubcriptionService, SubcriptionService>(); //TODO remove
            services.AddTransient <IResourceGroupService, ResourceGroupService>();
            services.AddTransient <INetworkService, NetworkService>();
            services.AddSingleton <ILocationsService, LocationsService>();
            services.AddTransient <IAdoProjectDataService, AdoProjectDataService>();
            services.AddTransient <IAdoProjectAccessDataService, AdoProjectAccessDataService>();

            #region SDK services

            services.AddTransient <IVmSdkService, VmSdkService>();
            services.AddTransient <ISubscriptionSdkService, SubscriptionSdkService>();
            services.AddTransient <IAdService, AdService>();

            bool UseChainTokenCredential = Configuration.GetValue <bool>("UseChainTokenCredential");
            if (UseChainTokenCredential)
            {
                services.AddTransient <ICsroTokenCredentialProvider, ChainnedCsroTokenCredentialProvider>(); //for personal
                //services.AddTransient<ICsroTokenCredentialProvider, ChainnedCsroTokenCredentialProvider>((op) =>
                //{
                //    var pr = new ChainnedCsroTokenCredentialProvider(azureAdOptions);
                //    return pr;
                //}); //for personal
            }
            else
            {
                services.AddTransient <ICsroTokenCredentialProvider, CsroTokenCredentialProvider>(); //for work
            }
            #endregion

            services.AddTransient <IProjectAdoServices, ProjectAdoServices>();
            services.AddTransient <IProcessAdoServices, ProcessAdoServices>();
            services.AddTransient <ISupportedRegionsService, SupportedRegionsService>();
            services.AddSingleton <ICacheProvider, CacheProvider>(); //testing

            //UI component for dialods
            services.AddTransient <ICsroDialogService, CsroDialogService>();

            services.AddMudServices();
            //services.AddApplicationInsightsTelemetry(Configuration["APPINSIGHTS_CONNECTIONSTRING"]);
            services.AddApplicationInsightsTelemetry();

            services.AddHealthChecksUI().AddInMemoryStorage();
        }