Example #1
0
        public async Task <PagedMessages <ArchivedMessage> > Handle(GetMessages request, CancellationToken cancellationToken)
        {
            ICosmosDbContainer messagesContainer = await _cosmosDbClient.GetContainer("messages");

            IQueryable <ArchivedMessage> query = messagesContainer.GetByLinq <ArchivedMessage>();

            query = ApplyFilters(query, request);
            query = query.OrderByDescending(m => m.MessageDate);
            int count = await messagesContainer.ResolveCount(query);

            query = ApplyPaging(query, request);
            CosmosDbResponse <IEnumerable <ArchivedMessage> > messages = await messagesContainer.ResolveWithStreamIterator(query);

            if (!messages.IsSuccessful)
            {
                throw new ApplicationException($"Error fetching messages: {messages.ErrorMessage}");
            }

            return(new PagedMessages <ArchivedMessage>()
            {
                Messages = messages.Result,
                PageIndex = request.MessageFilters.PageIndex,
                PageSize = request.MessageFilters.PageSize,
                TotalRecords = count
            });
        }
Example #2
0
 public TrackedCosmosDbContainer(IContainerDefinition definition, ICosmosDbContainer container, IChargeTracker <CosmosDbChargedResponse> chargeTracker, string feature, ICollection <string> context)
 {
     Definition      = definition;
     _innerContainer = container;
     ChargeTracker   = chargeTracker;
     Feature         = feature;
     Tags            = context;
     ChargeTracker   = chargeTracker;
 }
        public static ICosmosDbContainer AddTag(this ICosmosDbContainer container, string context)
        {
            TrackedCosmosDbContainer trackedContainer = container as TrackedCosmosDbContainer;

            if (trackedContainer != null)
            {
                trackedContainer.Tags.Add(context);
                return(trackedContainer);
            }
            return(container);
        }
 public CosmosDbContainerRepository(
     ICosmosDbContainer container,
     IEntityTypeNameResolver entityTypeNameResolver,
     IIdValueGenerator <TDomainEntity> idValueGenerator,
     IPartitionKeyResolver pkvResolver
     )
 {
     Container         = container;
     _idValueGenerator = idValueGenerator;
     _pkvResolver      = pkvResolver;
     _entityType       = entityTypeNameResolver.ResolveEntityTypeName <TDomainEntity>();
 }
Example #5
0
        public ICosmosDbContainer Create(Type creatorType, IContainerDefinition definition, ICosmosDbClient client)
        {
            if (Provider == null)
            {
                ICosmosDbContainer container = client
                                               .GetContainer(definition.ContainerId)
                                               .ConfigureAwait(false).GetAwaiter().GetResult();
                return(container);
            }

            return(Provider(creatorType, definition, client));
        }
