Skip to content

Commit 3c081f7

Browse files
committed
Merge pull request #234 from sharwell/AsyncIdentityService
Asynchronous IIdentityService
2 parents 279b749 + f87b896 commit 3c081f7

5 files changed

Lines changed: 99 additions & 3 deletions

File tree

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
namespace net.openstack.Core.Providers
2+
{
3+
using System;
4+
using System.Threading.Tasks;
5+
using net.openstack.Core.Domain;
6+
using net.openstack.Core.Exceptions.Response;
7+
using CancellationToken = System.Threading.CancellationToken;
8+
9+
/// <summary>
10+
/// Represents a provider for asynchronous operations on the OpenStack Identity Service.
11+
/// </summary>
12+
/// <seealso href="http://docs.openstack.org/api/openstack-identity-service/2.0/content/">OpenStack Identity Service API v2.0 Reference</seealso>
13+
/// <preliminary/>
14+
public interface IIdentityService
15+
{
16+
/// <summary>
17+
/// Authenticates the user for the specified identity.
18+
/// </summary>
19+
/// <remarks>
20+
/// This method always authenticates to the server, even if an unexpired, cached <see cref="UserAccess"/>
21+
/// is available for the specified identity.
22+
/// </remarks>
23+
/// <param name="identity">The identity of the user to authenticate.</param>
24+
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that the task will observe.</param>
25+
/// <returns>A <see cref="Task"/> object representing the asynchronous operation. When the task completes successfully, the <see cref="Task{TResult}.Result"/> property will contain a <see cref="UserAccess"/> object containing the authentication token, service catalog and user data.</returns>
26+
/// <exception cref="NotSupportedException">If the provider does not support the given <paramref name="identity"/> type.</exception>
27+
/// <exception cref="InvalidOperationException">If <paramref name="identity"/> is <c>null</c> and no default identity is available for the provider.</exception>
28+
/// <exception cref="ResponseException">If the authentication request failed.</exception>
29+
/// <seealso href="http://docs.openstack.org/api/openstack-identity-service/2.0/content/POST_authenticate_v2.0_tokens_.html">Authenticate (OpenStack Identity Service API v2.0 Reference)</seealso>
30+
Task<UserAccess> AuthenticateAsync(CloudIdentity identity, CancellationToken cancellationToken);
31+
32+
/// <summary>
33+
/// Gets the user access details, authenticating with the server if necessary.
34+
/// </summary>
35+
/// <remarks>
36+
/// If <paramref name="forceCacheRefresh"/> is <c>false</c> and a cached <see cref="UserAccess"/>
37+
/// is available for the specified <paramref name="identity"/>, this method may return the cached
38+
/// value without performing an authentication against the server. If <paramref name="forceCacheRefresh"/>
39+
/// is <c>true</c>, this method is equivalent to <see cref="AuthenticateAsync"/>.
40+
/// </remarks>
41+
/// <param name="identity">The identity of the user to authenticate.</param>
42+
/// <param name="forceCacheRefresh">If <c>true</c>, the user is always authenticated against the server; otherwise a cached <see cref="IdentityToken"/> may be returned.</param>
43+
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that the task will observe.</param>
44+
/// <returns>A <see cref="Task"/> object representing the asynchronous operation. When the task completes successfully, the <see cref="Task{TResult}.Result"/> property will contain a <see cref="UserAccess"/> object containing the authentication token, service catalog and user data.</returns>
45+
/// <exception cref="NotSupportedException">If the provider does not support the given <paramref name="identity"/> type.</exception>
46+
/// <exception cref="InvalidOperationException">If <paramref name="identity"/> is <c>null</c> and no default identity is available for the provider.</exception>
47+
/// <exception cref="ResponseException">If the REST API request failed.</exception>
48+
/// <seealso href="http://docs.openstack.org/api/openstack-identity-service/2.0/content/POST_authenticate_v2.0_tokens_.html">Authenticate (OpenStack Identity Service API v2.0 Reference)</seealso>
49+
Task<UserAccess> GetUserAccessAsync(CloudIdentity identity, bool forceCacheRefresh, CancellationToken cancellationToken);
50+
51+
/// <summary>
52+
/// Gets the authentication token for the specified identity. If necessary, the identity is authenticated
53+
/// on the server to obtain a token.
54+
/// </summary>
55+
/// <remarks>
56+
/// If a cached <see cref="IdentityToken"/> is available for the specified <paramref name="identity"/>,
57+
/// this method may return the cached value without performing an authentication against the server.
58+
/// </remarks>
59+
/// <param name="identity">The identity of the user to authenticate.</param>
60+
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that the task will observe.</param>
61+
/// <returns>A <see cref="Task"/> object representing the asynchronous operation. When the task completes successfully, the <see cref="Task{TResult}.Result"/> property will contain the user's authentication token.</returns>
62+
/// <exception cref="NotSupportedException">If the provider does not support the given <paramref name="identity"/> type.</exception>
63+
/// <exception cref="InvalidOperationException">If <paramref name="identity"/> is <c>null</c> and no default identity is available for the provider.</exception>
64+
/// <exception cref="ResponseException">If the authentication request failed.</exception>
65+
/// <seealso href="http://docs.openstack.org/api/openstack-identity-service/2.0/content/POST_authenticate_v2.0_tokens_.html">Authenticate (OpenStack Identity Service API v2.0 Reference)</seealso>
66+
Task<IdentityToken> GetTokenAsync(CloudIdentity identity, CancellationToken cancellationToken);
67+
}
68+
}

