Exemple #1
0
 public DeviceMongoPublisher(IMongoCollection <DeviceDto> targets,
                             PipelineDefinition <ChangeStreamDocument <DeviceDto>, ChangeStreamDocument <DeviceDto> > pipeline,
                             ChangeStreamOptions options)
 {
     cancelToken = tokenSource.Token;
     action      = () => { StartChangeStream(targets); };
     t           = new Task(action, cancelToken);
 }
 public LocationMongoPublisher(IMongoCollection <LocationDto> collection,
                               PipelineDefinition <ChangeStreamDocument <LocationDto>, ChangeStreamDocument <LocationDto> > pipeline,
                               ChangeStreamOptions options)
 {
     cancelToken = tokenSource.Token;
     action      = () => { StartChangeStream(collection); };
     t           = new Task(action, cancelToken);
 }
 /// <inheritdoc />
 public virtual Task <IChangeStreamCursor <TResult> > WatchAsync <TResult>(
     IClientSessionHandle session,
     PipelineDefinition <ChangeStreamDocument <BsonDocument>, TResult> pipeline,
     ChangeStreamOptions options         = null,
     CancellationToken cancellationToken = default(CancellationToken))
 {
     return(wrapped.WatchAsync(session, pipeline, options, cancellationToken));
 }
        public static BaseMongoDbRepository <T> GetSubscribingRepository()
        {
            if (CurrentSubscribingRepository == null)
            {
                lock (subscriberLockObject)
                {
                    var currentDocumentType = typeof(T);
                    var currentAssembly     = AppDomain.CurrentDomain.GetAssemblies().Where(a => !a.IsDynamic)
                                              .Single(query => query.FullName == currentDocumentType.Assembly.FullName);

                    foreach (Type exportedType in currentAssembly.GetExportedTypes().Where(query => query.BaseType != null && query.BaseType.UnderlyingSystemType != null && query.BaseType.UnderlyingSystemType.IsGenericType))
                    {
                        if (exportedType.BaseType.UnderlyingSystemType.GetGenericArguments().FirstOrDefault() == currentDocumentType)
                        {
                            CurrentSubscribingRepository = Activator.CreateInstance(exportedType) as BaseMongoDbRepository <T>;

                            var pipeline = new EmptyPipelineDefinition <ChangeStreamDocument <T> >().Match("{ operationType: /^[^d]/  }");
                            ChangeStreamOptions options = new ChangeStreamOptions()
                            {
                                FullDocument = ChangeStreamFullDocumentOption.UpdateLookup
                            };
                            var changeStream = CurrentSubscribingRepository.CurrentCollection.Watch(pipeline, options).ToEnumerable().GetEnumerator();

                            var task = Task.Run(() =>
                            {
                                while (true)
                                {
                                    try
                                    {
                                        changeStream.MoveNext();
                                        ChangeStreamDocument <T> next = changeStream.Current;
                                        var currentData = next.FullDocument;

                                        if (CurrentSubscribingRepository.SubscriptionTriggered == null)
                                        {
                                            continue;
                                        }

                                        var receivers = CurrentSubscribingRepository.SubscriptionTriggered.GetInvocationList();
                                        foreach (SubscriptionTriggeredEventHandler receiver in receivers)
                                        {
                                            receiver.BeginInvoke(CurrentSubscribingRepository, currentData, null, null);
                                        }
                                    }
                                    catch (Exception ex)
                                    {
                                    }
                                }
                            });

                            break;
                        }
                    }
                }
            }

            return(CurrentSubscribingRepository);
        }
        /// <summary>
        /// Listed to the changes in Mongo collection and synch the changes to ElasticSearch index.
        /// </summary>
        private void HandleChanges()
        {
            log.Info("HandleChanges begin");

            try
            {
                MongoClient   mongoClient   = new MongoClient(this.mongoConnectionString);
                ElasticClient elasticClient = new ElasticClient(new ConnectionSettings(new Uri(this.elasticConnectionString)));

                IMongoDatabase       database   = mongoClient.GetDatabase(this.databaseName);
                IMongoCollection <T> collection = database.GetCollection <T>(this.collectionName);

                this.cancellationToken.ThrowIfCancellationRequested();

                EnsureIndexCreated(elasticClient);

                //Get the whole document instead of just the changed portion
                ChangeStreamOptions options = new ChangeStreamOptions()
                {
                    FullDocument = ChangeStreamFullDocumentOption.UpdateLookup
                };

                var pipeline = new EmptyPipelineDefinition <ChangeStreamDocument <T> >()
                               .Match("{ operationType: { $in: [ 'insert', 'update', 'delete' ] } }");

                using (var stream = collection.Watch(pipeline, options))
                {
                    while (!this.cancellationToken.IsCancellationRequested)
                    {
                        try
                        {
                            if (stream.MoveNext())
                            {
                                var enumerator = stream.Current.GetEnumerator();
                                while (enumerator.MoveNext())
                                {
                                    HandleChange(elasticClient,
                                                 enumerator.Current.OperationType,
                                                 enumerator.Current.FullDocument);
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            log.Error($"HandleChanges failed.", ex);
                        }

                        Thread.Sleep(ChangeStreamCheckTimeout);

                        this.cancellationToken.ThrowIfCancellationRequested();
                    }
                }
            }
            catch (Exception ex)
            {
                log.Error($"HandleChanges failed.", ex);
            }
        }
Exemple #6
0
        public IChangeStreamCursor <ChangeStreamDocument <TModel> > Watch()
        {
            var options = new ChangeStreamOptions {
                FullDocument = ChangeStreamFullDocumentOption.UpdateLookup
            };
            var pipeline = new EmptyPipelineDefinition <ChangeStreamDocument <TModel> >().Match("{ operationType: { $in: [ 'insert', 'delete' ] } }");

            return(_mongoCollection.Watch <ChangeStreamDocument <TModel> >(pipeline, options));
        }
 public UnifiedCreateChangeStreamOnDatabaseOperation(
     IMongoDatabase database,
     BsonDocumentStagePipelineDefinition <ChangeStreamDocument <BsonDocument>, ChangeStreamDocument <BsonDocument> > pipeline,
     ChangeStreamOptions options)
 {
     _database = database;
     _pipeline = pipeline;
     _options  = options;
 }
 public UnifiedCreateChangeStreamOnClientOperation(
     IMongoClient client,
     BsonDocumentStagePipelineDefinition <ChangeStreamDocument <BsonDocument>, ChangeStreamDocument <BsonDocument> > pipeline,
     ChangeStreamOptions options)
 {
     _client   = client;
     _pipeline = pipeline;
     _options  = options;
 }
 public UnifiedCreateChangeStreamOnCollectionOperation(
     IMongoCollection <BsonDocument> collection,
     BsonDocumentStagePipelineDefinition <ChangeStreamDocument <BsonDocument>, ChangeStreamDocument <BsonDocument> > pipeline,
     ChangeStreamOptions options)
 {
     _collection = collection;
     _pipeline   = pipeline;
     _options    = options;
 }
        /// <summary>
        /// Fügt eine Organisation in die Datenbank hinzu
        /// </summary>
        /// <param name="entry"></param>
        //internal void AddOrganization(Organization entry)
        //{
        //    entry.Verify();
        //    organisations.InsertOne(entry);
        //}
        /// <summary>
        /// Listener Für Änderungen in der Entry Datenbank
        /// Sorgt mit hilfe von SignalR dafür, das die Frontends aktualsiert werden.
        /// Prüft ob es eine Organisation gibt, welche eine benachrichtigung z.b. über email aboniert hat und versendert die.
        /// Es ist auch möglich sich auf die PLZ 00000 zu Registrieren.
        /// </summary>
        private async void Listen()
        {
            var options = new ChangeStreamOptions {
                FullDocument = ChangeStreamFullDocumentOption.UpdateLookup
            };
            var pipeline = new EmptyPipelineDefinition <ChangeStreamDocument <Entry> >()
                           .Match("{ operationType: { $in: [ 'insert','replace', 'update' ] }}")
                           .Project("{ fullDocument: 1 }");

            using var cursor = requests.Watch(pipeline, options);
            await cursor.ForEachAsync(change =>
            {
                Entry entry = BsonSerializer.Deserialize <Entry>((BsonDocument)change.Elements.ToList()[1].Value);
                if (entry.zip.Equals("00000"))
                {
                    var send = entry.TrasportModel;
                    _hubContext.Clients.All.SendAsync("ItemChange", send);
                    //foreach (Organization organisation in organisations.Find("{ \"zips\": {$in: [ '00000', ]}}").ToList<Organization>())
                    //{
                    //    var notifikation = new Notifikation()
                    //    {
                    //        entry = entry.id.ToString(),
                    //        organisation = organisation.id.ToString(),
                    //        timestamp = DateTime.Now
                    //    };
                    //    if (TryAddNotifkation(notifikation))
                    //    {
                    //        notifikationFactory.Send(notifikation, organisation, entry);
                    //    }
                    //}
                }
                //else
                //{
                //    StringBuilder sb = new StringBuilder();
                //    for (int i = 0; i < entry.zip.Length; i++)
                //    {
                //        sb.Append('\'');
                //        sb.Append(entry.zip.Substring(0, entry.zip.Length - i));
                //        sb.Append("', ");
                //    }
                //    foreach (Organization organisation in organisations.Find($"{{ \"zips\": {{$in: [ {sb.ToString()} ]}}}}").ToList<Organization>())
                //    {
                //        var notifikation = new Notifikation()
                //        {
                //            entry = entry.id.ToString(),
                //            organisation = organisation.id.ToString(),
                //            timestamp = DateTime.Now
                //        };
                //        if (TryAddNotifkation(notifikation))
                //        {
                //            notifikationFactory.Send(notifikation, organisation, entry);
                //        }
                //    }
                //}
            });
        }
Exemple #11
0
        private ChangeStreamOptions ParseChangeStreamOptions(BsonDocument document)
        {
            var options = new ChangeStreamOptions();

            foreach (var element in document)
            {
                throw new FormatException($"Invalid change stream option: \"{element.Name}\".");
            }

            return(options);
        }
Exemple #12
0
        private static async Task TriggerChangeStreamAsync()
        {
            Console.WriteLine("TriggerChangeStream Method start");
            try
            {
                MongoClient dbClient = new MongoClient("mongodb://*****:*****@deliverymoment-cosmos-mongo-db.mongo.cosmos.azure.com:10255/?ssl=true&replicaSet=globaldb&maxIdleTimeMS=120000&appName=@deliverymoment-cosmos-mongo-db@");
                //Database List

                //Get Database and Collection
                Console.WriteLine("Get Database : deliverymoment-db :");
                IMongoDatabase db = dbClient.GetDatabase("deliverymoment-db");

                Console.WriteLine("Get Deilverymoment Collection :");

                var deliveryColl = db.GetCollection <BsonDocument>("delivery-moment​");

                Console.WriteLine("Changestream code start");

                //change feed code start
                var pipeline = new EmptyPipelineDefinition <ChangeStreamDocument <BsonDocument> >()
                               .Match(change => change.OperationType == ChangeStreamOperationType.Insert || change.OperationType == ChangeStreamOperationType.Update || change.OperationType == ChangeStreamOperationType.Replace)
                               .AppendStage <ChangeStreamDocument <BsonDocument>, ChangeStreamDocument <BsonDocument>, BsonDocument>(
                    "{ $project: { '_id': 1, 'fullDocument': 1, 'ns': 1, 'documentKey': 1 }}");

                var options = new ChangeStreamOptions
                {
                    FullDocument = ChangeStreamFullDocumentOption.UpdateLookup
                };

                var enumerator = deliveryColl.Watch(pipeline, options).ToEnumerable().GetEnumerator();
                Console.WriteLine("Reading Change stream while loop start");
                while (enumerator.MoveNext())
                {
                    //publish message to Confluent Kafka
                    var document = enumerator.Current;
                    Console.WriteLine($"Start publishing messaage : {document}");
                    await DeliveryMomentMessageHandler.PublishMessage(document.ToString());

                    Console.WriteLine($"End publishing messaage : {document}");
                }

                enumerator.Dispose();

                Console.WriteLine("Reading Change stream while loop end");
                //change feed code end
            }
            catch (Exception ex)
            {
                Console.WriteLine("Error: " + ex.Message);
            }

            Console.WriteLine("TriggerChangeStream Method end");
        }
Exemple #13
0
        public async Task <IChangeStreamCursor <ChangeStreamDocument <Notification> > > GetNotificationChangeStreamCursorAsync()
        {
            var            mongoClient = new MongoClient(_server);
            IMongoDatabase database    = mongoClient.GetDatabase(_database);
            var            collection  = database.GetCollection <Notification>(_collection);
            var            options     = new ChangeStreamOptions {
                FullDocument = ChangeStreamFullDocumentOption.UpdateLookup
            };
            var pipeline = new EmptyPipelineDefinition <ChangeStreamDocument <Notification> >().Match("{ operationType: { $in: [ 'insert' ] } }");
            IChangeStreamCursor <ChangeStreamDocument <Notification> > cursor = await collection.WatchAsync(pipeline, options);

            return(cursor);
        }
Exemple #14
0
        private async Task QueryCurrentAsync(string?streamFilter, StreamPosition lastPosition)
        {
            BsonDocument?resumeToken = null;

            var start =
                lastPosition.Timestamp.Timestamp > 0 ?
                lastPosition.Timestamp.Timestamp - 30 :
                SystemClock.Instance.GetCurrentInstant().Minus(Duration.FromSeconds(30)).ToUnixTimeSeconds();

            var changePipeline = Match(streamFilter);
            var changeStart    = new BsonTimestamp((int)start, 0);

            while (!stopToken.IsCancellationRequested)
            {
                var changeOptions = new ChangeStreamOptions();

                if (resumeToken != null)
                {
                    changeOptions.StartAfter = resumeToken;
                }
                else
                {
                    changeOptions.StartAtOperationTime = changeStart;
                }

                using (var cursor = eventStore.TypedCollection.Watch(changePipeline, changeOptions, stopToken.Token))
                {
                    var isRead = false;

                    await cursor.ForEachAsync(async change =>
                    {
                        if (change.OperationType == ChangeStreamOperationType.Insert)
                        {
                            foreach (var storedEvent in change.FullDocument.Filtered(lastPosition))
                            {
                                await eventSubscriber.OnEventAsync(this, storedEvent);
                            }
                        }

                        isRead = true;
                    }, stopToken.Token);

                    resumeToken = cursor.GetResumeToken();

                    if (!isRead)
                    {
                        await Task.Delay(1000);
                    }
                }
            }
        }
Exemple #15
0
        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            var options = new ChangeStreamOptions {
                FullDocument = ChangeStreamFullDocumentOption.UpdateLookup
            };
            var pipeline = new EmptyPipelineDefinition <ChangeStreamDocument <User> >()
                           .Match(x => x.OperationType == ChangeStreamOperationType.Replace || x.OperationType == ChangeStreamOperationType.Update);

            using var cursor = _users.Watch(pipeline, options, stoppingToken);
            await cursor.ForEachAsync(async document =>
            {
                await _userHubContext.SendUpdateAsync(document.FullDocument);
            }, stoppingToken);
        }
Exemple #16
0
        public void Test3()
        {
            var mockClient     = new Mock <IMongoClient>();
            var mockContext    = new Mock <IMongoContext>();
            var client         = mockClient.Object;
            var mockCollection = CreateMockCollection();
            var collection     = mockCollection.Object;
            var session        = new Mock <IClientSessionHandle>().Object;

            var options           = new ChangeStreamOptions();
            var cancellationToken = new CancellationTokenSource().Token;

            Book document = new Book();

            document.Author   = "asdas";
            document.BookName = "sadasd";

            document.Id = ObjectId.GenerateNewId().ToString();

            collection.InsertOne(document);

            mockContext.Setup(x => x.GetCollection <Book>("Book")).Returns(collection);


            BookstoreDatabaseSettings setting = new BookstoreDatabaseSettings();

            setting.BooksCollectionName = "Book";
            var mockIDBsettings = new Mock <IOptions <BookstoreDatabaseSettings> >();

            mockIDBsettings.Setup(x => x.Value).Returns(setting);

            BookService service = new BookService(mockIDBsettings.Object, mockContext.Object);
            var         result  = service.Create(document);

            mockContext.Verify(x => x.GetCollection <Book>("Book"), Times.Once);

            var filterDefinition = Builders <Book> .Filter.Eq("BookName", "sadasd");

            var options1 = new FindOptions <Book>(); // no projection


            var filterExpression = (Expression <Func <Book, bool> >)(x => x.BookName == "sadasd");

            //FindFluent<Book, Book> fluent;

            //mockCollection.Verify(x=>x.Find(filterExpression, null), Times.Once);

            mockCollection.Verify(m => m.FindAsync <Book>(It.IsAny <ExpressionFilterDefinition <Book> >(), options1, cancellationToken), Times.Once);
        }
Exemple #17
0
        private static ChangeStreamOptions BuildChangeStreamOptions(BsonDocument resumeToken)
        {
            var changeStreamOptions = new ChangeStreamOptions
            {
                FullDocument =
                    ChangeStreamFullDocumentOption
                    .UpdateLookup     // Confgure to get full document whilst getting the update operation [by default update does not include full document]
            };

            if (!resumeToken.GetElement("_data").Value.IsBsonNull)
            {
                changeStreamOptions.ResumeAfter = resumeToken; // Confugre the resume token here, if any
            }

            return(changeStreamOptions);
        }
        public void ChangeStreamExample3()
        {
            var client   = DriverTestConfiguration.Client;
            var database = client.GetDatabase("ChangeStreamExamples");

            database.DropCollection("inventory");
            var inventory = database.GetCollection <BsonDocument>("inventory");

            var documents = new[]
            {
                new BsonDocument("x", 1),
                new BsonDocument("x", 2)
            };

            IChangeStreamCursor <ChangeStreamDocument <BsonDocument> > previousCursor;
            {
                new Thread(() =>
                {
                    Thread.Sleep(TimeSpan.FromMilliseconds(100));
                    inventory.InsertMany(documents);
                })
                .Start();

                previousCursor = inventory.Watch(new ChangeStreamOptions {
                    BatchSize = 1
                });
                while (previousCursor.MoveNext() && previousCursor.Current.Count() == 0)
                {
                }                                                                            // keep calling MoveNext until we've read the first batch
            }

            {
                // Start Changestream Example 3
                var resumeToken = previousCursor.GetResumeToken();
                var options     = new ChangeStreamOptions {
                    ResumeAfter = resumeToken
                };
                var cursor = inventory.Watch(options);
                cursor.MoveNext();
                var next = cursor.Current.First();
                cursor.Dispose();
                // End Changestream Example 3

                next.FullDocument.Should().Be(documents[1]);
            }
        }
Exemple #19
0
        public async void ListenAsync()
        {
            var option = new ChangeStreamOptions {
                StartAtOperationTime = new BsonTimestamp((int)(DateTime.Now.ToUniversalTime() - new DateTime(1970, 1, 1, 0, 0, 0)).TotalSeconds, 0)
            };

            using (var cursor = await Collection.WatchAsync(option))
            {
                while (await cursor.MoveNextAsync())
                {
                    foreach (var csd in cursor.Current)
                    {
                        Cache.Replace(csd.FullDocument);
                    }
                }
            }
        }
Exemple #20
0
        private ChangeStreamOptions ParseChangeStreamOptions(BsonDocument document)
        {
            var options = new ChangeStreamOptions();

            foreach (var element in document)
            {
                switch (element.Name)
                {
                case "batchSize": options.BatchSize = element.Value.ToInt32(); break;

                default:
                    throw new FormatException($"Invalid change stream option: \"{element.Name}\".");
                }
            }

            return(options);
        }
Exemple #21
0
        public IEnumerator <ChangeStreamDocument <TEntity> > SubscribeToChangesStreamMany(
            PipelineDefinition <ChangeStreamDocument <TEntity>, ChangeStreamDocument <TEntity> > pipeline
            )
        {
            if (pipeline == null)
            {
                return(null);
            }

            var options = new ChangeStreamOptions
            {
                FullDocument = ChangeStreamFullDocumentOption.UpdateLookup
            };

            var cursor     = _mongoCollection.Watch(pipeline, options);
            var enumerator = cursor.ToEnumerable().GetEnumerator();

            return(enumerator);
        }
        public UnifiedCreateChangeStreamOnCollectionOperation Build(string targetCollectionId, BsonDocument arguments)
        {
            var collection = _entityMap.GetCollection(targetCollectionId);

            ChangeStreamOptions options = null;
            BsonDocumentStagePipelineDefinition <ChangeStreamDocument <BsonDocument>, ChangeStreamDocument <BsonDocument> > pipeline = null;

            foreach (var argument in arguments)
            {
                switch (argument.Name)
                {
                case "batchSize":
                    options ??= new ChangeStreamOptions();
                    options.BatchSize = argument.Value.AsInt32;
                    break;

                case "comment":
                    options ??= new ChangeStreamOptions();
                    options.Comment = argument.Value;
                    break;

                case "fullDocument":
                    options ??= new ChangeStreamOptions();
                    options.FullDocument = (ChangeStreamFullDocumentOption)Enum.Parse(typeof(ChangeStreamFullDocumentOption), argument.Value.AsString, true);
                    break;

                case "fullDocumentBeforeChange":
                    options ??= new ChangeStreamOptions();
                    options.FullDocumentBeforeChange = (ChangeStreamFullDocumentBeforeChangeOption)Enum.Parse(typeof(ChangeStreamFullDocumentBeforeChangeOption), argument.Value.AsString, true);
                    break;

                case "pipeline":
                    var stages = argument.Value.AsBsonArray.Cast <BsonDocument>();
                    pipeline = new BsonDocumentStagePipelineDefinition <ChangeStreamDocument <BsonDocument>, ChangeStreamDocument <BsonDocument> >(stages);
                    break;

                default:
                    throw new FormatException($"Invalid CreateChangeStreamOperation argument name: '{argument.Name}'.");
                }
            }

            return(new UnifiedCreateChangeStreamOnCollectionOperation(collection, pipeline, options));
        }
Exemple #23
0
        public void ChangeStreamExample3()
        {
            var client   = DriverTestConfiguration.Client;
            var database = client.GetDatabase("ChangeStreamExamples");

            database.DropCollection("inventory");
            var inventory = database.GetCollection <BsonDocument>("inventory");

            var documents = new[]
            {
                new BsonDocument("x", 1),
                new BsonDocument("x", 2)
            };

            ChangeStreamDocument <BsonDocument> lastChangeStreamDocument;
            {
                new Thread(() =>
                {
                    Thread.Sleep(TimeSpan.FromMilliseconds(100));
                    inventory.InsertMany(documents);
                })
                .Start();

                var enumerator = inventory.Watch().ToEnumerable().GetEnumerator();
                enumerator.MoveNext();
                lastChangeStreamDocument = enumerator.Current;
            }

            {
                // Start Changestream Example 3
                var resumeToken = lastChangeStreamDocument.ResumeToken;
                var options     = new ChangeStreamOptions {
                    ResumeAfter = resumeToken
                };
                var enumerator = inventory.Watch(options).ToEnumerable().GetEnumerator();
                enumerator.MoveNext();
                var next = enumerator.Current;
                enumerator.Dispose();
                // End Changestream Example 3

                next.FullDocument.Should().Be(documents[1]);
            }
        }
Exemple #24
0
        public void CreateChangeStreamOperation_for_collection_returns_expected_result()
        {
            var databaseNamespace   = new DatabaseNamespace("databaseName");
            var collectionNamespace = new CollectionNamespace(databaseNamespace, "collectionName");
            var mockCollection      = new Mock <IMongoCollection <BsonDocument> >();

            mockCollection.SetupGet(m => m.CollectionNamespace).Returns(collectionNamespace);
            var pipeline           = new EmptyPipelineDefinition <ChangeStreamDocument <BsonDocument> >().Limit(1);
            var documentSerializer = BsonDocumentSerializer.Instance;
            var options            = new ChangeStreamOptions
            {
                BatchSize                = 123,
                Collation                = new Collation("en-us"),
                FullDocument             = ChangeStreamFullDocumentOption.UpdateLookup,
                FullDocumentBeforeChange = ChangeStreamFullDocumentBeforeChangeOption.Off,
                MaxAwaitTime             = TimeSpan.FromSeconds(123),
                ResumeAfter              = new BsonDocument(),
                StartAfter               = new BsonDocument(),
                StartAtOperationTime     = new BsonTimestamp(1, 2)
            };
            var readConcern            = new ReadConcern();
            var messageEncoderSettings = new MessageEncoderSettings();
            var renderedPipeline       = RenderPipeline(pipeline);

            var result = ChangeStreamHelper.CreateChangeStreamOperation(mockCollection.Object, pipeline, documentSerializer, options, readConcern, messageEncoderSettings, true);

            result.BatchSize.Should().Be(options.BatchSize);
            result.Collation.Should().BeSameAs(options.Collation);
            result.CollectionNamespace.Should().BeSameAs(collectionNamespace);
            result.DatabaseNamespace.Should().BeNull();
            result.FullDocument.Should().Be(options.FullDocument);
            result.FullDocumentBeforeChange.Should().Be(options.FullDocumentBeforeChange);
            result.MaxAwaitTime.Should().Be(options.MaxAwaitTime);
            result.MessageEncoderSettings.Should().BeSameAs(messageEncoderSettings);
            result.Pipeline.Should().Equal(renderedPipeline.Documents);
            result.ReadConcern.Should().BeSameAs(readConcern);
            result.ResultSerializer.Should().BeOfType <ChangeStreamDocumentSerializer <BsonDocument> >();
            result.ResumeAfter.Should().BeSameAs(options.ResumeAfter);
            result.RetryRequested.Should().Be(true);
            result.StartAfter.Should().BeSameAs(options.StartAfter);
            result.StartAtOperationTime.Should().BeSameAs(options.StartAtOperationTime);
        }
        public static IObservable <ChangeStreamDocument <T> > WhenCollectionChanges <T>(this IMongoCollection <T> collection, CancellationToken cancellationToken = default, params ChangeStreamOperationType[] operationTypes)
        {
            if (operationTypes.Length == 0)
            {
                operationTypes = new[] { ChangeStreamOperationType.Insert, ChangeStreamOperationType.Update, ChangeStreamOperationType.Replace, ChangeStreamOperationType.Delete };
            }

            // { operationType: { $in: [...] } }
            var filter = new FilterDefinitionBuilder <ChangeStreamDocument <T> >()
                         .In(d => d.OperationType, operationTypes);

            var pipelineDefinition = new EmptyPipelineDefinition <ChangeStreamDocument <T> >()
                                     .Match(filter);

            var options = new ChangeStreamOptions()
            {
                FullDocument = ChangeStreamFullDocumentOption.UpdateLookup
            };
            var changeStreamCursor = collection.Watch(pipelineDefinition, options, cancellationToken);

            return(Observable.Create <ChangeStreamDocument <T> >(observer =>
            {
                Task.Run(async() =>
                {
                    while (true)
                    {
                        if (await changeStreamCursor.MoveNextAsync(cancellationToken))
                        {
                            foreach (var c in changeStreamCursor.Current)
                            {
                                observer.OnNext(c);
                                cancellationToken.ThrowIfCancellationRequested();
                            }
                        }

                        cancellationToken.ThrowIfCancellationRequested();
                    }
                }, cancellationToken);

                return Disposable.Create(() => changeStreamCursor.Dispose());
            }));
        }
Exemple #26
0
        public async Task SubscribeById(string docId)
        {
            // Much of the streaming options, query is taken from here.
            // https://stackoverflow.com/questions/48672584/how-to-set-mongodb-change-stream-operationtype-in-the-c-sharp-driver

            // Set options.
            // Get the whole document instead of just the changed portion
            var options = new ChangeStreamOptions()
            {
                FullDocument = ChangeStreamFullDocumentOption.UpdateLookup
            };

            // Set our matching criteria
            // Example: The operationType can be one of the following: insert, update, replace, delete, invalidate
            // Example: var pipeline = new EmptyPipelineDefinition<ChangeStreamDocument<BsonDocument>>().Match("{ operationType: { $in: [ 'replace', 'insert', 'update' ] } }");
            var pipeline = new EmptyPipelineDefinition <ChangeStreamDocument <TargetDto> >()
                           .Match(t => t.FullDocument.Id == Guid.Parse(""));

            Guid subscriptionId = _targetDbService.Subscribe(pipeline, options);
        }
        public override void Watch(Action <EventRecord> callback)
        {
            var options = new ChangeStreamOptions()
            {
                FullDocument = ChangeStreamFullDocumentOption.UpdateLookup
            };

            var pipeline = new EmptyPipelineDefinition <ChangeStreamDocument <EventRecord> >().Match("{ operationType: { $in: [ 'insert' ] } }");

            var changesCursor = Collection
                                .Watch(pipeline, options)
                                .ToEnumerable()
                                .GetEnumerator();

            while (changesCursor.MoveNext())
            {
                var record = changesCursor.Current.FullDocument;
                InvokeCallback(callback, record);
            }
        }
Exemple #28
0
        public async IAsyncEnumerable <Envelope> Watch(
            Checkpoint?checkpoint,
            CancellationToken cancellation
            )
        {
            while (!await EventsCollectionExists())
            {
                _logger.LogDebug("Waiting for events collection to appear...");
                await Task.Delay(100, cancellation);
            }

            var envelopes = Load(checkpoint, cancellation);

            checkpoint ??= new Checkpoint();
            await foreach (var envelope in envelopes)
            {
                checkpoint.Value = envelope.MessageId;
                yield return(envelope);
            }

            var options = new ChangeStreamOptions {
                FullDocument = ChangeStreamFullDocumentOption.UpdateLookup,
            };
            var from = CheckpointToFilter(d => d["FullDocument"]["_id"], checkpoint);

            var pipeline = new EmptyPipelineDefinition <ChangeStreamDocument <Envelope> >()
                           .Match(x => x.OperationType == ChangeStreamOperationType.Insert)
                           .Match(x => from.Inject());

            using var cursor = await _events.WatchAsync(pipeline, options, cancellation);

            while (await cursor.MoveNextAsync(cancellation))
            {
                foreach (var change in cursor.Current)
                {
                    yield return(change.FullDocument);
                }
            }
        }
Exemple #29
0
        public static void hookMessage(User sender, User reciever)
        {
            var options = new ChangeStreamOptions {
                FullDocument = ChangeStreamFullDocumentOption.UpdateLookup
            };
            var change = getObjectCollection().Watch(options).ToEnumerable().GetEnumerator();

            while (change.MoveNext())
            {
                var query = Builders <Message> .Filter.Eq("Sender", sender.Username)
                            & Builders <Message> .Filter.Eq("Reciever", reciever.Username)
                            & Builders <Message> .Filter.Eq("Status", "0");

                var list = getObjectCollection().Find(query).ToList();
                foreach (Message DocMsg in list)
                {
                    Console.WriteLine(DocMsg.Sender + " to " + DocMsg.Reciever + " : " + DocMsg.MessageText);
                    msgstack.Enqueue(DocMsg);
                    UpdateReadStatus(DocMsg);
                }
            }
        }
        public void ChangeStreamExample2()
        {
            var client   = DriverTestConfiguration.Client;
            var database = client.GetDatabase("ChangeStreamExamples");

            database.DropCollection("inventory");
            var inventory = database.GetCollection <BsonDocument>("inventory");

            var document = new BsonDocument("x", 1);

            inventory.InsertOne(document);
            new Thread(() =>
            {
                Thread.Sleep(TimeSpan.FromMilliseconds(100));
                var filter = new BsonDocument("_id", document["_id"]);
                var update = "{ $set : { x : 2 } }";
                inventory.UpdateOne(filter, update);
            })
            .Start();

            // Start Changestream Example 2
            var options = new ChangeStreamOptions {
                FullDocument = ChangeStreamFullDocumentOption.UpdateLookup
            };
            var cursor = inventory.Watch(options);

            while (cursor.MoveNext() && cursor.Current.Count() == 0)
            {
            }                                                            // keep calling MoveNext until we've read the first batch
            var next = cursor.Current.First();

            cursor.Dispose();
            // End Changestream Example 2

            var expectedFullDocument = document.Set("x", 2);

            next.FullDocument.Should().Be(expectedFullDocument);
        }