public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { var resultJson = JObject.Load(reader); var rdfType = resultJson["$type"].ToObject <string>(); BaseNotification result; switch (rdfType) { case "App.RRSRC.Feeds.DataAvailable": { result = new DataAvailableNotification { SnapshotRevisionId = resultJson["SnapshotRevisionId"].ToObject <string>(), URLs = resultJson["URLs"].ToObject <string[]>() }; break; } case "Service.Feeds.Expired": { result = new ExpiredNotification(); break; } default: { throw new NotSupportedException(); } } result.ChannelId = resultJson["ChannelId"].ToObject <Guid>(); result.ConsumerId = resultJson["ConsumerId"].ToObject <string>(); return(result); }
static string Base64Content(DataAvailableNotification notification) { using var ms = new MemoryStream(); ms.Write(Encoding.UTF8.GetBytes(notification.ContentType.Value)); ms.Write(BitConverter.GetBytes((int)notification.Origin)); ms.Write(Encoding.UTF8.GetBytes(notification.Recipient.Value)); ms.Write(BitConverter.GetBytes(notification.SupportsBundling.Value)); ms.Write(BitConverter.GetBytes(notification.Weight.Value)); return(Convert.ToBase64String(ms.ToArray())); }
private static bool ExpectedNotification(DataAvailableNotification notification, DataAvailableNotificationDto dto) { return (notification.NotificationId == new Uuid(dto.Uuid) && notification.Recipient.Value == dto.Recipient && notification.Origin.ToString() == dto.Origin && notification.ContentType.Value == dto.ContentType && notification.Weight.Value == dto.Weight && notification.SupportsBundling.Value == dto.SupportsBundling && notification.SequenceNumber.Value == dto.SequenceNumber); }
private static CosmosCatalogEntry CreateCatalogEntry(DataAvailableNotification notification) { var partitionKey = string.Join( '_', notification.Recipient.Value, notification.Origin); return(new CosmosCatalogEntry { Id = Guid.NewGuid().ToString(), ContentType = notification.ContentType.Value, NextSequenceNumber = notification.SequenceNumber.Value, PartitionKey = partitionKey }); }
public static CosmosDataAvailable Map(DataAvailableNotification notification, string partitionKey) { return(new CosmosDataAvailable { Id = notification.NotificationId.ToString(), Recipient = notification.Recipient.Value, ContentType = notification.ContentType.Value, Origin = notification.Origin.ToString(), SupportsBundling = notification.SupportsBundling.Value, RelativeWeight = notification.Weight.Value, SequenceNumber = notification.SequenceNumber.Value, PartitionKey = partitionKey, DocumentType = notification.DocumentType.Value }); }
private static CosmosCabinetDrawer CreateEmptyDrawer(DataAvailableNotification notification) { var partitionKey = string.Join( '_', notification.Recipient.Value, notification.Origin, notification.ContentType.Value); return(new CosmosCabinetDrawer { Id = Guid.NewGuid().ToString(), PartitionKey = partitionKey, OrderBy = notification.SequenceNumber.Value, Position = 0 }); }
public async Task SaveAsync_IdempotencyFailed_ThrowsException() { // Arrange await using var host = await SubDomainIntegrationTestHost.InitializeAsync().ConfigureAwait(false); var scope = host.BeginScope(); var dataAvailableNotificationRepository = scope.GetInstance <IDataAvailableNotificationRepository>(); var recipient = new LegacyActorId(new MockedGln()); var notification1 = new DataAvailableNotification( new Uuid(Guid.NewGuid()), recipient, new ContentType("a"), DomainOrigin.Charges, new SupportsBundling(true), new Weight(1), new SequenceNumber(1), new DocumentType("RSM??")); var notification2 = new DataAvailableNotification( notification1.NotificationId, notification1.Recipient, new ContentType("b"), notification1.Origin, notification1.SupportsBundling, notification1.Weight, new SequenceNumber(2), new DocumentType("RSM??")); var notifications = new[] { notification1, notification2 }; // Act + Assert await Assert .ThrowsAsync <ValidationException>( () => dataAvailableNotificationRepository.SaveAsync(new CabinetKey(notifications[0]), notifications)) .ConfigureAwait(false); }
private async Task <bool> CheckIdempotencyAsync(DataAvailableNotification notification) { var documentId = notification.NotificationId.AsGuid(); var partitionKey = documentId.ToByteArray()[0]; var uniqueId = new CosmosUniqueId { Id = $"{documentId}", PartitionKey = $"{partitionKey}", Content = Base64Content(notification) }; try { await _repositoryContainer .Idempotency .CreateItemAsync(uniqueId) .ConfigureAwait(false); return(false); } catch (CosmosException ex) when(ex.StatusCode == HttpStatusCode.Conflict) { var conflictingItem = await _repositoryContainer .Idempotency .ReadItemAsync <CosmosUniqueId>( uniqueId.Id, new PartitionKey(uniqueId.PartitionKey)) .ConfigureAwait(false); if (string.Equals(conflictingItem.Resource.Content, uniqueId.Content, StringComparison.Ordinal)) { return(true); } throw new ValidationException($"Idempotency check failed for DataAvailable {documentId}.", ex); }