Ejemplo n.º 1
0
        private static MessageJournalFilter ConfigureFilter(IHttpResourceRequest request, ICollection <ErrorModel> errors)
        {
            var filter = new MessageJournalFilter();
            var topic  = request.QueryString["topic"];

            if (!string.IsNullOrWhiteSpace(topic))
            {
                filter.Topics = topic.Split(',')
                                .Select(t => (TopicName)t)
                                .ToList();
            }

            var category = request.QueryString["category"];

            if (!string.IsNullOrWhiteSpace(category))
            {
                filter.Categories = category.Split(',')
                                    .Select(t => (MessageJournalCategory)t.Trim())
                                    .ToList();
            }

            filter.From        = GetDateTime("from", request, errors);
            filter.To          = GetDateTime("to", request, errors);
            filter.Origination = GetUri("origination", request, errors);
            filter.Destination = GetUri("destination", request, errors);
            filter.MessageName = request.QueryString["messageName"];
            filter.RelatedTo   = GetMessageId("relatedTo", request, errors);

            return(filter);
        }
Ejemplo n.º 2
0
 protected void GivenFilter(Action <MessageJournalFilter> apply)
 {
     if (Filter == null)
     {
         Filter = new MessageJournalFilter();
     }
     apply(Filter);
 }
Ejemplo n.º 3
0
        private FilterDefinition <MessageJournalEntryDocument> BuildFilter(MessageJournalFilter filter, FilterDefinition <MessageJournalEntryDocument> filterDef,
                                                                           FilterDefinitionBuilder <MessageJournalEntryDocument> fb)
        {
            if (filter == null)
            {
                return(filterDef);
            }

            if (filter.Topics.Any())
            {
                var topics = filter.Topics.Select(Normalize);
                filterDef = filterDef & fb.In(e => e.Topic, topics);
            }

            if (filter.Categories.Any())
            {
                var categories = filter.Categories.Select(Normalize);
                filterDef = filterDef & fb.In(e => e.Category, categories);
            }

            if (filter.From != null)
            {
                filterDef = filterDef & fb.Gte(e => e.Timestamp, filter.From);
            }

            if (filter.To != null)
            {
                filterDef = filterDef & fb.Lte(e => e.Timestamp, filter.To);
            }

            if (filter.Origination != null)
            {
                var origination = Normalize(filter.Origination);
                filterDef = filterDef & fb.Eq(e => e.Origination, origination);
            }

            if (filter.Destination != null)
            {
                var destination = Normalize(filter.Destination);
                filterDef = filterDef & fb.Eq(e => e.Destination, destination);
            }

            if (!string.IsNullOrWhiteSpace(filter.MessageName))
            {
                var partial = Normalize(filter.MessageName);
                var pattern = ".*" + Regex.Escape(partial) + ".*";
                var regex   = new BsonRegularExpression(pattern, "i");
                filterDef = filterDef & fb.Regex(e => e.MessageName, regex);
            }

            if (filter.RelatedTo != null)
            {
                var relatedTo = Normalize(filter.RelatedTo);
                filterDef = filterDef & fb.Eq(e => e.RelatedTo, relatedTo);
            }

            return(filterDef);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Reads messages from the journal
        /// </summary>
        /// <param name="start">The first position to read or <c>null</c> to begin reading from
        /// the beginning of the journal</param>
        /// <param name="count">The maximum number of messages to read</param>
        /// <param name="filter">(Optional) Constraints on which messages should be read</param>
        /// <param name="cancellationToken">(Optional) A token that the caller can use to
        /// request cancelation of the read operation</param>
        /// <returns>Returns a task whose result is the journal messages and meta data returned
        /// by the server</returns>
        public async Task <MessageJournalReadResult> Read(string start, int count, MessageJournalFilter filter = null,
                                                          CancellationToken cancellationToken = default(CancellationToken))
        {
            var httpClient  = await _httpClient;
            var relativeUri = new Uri("journal?" + BuildQuery(start, count, filter), UriKind.Relative);

            using (var responseMessage = await httpClient.GetAsync(relativeUri, cancellationToken))
            {
                responseMessage.EnsureSuccessStatusCode();
                return(await ParseResponseContent(responseMessage));
            }
        }
Ejemplo n.º 5
0
        private static string BuildQuery(string start, int count, MessageJournalFilter filter)
        {
            var queryParameters = new Dictionary <string, string>();

            if (start != null)
            {
                queryParameters["start"] = start;
            }
            queryParameters["count"] = count.ToString();

            if (filter != null)
            {
                if (filter.Topics.Count > 0)
                {
                    queryParameters["topic"] = string.Join(",", filter.Topics);
                }
                if (filter.Categories.Count > 0)
                {
                    queryParameters["category"] = string.Join(",", filter.Categories);
                }
                if (filter.From != null)
                {
                    queryParameters["from"] = FormatDate(filter.From);
                }
                if (filter.To != null)
                {
                    queryParameters["to"] = FormatDate(filter.To);
                }
                if (filter.Origination != null)
                {
                    queryParameters["origination"] = filter.Origination.ToString();
                }
                if (filter.Destination != null)
                {
                    queryParameters["destination"] = filter.Destination.ToString();
                }
                if (!string.IsNullOrWhiteSpace(filter.MessageName))
                {
                    queryParameters["messageName"] = filter.MessageName;
                }
                if (filter.RelatedTo != null)
                {
                    queryParameters["relatedTo"] = filter.RelatedTo;
                }
            }
            return(string.Join("&", queryParameters
                               .Select(p => p.Key + "=" + UrlEncoder.Encode(p.Value))));
        }
Ejemplo n.º 6
0
        private static bool IsExpectedFilter(MessageJournalFilter mf)
        {
            Assert.Equal(2, mf.Topics.Count);
            Assert.Equal(2, mf.Categories.Count);
            Assert.Contains((TopicName)"FooEvents", mf.Topics);
            Assert.Contains((TopicName)"BarEvents", mf.Topics);
            Assert.Contains((MessageJournalCategory)"Received", mf.Categories);
            Assert.Contains((MessageJournalCategory)"Received", mf.Categories);
            Assert.Equal(new DateTime(2017, 8, 9, 15, 31, 11, DateTimeKind.Utc).AddMilliseconds(12), mf.From);
            Assert.Equal(new DateTime(2017, 8, 10, 0, 0, 0, DateTimeKind.Utc), mf.To);
            Assert.Equal(new Uri("http://localhost:8089/platibus"), mf.Origination);
            Assert.Equal(new Uri("http://localhost:8090/platibus"), mf.Destination);
            Assert.Equal("event", mf.MessageName);
            Assert.Equal(new Guid("{637D88F6-48AC-4521-BD45-EA0965022AEC}"), mf.RelatedTo);

            return(true);
        }
Ejemplo n.º 7
0
        public JournalingUpdateService(IMessageJournal messageJournal,
                                       ISerializationService serializationService,
                                       IJournalConsumerProgressTracker tracker,
                                       IMongoDatabase database,
                                       IMessageNamingService messageNamingService,
                                       IConfiguration configuration)
        {
            _messageJournal       = messageJournal;
            _serializationService = serializationService;
            _tracker = tracker;
            _messageNamingService = messageNamingService;

            _eventProcessor = new CustomerJournalEventProcessor(database);

            // MessageJournalFilter does not work with mongo2 go
            if (configuration.GetValue <bool>("UseMongo2Go"))
            {
                Filter = null;
            }
        }
Ejemplo n.º 8
0
        protected virtual async Task AssertSentMessageIsWrittenToJournal()
        {
            var beginningOfJournal = await MessageJournal.GetBeginningOfJournal();

            var filter = new MessageJournalFilter
            {
                Categories = { MessageJournalCategory.Sent }
            };
            var readResult = await MessageJournal.Read(beginningOfJournal, 100, filter);

            Assert.NotNull(readResult);
            var messages = readResult.Entries.Select(jm => jm.Data);

            Assert.Contains(Message, messages, new MessageEqualityComparer());

            foreach (var entry in readResult.Entries)
            {
                Assert.Equal(entry.Category, MessageJournalCategory.Sent);
                Assert.Equal(entry.Data.Headers.Sent, entry.Timestamp, new WithinOneSecondDateTimeEqualityComparer());
            }
        }
Ejemplo n.º 9
0
        public async Task <ActionResult> Index(MessageJournalIndexModel model)
        {
            var updatedModel = await InitIndexModel();

            updatedModel.Start             = model.Start;
            updatedModel.Count             = model.Count;
            updatedModel.FilterCategories  = model.FilterCategories;
            updatedModel.FilterTopics      = model.FilterTopics;
            updatedModel.FilterFrom        = model.FilterFrom;
            updatedModel.FilterTo          = model.FilterTo;
            updatedModel.FilterOrigination = model.FilterOrigination;
            updatedModel.FilterDestination = model.FilterDestination;
            updatedModel.FilterRelatedTo   = model.FilterRelatedTo;
            updatedModel.FilterMessageName = model.FilterMessageName;
            updatedModel.ReadAttempted     = true;

            var accessToken = GetAccessToken();
            var credentials = new BearerCredentials(accessToken);

            using (var journalClient = new HttpMessageJournalClient(ApiBaseUri, credentials))
            {
                var filter = new MessageJournalFilter
                {
                    Topics      = model.FilterTopics.Select(t => (TopicName)t).ToList(),
                    Categories  = model.FilterCategories.Select(c => (MessageJournalCategory)c).ToList(),
                    From        = model.FilterFrom,
                    To          = model.FilterTo,
                    Origination = model.FilterOrigination,
                    Destination = model.FilterDestination,
                    MessageName = model.FilterMessageName,
                    RelatedTo   = model.FilterRelatedTo
                };
                var readResult = await journalClient.Read(model.Start, model.Count, filter);

                updatedModel.Result = readResult;
            }
            return(View(updatedModel));
        }
 /// <inheritdoc />
 public override Task <MessageJournalReadResult> Read(MessageJournalPosition start, int count, MessageJournalFilter filter = null,
                                                      CancellationToken cancellationToken = new CancellationToken())
 {
     CheckDisposed();
     return(_commandExecutor.ExecuteRead(
                () => base.Read(start, count, filter, cancellationToken),
                cancellationToken));
 }
Ejemplo n.º 11
0
        private static bool MatchesFilter(MessageJournalFilter filter, MessageJournalEntry entry)
        {
            if (filter == null)
            {
                return(true);
            }

            var headers = entry.Data.Headers;

            if (!string.IsNullOrWhiteSpace(filter.MessageName))
            {
                var messageName = (string)headers.MessageName;
                if (!messageName.Contains(filter.MessageName))
                {
                    return(false);
                }
            }

            if (filter.Topics.Any())
            {
                var topic = headers.Topic;
                if (!filter.Topics.Contains(topic))
                {
                    return(false);
                }
            }

            if (filter.Categories.Any())
            {
                var category = entry.Category;
                if (!filter.Categories.Contains(category))
                {
                    return(false);
                }
            }

            var timestamp = entry.Timestamp;

            if (filter.From > timestamp)
            {
                return(false);
            }
            if (filter.To <= timestamp)
            {
                return(false);
            }

            if (filter.Origination != null)
            {
                var origination = headers.Origination;
                if (!origination.Equals(filter.Origination))
                {
                    return(false);
                }
            }

            if (filter.Destination != null)
            {
                var destination = headers.Destination;
                if (!destination.Equals(filter.Destination))
                {
                    return(false);
                }
            }

            if (filter.RelatedTo != null)
            {
                var relatedTo = headers.RelatedTo;
                if (!relatedTo.Equals(filter.RelatedTo))
                {
                    return(false);
                }
            }

            return(true);
        }
Ejemplo n.º 12
0
        public virtual Task <MessageJournalReadResult> Read(MessageJournalPosition start, int count, MessageJournalFilter filter = null,
                                                            CancellationToken cancellationToken = default(CancellationToken))
        {
            var myStart = (Position)start;
            IList <MessageJournalEntry> myEntries;

            lock (_syncRoot)
            {
                myEntries = _entries.Skip(myStart.Index)
                            .Where(entry => MatchesFilter(filter, entry))
                            .Take(count + 1)
                            .ToList();
            }

            var next         = myStart;
            var endOfJournal = myEntries.Count <= count;

            if (myEntries.Any())
            {
                var lastIndex = myEntries.Select(e => e.Position).OfType <Position>().Max(p => p.Index);
                next = new Position(lastIndex + 1);
            }
            var readResult = new MessageJournalReadResult(start, next, endOfJournal, myEntries.Take(count));

            return(Task.FromResult(readResult));
        }
Ejemplo n.º 13
0
        /// <inheritdoc />
        public virtual async Task <MessageJournalReadResult> Read(MessageJournalPosition start, int count, MessageJournalFilter filter = null, CancellationToken cancellationToken = default(CancellationToken))
        {
            var myFilter          = filter ?? new MessageJournalFilter();
            var next              = start;
            var journaledMessages = new List <MessageJournalEntry>();
            var endOfJournal      = true;
            var connection        = ConnectionProvider.GetConnection();

            try
            {
                var commandBuilder = CommandBuilders.NewSelectJournaledMessagesCommandBuilder();
                commandBuilder.Categories  = myFilter.Categories.Select(c => (string)c).ToList();
                commandBuilder.Topics      = myFilter.Topics.Select(t => (string)t).ToList();
                commandBuilder.From        = myFilter.From;
                commandBuilder.To          = myFilter.To;
                commandBuilder.Origination = myFilter.Origination;
                commandBuilder.Destination = myFilter.Destination;
                commandBuilder.RelatedTo   = myFilter.RelatedTo;
                commandBuilder.MessageName = myFilter.MessageName;
                commandBuilder.Start       = ((SQLMessageJournalPosition)start).Id;
                commandBuilder.Count       = count + 1;

                using (var scope = new TransactionScope(TransactionScopeOption.Suppress, TransactionScopeAsyncFlowOption.Enabled))
                {
                    using (var command = commandBuilder.BuildDbCommand(connection))
                    {
                        using (var reader = await command.ExecuteReaderAsync(cancellationToken))
                        {
                            while (await reader.ReadAsync(cancellationToken))
                            {
                                var record = commandBuilder.BuildJournaledMessageRecord(reader);
                                next = new SQLMessageJournalPosition(record.Id);
                                if (journaledMessages.Count < count)
                                {
                                    var category         = record.Category;
                                    var timestamp        = record.Timestamp;
                                    var headers          = DeserializeHeaders(record.Headers);
                                    var messageContent   = record.Content;
                                    var offset           = new SQLMessageJournalPosition(record.Id);
                                    var message          = new Message(headers, messageContent);
                                    var journaledMessage = new MessageJournalEntry(category, offset, timestamp, message);
                                    journaledMessages.Add(journaledMessage);

                                    next = new SQLMessageJournalPosition(record.Id + 1);
                                }
                                else
                                {
                                    endOfJournal = false;
                                }
                            }
                        }
                    }
                    scope.Complete();
                }
            }
            finally
            {
                ConnectionProvider.ReleaseConnection(connection);
            }

            return(new MessageJournalReadResult(start, next, endOfJournal, journaledMessages));
        }
Ejemplo n.º 14
0
        /// <inheritdoc />
        public async Task <MessageJournalReadResult> Read(MessageJournalPosition start, int count, MessageJournalFilter filter = null,
                                                          CancellationToken cancellationToken = new CancellationToken())
        {
            var fb        = Builders <MessageJournalEntryDocument> .Filter;
            var filterDef = fb.Gte(mje => mje.Id, ((MongoDBMessageJournalPosition)start).Id);

            filterDef = BuildFilter(filter, filterDef, fb);

            var options = new FindOptions();

            if (_collationSupported)
            {
                options.Collation = _collation;
            }

            var entryDocuments = await _messageJournalEntries.Find(filterDef, options)
                                 .Limit(count + 1)
                                 .ToListAsync(cancellationToken);

            var endOfJournal = entryDocuments.Count <= count;
            var nextId       = entryDocuments.Select(e => e.Id).LastOrDefault();

            if (endOfJournal)
            {
                nextId = new ObjectId(nextId.Timestamp, nextId.Machine, nextId.Pid, nextId.Increment + 1);
            }

            var nextPosition = new MongoDBMessageJournalPosition(nextId);
            var entries      = new List <MessageJournalEntry>();

            foreach (var entryDocument in entryDocuments.Take(count))
            {
                var position  = new MongoDBMessageJournalPosition(entryDocument.Id);
                var timestamp = entryDocument.Timestamp;
                var category  = entryDocument.Category;
                var headers   = new MessageHeaders(entryDocument.Headers);
                var message   = new Message(headers, entryDocument.Content);
                entries.Add(new MessageJournalEntry(category, position, timestamp, message));
            }

            return(new MessageJournalReadResult(start, nextPosition, endOfJournal, entries));
        }