예제 #1
0
    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);
    }
예제 #2
0
 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);
 }
예제 #4
0
        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
            });
        }
예제 #5
0
 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
     });
 }
예제 #6
0
        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
            });
        }
예제 #7
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);
        }
예제 #8
0
        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);
            }