Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 19 additions & 2 deletions src/CallfireApiClient.IntegrationTests/Api/ProxyIntegrationTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
}
1 change: 1 addition & 0 deletions src/CallfireApiClient/CallfireApiClient.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@
<Compile Include="InternalServerErrorException.cs" />
<Compile Include="Logger.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="ClientConfig.cs" />
<Compile Include="RequestFilter.cs" />
<Compile Include="ResourceNotFoundException.cs" />
<Compile Include="RestApiClient.cs" />
Expand Down
6 changes: 6 additions & 0 deletions src/CallfireApiClient/CallfireClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@ namespace CallfireApiClient
/// </summary>
public class CallfireClient
{

public void SetClientConfig(ClientConfig config)
{
RestApiClient.ClientConfig = config;
}

public RestApiClient RestApiClient { get; set; }

readonly Lazy<MeApi> _MeApi;
Expand Down
39 changes: 39 additions & 0 deletions src/CallfireApiClient/ClientConfig.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@

namespace CallfireApiClient
{
/// <summary>
/// object to include client configuration parameters
/// <summary>
public class ClientConfig
{
/// <summary>
/// Returns base URL path for all Callfire's API 2.0 endpoints
/// <summary>/
/// <returns>string representation of base URL path</returns>
public string ApiBasePath { get; set; }

/// <summary>
/// Returns proxy adress for all Callfire's API 2.0 endpoints
/// <summary>/
/// <returns>string representation of proxy adress</returns>
public string ProxyAddress { get; set; }

/// <summary>
/// Returns proxy port for all Callfire's API 2.0 endpoints
/// <summary>/
/// <returns>string representation of proxy port</returns>
public int ProxyPort { get; set; }

/// <summary>
/// Returns proxy login for all Callfire's API 2.0 endpoints
/// <summary>/
/// <returns>string representation of proxy login</returns>
public string ProxyLogin { get; set; }

/// <summary>
/// Returns proxy password for all Callfire's API 2.0 endpoints
/// <summary>/
/// <returns>string representation of proxy login</returns>
public string ProxyPassword { get; set; }
}
}
4 changes: 4 additions & 0 deletions src/CallfireApiClient/ClientConstants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand All @@ -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";
}
}
123 changes: 85 additions & 38 deletions src/CallfireApiClient/RestApiClient.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using System;
using RestSharp;
using CallfireApiClient.Api.Common.Model.Request;
using RestSharp.Authenticators;
using System.Collections.Generic;
using System.Configuration;
Expand All @@ -10,8 +9,6 @@
using System.Collections;
using System.Text;
using System.IO;
using System.Reflection;
using System.Diagnostics;
using System.Net;

namespace CallfireApiClient
Expand All @@ -21,25 +18,35 @@ namespace CallfireApiClient
/// </summary>
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();
}
}

/// <summary>
/// RestSharp client configured to query Callfire API
/// <summary>/
/// <returns>RestSharp client interface</returns>
public IRestClient RestClient { get; set; }

/// <summary>
/// Returns base URL path for all Callfire's API 2.0 endpoints
/// <summary>/
/// <returns>string representation of base URL path</returns>
public string ApiBasePath { get; private set; }

/// <summary>
/// Returns HTTP request filters associated with API client
/// </summary>
Expand All @@ -50,16 +57,16 @@ public class RestApiClient
/// loads client configuration
/// </summary>
static RestApiClient() {
ClientConfig = LoadAppSettings();
ApplicationConfig = LoadAppSettings();
}

/// <summary>
/// Get client configuration
/// </summary>
/// <value>configuration properties collection</value>
public static KeyValueConfigurationCollection getClientConfig()
public static KeyValueConfigurationCollection getApplicationConfig()
{
return ClientConfig;
return ApplicationConfig;
}

/// <summary>
Expand All @@ -70,60 +77,100 @@ public static KeyValueConfigurationCollection getClientConfig()
/// </param>
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<RequestFilter>();

SetUpRestClientProxy();
}

/// <summary>
/// Loads client's app settings config section
/// </summary>
public static KeyValueConfigurationCollection LoadAppSettings()
{
var path = typeof(RestApiClient).Assembly.Location;
var config = ConfigurationManager.OpenExeConfiguration(path);
var appSettings = (AppSettingsSection)config.GetSection("appSettings");
return appSettings.Settings;
}

/// <summary>
/// Set up client's app config parameters from app settings
/// </summary>
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);
}

/// <summary>
/// Configure app proxy parameters
/// </summary>
private void ConfigureProxyParameters(String proxyAddress, String proxyCredentials)
{
if (!String.IsNullOrEmpty(proxyAddress))
{
Logger.Debug("Configuring proxy host for client: {} auth: {}", proxyAddress, proxyCredentials);
char[] delimiterChars = { ':' };
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<RequestFilter>();
}

/// <summary>
/// Loads client's app settings config section
/// Set up client's app proxy
/// </summary>
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;
}

/// <summary>
Expand Down Expand Up @@ -266,7 +313,7 @@ public Stream GetFileData(string path, IEnumerable<KeyValuePair<string, object>>
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<T>(restRequest);
}
Expand Down Expand Up @@ -294,7 +341,7 @@ public Stream GetFileData(string path, IEnumerable<KeyValuePair<string, object>>

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<T>(restRequest);
}
Expand Down