src/corelib/Providers/Rackspace/CloudIdentityProvider.cs

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,20 @@
22
using System.Collections.Generic;
33
using System.Linq;
44
using System.Net;
5+
using System.Threading.Tasks;
56
using JSIStudios.SimpleRESTServices.Client;
67
using JSIStudios.SimpleRESTServices.Client.Json;
78
using net.openstack.Core;
89
using net.openstack.Core.Caching;
910
using net.openstack.Core.Domain;
1011
using net.openstack.Core.Exceptions.Response;
1112
using net.openstack.Core.Providers;
12-
using net.openstack.Core.Validators;
1313
using net.openstack.Providers.Rackspace.Objects;
1414
using net.openstack.Providers.Rackspace.Objects.Request;
1515
using net.openstack.Providers.Rackspace.Objects.Response;
1616
using Newtonsoft.Json;
1717
using Newtonsoft.Json.Linq;
18+
using CancellationToken = System.Threading.CancellationToken;
1819

1920
namespace net.openstack.Providers.Rackspace
2021
{
@@ -25,7 +26,7 @@ namespace net.openstack.Providers.Rackspace
2526
/// <seealso href="http://docs.openstack.org/api/openstack-identity-service/2.0/content/">OpenStack Identity Service API v2.0 Reference</seealso>
2627
/// <seealso href="http://docs.rackspace.com/auth/api/v2.0/auth-client-devguide/content/index.html">Rackspace Cloud Identity Client Developer Guide - API v2.0</seealso>
2728
/// <threadsafety static="true" instance="false"/>
28-
public class CloudIdentityProvider : ProviderBase<IIdentityProvider>, IExtendedCloudIdentityProvider, IIdentityProvider
29+
public class CloudIdentityProvider : ProviderBase<IIdentityProvider>, IExtendedCloudIdentityProvider, IIdentityProvider, IIdentityService
2930
{
3031
/// <summary>
3132
/// This is the backing field for the <see cref="TokenCache"/> property.
@@ -694,6 +695,13 @@ public virtual IdentityToken GetToken(CloudIdentity identity, bool forceCacheRef
694695
return auth.Token;
695696
}
696697

698+
/// <inheritdoc/>
699+
public virtual Task<IdentityToken> GetTokenAsync(CloudIdentity identity, CancellationToken cancellationToken)
700+
{
701+
return GetUserAccessAsync(identity, false, cancellationToken)
702+
.ContinueWith(task => task.Result.Token, TaskContinuationOptions.ExecuteSynchronously);
703+
}
704+
697705
/// <inheritdoc/>
698706
public virtual UserAccess Authenticate(CloudIdentity identity)
699707
{
@@ -702,6 +710,13 @@ public virtual UserAccess Authenticate(CloudIdentity identity)
702710
return GetUserAccess(identity, true);
703711
}
704712

713+
/// <inheritdoc/>
714+
public virtual Task<UserAccess> AuthenticateAsync(CloudIdentity identity, CancellationToken cancellationToken)
715+
{
716+
CheckIdentity(identity);
717+
return GetUserAccessAsync(identity, true, cancellationToken);
718+
}
719+
705720
/// <inheritdoc/>
706721
public virtual UserAccess GetUserAccess(CloudIdentity identity, bool forceCacheRefresh = false)
707722
{
@@ -733,6 +748,12 @@ public virtual UserAccess GetUserAccess(CloudIdentity identity, bool forceCacheR
733748
return userAccess;
734749
}
735750

751+
/// <inheritdoc/>
752+
public virtual Task<UserAccess> GetUserAccessAsync(CloudIdentity identity, bool forceCacheRefresh, CancellationToken cancellationToken)
753+
{
754+
return Task.Factory.StartNew(() => GetUserAccess(identity, forceCacheRefresh), cancellationToken);
755+
}
756+
736757
/// <summary>
737758
/// Gets the authentication token for the specified impersonation identity. If necessary, the
738759
/// identity is authenticated on the server to obtain a token.

src/corelib/Providers/Rackspace/ProviderBase`1.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -994,7 +994,12 @@ protected virtual Task<Uri> GetBaseUriAsync(CancellationToken cancellationToken)
994994
/// <preliminary/>
995995
protected virtual Task<Tuple<IdentityToken, Uri>> AuthenticateServiceAsync(CancellationToken cancellationToken)
996996
{
997-
Task<IdentityToken> authenticate = Task.Factory.StartNew(() => IdentityProvider.GetToken(GetDefaultIdentity(null)));
997+
Task<IdentityToken> authenticate;
998+
IIdentityService identityService = IdentityProvider as IIdentityService;
999+
if (identityService != null)
1000+
authenticate = identityService.GetTokenAsync(GetDefaultIdentity(null), cancellationToken);
1001+
else
1002+
authenticate = Task.Factory.StartNew(() => IdentityProvider.GetToken(GetDefaultIdentity(null)));
9981003

9991004
Func<Task<IdentityToken>, Task<Tuple<IdentityToken, Uri>>> getBaseUri =
10001005
task =>

src/corelib/corelib.v3.5.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@
118118
<Compile Include="Core\ParallelExtensionsExtras\TaskFactoryExtensions_ContinueWhenAllAny.cs" />
119119
<Compile Include="Core\ParallelExtensionsExtras\TaskFactoryExtensions_Delayed.cs" />
120120
<Compile Include="Core\ParallelExtensionsExtras\TaskFactoryExtensions_From.cs" />
121+
<Compile Include="Core\Providers\IIdentityService.cs" />
121122
<Compile Include="Core\Providers\NamespaceDoc.cs" />
122123
<Compile Include="Core\ResourceIdentifier`1.cs" />
123124
<Compile Include="Core\ResponseExtensions.cs" />

src/corelib/corelib.v4.0.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@
108108
<Compile Include="Core\ParallelExtensionsExtras\TaskFactoryExtensions_ContinueWhenAllAny.cs" />
109109
<Compile Include="Core\ParallelExtensionsExtras\TaskFactoryExtensions_Delayed.cs" />
110110
<Compile Include="Core\ParallelExtensionsExtras\TaskFactoryExtensions_From.cs" />
111+
<Compile Include="Core\Providers\IIdentityService.cs" />
111112
<Compile Include="Core\Providers\NamespaceDoc.cs" />
112113
<Compile Include="Core\ResourceIdentifier`1.cs" />
113114
<Compile Include="Core\ResponseExtensions.cs" />

0 commit comments

Comments
 (0)