mirror of
https://github.com/bitwarden/server
synced 2025-12-31 23:53:17 +00:00
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>
This commit is contained in:
62
src/Core/NotificationHub/NotificationHubPool.cs
Normal file
62
src/Core/NotificationHub/NotificationHubPool.cs
Normal file
@@ -0,0 +1,62 @@
|
||||
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); } }
|
||||
}
|
||||
Reference in New Issue
Block a user