diff --git a/src/CallfireApiClient.IntegrationTests/Api/ProxyIntegrationTest.cs b/src/CallfireApiClient.IntegrationTests/Api/ProxyIntegrationTest.cs index 0ab788f..32c1a70 100644 --- a/src/CallfireApiClient.IntegrationTests/Api/ProxyIntegrationTest.cs +++ b/src/CallfireApiClient.IntegrationTests/Api/ProxyIntegrationTest.cs @@ -9,11 +9,28 @@ public class ProxyIntegrationTest [Test] public void QueryCallfireThroughProxyWithBasicAuth() { - RestApiClient.getClientConfig().Add(ClientConstants.PROXY_ADDRESS_PROPERTY, "localhost:3128"); - RestApiClient.getClientConfig().Add(ClientConstants.PROXY_CREDENTIALS_PROPERTY, "proxyuser:proxypass"); + RestApiClient.getApplicationConfig().Add(ClientConstants.PROXY_ADDRESS_PROPERTY, "localhost:3128"); + RestApiClient.getApplicationConfig().Add(ClientConstants.PROXY_CREDENTIALS_PROPERTY, "proxyuser:proxypass"); CallfireClient Client = new CallfireClient("", ""); var account = Client.MeApi.GetAccount(); Console.WriteLine("account: " + account); } + + [Test] + public void QueryCallfireThroughProxyWithProxy() + { + CallfireClient Client = new CallfireClient("", ""); + + Client.SetClientConfig(new ClientConfig(){ + ApiBasePath = "https://api.callfire.com/v2", + ProxyAddress = "localhost", + ProxyPort = 3128, + ProxyLogin = "proxyuser", + ProxyPassword = "proxypass" + }); + + var account = Client.MeApi.GetAccount(); + Console.WriteLine("account: " + account); + } } } diff --git a/src/CallfireApiClient/CallfireApiClient.csproj b/src/CallfireApiClient/CallfireApiClient.csproj index e60c1d6..697aa96 100644 --- a/src/CallfireApiClient/CallfireApiClient.csproj +++ b/src/CallfireApiClient/CallfireApiClient.csproj @@ -179,6 +179,7 @@ + diff --git a/src/CallfireApiClient/CallfireClient.cs b/src/CallfireApiClient/CallfireClient.cs index f461f25..c1f23b2 100644 --- a/src/CallfireApiClient/CallfireClient.cs +++ b/src/CallfireApiClient/CallfireClient.cs @@ -16,6 +16,12 @@ namespace CallfireApiClient /// public class CallfireClient { + + public void SetClientConfig(ClientConfig config) + { + RestApiClient.ClientConfig = config; + } + public RestApiClient RestApiClient { get; set; } readonly Lazy _MeApi; diff --git a/src/CallfireApiClient/ClientConfig.cs b/src/CallfireApiClient/ClientConfig.cs new file mode 100644 index 0000000..bc4babf --- /dev/null +++ b/src/CallfireApiClient/ClientConfig.cs @@ -0,0 +1,39 @@ + +namespace CallfireApiClient +{ + /// + /// object to include client configuration parameters + /// + public class ClientConfig + { + /// + /// Returns base URL path for all Callfire's API 2.0 endpoints + /// / + /// string representation of base URL path + public string ApiBasePath { get; set; } + + /// + /// Returns proxy adress for all Callfire's API 2.0 endpoints + /// / + /// string representation of proxy adress + public string ProxyAddress { get; set; } + + /// + /// Returns proxy port for all Callfire's API 2.0 endpoints + /// / + /// string representation of proxy port + public int ProxyPort { get; set; } + + /// + /// Returns proxy login for all Callfire's API 2.0 endpoints + /// / + /// string representation of proxy login + public string ProxyLogin { get; set; } + + /// + /// Returns proxy password for all Callfire's API 2.0 endpoints + /// / + /// string representation of proxy login + public string ProxyPassword { get; set; } + } +} \ No newline at end of file diff --git a/src/CallfireApiClient/ClientConstants.cs b/src/CallfireApiClient/ClientConstants.cs index 4aa465e..0ff528b 100644 --- a/src/CallfireApiClient/ClientConstants.cs +++ b/src/CallfireApiClient/ClientConstants.cs @@ -13,6 +13,8 @@ public static class ClientConstants public const string LOG_FILE_LISTENER_NAME = "CallfireLogFile"; public const string CONFIG_API_BASE_PATH = "CallFireBasePath"; + public const string API_BASE_PATH_DEFAULT_VALUE = "https://api.callfire.com/v2"; + public const string CONFIG_CLIENT_NAME = "CallFireClientVersion"; public const string PROXY_ADDRESS_PROPERTY = "com.callfire.api.client.proxy.address"; @@ -24,5 +26,7 @@ public static class ClientConstants public const string GENERIC_HELP_LINK = "https://answers.callfire.com/hc/en-us"; public static readonly DateTime EPOCH = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); + + public static string DEFAULT_FILE_CONTENT_TYPE = "application/octet-stream"; } } \ No newline at end of file diff --git a/src/CallfireApiClient/RestApiClient.cs b/src/CallfireApiClient/RestApiClient.cs index 4e52e22..36972f4 100644 --- a/src/CallfireApiClient/RestApiClient.cs +++ b/src/CallfireApiClient/RestApiClient.cs @@ -1,6 +1,5 @@ using System; using RestSharp; -using CallfireApiClient.Api.Common.Model.Request; using RestSharp.Authenticators; using System.Collections.Generic; using System.Configuration; @@ -10,8 +9,6 @@ using System.Collections; using System.Text; using System.IO; -using System.Reflection; -using System.Diagnostics; using System.Net; namespace CallfireApiClient @@ -21,12 +18,28 @@ namespace CallfireApiClient /// public class RestApiClient { - private const string DEFAULT_FILE_CONTENT_TYPE = "application/octet-stream"; - - private readonly Logger Logger = new Logger(); private readonly ISerializer JsonSerializer; private readonly IDeserializer JsonDeserializer; - private static KeyValueConfigurationCollection ClientConfig; + private static Logger Logger = new Logger(); + + private static KeyValueConfigurationCollection ApplicationConfig; + + private ClientConfig _ClientConfig = new ClientConfig(); + + public ClientConfig ClientConfig + { + get + { + return _ClientConfig; + } + + set + { + _ClientConfig = value; + RestClient.BaseUrl = !string.IsNullOrWhiteSpace(value.ApiBasePath) ? new Uri(value.ApiBasePath) : RestClient.BaseUrl; + SetUpRestClientProxy(); + } + } /// /// RestSharp client configured to query Callfire API @@ -34,12 +47,6 @@ public class RestApiClient /// RestSharp client interface public IRestClient RestClient { get; set; } - /// - /// Returns base URL path for all Callfire's API 2.0 endpoints - /// / - /// string representation of base URL path - public string ApiBasePath { get; private set; } - /// /// Returns HTTP request filters associated with API client /// @@ -50,16 +57,16 @@ public class RestApiClient /// loads client configuration /// static RestApiClient() { - ClientConfig = LoadAppSettings(); + ApplicationConfig = LoadAppSettings(); } /// /// Get client configuration /// /// configuration properties collection - public static KeyValueConfigurationCollection getClientConfig() + public static KeyValueConfigurationCollection getApplicationConfig() { - return ClientConfig; + return ApplicationConfig; } /// @@ -70,19 +77,60 @@ public static KeyValueConfigurationCollection getClientConfig() /// public RestApiClient(IAuthenticator authenticator) { - ApiBasePath = ClientConfig[ClientConstants.CONFIG_API_BASE_PATH].Value; + SetAppSettings(); + JsonSerializer = new CallfireJsonConverter(); JsonDeserializer = JsonSerializer as IDeserializer; - RestClient = new RestClient(ApiBasePath); + RestClient = new RestClient(_ClientConfig.ApiBasePath); RestClient.Authenticator = authenticator; RestClient.UserAgent = this.GetType().Assembly.GetName().Name + "-csharp-" + this.GetType().Assembly.GetName().Version; RestClient.AddHandler("application/json", JsonDeserializer); + Filters = new SortedSet(); + + SetUpRestClientProxy(); + } + + /// + /// Loads client's app settings config section + /// + public static KeyValueConfigurationCollection LoadAppSettings() + { + var path = typeof(RestApiClient).Assembly.Location; + var config = ConfigurationManager.OpenExeConfiguration(path); + var appSettings = (AppSettingsSection)config.GetSection("appSettings"); + return appSettings.Settings; + } + + /// + /// Set up client's app config parameters from app settings + /// + private void SetAppSettings() + { + //basePath + var basePath = ApplicationConfig[ClientConstants.CONFIG_API_BASE_PATH]; - String proxyAddress = ClientConfig[ClientConstants.PROXY_ADDRESS_PROPERTY]?.Value; - String proxyCredentials = ClientConfig[ClientConstants.PROXY_CREDENTIALS_PROPERTY]?.Value; + if (basePath == null || string.IsNullOrWhiteSpace(basePath.Value)) + { + _ClientConfig.ApiBasePath = ClientConstants.API_BASE_PATH_DEFAULT_VALUE; + } + else + { + _ClientConfig.ApiBasePath = basePath.Value; + } + + //proxy + String proxyAddress = ApplicationConfig[ClientConstants.PROXY_ADDRESS_PROPERTY]?.Value; + String proxyCredentials = ApplicationConfig[ClientConstants.PROXY_CREDENTIALS_PROPERTY]?.Value; + ConfigureProxyParameters(proxyAddress, proxyCredentials); + } + /// + /// Configure app proxy parameters + /// + private void ConfigureProxyParameters(String proxyAddress, String proxyCredentials) + { if (!String.IsNullOrEmpty(proxyAddress)) { Logger.Debug("Configuring proxy host for client: {} auth: {}", proxyAddress, proxyCredentials); @@ -90,40 +138,39 @@ public RestApiClient(IAuthenticator authenticator) String[] parsedAddress = proxyAddress.Split(delimiterChars); String[] parsedCredentials = (proxyCredentials == null ? "" : proxyCredentials).Split(delimiterChars); int portValue = parsedAddress.Length > 1 ? ClientUtils.StrToIntDef(parsedAddress[1], ClientConstants.DEFAULT_PROXY_PORT) : ClientConstants.DEFAULT_PROXY_PORT; - WebProxy proxy = new WebProxy(parsedAddress[0], portValue); - + if (!String.IsNullOrEmpty(proxyCredentials)) { if (parsedCredentials.Length > 1) { - proxy.Credentials = new NetworkCredential(parsedCredentials[0], parsedCredentials[1]); + _ClientConfig.ProxyAddress = parsedAddress[0]; + _ClientConfig.ProxyPort = portValue; + _ClientConfig.ProxyLogin = parsedCredentials[0]; + _ClientConfig.ProxyPassword = parsedCredentials[1]; } else { Logger.Debug("Proxy credentials have wrong format, must be username:password"); } } - RestClient.Proxy = proxy; } - - Filters = new SortedSet(); } /// - /// Loads client's app settings config section + /// Set up client's app proxy /// - public static KeyValueConfigurationCollection LoadAppSettings() + private void SetUpRestClientProxy() { - var path = typeof(RestApiClient).Assembly.Location; - var config = ConfigurationManager.OpenExeConfiguration(path); - var appSettings = (AppSettingsSection)config.GetSection("appSettings"); - var basePath = appSettings.Settings[ClientConstants.CONFIG_API_BASE_PATH]; - if (basePath == null || string.IsNullOrWhiteSpace(basePath.Value)) + if (!String.IsNullOrEmpty(_ClientConfig.ProxyAddress)) + { + WebProxy proxy = new WebProxy(_ClientConfig.ProxyAddress, _ClientConfig.ProxyPort); + proxy.Credentials = new NetworkCredential(_ClientConfig.ProxyLogin, _ClientConfig.ProxyPassword); + RestClient.Proxy = proxy; + } + else { - throw new CallfireClientException("Cannot read " + ClientConstants.CONFIG_API_BASE_PATH + - " property from configuration file at: " + path + ".config"); + Logger.Debug("Proxy wasn't configured, please check input parameters"); } - return appSettings.Settings; } /// @@ -266,7 +313,7 @@ public Stream GetFileData(string path, IEnumerable> var queryParams = ClientUtils.BuildQueryParams("name", fileName); var restRequest = CreateRestRequest(path, Method.POST, queryParams); restRequest.AddHeader("Content-Type", "multipart/form-data"); - restRequest.AddFileBytes("file", File.ReadAllBytes(filePath), Path.GetFileName(filePath), contentType != null ? contentType : DEFAULT_FILE_CONTENT_TYPE); + restRequest.AddFileBytes("file", File.ReadAllBytes(filePath), Path.GetFileName(filePath), contentType != null ? contentType : ClientConstants.DEFAULT_FILE_CONTENT_TYPE); restRequest.AddParameter("name", fileName); return DoRequest(restRequest); } @@ -294,7 +341,7 @@ public Stream GetFileData(string path, IEnumerable> var restRequest = CreateRestRequest(path, Method.POST, queryParams); restRequest.AddHeader("Content-Type", "multipart/form-data"); - restRequest.AddFileBytes("file", File.ReadAllBytes(filePath), Path.GetFileName(filePath), DEFAULT_FILE_CONTENT_TYPE); + restRequest.AddFileBytes("file", File.ReadAllBytes(filePath), Path.GetFileName(filePath), ClientConstants.DEFAULT_FILE_CONTENT_TYPE); restRequest.AddParameter("name", fileName); return DoRequest(restRequest); }