Example #6
0
        public static async Task <ICosmosDbContainer> GetContainerForFeature(this ICosmosDbClient client, string containerId, string featureToTrack)
        {
            ICosmosDbContainer container = await client.GetContainer(containerId);

            TrackedCosmosDbContainer trackedContainer = container as TrackedCosmosDbContainer;

            if (trackedContainer != null)
            {
                trackedContainer.Feature = featureToTrack;
                return(trackedContainer);
            }
            return(container);
        }
 public static ICosmosDbContainer WithContext(this ICosmosDbContainer container, string context)
 {
     if (container is TrackedCosmosDbContainer trackedCosmosDbContainer)
     {
         trackedCosmosDbContainer.Context.Add(context);
         return(trackedCosmosDbContainer);
     }
     else
     {
         var chargeTracker = container.Client.ServiceProvider.GetRequiredService <IChargeTracker <CosmosDbChargedResponse> >();
         return(new TrackedCosmosDbContainer(container.Definition, container, chargeTracker, "Global", new List <string> {
             context
         }));
     }
 }
        public async Task <IEnumerable <HealthCheckInfo> > Handle(GetHealthCheckInfo request, CancellationToken cancellationToken)
        {
            IList <HealthCheckInfo> healthCheckInfoList = new List <HealthCheckInfo>();

            //Get the latest HealthCheck Requests from Cosmos DB
            ICosmosDbContainer messagesContainer = await _cosmosDbClient.GetContainer("messages");

            IQueryable <ArchivedMessage> query = messagesContainer.GetByLinq <ArchivedMessage>();

            query = query.Where(m => m.Message.MessageType == typeof(HealthCheckRequest).AssemblyQualifiedName)
                    .OrderByDescending(m => m.MessageDate)
                    .Take(12);                     // last hour

            CosmosDbResponse <IEnumerable <ArchivedMessage> > messages = await messagesContainer.ResolveWithStreamIterator(query);

            if (!messages.IsSuccessful)
            {
                throw new ApplicationException($"Error fetching messages: {messages.ErrorMessage}");
            }

            foreach (var message in messages.Result)
            {
                var heathCheckRequest = message.Message as HealthCheckRequest;
                var healthCheckInfo   = new HealthCheckInfo
                {
                    HealthCheckRequest = heathCheckRequest
                };

                //Search the HealthCheck Responses using the correlationId
                IEnumerable <ArchivedMessage> healthCheckResponses = await GetHealthCheckResponsesByCorrelationId(message.Message.CorrelationId);

                foreach (var response in healthCheckResponses)
                {
                    HealthCheckResponse healthCheckResponse = (HealthCheckResponse)response.Message;
                    healthCheckResponse.ResponseStatus = healthCheckResponse.AggregateTestResults();
                    MarkDelayedHealthyResponseAsWarning(healthCheckResponse, heathCheckRequest.MessageDate);
                    healthCheckInfo.HealthCheckResponses.Add(healthCheckResponse);
                }

                AddErrorsForMissingServices(healthCheckInfo);
                AggregateResult(healthCheckInfo);

                healthCheckInfoList.Add(healthCheckInfo);
            }


            return(healthCheckInfoList);
        }
        public async Task <IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req,
            ILogger log)
        {
            log.LogInformation("C# HTTP trigger Test Storing a message!");

            var message = new ArchivedMessage(new TestMessage()
            {
                Description = "This is a test message with a random value of " + new Random().Next(0, int.MaxValue)
            });

            ICosmosDbContainer cosmosContainer = await _cosmosClient.GetContainer <ArchivedMessage>();

            CosmosDbResponse <ArchivedMessage> cosmosResponse = await cosmosContainer.Add(message.Id, message);

            return(new OkObjectResult($"Cosmos Response: {cosmosResponse.IsSuccessful}"));
        }
