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
200 changes: 192 additions & 8 deletions src/corelib/Providers/Rackspace/CloudLoadBalancerProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
using net.openstack.Providers.Rackspace.Objects.LoadBalancers.Request;
using net.openstack.Providers.Rackspace.Objects.LoadBalancers.Response;
using net.openstack.Providers.Rackspace.Validators;
using Newtonsoft.Json.Linq;
using CancellationToken = System.Threading.CancellationToken;
using JsonRestServices = JSIStudios.SimpleRESTServices.Client.Json.JsonRestServices;

Expand Down Expand Up @@ -945,25 +946,119 @@ public Task<IEnumerable<string>> ListAllowedDomainsAsync(CancellationToken cance
/// <inheritdoc/>
public Task<IEnumerable<LoadBalancer>> ListBillableLoadBalancersAsync(DateTimeOffset? startTime, DateTimeOffset? endTime, int? offset, int? limit, CancellationToken cancellationToken)
{
throw new NotImplementedException();
if (endTime < startTime)
throw new ArgumentOutOfRangeException("endTime");
if (offset < 0)
throw new ArgumentOutOfRangeException("offset");
if (limit <= 0)
throw new ArgumentOutOfRangeException("limit");

UriTemplate template = new UriTemplate("/loadbalancers/billable?startTime={startTime}&endTime={endTime}&offset={offset}&limit={limit}");
var parameters = new Dictionary<string, string>();
if (startTime != null)
parameters.Add("startTime", startTime.Value.ToString("yyyy-MM-dd"));
if (endTime != null)
parameters.Add("endTime", endTime.Value.ToString("yyyy-MM-dd"));
if (offset != null)
parameters.Add("offset", offset.ToString());
if (limit != null)
parameters.Add("limit", limit.ToString());

Func<Task<Tuple<IdentityToken, Uri>>, HttpWebRequest> prepareRequest =
PrepareRequestAsyncFunc(HttpMethod.GET, template, parameters);

Func<Task<HttpWebRequest>, Task<ListLoadBalancersResponse>> requestResource =
GetResponseAsyncFunc<ListLoadBalancersResponse>(cancellationToken);

Func<Task<ListLoadBalancersResponse>, IEnumerable<LoadBalancer>> resultSelector =
task => (task.Result != null ? task.Result.LoadBalancers : null) ?? Enumerable.Empty<LoadBalancer>();

return AuthenticateServiceAsync(cancellationToken)
.ContinueWith(prepareRequest)
.ContinueWith(requestResource).Unwrap()
.ContinueWith(resultSelector);
}

/// <inheritdoc/>
public Task<IEnumerable<LoadBalancerUsage>> ListAccountLevelUsageAsync(DateTimeOffset? startTime, DateTimeOffset? endTime, CancellationToken cancellationToken)
{
throw new NotImplementedException();
if (endTime < startTime)
throw new ArgumentOutOfRangeException("endTime");

UriTemplate template = new UriTemplate("/loadbalancers/usage?startTime={startTime}&endTime={endTime}");
var parameters = new Dictionary<string, string>();
if (startTime != null)
parameters.Add("startTime", startTime.Value.ToString("yyyy-MM-dd"));
if (endTime != null)
parameters.Add("endTime", endTime.Value.ToString("yyyy-MM-dd"));

Func<Task<Tuple<IdentityToken, Uri>>, HttpWebRequest> prepareRequest =
PrepareRequestAsyncFunc(HttpMethod.GET, template, parameters);

Func<Task<HttpWebRequest>, Task<ListLoadBalancerUsageResponse>> requestResource =
GetResponseAsyncFunc<ListLoadBalancerUsageResponse>(cancellationToken);

Func<Task<ListLoadBalancerUsageResponse>, IEnumerable<LoadBalancerUsage>> resultSelector =
task => (task.Result != null ? task.Result.UsageRecords : null) ?? Enumerable.Empty<LoadBalancerUsage>();

return AuthenticateServiceAsync(cancellationToken)
.ContinueWith(prepareRequest)
.ContinueWith(requestResource).Unwrap()
.ContinueWith(resultSelector);
}

/// <inheritdoc/>
public Task<IEnumerable<LoadBalancerUsage>> ListHistoricalUsageAsync(LoadBalancerId loadBalancerId, DateTimeOffset? startTime, DateTimeOffset? endTime, CancellationToken cancellationToken1)
public Task<IEnumerable<LoadBalancerUsage>> ListHistoricalUsageAsync(LoadBalancerId loadBalancerId, DateTimeOffset? startTime, DateTimeOffset? endTime, CancellationToken cancellationToken)
{
throw new NotImplementedException();
if (loadBalancerId == null)
throw new ArgumentNullException("loadBalancerId");
if (endTime < startTime)
throw new ArgumentOutOfRangeException("endTime");

UriTemplate template = new UriTemplate("/loadbalancers/{loadBalancerId}/usage?startTime={startTime}&endTime={endTime}");
var parameters = new Dictionary<string, string> { { "loadBalancerId", loadBalancerId.Value } };
if (startTime != null)
parameters.Add("startTime", startTime.Value.ToString("yyyy-MM-dd"));
if (endTime != null)
parameters.Add("endTime", endTime.Value.ToString("yyyy-MM-dd"));

Func<Task<Tuple<IdentityToken, Uri>>, HttpWebRequest> prepareRequest =
PrepareRequestAsyncFunc(HttpMethod.GET, template, parameters);

Func<Task<HttpWebRequest>, Task<ListLoadBalancerUsageResponse>> requestResource =
GetResponseAsyncFunc<ListLoadBalancerUsageResponse>(cancellationToken);

Func<Task<ListLoadBalancerUsageResponse>, IEnumerable<LoadBalancerUsage>> resultSelector =
task => (task.Result != null ? task.Result.UsageRecords : null) ?? Enumerable.Empty<LoadBalancerUsage>();

return AuthenticateServiceAsync(cancellationToken)
.ContinueWith(prepareRequest)
.ContinueWith(requestResource).Unwrap()
.ContinueWith(resultSelector);
}

/// <inheritdoc/>
public Task<IEnumerable<LoadBalancerUsage>> ListCurrentUsageAsync(LoadBalancerId loadBalancerId, CancellationToken cancellationToken)
{
throw new NotImplementedException();
if (loadBalancerId == null)
throw new ArgumentNullException("loadBalancerId");

UriTemplate template = new UriTemplate("/loadbalancers/{loadBalancerId}/usage/current");
var parameters = new Dictionary<string, string> { { "loadBalancerId", loadBalancerId.Value } };

Func<Task<Tuple<IdentityToken, Uri>>, HttpWebRequest> prepareRequest =
PrepareRequestAsyncFunc(HttpMethod.GET, template, parameters);

Func<Task<HttpWebRequest>, Task<ListLoadBalancerUsageResponse>> requestResource =
GetResponseAsyncFunc<ListLoadBalancerUsageResponse>(cancellationToken);

Func<Task<ListLoadBalancerUsageResponse>, IEnumerable<LoadBalancerUsage>> resultSelector =
task => (task.Result != null ? task.Result.UsageRecords : null) ?? Enumerable.Empty<LoadBalancerUsage>();

return AuthenticateServiceAsync(cancellationToken)
.ContinueWith(prepareRequest)
.ContinueWith(requestResource).Unwrap()
.ContinueWith(resultSelector);
}

/// <inheritdoc/>
Expand Down Expand Up @@ -1243,19 +1338,108 @@ public Task ClearAccessListAsync(LoadBalancerId loadBalancerId, AsyncCompletionO
/// <inheritdoc/>
public Task<HealthMonitor> GetHealthMonitorAsync(LoadBalancerId loadBalancerId, CancellationToken cancellationToken)
{
throw new NotImplementedException();
if (loadBalancerId == null)
throw new ArgumentNullException("loadBalancerId");

UriTemplate template = new UriTemplate("/loadbalancers/{loadBalancerId}/healthmonitor");
var parameters = new Dictionary<string, string>()
{
{ "loadBalancerId", loadBalancerId.Value }
};

Func<Task<Tuple<IdentityToken, Uri>>, HttpWebRequest> prepareRequest =
PrepareRequestAsyncFunc(HttpMethod.GET, template, parameters);

Func<Task<HttpWebRequest>, Task<JObject>> requestResource =
GetResponseAsyncFunc<JObject>(cancellationToken);

Func<Task<JObject>, HealthMonitor> resultSelector =
task =>
{
if (task.Result == null)
return null;

JObject healthMonitorObject = task.Result["healthMonitor"] as JObject;
if (healthMonitorObject == null)
return null;

return HealthMonitor.FromJObject(healthMonitorObject);
};

return AuthenticateServiceAsync(cancellationToken)
.ContinueWith(prepareRequest)
.ContinueWith(requestResource).Unwrap()
.ContinueWith(resultSelector);
}

/// <inheritdoc/>
public Task SetHealthMonitorAsync(LoadBalancerId loadBalancerId, HealthMonitor monitor, AsyncCompletionOption completionOption, CancellationToken cancellationToken, IProgress<LoadBalancer> progress)
{
throw new NotImplementedException();
if (loadBalancerId == null)
throw new ArgumentNullException("loadBalancerId");
if (monitor == null)
throw new ArgumentNullException("monitor");

UriTemplate template = new UriTemplate("/loadbalancers/{loadBalancerId}/healthmonitor");
var parameters = new Dictionary<string, string>()
{
{ "loadBalancerId", loadBalancerId.Value }
};

Func<Task<Tuple<IdentityToken, Uri>>, Task<HttpWebRequest>> prepareRequest =
PrepareRequestAsyncFunc(HttpMethod.PUT, template, parameters, monitor);

Func<Task<HttpWebRequest>, Task<string>> requestResource =
GetResponseAsyncFunc(cancellationToken);

Func<Task<string>, Task<LoadBalancer>> resultSelector =
task =>
{
task.PropagateExceptions();
if (completionOption == AsyncCompletionOption.RequestCompleted)
return WaitForLoadBalancerToLeaveStateAsync(loadBalancerId, LoadBalancerStatus.PendingUpdate, cancellationToken, progress);

return InternalTaskExtensions.CompletedTask(default(LoadBalancer));
};

return AuthenticateServiceAsync(cancellationToken)
.ContinueWith(prepareRequest).Unwrap()
.ContinueWith(requestResource).Unwrap()
.ContinueWith(resultSelector).Unwrap();
}

/// <inheritdoc/>
public Task RemoveHealthMonitorAsync(LoadBalancerId loadBalancerId, AsyncCompletionOption completionOption, CancellationToken cancellationToken, IProgress<LoadBalancer> progress)
{
throw new NotImplementedException();
if (loadBalancerId == null)
throw new ArgumentNullException("loadBalancerId");

UriTemplate template = new UriTemplate("/loadbalancers/{loadBalancerId}/healthmonitor");
var parameters = new Dictionary<string, string>()
{
{ "loadBalancerId", loadBalancerId.Value },
};

Func<Task<Tuple<IdentityToken, Uri>>, HttpWebRequest> prepareRequest =
PrepareRequestAsyncFunc(HttpMethod.DELETE, template, parameters);

Func<Task<HttpWebRequest>, Task<string>> requestResource =
GetResponseAsyncFunc(cancellationToken);

Func<Task<string>, Task<LoadBalancer>> resultSelector =
task =>
{
task.PropagateExceptions();
if (completionOption == AsyncCompletionOption.RequestCompleted)
return WaitForLoadBalancerToLeaveStateAsync(loadBalancerId, LoadBalancerStatus.PendingUpdate, cancellationToken, progress);

return InternalTaskExtensions.CompletedTask(default(LoadBalancer));
};

return AuthenticateServiceAsync(cancellationToken)
.ContinueWith(prepareRequest)
.ContinueWith(requestResource).Unwrap()
.ContinueWith(resultSelector).Unwrap();
}

/// <inheritdoc/>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
namespace net.openstack.Providers.Rackspace.Objects.LoadBalancers
{
using Newtonsoft.Json;

/// <summary>
/// This class models the JSON object used to represent a custom <see cref="HealthMonitor"/>.
/// </summary>
/// <threadsafety static="true" instance="false"/>
/// <preliminary/>
[JsonObject(MemberSerialization.OptIn)]
public class CustomHealthMonitor : HealthMonitor
{
/// <summary>
/// Initializes a new instance of the <see cref="CustomHealthMonitor"/> class
/// during JSON deserialization.
/// </summary>
[JsonConstructor]
protected CustomHealthMonitor()
{
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
{
using System;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

/// <summary>
/// This is the base class for load balancer health monitoring configurations.
Expand All @@ -13,7 +14,6 @@
/// <threadsafety static="true" instance="false"/>
/// <preliminary/>
[JsonObject(MemberSerialization.OptIn)]
[JsonConverter(typeof(HealthMonitor.Converter))]
public abstract class HealthMonitor
{
/// <summary>
Expand Down Expand Up @@ -131,26 +131,28 @@ public int? AttemptsBeforeDeactivation
}
}

/// <inheritdoc/>
protected class Converter : JsonConverter
/// <summary>
/// Deserializes a JSON object to a <see cref="HealthMonitor"/> instance of the proper type.
/// </summary>
/// <param name="jsonObject">The JSON object representing the health monitor.</param>
/// <returns>A <see cref="HealthMonitor"/> object corresponding to the JSON object.</returns>
/// <exception cref="ArgumentNullException">If <paramref name="jsonObject"/> is <c>null</c>.</exception>
public static HealthMonitor FromJObject(JObject jsonObject)
{
/// <inheritdoc/>
public override bool CanConvert(Type objectType)
{
throw new NotImplementedException();
}

/// <inheritdoc/>
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
throw new NotImplementedException();
}

/// <inheritdoc/>
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
if (jsonObject == null)
throw new ArgumentNullException("jsonObject");

JValue typeValue = jsonObject["type"] as JValue;
if (typeValue == null)
return null;

HealthMonitorType type = typeValue.ToObject<HealthMonitorType>();
if (type == HealthMonitorType.Connect)
return jsonObject.ToObject<ConnectionHealthMonitor>();
else if (type == HealthMonitorType.Http || type == HealthMonitorType.Https)
return jsonObject.ToObject<WebServerHealthMonitor>();
else
return jsonObject.ToObject<CustomHealthMonitor>();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.Collections.ObjectModel;
using System.Linq;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

/// <summary>
/// Represents a load balancer configuration.
Expand Down Expand Up @@ -86,7 +87,7 @@ public class LoadBalancerConfiguration<TNodeConfiguration>
/// This is the backing field for the <see cref="HealthMonitor"/> property.
/// </summary>
[JsonProperty("healthMonitor", DefaultValueHandling = DefaultValueHandling.Ignore)]
private HealthMonitor _healthMonitor;
private JObject _healthMonitor;

/// <summary>
/// This is the backing field for the <see cref="Metadata"/> property.
Expand Down Expand Up @@ -190,7 +191,7 @@ public LoadBalancerConfiguration(string name, LoadBalancingProtocol protocol, IE
if (contentCaching.HasValue)
_contentCaching = contentCaching.Value ? LoadBalancerEnabledFlag.True : LoadBalancerEnabledFlag.False;
_connectionThrottle = connectionThrottle;
_healthMonitor = healthMonitor;
_healthMonitor = healthMonitor != null ? JObject.FromObject(healthMonitor) : null;
_metadata = metadata != null ? metadata.ToArray() : null;
_timeout = timeout != null ? (int?)timeout.Value.TotalSeconds : null;
_sessionPersistence = sessionPersistence;
Expand Down Expand Up @@ -340,7 +341,10 @@ public HealthMonitor HealthMonitor
{
get
{
return _healthMonitor;
if (_healthMonitor == null)
return null;

return HealthMonitor.FromJObject(_healthMonitor);
}
}

Expand Down
Loading