2021-05-17 09:43:02 -05:00
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
using System.Linq;
|
2021-07-07 10:49:59 -04:00
|
|
|
|
using System.Text;
|
2021-05-17 09:43:02 -05:00
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
|
using Azure.Storage.Queues;
|
2021-07-02 17:11:33 -04:00
|
|
|
|
using Bit.Core.Utilities;
|
2021-05-17 09:43:02 -05:00
|
|
|
|
using Newtonsoft.Json;
|
|
|
|
|
|
|
|
|
|
|
|
namespace Bit.Core.Services
|
|
|
|
|
|
{
|
|
|
|
|
|
public abstract class AzureQueueService<T>
|
|
|
|
|
|
{
|
|
|
|
|
|
protected QueueClient _queueClient;
|
|
|
|
|
|
protected JsonSerializerSettings _jsonSettings;
|
|
|
|
|
|
|
|
|
|
|
|
protected AzureQueueService(QueueClient queueClient, JsonSerializerSettings jsonSettings)
|
|
|
|
|
|
{
|
|
|
|
|
|
_queueClient = queueClient;
|
|
|
|
|
|
_jsonSettings = jsonSettings;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2021-07-07 10:49:59 -04:00
|
|
|
|
public async Task CreateAsync(T message)
|
|
|
|
|
|
{
|
|
|
|
|
|
var json = JsonConvert.SerializeObject(message, _jsonSettings);
|
|
|
|
|
|
var base64 = CoreHelpers.Base64EncodeString(json);
|
|
|
|
|
|
await _queueClient.SendMessageAsync(base64);
|
|
|
|
|
|
}
|
2021-05-17 09:43:02 -05:00
|
|
|
|
|
|
|
|
|
|
public async Task CreateManyAsync(IEnumerable<T> messages)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (messages?.Any() != true)
|
|
|
|
|
|
{
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2021-07-07 10:49:59 -04:00
|
|
|
|
if (!messages.Skip(1).Any())
|
|
|
|
|
|
{
|
|
|
|
|
|
await CreateAsync(messages.First());
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
foreach (var json in SerializeMany(messages, _jsonSettings))
|
2021-05-17 09:43:02 -05:00
|
|
|
|
{
|
|
|
|
|
|
await _queueClient.SendMessageAsync(json);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2021-07-07 10:49:59 -04:00
|
|
|
|
protected IEnumerable<string> SerializeMany(IEnumerable<T> messages, JsonSerializerSettings jsonSettings)
|
2021-05-17 09:43:02 -05:00
|
|
|
|
{
|
2021-07-07 10:49:59 -04:00
|
|
|
|
// Calculate Base-64 encoded text with padding
|
|
|
|
|
|
int getBase64Size(int byteCount) => ((4 * byteCount / 3) + 3) & ~3;
|
2021-07-02 17:11:33 -04:00
|
|
|
|
|
2021-07-07 10:49:59 -04:00
|
|
|
|
var messagesList = new List<string>();
|
|
|
|
|
|
var messagesListSize = 0;
|
2021-12-16 15:35:09 +01:00
|
|
|
|
|
2021-07-07 10:49:59 -04:00
|
|
|
|
int calculateByteSize(int totalSize, int toAdd) =>
|
|
|
|
|
|
// Calculate the total length this would be w/ "[]" and commas
|
|
|
|
|
|
getBase64Size(totalSize + toAdd + messagesList.Count + 2);
|
2021-05-17 09:43:02 -05:00
|
|
|
|
|
2021-07-07 10:49:59 -04:00
|
|
|
|
// Format the final array string, i.e. [{...},{...}]
|
|
|
|
|
|
string getArrayString()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (messagesList.Count == 1)
|
2021-05-17 09:43:02 -05:00
|
|
|
|
{
|
2021-07-07 10:49:59 -04:00
|
|
|
|
return CoreHelpers.Base64EncodeString(messagesList[0]);
|
2021-05-17 09:43:02 -05:00
|
|
|
|
}
|
2021-07-07 10:49:59 -04:00
|
|
|
|
return CoreHelpers.Base64EncodeString(
|
|
|
|
|
|
string.Concat("[", string.Join(',', messagesList), "]"));
|
|
|
|
|
|
}
|
2021-12-16 15:35:09 +01:00
|
|
|
|
|
2021-07-07 10:49:59 -04:00
|
|
|
|
var serializedMessages = messages.Select(message =>
|
|
|
|
|
|
JsonConvert.SerializeObject(message, jsonSettings));
|
|
|
|
|
|
|
|
|
|
|
|
foreach (var message in serializedMessages)
|
|
|
|
|
|
{
|
|
|
|
|
|
var messageSize = Encoding.UTF8.GetByteCount(message);
|
|
|
|
|
|
if (calculateByteSize(messagesListSize, messageSize) > _queueClient.MessageMaxBytes)
|
2021-05-17 09:43:02 -05:00
|
|
|
|
{
|
2021-07-07 10:49:59 -04:00
|
|
|
|
yield return getArrayString();
|
|
|
|
|
|
messagesListSize = 0;
|
|
|
|
|
|
messagesList.Clear();
|
2021-05-17 09:43:02 -05:00
|
|
|
|
}
|
2021-07-07 10:49:59 -04:00
|
|
|
|
|
|
|
|
|
|
messagesList.Add(message);
|
|
|
|
|
|
messagesListSize += messageSize;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (messagesList.Any())
|
|
|
|
|
|
{
|
|
|
|
|
|
yield return getArrayString();
|
2021-05-17 09:43:02 -05:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|