Example #10
0
        public static void AddCosmosContext <TContext>(this IServiceCollection services) where TContext : CosmosContext, new()
        {
            services.AddTransient(typeof(TContext), provider =>
            {
                var cosmosDbClient     = provider.GetRequiredService <ICosmosDbClient>();
                var cosmosContext      = new TContext();
                Type cosmosContextType = typeof(TContext);

                // concrete repository type to instantiate against the IRepository<> interface
                Type repoType = typeof(CosmosDbContainerRepository <>);

                IEnumerable <PropertyInfo> contextRepositories = cosmosContextType.GetProperties()
                                                                 .Where(prop =>
                                                                        prop.PropertyType.IsInterface &&
                                                                        prop.PropertyType.IsGenericType &&
                                                                        prop.PropertyType.GetGenericTypeDefinition() == typeof(IRepository <>));

                foreach (PropertyInfo prop in contextRepositories)
                {
                    Type repositoryEntityGenericType = prop.PropertyType.GetGenericArguments()[0];
                    Type constructedRepoType         = repoType.MakeGenericType(repositoryEntityGenericType);

                    // TODO: how can we allow multiple repos of the same type but with different names and pk paths?
                    // We somehow have to search via ContainerDefs or... rework the whole config story...and have a Config() method on the CosmosContext that
                    // we use to configure each repository individually...
                    ContainerDefinition containerDefinition = cosmosDbClient.GetContainerDefinitionForType(prop.PropertyType.GetGenericArguments()[0]);

                    ICosmosDbContainer container = cosmosDbClient.CreateContainer(containerDefinition).ConfigureAwait(false).GetAwaiter().GetResult();

                    var entityTypeNameResolverInstance = new CosmosDbEntityTypeNameResolver();
                    var pkvResolver = new CosmosDbPartitionKeyResolver();

                    var idValueGeneratorType         = typeof(CosmosDbIdValueGenerator <>);
                    var idValueGeneratorInstanceType = idValueGeneratorType.MakeGenericType(repositoryEntityGenericType);
                    var idValueGeneratorInstance     = Activator.CreateInstance(idValueGeneratorInstanceType);

                    object repoInstance = Activator.CreateInstance(constructedRepoType, args: new object[] { container, entityTypeNameResolverInstance, idValueGeneratorInstance, pkvResolver });
                    prop.SetValue(cosmosContext, repoInstance);
                }

                return(cosmosContext);
            });
        }
        private async Task <IEnumerable <ArchivedMessage> > GetHealthCheckResponsesByCorrelationId(string correlationId)
        {
            ICosmosDbContainer messagesContainer = await _cosmosDbClient.GetContainer("messages");

            IQueryable <ArchivedMessage> queryHealthCheckResponse = messagesContainer.GetByLinq <ArchivedMessage>();

            queryHealthCheckResponse = queryHealthCheckResponse.Where(m =>
                                                                      m.Message.MessageType == typeof(HealthCheckResponse).AssemblyQualifiedName &&
                                                                      m.Message.CorrelationId == correlationId);

            CosmosDbResponse <IEnumerable <ArchivedMessage> > messages = await messagesContainer.ResolveWithStreamIterator(queryHealthCheckResponse);

            if (!messages.IsSuccessful)
            {
                throw new ApplicationException($"Error fetching messages: {messages.ErrorMessage}");
            }

            return(messages.Result);
        }
