Skip to content

Commit

Permalink
Merge pull request #37 from sharwell/Documentation
Browse files Browse the repository at this point in the history
Updated documentation
  • Loading branch information
alanquillin committed Aug 2, 2013
2 parents 7d286a4 + 1e333f7 commit 83365b3
Show file tree
Hide file tree
Showing 36 changed files with 832 additions and 61 deletions.
69 changes: 69 additions & 0 deletions src/corelib/Core/Caching/UserAccessCache.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,46 @@

namespace net.openstack.Core.Caching
{
/// <summary>
/// Provides a thread-safe cache of <see cref="UserAccess"/> objects. A default shared
/// instance is available through <see cref="UserAccessCache.Instance"/>.
/// </summary>
public class UserAccessCache : ICache<UserAccess>
{
private static readonly Lazy<UserAccessCache> _instance = new Lazy<UserAccessCache>(CreateInstance, true);

private readonly ConcurrentDictionary<string, UserAccess> _tokenCache = new ConcurrentDictionary<string, UserAccess>();

/// <summary>
/// Gets a <see cref="UserAccess"/> cached for a particular key, updating the value if necessary.
/// </summary>
/// <remarks>
/// This method returns a previously cached <see cref="UserAccess"/> when possible. If any
/// of the following conditions are met, the <paramref name="refreshCallback"/> function
/// will be called to obtain a new value for <paramref name="key"/> which is then added to
/// the cache, replacing any previously cached value.
///
/// <list type="bullet">
/// <item>The cache does not contain any value associated with <paramref name="key"/>.</item>
/// <item><paramref name="forceCacheRefresh"/> is <c>true</c>.</item>
/// <item>The previously cached <see cref="UserAccess"/> for <paramref name="key"/> has expired
/// (see <see cref="IdentityToken.IsExpired()"/>).</item>
/// </list>
///
/// <para>If any of the above conditions is met and <paramref name="refreshCallback"/> is <c>null</c>,
/// the previously cached value for <paramref name="key"/>, if any, is removed from the cache
/// and the method returns <c>null</c>.</para>
/// </remarks>
/// <param name="key">The key.</param>
/// <param name="refreshCallback">A function which returns a new value for the specified <paramref name="key"/>,
/// or <c>null</c> if no update function available (see remarks). This function may perform a synchronous
/// authentication to an <see cref="IIdentityProvider"/>.</param>
/// <param name="forceCacheRefresh">If <c>true</c>, the value associated with <paramref name="key"/> will be always be refreshed by calling <paramref name="refreshCallback"/>, even if a value is already cached.</param>
/// <returns>
/// The cached <see cref="UserAccess"/> associated with the specified <paramref name="key"/>.
/// If no cached value is available (see remarks), the method returns <c>null</c>.
/// </returns>
/// <exception cref="ArgumentNullException">If <paramref name="key"/> is <c>null</c>.</exception>
public UserAccess Get(string key, Func<UserAccess> refreshCallback, bool forceCacheRefresh = false)
{
UserAccess userAccess;
Expand Down Expand Up @@ -64,6 +98,9 @@ public UserAccess Get(string key, Func<UserAccess> refreshCallback, bool forceCa
return userAccess;
}

/// <summary>
/// Gets a default instance of <see cref="UserAccessCache"/>.
/// </summary>
public static UserAccessCache Instance
{
get
Expand All @@ -84,8 +121,40 @@ private static bool IsValid(UserAccess userAccess)
}
}

/// <summary>
/// Represents a thread-safe cache of objects identified by string keys.
/// </summary>
/// <typeparam name="T">Type type of objects stored in the cache.</typeparam>
public interface ICache<T>
{
/// <summary>
/// Gets a value cached for a particular key, updating the value if necessary.
/// </summary>
/// <remarks>
/// This method returns a previously cached value when possible. If any of the following
/// conditions are met, the <paramref name="refreshCallback"/> function will be called to
/// obtain a new value for <paramref name="key"/> which is then added to the cache,
/// replacing any previously cached value.
///
/// <list type="bullet">
/// <item>The cache does not contain any value associated with <paramref name="key"/>.</item>
/// <item><paramref name="forceCacheRefresh"/> is <c>true</c>.</item>
/// <item>The previously cached value for <paramref name="key"/> is no longer valid. The exact
/// algorithm for determining whether or not a value is valid in implementation-defined.</item>
/// </list>
///
/// <para>If any of the above conditions is met and <paramref name="refreshCallback"/> is <c>null</c>,
/// the previously cached value for <paramref name="key"/>, if any, is removed from the cache
/// and the default value for <typeparamref name="T"/> is returned.</para>
/// </remarks>
/// <param name="key">The key.</param>
/// <param name="refreshCallback">A function which returns a new value for the specified <paramref name="key"/>, or <c>null</c> if no update function available (see remarks).</param>
/// <param name="forceCacheRefresh">If <c>true</c>, the value associated with <paramref name="key"/> will be always be refreshed by calling <paramref name="refreshCallback"/>, even if a value is already cached.</param>
/// <returns>
/// The cached value associated with the specified <paramref name="key"/>. If no cached value is
/// available (see remarks), the method returns the default value for <typeparamref name="T"/>.
/// </returns>
/// <exception cref="ArgumentNullException">If <paramref name="key"/> is <c>null</c>.</exception>
T Get(string key, Func<T> refreshCallback, bool forceCacheRefresh = false);
}
}
16 changes: 15 additions & 1 deletion src/corelib/Core/Domain/Mapping/IJsonObjectMapper.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,23 @@
using Newtonsoft.Json.Linq;
using System;
using Newtonsoft.Json.Linq;

namespace net.openstack.Core.Domain.Mapping
{
/// <summary>
/// Represents an object that can convert between generic <see cref="JObject"/> instances
/// and instances of another specific type.
/// </summary>
/// <typeparam name="T">The type which can be converted to and from <see cref="JObject"/>.</typeparam>
public interface IJsonObjectMapper<T> : IObjectMapper<JObject, T>
{
/// <summary>
/// Converts a JSON string representation of <typeparamref name="T"/> to an instance
/// of <typeparamref name="T"/>.
/// </summary>
/// <param name="rawJson">The JSON string representation.</param>
/// <returns>An instance of <typeparamref name="T"/> represented by <paramref name="rawJson"/>.</returns>
/// <exception cref="ArgumentNullException">If <paramref name="rawJson"/> is <c>null</c>.</exception>
/// <exception cref="NotSupportedException">If the conversion cannot be performed.</exception>
T Map(string rawJson);
}
}
34 changes: 33 additions & 1 deletion src/corelib/Core/Domain/Mapping/IObjectMapper.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,41 @@
namespace net.openstack.Core.Domain.Mapping
{
using System;
using System.ComponentModel;

/// <summary>
/// Represents an object that can convert between instances of two specific types.
/// </summary>
/// <remarks>
/// This interface is similar to a <see cref="TypeConverter"/> which only supports
/// conversions between exactly two concrete types.
/// </remarks>
/// <typeparam name="TFrom">The first type.</typeparam>
/// <typeparam name="TTo">The second type.</typeparam>
public interface IObjectMapper<TFrom, TTo>
{
/// <summary>
/// Converts an instance of <typeparamref name="TFrom"/> to an instance of <typeparamref name="TTo"/>.
/// </summary>
/// <remarks>
/// This method provides behavior similar to a strongly-typed implementation
/// of <see cref="TypeConverter.ConvertTo(object, Type)"/>.
/// </remarks>
/// <param name="from">The instance to convert.</param>
/// <returns>The converted instance.</returns>
/// <exception cref="NotSupportedException">The conversion cannot be performed.</exception>
TTo Map(TFrom from);

/// <summary>
/// Converts an instance of <typeparamref name="TTo"/> to an instance of <typeparamref name="TFrom"/>.
/// </summary>
/// <remarks>
/// This method provides behavior similar to a strongly-typed implementation
/// of <see cref="TypeConverter.ConvertFrom(object)"/>.
/// </remarks>
/// <param name="to">The instance to convert.</param>
/// <returns>The converted instance.</returns>
/// <exception cref="NotSupportedException">The conversion cannot be performed.</exception>
TFrom Map(TTo to);
}
}
}
3 changes: 3 additions & 0 deletions src/corelib/Core/Domain/Mapping/NetworkResponseJsonMapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ namespace net.openstack.Core.Domain.Mapping
{
internal class NetworkResponseJsonMapper : IJsonObjectMapper<Network>
{
/// <inheritdoc/>
public Network Map(JObject @from)
{
if (from == null)
Expand All @@ -18,11 +19,13 @@ public Network Map(JObject @from)
};
}

/// <inheritdoc/>
public JObject Map(Network to)
{
throw new System.NotImplementedException();
}

/// <inheritdoc/>
public Network Map(string rawJson)
{
if (string.IsNullOrWhiteSpace(rawJson))
Expand Down
33 changes: 30 additions & 3 deletions src/corelib/Core/Exceptions/CDNNotEnabledException.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,42 @@
using System;
using System.Runtime.Serialization;
using net.openstack.Core.Providers;

namespace net.openstack.Core.Exceptions
{
/// <summary>
/// The exception that is thrown when an attempt is made to modify CDN properties
/// of a container which is not CDN-enabled.
/// </summary>
/// <seealso cref="IObjectStorageProvider"/>
[Serializable]
public class CDNNotEnabledException : Exception
public class CDNNotEnabledException : InvalidOperationException
{
public CDNNotEnabledException() { }
/// <summary>
/// Initializes a new instance of the <see cref="CDNNotEnabledException"/> class.
/// </summary>
public CDNNotEnabledException()
: base("The specified container is not CDN-enabled.")
{
}

public CDNNotEnabledException(string message) : base(message) { }
/// <summary>
/// Initializes a new instance of the <see cref="CDNNotEnabledException"/> class
/// with the specified error message.
/// </summary>
/// <param name="message">The message that describes the error.</param>
public CDNNotEnabledException(string message)
: base(message)
{
}

/// <summary>
/// Initializes a new instance of the <see cref="CDNNotEnabledException"/> class with
/// serialized data.
/// </summary>
/// <param name="info">The <see cref="SerializationInfo"/> that holds the serialized object data about the exception being thrown.</param>
/// <param name="context">The <see cref="StreamingContext"/> that contains contextual information about the source or destination.</param>
/// <exception cref="ArgumentNullException">If <paramref name="info"/> is <c>null</c>.</exception>
protected CDNNotEnabledException(SerializationInfo info, StreamingContext context)
: base(info, context)
{
Expand Down
32 changes: 29 additions & 3 deletions src/corelib/Core/Exceptions/CidrFormatException.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,41 @@
using System;
using System.Runtime.Serialization;
using net.openstack.Core.Validators;

namespace net.openstack.Core.Exceptions
{
/// <summary>
/// Represents errors that occur while validating a CIDR.
/// </summary>
/// <seealso cref="INetworksValidator.ValidateCidr"/>
[Serializable]
public class CidrFormatException : Exception
public class CidrFormatException : FormatException
{
public CidrFormatException() { }
/// <summary>
/// Initializes a new instance of the <see cref="CidrFormatException"/> class.
/// </summary>
public CidrFormatException()
: base("The specified CIDR is not in the correct format.")
{
}

public CidrFormatException(string message) : base(message) { }
/// <summary>
/// Initializes a new instance of the <see cref="CidrFormatException"/> class
/// with the specified error message.
/// </summary>
/// <param name="message">The message that describes the error.</param>
public CidrFormatException(string message)
: base(message)
{
}

/// <summary>
/// Initializes a new instance of the <see cref="CidrFormatException"/> class with
/// serialized data.
/// </summary>
/// <param name="info">The <see cref="SerializationInfo"/> that holds the serialized object data about the exception being thrown.</param>
/// <param name="context">The <see cref="StreamingContext"/> that contains contextual information about the source or destination.</param>
/// <exception cref="ArgumentNullException">If <paramref name="info"/> is <c>null</c>.</exception>
protected CidrFormatException(SerializationInfo info, StreamingContext context)
: base(info, context)
{
Expand Down
33 changes: 30 additions & 3 deletions src/corelib/Core/Exceptions/ContainerNameException.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,42 @@
using System;
using System.Runtime.Serialization;
using net.openstack.Core.Providers;
using net.openstack.Core.Validators;

namespace net.openstack.Core.Exceptions
{
/// <summary>
/// Represents errors that occur while validating a container name for an <see cref="IObjectStorageProvider"/>.
/// </summary>
/// <seealso cref="IObjectStorageValidator.ValidateContainerName"/>
[Serializable]
public class ContainerNameException : Exception
public class ContainerNameException : ArgumentException
{
public ContainerNameException() { }
/// <summary>
/// Initializes a new instance of the <see cref="ContainerNameException"/> class.
/// </summary>
public ContainerNameException()
: base("The specified container name is not valid.")
{
}

public ContainerNameException(string message) : base(message) { }
/// <summary>
/// Initializes a new instance of the <see cref="ContainerNameException"/> class
/// with the specified error message.
/// </summary>
/// <param name="message">The message that describes the error.</param>
public ContainerNameException(string message)
: base(message)
{
}

/// <summary>
/// Initializes a new instance of the <see cref="ContainerNameException"/> class with
/// serialized data.
/// </summary>
/// <param name="info">The <see cref="SerializationInfo"/> that holds the serialized object data about the exception being thrown.</param>
/// <param name="context">The <see cref="StreamingContext"/> that contains contextual information about the source or destination.</param>
/// <exception cref="ArgumentNullException">If <paramref name="info"/> is <c>null</c>.</exception>
protected ContainerNameException(SerializationInfo info, StreamingContext context)
: base(info, context)
{
Expand Down
24 changes: 22 additions & 2 deletions src/corelib/Core/Exceptions/InvalidCloudIdentityException.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,33 @@
using System;
using System.Runtime.Serialization;
using net.openstack.Core.Domain;

namespace net.openstack.Core.Exceptions
{
/// <summary>
/// The exception thrown when the <see cref="CloudIdentity"/> instance passed
/// to a provider method is not supported by that provider.
/// </summary>
[Serializable]
internal class InvalidCloudIdentityException : Exception
internal class InvalidCloudIdentityException : NotSupportedException
{
public InvalidCloudIdentityException(string message) : base(message) {}
/// <summary>
/// Initializes a new instance of the <see cref="InvalidCloudIdentityException"/> class
/// with the specified error message.
/// </summary>
/// <param name="message">The message that describes the error.</param>
public InvalidCloudIdentityException(string message)
: base(message)
{
}

/// <summary>
/// Initializes a new instance of the <see cref="InvalidCloudIdentityException"/> class with
/// serialized data.
/// </summary>
/// <param name="info">The <see cref="SerializationInfo"/> that holds the serialized object data about the exception being thrown.</param>
/// <param name="context">The <see cref="StreamingContext"/> that contains contextual information about the source or destination.</param>
/// <exception cref="ArgumentNullException">If <paramref name="info"/> is <c>null</c>.</exception>
protected InvalidCloudIdentityException(SerializationInfo info, StreamingContext context)
: base(info, context)
{
Expand Down
21 changes: 19 additions & 2 deletions src/corelib/Core/Exceptions/NoDefaultRegionSetException.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,30 @@

namespace net.openstack.Core.Exceptions
{
/// <summary>
/// The exception that is thrown when a service endpoint could not be obtained because
/// no region was specified and no default region is available for the provider.
/// </summary>
[Serializable]
public class NoDefaultRegionSetException : Exception
public class NoDefaultRegionSetException : InvalidOperationException
{
public NoDefaultRegionSetException(string message) : base(message)
/// <summary>
/// Initializes a new instance of the <see cref="NoDefaultRegionSetException"/> class
/// with the specified error message.
/// </summary>
/// <param name="message">The message that describes the error.</param>
public NoDefaultRegionSetException(string message)
: base(message)
{
}

/// <summary>
/// Initializes a new instance of the <see cref="NoDefaultRegionSetException"/> class with
/// serialized data.
/// </summary>
/// <param name="info">The <see cref="SerializationInfo"/> that holds the serialized object data about the exception being thrown.</param>
/// <param name="context">The <see cref="StreamingContext"/> that contains contextual information about the source or destination.</param>
/// <exception cref="ArgumentNullException">If <paramref name="info"/> is <c>null</c>.</exception>
protected NoDefaultRegionSetException(SerializationInfo info, StreamingContext context)
: base(info, context)
{
Expand Down
Loading

0 comments on commit 83365b3

Please sign in to comment.