private static void RegisterAgentType(IServiceCollection services, Type implementationType, ServiceAgentSettings settings, Action <IServiceProvider, HttpClient> clientCreatedAction, Action <string, IHttpClientBuilder> clientBuiltAction) { // registering service agents with generic parameters causes an error: "Late bound operations cannot be performed on types or methods for which ContainsGenericParameters is true." if (implementationType.ContainsGenericParameters) { throw new Exception($"Error registering service {implementationType.Name}. A service agent with generic parameters can't be registered at runtime and must be registered with the service collection via the AddSingleServiceAgent<T> method"); } // the specified type will be registered in the service collection as a transient service IHttpClientBuilder builder = services.AddHttpClient(implementationType.Name, (serviceProvider, client) => { var serviceSettings = settings.GetServiceSettings(implementationType.Name); ConfigureHttpClient(serviceProvider, client, serviceSettings, clientCreatedAction); }); var interfaceType = implementationType.FindInterfaces(new TypeFilter(MyInterfaceFilter), implementationType.Name).SingleOrDefault(); if (interfaceType != null) { // find the desired generic method for creating a typed HttpClient var genericMethods = typeof(HttpClientBuilderExtensions).GetMethods() .Where(m => m.Name == "AddTypedClient" && m.IsGenericMethod == true && m.GetParameters().Count() == 1 && m.GetGenericArguments().Count() == 2).ToList(); if (genericMethods == null || genericMethods.Count != 1) { throw new Exception("Unable to find suitable method for constructing a typed HttpClient"); } var genericMethod = genericMethods.First().MakeGenericMethod(interfaceType, implementationType); genericMethod.Invoke(builder, new object[] { builder }); } else { // find the desired generic method for creating a typed HttpClient var genericMethods = typeof(HttpClientBuilderExtensions).GetMethods() .Where(m => m.Name == "AddTypedClient" && m.IsGenericMethod == true && m.GetParameters().Count() == 1 && m.GetGenericArguments().Count() == 1).ToList(); if (genericMethods == null || genericMethods.Count != 1) { throw new Exception("Unable to find suitable method for constructing a typed HttpClient"); } var genericMethod = genericMethods.First().MakeGenericMethod(implementationType); genericMethod.Invoke(builder, new object[] { builder }); } // invoke additional actions for HttpClientBuilder ex. attaching DelegatingHandlers clientBuiltAction?.Invoke(implementationType.Name, builder); }
private void GenericAgentIsRegistratedAsScoped() { var services = new ServiceCollection(); services.AddServiceAgents(settings => { settings.FileName = Path.Combine(Directory.GetCurrentDirectory(), "_TestData/serviceagentconfig_4.json"); }, assembly: typeof(AddServiceAgentsTests).GetTypeInfo().Assembly); var registrations = services.Where(sd => sd.ServiceType == typeof(GenericAgent <>)) .ToArray(); Assert.Equal(1, registrations.Count()); Assert.Equal(ServiceLifetime.Scoped, registrations[0].Lifetime); registrations = services.Where(sd => sd.ServiceType == typeof(IConfigureOptions <ServiceAgentSettings>)) .ToArray(); var configOptions = registrations[0].ImplementationInstance as IConfigureOptions <ServiceAgentSettings>; Assert.NotNull(configOptions); var serviceAgentSettings = new ServiceAgentSettings(); configOptions.Configure(serviceAgentSettings); Assert.Equal(1, serviceAgentSettings.Services.Count); var serviceSettings = serviceAgentSettings.Services["GenericAgent"]; Assert.NotNull(serviceSettings); }
private void HttpClientCreatedActionIsExecuted() { var serviceAgentSettings = new ServiceAgentSettings(); HttpClient passedClient = null; IServiceProvider passedServiceProvider = null; var services = new ServiceCollection(); services.AddServiceAgents(s => { s.FileName = Path.Combine(Directory.GetCurrentDirectory(), "_TestData/serviceagentconfig_3.json"); s.Section = "InterfaceImplementingAgent"; }, (serviceProvider, client) => { // actions for the client created function passedClient = client; passedServiceProvider = serviceProvider; }, assembly: typeof(AddServiceAgentsTests).GetTypeInfo().Assembly ); /// get the registrated TestAgent > this also creates an HttpClient and executes the clientCreatedAction var registration = services.Single(sd => sd.ServiceType == typeof(IInterfaceImplementingAgent)); var agent = registration.ImplementationFactory.Invoke(services.BuildServiceProvider()) as InterfaceImplementingAgent; Assert.NotNull(passedClient); Assert.NotNull(passedServiceProvider); }
private void GenericAgentIsRegistratedAsTransient() { var services = new ServiceCollection(); services.AddSingleServiceAgent <GenericAgent <string> >(settings => { settings.AuthScheme = "None"; settings.Host = "test.be"; settings.Path = "api"; settings.Port = "5001"; settings.Scheme = "http"; //settings.FileName = Path.Combine(Directory.GetCurrentDirectory(), "_TestData/serviceagentconfig_4.json"); }, assembly: typeof(AddServiceAgentsTests).GetTypeInfo().Assembly); var registrations = services.Where(sd => sd.ServiceType == typeof(GenericAgent <string>)) .ToArray(); Assert.Single(registrations); Assert.Equal(ServiceLifetime.Transient, registrations[0].Lifetime); registrations = services.Where(sd => sd.ServiceType == typeof(IConfigureOptions <ServiceAgentSettings>)) .ToArray(); var configOptions = registrations[0].ImplementationInstance as IConfigureOptions <ServiceAgentSettings>; Assert.NotNull(configOptions); var serviceAgentSettings = new ServiceAgentSettings(); configOptions.Configure(serviceAgentSettings); Assert.Equal(1, serviceAgentSettings.Services.Count); }
private void ServiceAgentSettingsActionIsPassed() { var serviceAgentSettings = new ServiceAgentSettings(); var services = new ServiceCollection(); services.AddServiceAgents(json => { json.FileName = Path.Combine(Directory.GetCurrentDirectory(), "_TestData/serviceagentconfig_1.json"); }, settings => { settings.Services["TestAgent"].Port = "15000"; }, null, assembly: typeof(AddServiceAgentsTests).GetTypeInfo().Assembly); var registrations = services.Where(sd => sd.ServiceType == typeof(IConfigureOptions <ServiceAgentSettings>)) .ToArray(); Assert.Single(registrations); Assert.Equal(ServiceLifetime.Singleton, registrations[0].Lifetime); var configOptions = registrations[0].ImplementationInstance as IConfigureOptions <ServiceAgentSettings>; Assert.NotNull(configOptions); serviceAgentSettings = new ServiceAgentSettings(); configOptions.Configure(serviceAgentSettings); var serviceSettings = serviceAgentSettings.Services["TestAgent"]; Assert.NotNull(serviceSettings); Assert.Equal("15000", serviceSettings.Port); }
private static IServiceCollection AddSingleServiceAgent <T>(this IServiceCollection services, Assembly callingAssembly, Action <ServiceSettings> serviceSettingsSetupAction, Action <IServiceProvider, HttpClient> clientCreatedAction, Action <string, IHttpClientBuilder> clientBuiltAction = null) where T : AgentBase { if (serviceSettingsSetupAction == null) { throw new ArgumentNullException(nameof(serviceSettingsSetupAction), $"{nameof(serviceSettingsSetupAction)} cannot be null."); } // read service agent settings in local variable var serviceSettings = new ServiceSettings(); serviceSettingsSetupAction.Invoke(serviceSettings); // configure service agent settings for DI container services.Configure <ServiceAgentSettings>(s => { s.Services.Add(typeof(T).Name, serviceSettings); }); ServiceAgentSettings serviceAgentSettings = new ServiceAgentSettings(); serviceAgentSettings.Services.Add(typeof(T).Name, serviceSettings); RegisterServices <T>(services, serviceAgentSettings, callingAssembly, clientCreatedAction, clientBuiltAction); return(services); }
private void HttpClientFactoryClientActionIsPassed() { var serviceAgentSettings = new ServiceAgentSettings(); HttpClient passedClient = null; IServiceProvider passedServiceProvider = null; var services = new ServiceCollection(); services.AddServiceAgents(s => { s.FileName = Path.Combine(Directory.GetCurrentDirectory(), "_TestData/serviceagentconfig_1.json"); s.Section = "TestAgent"; }, (serviceProvider, client) => { passedClient = client; passedServiceProvider = serviceProvider; }, assembly: typeof(AddServiceAgentsTests).GetTypeInfo().Assembly ); ///get the registrated HttpFactory var registration = services.Single(sd => sd.ServiceType == typeof(IHttpClientFactory)); //Manually call the CreateClient on the factory (this normally happens when the service agent gets resolved var factory = registration.ImplementationFactory.Invoke(null) as HttpClientFactory; factory.CreateClient(serviceAgentSettings, new ServiceSettings { Host = "test.be" }); Assert.NotNull(passedClient); }
private ServiceAgentSettings CreateServiceAgentSettings() { var settings = new ServiceAgentSettings(); settings.Services.Add("TestAgent", new ServiceSettings { Scheme = HttpSchema.Http, Host = "localhost" }); return(settings); }
private static void RegisterServices <T>(IServiceCollection services, ServiceAgentSettings settings, Assembly assembly, Action <IServiceProvider, HttpClient> clientCreatedAction, Action <string, IHttpClientBuilder> clientBuiltAction) where T : AgentBase { RegisterAgentType <T>(services, settings, clientCreatedAction, clientBuiltAction); RegisterCommonServices(services); }
public void ThrowExceptionWhenNonHttpsSchemeUsedWithBasicAuthentication() { var serviceAgentSettings = new ServiceAgentSettings { }; var settings = new ServiceSettings { AuthScheme = AuthScheme.Basic, BasicAuthUserName = "******", BasicAuthPassword = "******", Scheme = HttpSchema.Http, Host = "test.be", Path = "api" }; var clientFactory = new HttpClientFactory(CreateServiceProvider(settings)); Assert.Throws <ServiceAgentException>(() => clientFactory.CreateClient(serviceAgentSettings, settings)); }
private void SetApiKeyAuthHeader(HttpClient client, ServiceAgentSettings serviceAgentSettings, ServiceSettings settings) { if (settings.UseGlobalApiKey) { client.DefaultRequestHeaders.Add(settings.ApiKeyHeaderName, serviceAgentSettings.GlobalApiKey); } else { client.DefaultRequestHeaders.Add(settings.ApiKeyHeaderName, settings.ApiKey); } }
private IServiceProvider CreateServiceProvider(ServiceAgentSettings settings) { var serviceProviderMock = new Mock <IServiceProvider>(); if (settings != null) { serviceProviderMock.Setup(p => p.GetService(typeof(IOptions <ServiceAgentSettings>))).Returns(Options.Create(settings)); } return(serviceProviderMock.Object); }
public void DoesntThrowExceptionWhenNonHttpsSchemeUsedWithBasicAuthenticationInDevelopmentEnvironment() { var serviceAgentSettings = new ServiceAgentSettings { }; var settings = new ServiceSettings { AuthScheme = AuthScheme.Basic, BasicAuthUserName = "******", BasicAuthPassword = "******", Scheme = HttpSchema.Http, Host = "test.be", Path = "api" }; var clientFactory = new HttpClientFactory(CreateServiceProvider(settings, isDevelopmentEnvironment: true)); clientFactory.CreateClient(serviceAgentSettings, settings); }
public void CreateClientWithCustomApiKeyHeader() { var serviceAgentSettings = new ServiceAgentSettings(); var settings = new ServiceSettings { AuthScheme = AuthScheme.ApiKey, ApiKeyHeaderName = "api-key", ApiKey = "localapikey", Scheme = HttpSchema.Http, Host = "test.be", Path = "api" }; var clientFactory = new HttpClientFactory(CreateServiceProvider(settings)); var client = clientFactory.CreateClient(serviceAgentSettings, settings); Assert.NotNull(client); Assert.Equal("localapikey", client.DefaultRequestHeaders.First(h => h.Key == "api-key").Value.First()); }
private ServiceSettings GetServiceSettings(ServiceAgentSettings serviceAgentSettings) { if (serviceAgentSettings.Services.Any(s => s.Key == GetType().Name)) { return(serviceAgentSettings.Services[GetType().Name]); } if (serviceAgentSettings.Services.Any(s => GetType().Name.Contains(s.Key))) { return(serviceAgentSettings.Services.FirstOrDefault(s => GetType().Name.Contains(s.Key)).Value); } throw new Exception($"Settings not found for service agent {GetType().Name}"); }
public void CreateDefaultClient() { var serviceAgentSettings = new ServiceAgentSettings(); var settings = new ServiceSettings { Scheme = HttpSchema.Http, Host = "test.be", Path = "api" }; var clientFactory = new HttpClientFactory(CreateServiceProvider(settings)); var client = clientFactory.CreateClient(serviceAgentSettings, settings); Assert.NotNull(client); Assert.Equal("http://test.be/api/", client.BaseAddress.AbsoluteUri); Assert.Equal("application/json", client.DefaultRequestHeaders.Accept.Single().MediaType); Assert.Null(client.DefaultRequestHeaders.Authorization); }
public void CreateClientWithBasicAuthenticationAndDomain() { var serviceAgentSettings = new ServiceAgentSettings { }; var settings = new ServiceSettings { AuthScheme = AuthScheme.Basic, BasicAuthDomain = "ICA", BasicAuthUserName = "******", BasicAuthPassword = "******", Host = "test.be", Path = "api" }; var clientFactory = new HttpClientFactory(CreateServiceProvider(settings)); var client = clientFactory.CreateClient(serviceAgentSettings, settings); Assert.NotNull(client); Assert.Equal(AuthScheme.Basic, client.DefaultRequestHeaders.Authorization.Scheme); Assert.Equal("SUNBXEFsYWRkaW46T3BlblNlc2FtZQ==", client.DefaultRequestHeaders.Authorization.Parameter); }
public void CreateClientWithOAuthClientCredentials() { var serviceAgentSettings = new ServiceAgentSettings { }; var settings = new ServiceSettings { AuthScheme = AuthScheme.OAuthClientCredentials, OAuthClientId = "clientId", OAuthClientSecret = "clientSecret", Host = "test.be", Path = "api" }; var clientFactory = new HttpClientFactory(CreateServiceProvider(settings)); var client = clientFactory.CreateClient(serviceAgentSettings, settings); Assert.NotNull(client); Assert.Equal(AuthScheme.Bearer, client.DefaultRequestHeaders.Authorization.Scheme); Assert.Equal("AccessToken", client.DefaultRequestHeaders.Authorization.Parameter); }
public void CreateClientWithBasicAuthentication() { var serviceAgentSettings = new ServiceAgentSettings { }; var settings = new ServiceSettings { AuthScheme = AuthScheme.Basic, BasicAuthUserName = "******", BasicAuthPassword = "******", Host = "test.be", Path = "api" }; var clientFactory = new HttpClientFactory(CreateServiceProvider(settings)); var client = clientFactory.CreateClient(serviceAgentSettings, settings); Assert.NotNull(client); Assert.Equal(AuthScheme.Basic, client.DefaultRequestHeaders.Authorization.Scheme); Assert.Equal("QWxhZGRpbjpPcGVuU2VzYW1l", client.DefaultRequestHeaders.Authorization.Parameter); }
public void AfterClientCreatedGetsRaised() { var serviceAgentSettings = new ServiceAgentSettings(); var settings = new ServiceSettings { AuthScheme = AuthScheme.Bearer, Scheme = HttpSchema.Http, Host = "test.be", Path = "api" }; var clientFactory = new HttpClientFactory(CreateServiceProvider(settings)); HttpClient passedClient = null; clientFactory.AfterClientCreated += (sp, c) => passedClient = c; clientFactory.CreateClient(serviceAgentSettings, settings); Assert.NotNull(passedClient); }
private IServiceProvider CreateServiceProvider(ServiceAgentSettings settings) { var serviceProviderMock = new Mock<IServiceProvider>(); if (settings != null) serviceProviderMock.Setup(p => p.GetService(typeof(IOptions<ServiceAgentSettings>))).Returns(Options.Create(settings)); var authContextMock = new Mock<IAuthContext>(); authContextMock.Setup(c => c.UserToken).Returns("TokenValue"); serviceProviderMock.Setup(p => p.GetService(typeof(IAuthContext))).Returns(authContextMock.Object); serviceProviderMock.Setup(p => p.GetService(typeof(IHttpClientFactory))).Returns(new HttpClientFactory(serviceProviderMock.Object)); return serviceProviderMock.Object; }
private static void RegisterServices(IServiceCollection services, ServiceAgentSettings settings, Assembly assembly, Action <IServiceProvider, HttpClient> clientAction) { RegisterClientFactory(services, clientAction); var assemblyTypes = assembly.GetTypes(); foreach (var item in settings.Services) { var type = assemblyTypes.Single(t => t.GetTypeInfo().BaseType == typeof(AgentBase) && t.Name.StartsWith(item.Key)); RegisterAgentType(services, assemblyTypes, type); } services.AddScoped <ITokenHelper, TokenHelper>(); }
private static void RegisterAgentType <T>(IServiceCollection services, ServiceAgentSettings settings, Action <IServiceProvider, HttpClient> clientCreatedAction, Action <string, IHttpClientBuilder> clientBuiltAction) where T : class { // the type specified will be registered in the service collection as a transient service IHttpClientBuilder builder = services.AddHttpClient <T>(typeof(T).Name).ConfigureHttpClient((serviceProvider, client) => { var serviceSettings = settings.GetServiceSettings(typeof(T).Name); ConfigureHttpClient(serviceProvider, client, serviceSettings, clientCreatedAction); }); // invoke additional actions for HttpClientBuilder ex. attaching DelegatingHandlers clientBuiltAction?.Invoke(typeof(T).Name, builder); }
public ServiceAgentInstaller() { var settings = new ServiceAgentSettings(); this.processInstaller = new ServiceProcessInstaller(); this.serviceInstaller = new ServiceInstaller(); this.processInstaller.Account = settings.Account; this.processInstaller.Password = settings.ServiceAccountPassword; this.processInstaller.Username = settings.ServiceAccountUser; this.serviceInstaller.Description = settings.ServiceDescription; this.serviceInstaller.ServiceName = settings.ServiceName; this.serviceInstaller.StartType = settings.ServiceStartMode; this.Installers.AddRange(new Installer[] { this.processInstaller, this.serviceInstaller }); }
private static void RegisterServices(IServiceCollection services, ServiceAgentSettings settings, Assembly assembly, Action <IServiceProvider, HttpClient> clientCreatedAction, Action <string, IHttpClientBuilder> clientBuiltAction) { var assemblyTypes = assembly.GetTypes(); foreach (var item in settings.Services) { var type = assemblyTypes.Single(t => typeof(AgentBase).IsAssignableFrom(t.GetTypeInfo().BaseType) && t.Name.StartsWith(item.Key)); RegisterAgentType(services, type, settings, clientCreatedAction, clientBuiltAction); } RegisterCommonServices(services); }
private IServiceProvider CreateServiceProvider(ServiceAgentSettings settings) { var serviceProviderMock = new Mock <IServiceProvider>(); if (settings != null) { serviceProviderMock.Setup(p => p.GetService(typeof(IOptions <ServiceAgentSettings>))).Returns(Options.Create(settings)); } var authContextMock = new Mock <IAuthContext>(); authContextMock.Setup(c => c.UserToken).Returns("TokenValue"); serviceProviderMock.Setup(p => p.GetService(typeof(IAuthContext))).Returns(authContextMock.Object); serviceProviderMock.Setup(p => p.GetService(typeof(IRequestHeaderHelper))).Returns(new RequestHeaderHelper(serviceProviderMock.Object)); return(serviceProviderMock.Object); }
private void ServiceAgentSettingsIsRegistratedAsScoped() { var services = new ServiceCollection(); services.AddSingleServiceAgent <TestAgent>(settings => { settings.AuthScheme = AuthScheme.Bearer; settings.Host = "test.be"; settings.Path = "api"; settings.Port = "5000"; settings.Scheme = HttpSchema.Http; settings.UseGlobalApiKey = true; settings.ApiKey = "localapikey"; }); var registrations = services.Where(sd => sd.ServiceType == typeof(IConfigureOptions <ServiceAgentSettings>)) .ToArray(); Assert.Equal(1, registrations.Count()); Assert.Equal(ServiceLifetime.Singleton, registrations[0].Lifetime); var configOptions = registrations[0].ImplementationInstance as IConfigureOptions <ServiceAgentSettings>; Assert.NotNull(configOptions); var serviceAgentSettings = new ServiceAgentSettings(); configOptions.Configure(serviceAgentSettings); Assert.Equal(1, serviceAgentSettings.Services.Count); var serviceSettings = serviceAgentSettings.Services["TestAgent"]; Assert.NotNull(serviceSettings); Assert.Equal(AuthScheme.Bearer, serviceSettings.AuthScheme); Assert.Equal("test.be", serviceSettings.Host); Assert.Equal("api", serviceSettings.Path); Assert.Equal("5000", serviceSettings.Port); Assert.Equal(HttpSchema.Http, serviceSettings.Scheme); Assert.False(serviceSettings.UseGlobalApiKey); Assert.Equal("localapikey", serviceSettings.ApiKey); }
public void CreateClientWithHeaders() { var serviceAgentSettings = new ServiceAgentSettings(); var headers = new Dictionary <string, string>() { { "api-key", "localapikey" }, { "X-Custom-Header", "customvalue" }, }; var settings = new ServiceSettings { Headers = headers, Scheme = HttpSchema.Http, Host = "test.be", Path = "api" }; var clientFactory = new HttpClientFactory(CreateServiceProvider(settings)); var client = clientFactory.CreateClient(serviceAgentSettings, settings); Assert.NotNull(client); Assert.Equal("localapikey", client.DefaultRequestHeaders.First(h => h.Key == "api-key").Value.First()); Assert.Equal("customvalue", client.DefaultRequestHeaders.First(h => h.Key == "X-Custom-Header").Value.First()); }
public HttpClient CreateClient(ServiceAgentSettings serviceAgentSettings, ServiceSettings settings) { var client = new HttpClient { BaseAddress = new Uri(settings.Url) }; client.DefaultRequestHeaders.Accept.Clear(); client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); switch (settings.AuthScheme) { case AuthScheme.OAuthClientCredentials: SetOAuthClientCredentialsAuthHeader(client, settings); break; case AuthScheme.Bearer: SetBearerAuthHeader(client); break; case AuthScheme.Basic: SetBasicAuthHeader(client, settings); break; default: break; } if (settings.Headers != null) { foreach (var header in settings?.Headers) { client.DefaultRequestHeaders.Add(header.Key, header.Value); } } if (AfterClientCreated != null) { AfterClientCreated(_serviceProvider, client); } return(client); }
private void MultipleServiceAgents() { var services = new ServiceCollection(); services.AddServiceAgents(settings => { settings.FileName = Path.Combine(Directory.GetCurrentDirectory(), "_TestData/serviceagentconfig_2.json"); }, assembly: typeof(AddServiceAgentsTests).GetTypeInfo().Assembly); var registrations = services.Where(sd => sd.ServiceType == typeof(IConfigureOptions <ServiceAgentSettings>)) .ToArray(); var configOptions = registrations[0].ImplementationInstance as IConfigureOptions <ServiceAgentSettings>; Assert.NotNull(configOptions); var serviceAgentSettings = new ServiceAgentSettings(); configOptions.Configure(serviceAgentSettings); Assert.Equal(2, serviceAgentSettings.Services.Count); var serviceSettings = serviceAgentSettings.Services["TestAgent"]; Assert.NotNull(serviceSettings); Assert.Equal("None", serviceSettings.AuthScheme); Assert.Equal("test.be", serviceSettings.Host); Assert.Equal("api", serviceSettings.Path); Assert.Equal("5001", serviceSettings.Port); Assert.Equal(HttpSchema.Http, serviceSettings.Scheme); serviceSettings = serviceAgentSettings.Services["OtherTestAgent"]; Assert.NotNull(serviceSettings); Assert.Equal(AuthScheme.Bearer, serviceSettings.AuthScheme); Assert.Equal("other.be", serviceSettings.Host); Assert.Equal("path", serviceSettings.Path); Assert.Equal("5002", serviceSettings.Port); Assert.Equal(HttpSchema.Https, serviceSettings.Scheme); }