Files
server/src/Core/NotificationHub/NotificationHubPool.cs

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

63 lines
2.8 KiB
C#
Raw Normal View History

Shard notification hub (#4450) * Allow for binning of comb IDs by date and value * Introduce notification hub pool * Replace device type sharding with comb + range sharding * Fix proxy interface * Use enumerable services for multiServiceNotificationHub * Fix push interface usage * Fix push notification service dependencies * Fix push notification keys * Fixup documentation * Remove deprecated settings * Fix tests * PascalCase method names * Remove unused request model properties * Remove unused setting * Improve DateFromComb precision * Prefer readonly service enumerable * Pascal case template holes * Name TryParse methods TryParse * Apply suggestions from code review Co-authored-by: Justin Baur <19896123+justindbaur@users.noreply.github.com> * AllClients is a set of clients and must be deduplicated * Fix registration start time * Add logging to initialization of a notification hub * more logging * Add lower level logging for hub settings * Log when connection is resolved * Improve log message * Log pushes to notification hub * temporarily elevate log messages for visibility * Log in multi-service when relaying to another push service * Revert to more reasonable logging free of user information * Fixup merge Deleting user was extracted to a command in #4803, this updates that work to use just the device ids as I did elsewhere in abd67e8ec * Do not use bouncy castle exception types * Add required services for logging --------- Co-authored-by: Justin Baur <19896123+justindbaur@users.noreply.github.com> Co-authored-by: bnagawiecki <107435978+bnagawiecki@users.noreply.github.com>
2024-10-22 09:20:57 -07:00
using Bit.Core.Settings;
using Bit.Core.Utilities;
using Microsoft.Azure.NotificationHubs;
using Microsoft.Extensions.Logging;
namespace Bit.Core.NotificationHub;
public class NotificationHubPool : INotificationHubPool
{
private List<NotificationHubConnection> _connections { get; }
private readonly IEnumerable<INotificationHubClient> _clients;
private readonly ILogger<NotificationHubPool> _logger;
public NotificationHubPool(ILogger<NotificationHubPool> logger, GlobalSettings globalSettings)
{
_logger = logger;
_connections = FilterInvalidHubs(globalSettings.NotificationHubPool.NotificationHubs);
_clients = _connections.GroupBy(c => c.ConnectionString).Select(g => g.First().HubClient);
}
private List<NotificationHubConnection> FilterInvalidHubs(IEnumerable<GlobalSettings.NotificationHubSettings> hubs)
{
List<NotificationHubConnection> result = new();
_logger.LogDebug("Filtering {HubCount} notification hubs", hubs.Count());
foreach (var hub in hubs)
{
var connection = NotificationHubConnection.From(hub);
if (!connection.IsValid)
{
_logger.LogWarning("Invalid notification hub settings: {HubName}", hub.HubName ?? "hub name missing");
continue;
}
_logger.LogDebug("Adding notification hub: {ConnectionLogString}", connection.LogString);
result.Add(connection);
}
return result;
}
/// <summary>
/// Gets the NotificationHubClient for the given comb ID.
/// </summary>
/// <param name="comb"></param>
/// <returns></returns>
/// <exception cref="InvalidOperationException">Thrown when no notification hub is found for a given comb.</exception>
public NotificationHubClient ClientFor(Guid comb)
{
var possibleConnections = _connections.Where(c => c.RegistrationEnabled(comb)).ToArray();
if (possibleConnections.Length == 0)
{
throw new InvalidOperationException($"No valid notification hubs are available for the given comb ({comb}).\n" +
$"The comb's datetime is {CoreHelpers.DateFromComb(comb)}." +
$"Hub start and end times are configured as follows:\n" +
string.Join("\n", _connections.Select(c => $"Hub {c.HubName} - Start: {c.RegistrationStartDate}, End: {c.RegistrationEndDate}")));
}
var resolvedConnection = possibleConnections[CoreHelpers.BinForComb(comb, possibleConnections.Length)];
_logger.LogTrace("Resolved notification hub for comb {Comb} out of {HubCount} hubs.\n{ConnectionInfo}", comb, possibleConnections.Length, resolvedConnection.LogString);
return resolvedConnection.HubClient;
}
public INotificationHubProxy AllClients { get { return new NotificationHubClientProxy(_clients); } }
}