Example #12
0
        public static IServiceCollection AddSpendOps(this IServiceCollection services)
        {
            services.TryAddSingleton <ICosmosDbContainerFactory>(provider =>
            {
                var factory = new CosmosDbContainerFactory
                {
                    Provider = (creatorType, containerDefinition, cosmosDbClient) =>
                    {
                        var chargeTracker            = cosmosDbClient.ServiceProvider.GetService <IChargeTracker <CosmosDbChargedResponse> >();
                        ICosmosDbContainer container = cosmosDbClient.GetContainer(containerDefinition.ContainerId)
                                                       .ConfigureAwait(false).GetAwaiter().GetResult();
                        return(new TrackedCosmosDbContainer(containerDefinition, container, chargeTracker, creatorType.Name));
                    }
                };

                return(factory);
            });

            return(services);
        }
        public static void AddCosmosDbContext <TContext>(this IServiceCollection services) where TContext : DbContext, new()
        {
            services.AddTransient(typeof(TContext), provider =>
            {
                var cosmosDbClient = provider.GetRequiredService <ICosmosDbClient>();
                var instance       = new TContext();
                Type instanceType  = typeof(TContext);

                // concrete repository type to instantiate against the IRepository<> interface
                Type repoType = typeof(CosmosDbContainerRepository <>);

                IEnumerable <PropertyInfo> contextRepositories = instanceType.GetProperties()
                                                                 .Where(prop =>
                                                                        prop.PropertyType.IsInterface &&
                                                                        prop.PropertyType.IsGenericType &&
                                                                        prop.PropertyType.GetGenericTypeDefinition() == typeof(IRepository <>));

                var containerFactory = provider.GetRequiredService <ICosmosDbContainerFactory>();

                foreach (PropertyInfo prop in contextRepositories)
                {
                    Type repositoryEntityGenericType        = prop.PropertyType.GetGenericArguments()[0];
                    Type constructedRepoType                = repoType.MakeGenericType(repositoryEntityGenericType);
                    ContainerDefinition containerDefinition = cosmosDbClient.GetContainerDefinitionForType(prop.PropertyType.GetGenericArguments()[0]);

                    ICosmosDbContainer container = containerFactory.Create(instanceType, containerDefinition, cosmosDbClient);

                    var entityTypeNameResolverInstance = new CosmosDbEntityTypeNameResolver();
                    var pkvResolver = new CosmosDbPartitionKeyResolver();

                    var idValueGeneratorType         = typeof(CosmosDbIdValueGenerator <>);
                    var idValueGeneratorInstanceType = idValueGeneratorType.MakeGenericType(repositoryEntityGenericType);
                    var idValueGeneratorInstance     = Activator.CreateInstance(idValueGeneratorInstanceType);

                    object repoInstance = Activator.CreateInstance(constructedRepoType, args: new object[] { container, entityTypeNameResolverInstance, idValueGeneratorInstance, pkvResolver });
                    prop.SetValue(instance, repoInstance);
                }

                return(instance);
            });
        }
        public async Task Run([ServiceBusTrigger("%ServiceBusTopic%", "%ServiceBusSubscription%", Connection = "ServiceBusConnectionString")] string messageString, ILogger log)
        {
            MessageBase originalMessage = null;

            try
            {
                originalMessage = _messageReader.ReadMessage(messageString);
                var archivedMessage = new ArchivedMessage(originalMessage);

                if (archivedMessage.MessageTypeName.Equals(nameof(HealthCheckRequest)))
                {
                    await HandleHealthCheckRequest(_messageReader.ReadMessage <HealthCheckRequest>(messageString));
                }

                ICosmosDbContainer cosmosContainer = await _cosmosClient.GetContainer <ArchivedMessage>();

                CosmosDbResponse <ArchivedMessage> cosmosResponse =
                    await cosmosContainer.Add(archivedMessage.Id, archivedMessage);

                if (!cosmosResponse.IsSuccessful)
                {
                    throw new ApplicationException(
                              $"MessageStorage failed to write message {archivedMessage.Message.MessageId} of type {archivedMessage.Message.MessageType}. {cosmosResponse.ErrorMessage}");
                }
            }
            catch (Exception storeException)
            {
                try
                {
                    log.LogError(storeException, "exception saving to MessageStorage. OriginalMessage: " + messageString);
                    await _messageSender.SendException(storeException, originalMessage);
                }
                catch (Exception sendException)
                {
                    log.LogCritical(sendException, "Exception attempting to save an error message to the bus! This is very bad!");
                }
                throw;
            }
        }
        public async Task <bool> Handle(ResubmitMessage request, CancellationToken cancellationToken)
        {
            ICosmosDbContainer messagesContainer = await _cosmosDbClient.GetContainer("messages");

            var cosmosResponse = await messagesContainer.Get <ArchivedMessage>(request.MessageId, request.MessageId);

            if (!cosmosResponse.IsSuccessful)
            {
                throw new ApplicationException("Cosmos error: " + cosmosResponse.ErrorMessage);
            }

            var archivedMessage = cosmosResponse.Result;

            if (archivedMessage != null && archivedMessage.Message != null)
            {
                var message = archivedMessage.Message;
                message.MessageId   = Guid.NewGuid().ToString();
                message.MessageDate = _dateTimeProvider.UtcNow;
                await _messageSender.SendMessage(message);

                return(true);
            }
            return(false);
        }
Example #16
0
 public TrackedCosmosDbContainer(IContainerDefinition definition, ICosmosDbContainer container, IChargeTracker <CosmosDbChargedResponse> chargeTracker, string feature)
     : this(definition, container, chargeTracker, feature, new List <string>())
 {
 }
 public ICosmosDbContainer Create(ICosmosDbContainer container)
 {
     return(new TrackedCosmosDbContainer(container.Definition, container, _chargeTracker, "Unspecified Feature"));
 }
Example #18
0
 public WorkspaceRepository(ICosmosDbContainer cosmosDbContainer) : base(cosmosDbContainer)
 {
 }
 public CosmosDBRepository(ICosmosDbContainer cosmosDbContainer)
 {
     _container = cosmosDbContainer.GetContainer(ContainerName);
 }