Skip to content

Commit

Permalink
Add #nullable for Endpoint related classes (#2101)
Browse files Browse the repository at this point in the history
* Add #nullable for Endpoint classes

* update

* update

* update

* update
  • Loading branch information
terencefan authored Dec 3, 2024
1 parent a789992 commit 64b9805
Show file tree
Hide file tree
Showing 14 changed files with 1,889 additions and 1,788 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,112 +8,111 @@
using System.Text;
using System.Threading.Tasks;

namespace Microsoft.Azure.SignalR.AspNet
namespace Microsoft.Azure.SignalR.AspNet;

internal class ServiceEndpointProvider : IServiceEndpointProvider
{
internal class ServiceEndpointProvider : IServiceEndpointProvider
{
public static readonly string ConnectionStringNotFound =
"No connection string was specified. " +
$"Please specify a configuration entry for {Constants.Keys.ConnectionStringDefaultKey}, " +
"or explicitly pass one using IAppBuilder.RunAzureSignalR(connectionString) in Startup.ConfigureServices.";
public static readonly string ConnectionStringNotFound =
"No connection string was specified. " +
$"Please specify a configuration entry for {Constants.Keys.ConnectionStringDefaultKey}, " +
"or explicitly pass one using IAppBuilder.RunAzureSignalR(connectionString) in Startup.ConfigureServices.";

private const string ClientPath = "aspnetclient";
private const string ClientPath = "aspnetclient";

private const string ServerPath = "aspnetserver";
private const string ServerPath = "aspnetserver";

private readonly string _audienceBaseUrl;
private readonly string _audienceBaseUrl;

private readonly string _clientEndpoint;
private readonly string _clientEndpoint;

private readonly string _serverEndpoint;
private readonly string _serverEndpoint;

private readonly IAccessKey _accessKey;
private readonly IAccessKey _accessKey;

private readonly string _appName;
private readonly string _appName;

private readonly TimeSpan _accessTokenLifetime;
private readonly TimeSpan _accessTokenLifetime;

private readonly AccessTokenAlgorithm _algorithm;
private readonly AccessTokenAlgorithm _algorithm;

public IWebProxy Proxy { get; }
public IWebProxy Proxy { get; }

public ServiceEndpointProvider(ServiceEndpoint endpoint, ServiceOptions options)
{
_accessTokenLifetime = options.AccessTokenLifetime;
public ServiceEndpointProvider(ServiceEndpoint endpoint, ServiceOptions options)
{
_accessTokenLifetime = options.AccessTokenLifetime;

// Version is ignored for aspnet signalr case
_audienceBaseUrl = endpoint.AudienceBaseUrl;
_clientEndpoint = endpoint.ClientEndpoint.AbsoluteUri;
_serverEndpoint = endpoint.ServerEndpoint.AbsoluteUri;
_accessKey = endpoint.AccessKey;
_appName = options.ApplicationName;
_algorithm = options.AccessTokenAlgorithm;
// Version is ignored for aspnet signalr case
_audienceBaseUrl = endpoint.AudienceBaseUrl;
_clientEndpoint = endpoint.ClientEndpoint.AbsoluteUri;
_serverEndpoint = endpoint.ServerEndpoint.AbsoluteUri;
_accessKey = endpoint.AccessKey;
_appName = options.ApplicationName;
_algorithm = options.AccessTokenAlgorithm;

Proxy = options.Proxy;
}
Proxy = options.Proxy;
}

public Task<string> GenerateClientAccessTokenAsync(string hubName = null, IEnumerable<Claim> claims = null, TimeSpan? lifetime = null)
{
var audience = $"{_audienceBaseUrl}{ClientPath}";
public Task<string> GenerateClientAccessTokenAsync(string hubName = null, IEnumerable<Claim> claims = null, TimeSpan? lifetime = null)
{
var audience = $"{_audienceBaseUrl}{ClientPath}";

return _accessKey.GenerateAccessTokenAsync(audience, claims, lifetime ?? _accessTokenLifetime, _algorithm);
}
return _accessKey.GenerateAccessTokenAsync(audience, claims, lifetime ?? _accessTokenLifetime, _algorithm);
}

public string GetClientEndpoint(string hubName = null, string originalPath = null, string queryString = null)
{
var queryBuilder = new StringBuilder();

public string GetClientEndpoint(string hubName = null, string originalPath = null, string queryString = null)
if (!string.IsNullOrEmpty(queryString))
{
var queryBuilder = new StringBuilder();
queryBuilder.Append(queryString);
}

if (!string.IsNullOrEmpty(queryString))
if (!string.IsNullOrEmpty(originalPath))
{
if (queryBuilder.Length == 0)
{
queryBuilder.Append(queryString);
queryBuilder.Append("?");
}

if (!string.IsNullOrEmpty(originalPath))
else
{
if (queryBuilder.Length == 0)
{
queryBuilder.Append("?");
}
else
{
queryBuilder.Append("&");
}

queryBuilder
.Append(Constants.QueryParameter.OriginalPath)
.Append("=")
.Append(WebUtility.UrlEncode(originalPath));
queryBuilder.Append("&");
}

return $"{_clientEndpoint}{ClientPath}{queryBuilder}";
queryBuilder
.Append(Constants.QueryParameter.OriginalPath)
.Append("=")
.Append(WebUtility.UrlEncode(originalPath));
}

public string GetServerEndpoint(string hubName)
return $"{_clientEndpoint}{ClientPath}{queryBuilder}";
}

public string GetServerEndpoint(string hubName)
{
return $"{_serverEndpoint}{ServerPath}/?hub={GetPrefixedHubName(_appName, hubName)}";
}

public IAccessTokenProvider GetServerAccessTokenProvider(string hubName, string serverId)
{
if (_accessKey is MicrosoftEntraAccessKey key)
{
return $"{_serverEndpoint}{ServerPath}/?hub={GetPrefixedHubName(_appName, hubName)}";
return new MicrosoftEntraTokenProvider(key);
}

public IAccessTokenProvider GetServerAccessTokenProvider(string hubName, string serverId)
else if (_accessKey is AccessKey key2)
{
if (_accessKey is MicrosoftEntraAccessKey key)
{
return new MicrosoftEntraTokenProvider(key);
}
else if (_accessKey is AccessKey key2)
{
var audience = $"{_audienceBaseUrl}{ServerPath}/?hub={GetPrefixedHubName(_appName, hubName)}";
var claims = serverId != null ? new[] { new Claim(ClaimTypes.NameIdentifier, serverId) } : null;
return new LocalTokenProvider(key2, audience, claims, _algorithm, _accessTokenLifetime);
}
else
{
throw new ArgumentNullException(nameof(AccessKey));
}
var audience = $"{_audienceBaseUrl}{ServerPath}/?hub={GetPrefixedHubName(_appName, hubName)}";
var claims = serverId != null ? new[] { new Claim(ClaimTypes.NameIdentifier, serverId) } : null;
return new LocalTokenProvider(key2, audience, claims, _algorithm, _accessTokenLifetime);
}

private string GetPrefixedHubName(string applicationName, string hubName)
else
{
return string.IsNullOrEmpty(applicationName) ? hubName.ToLower() : $"{applicationName.ToLower()}_{hubName.ToLower()}";
throw new ArgumentNullException(nameof(AccessKey));
}
}

private string GetPrefixedHubName(string applicationName, string hubName)
{
return string.IsNullOrEmpty(applicationName) ? hubName.ToLower() : $"{applicationName.ToLower()}_{hubName.ToLower()}";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,30 +7,30 @@

namespace Microsoft.Azure.SignalR;

#nullable enable

internal class HubServiceEndpoint : ServiceEndpoint
{
private static long s_currentIndex;

private readonly ServiceEndpoint _endpoint;

private readonly long _uniqueIndex;

private TaskCompletionSource<bool> _scaleTcs;
private TaskCompletionSource<bool>? _scaleTcs;

public string Hub { get; }

public override string Name => _endpoint.Name;

public IServiceEndpointProvider Provider { get; }

public IServiceConnectionContainer ConnectionContainer { get; set; }
public IServiceConnectionContainer? ConnectionContainer { get; set; }

/// <summary>
/// Task waiting for HubServiceEndpoint turn ready when live add/remove endpoint
/// </summary>
public Task ScaleTask => _scaleTcs?.Task ?? Task.CompletedTask;

public long UniqueIndex => _uniqueIndex;
public long UniqueIndex { get; }

// Value here is not accurate.
internal override bool PendingReload => throw new NotSupportedException();
Expand All @@ -43,7 +43,7 @@ public HubServiceEndpoint(string hub,
Provider = provider;
_endpoint = endpoint;
_scaleTcs = endpoint.PendingReload ? new TaskCompletionSource<bool>(TaskCreationOptions.RunContinuationsAsynchronously) : null;
_uniqueIndex = Interlocked.Increment(ref s_currentIndex);
UniqueIndex = Interlocked.Increment(ref s_currentIndex);
}

public void CompleteScale()
Expand Down
Loading

0 comments on commit 64b9805

Please sign in to comment.