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 }); }
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>(); }
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)); }
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}")); }
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); }
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); }
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")); }
public WorkspaceRepository(ICosmosDbContainer cosmosDbContainer) : base(cosmosDbContainer) { }
public CosmosDBRepository(ICosmosDbContainer cosmosDbContainer) { _container = cosmosDbContainer.GetContainer(ContainerName); }