private async Task BroadcastOperationAsync( ChangeStreamOperationType operationType, RecordedEventDocument document ) { switch (operationType) { case ChangeStreamOperationType.Insert: { var recordedEvent = RecordedEvent.FromDocument(document); Console.WriteLine("Broadcasting insert:"); Console.WriteLine(Encoding.UTF8.GetString(recordedEvent.Data)); await _hub.Clients.All.EventRecorded(recordedEvent); break; } case ChangeStreamOperationType.Update: case ChangeStreamOperationType.Replace: case ChangeStreamOperationType.Delete: case ChangeStreamOperationType.Invalidate: case ChangeStreamOperationType.Rename: case ChangeStreamOperationType.Drop: break; default: throw new ArgumentOutOfRangeException(nameof(operationType), operationType, null); } }
public void Serialize_should_have_expected_result( ChangeStreamOperationType operationType, string resumeTokenJson, string databaseName, string collectionName, string documentKeyJson, string updateDescriptionJson, string fullDocumentJson, string expectedJson) { var subject = CreateSubject(); var value = new ChangeStreamDocument <BsonDocument>( ParseBsonDocument(resumeTokenJson), operationType, CreateCollectionNamespace(databaseName, collectionName), ParseBsonDocument(documentKeyJson), ParseUpdateDescription(updateDescriptionJson), ParseBsonDocument(fullDocumentJson)); string json; using (var textWriter = new StringWriter()) using (var writer = new JsonWriter(textWriter)) { var context = BsonSerializationContext.CreateRoot(writer); subject.Serialize(context, value); json = textWriter.ToString(); } json.Should().Be(expectedJson); }
public void Deserialize_should_return_expected_result( string json, string expectedResumeTokenJson, ChangeStreamOperationType expectedOperationType, string expectedDatabaseName, string expectedCollectionName, string expectedDocumentKeyJson, string expectedUpdateDescriptionJson, string expectedFullDocumentJson ) { var subject = CreateSubject(); var expectedCollectionNamespace = CreateCollectionNamespace(expectedDatabaseName, expectedCollectionName); var expectedDocumentKey = ParseBsonDocument(expectedDocumentKeyJson); var expectedFullDocument = ParseBsonDocument(expectedFullDocumentJson); var expectedResumeToken = ParseBsonDocument(expectedResumeTokenJson); var expectedUpdateDescription = ParseUpdateDescription(expectedUpdateDescriptionJson); ChangeStreamDocument <BsonDocument> result; using (var reader = new JsonReader(json)) { var context = BsonDeserializationContext.CreateRoot(reader); result = subject.Deserialize(context); } result.CollectionNamespace.Should().Be(expectedCollectionNamespace); result.DocumentKey.Should().Be(expectedDocumentKey); result.FullDocument.Should().Be(expectedFullDocument); result.OperationType.Should().Be(expectedOperationType); result.ResumeToken.Should().Be(expectedResumeToken); result.UpdateDescription.ShouldBeEquivalentTo(expectedUpdateDescription); }
public static string Create(BsonDocument document, ChangeStreamOperationType operationType, string defaultEventPrefix) { var prefix = defaultEventPrefix; if (document != null && document.TryGetValue("_t", out var t)) { prefix = (string)t; } switch (operationType) { case ChangeStreamOperationType.Insert: return($"{prefix}Created"); case ChangeStreamOperationType.Update: return($"{prefix}Updated"); case ChangeStreamOperationType.Replace: return($"{prefix}Updated"); case ChangeStreamOperationType.Delete: return($"{prefix}Deleted"); default: throw new Exception($"Unsupported operation type {operationType}."); } }
private void HandleChange(ElasticClient elasticClient, ChangeStreamOperationType changeType, T document) { log.Info($"HandleChange begin, changeType: {changeType}, document.id: {document.id}"); try { switch (changeType) { case ChangeStreamOperationType.Insert: elasticClient.Index <T>(document, i => i.Index(this.indexName) .Id(document.id) .Refresh(Refresh.True)); break; case ChangeStreamOperationType.Update: // We used .Index() instead of Update() since we are updating all the fields elasticClient.Index <T>(document, i => i.Index(this.indexName) .Id(document.id) .Refresh(Refresh.True)); break; case ChangeStreamOperationType.Delete: elasticClient.Delete <T>(document.id, d => d.Index(this.indexName)); break; } } catch (Exception ex) { log.Error($"HandleChange failed, changeType: {changeType}, document: {JsonConvert.SerializeObject(document)}.", ex); } log.Info("HandleChange end"); }
protected Task cofigureWatcher <WatchType>( IMongoCollection <WatchType> collectionToMonitor, Func <ChangeStreamDocument <WatchType>, Task> watchFunction, ChangeStreamOperationType operationType, ChangeStreamFullDocumentOption changeStreamDocumentOption = ChangeStreamFullDocumentOption.UpdateLookup, byte secondsToWait = 2) { var pipeline = new EmptyPipelineDefinition <ChangeStreamDocument <WatchType> >().Match(x => x.OperationType == operationType); return(buildWatcher(pipeline, changeStreamDocumentOption, secondsToWait, watchFunction, collectionToMonitor)); }
public void Deserialize_should_return_expected_result(string json, ChangeStreamOperationType expectedResult) { var subject = CreateSubject(); ChangeStreamOperationType result; using (var reader = new JsonReader(json)) { var context = BsonDeserializationContext.CreateRoot(reader); result = subject.Deserialize(context); } result.Should().Be(expectedResult); }
// constructors /// <summary> /// Initializes a new instance of the <see cref="ChangeStreamDocument{TDocument}" /> class. /// </summary> /// <param name="resumeToken">The resume token.</param> /// <param name="operationType">Type of the operation.</param> /// <param name="collectionNamespace">Namespace of the collection.</param> /// <param name="documentKey">The document key.</param> /// <param name="updateDescription">The update description.</param> /// <param name="fullDocument">The full document.</param> public ChangeStreamDocument( BsonDocument resumeToken, ChangeStreamOperationType operationType, CollectionNamespace collectionNamespace, BsonDocument documentKey, ChangeStreamUpdateDescription updateDescription, TDocument fullDocument) { _resumeToken = Ensure.IsNotNull(resumeToken, nameof(resumeToken)); _operationType = operationType; _collectionNamespace = collectionNamespace; // can be null when operationType is Invalidate _documentKey = documentKey; // can be null _updateDescription = updateDescription; // can be null _fullDocument = fullDocument; // can be null }
protected void ChangeStreamsSync(ChangeStreamOperationType changeStreamOperationType, Action <TEntity> action) { var pipeline = new EmptyPipelineDefinition <ChangeStreamDocument <TEntity> >().Match(x => x.OperationType == changeStreamOperationType); using (var cursor = Collection <TEntity>().Watch(pipeline)) { cursor.ForEachAsync(change => { if (change.OperationType == changeStreamOperationType) { action(change.FullDocument); } }); } }
public void Serialize_should_have_expected_result(ChangeStreamOperationType value, string expectedResult) { var subject = CreateSubject(); string result; using (var textWriter = new StringWriter()) using (var writer = new JsonWriter(textWriter)) { var context = BsonSerializationContext.CreateRoot(writer); subject.Serialize(context, value); result = textWriter.ToString(); } result.Should().Be(expectedResult); }
public void OperationType_should_return_expected_result(string operationTypeName, ChangeStreamOperationType expectedResult) { var backingDocument = new BsonDocument { { "other", 1 }, { "operationType", operationTypeName } }; var subject = CreateSubject(backingDocument: backingDocument); var result = subject.OperationType; result.Should().Be(expectedResult); }
/// <summary> /// When we receive a event from DbMongoManager when the db is modified. /// </summary> /// <param name="operationType"></param> /// <param name="type"></param> /// <param name="obj"></param> public virtual void OnDbModified(ChangeStreamOperationType operationType, Type type, BaseType obj) { }
/// <summary> /// When we receive a event from DbMongoManager when the db is modified. /// </summary> /// <param name="operationType"></param> /// <param name="type"></param> /// <param name="obj"></param> public override void OnDbModified(ChangeStreamOperationType operationType, Type type, BaseType obj) { log.Debug($"UpdatesHubHandler.OnDbModified() called with operation {operationType}"); EventNotifierOperation?notifierOperationType = null; switch (operationType) { case ChangeStreamOperationType.Delete: notifierOperationType = EventNotifierOperation.Delete; break; case ChangeStreamOperationType.Insert: notifierOperationType = EventNotifierOperation.Create; break; case ChangeStreamOperationType.Update: case ChangeStreamOperationType.Replace: notifierOperationType = EventNotifierOperation.Update; break; } if (notifierOperationType == null) { return; } // Users connection updates. if (type == typeof(Users)) { UpdateUsers(obj as Users); } // Events based Tasks. else if (type == typeof(Ingredients)) { Ingredients ingredient = obj as Ingredients; if (notifierOperationType.Value == EventNotifierOperation.Delete) { HandleDeletedIngredient(ingredient); } else { ingredient.Price = IngredientPrices.Get(ingredient._id); } SendMessage(notifierOperationType.Value, ingredient); } else if (type == typeof(IngredientPrices)) { IngredientPrices price = obj as IngredientPrices; Ingredients ingredient = Ingredients.Get(price.IngredientId, price.UserId); SendMessage(notifierOperationType.Value, ingredient); } else if (type == typeof(Recipes)) { Recipes recipe = obj as Recipes; if (notifierOperationType.Value == EventNotifierOperation.Delete) { HandleDeletedRecipe(recipe); } else { recipe = Recipes.Get(obj._id); } SendMessage(notifierOperationType.Value, recipe); } else if (type == typeof(Weeks)) { Weeks week = obj as Weeks; week = Weeks.GetWeek(week.UserId); SendMessage(notifierOperationType.Value, week); } else if (type == typeof(WeekIngredients)) { WeekIngredients weekIngredients = obj as WeekIngredients; weekIngredients = WeekIngredients.Get(weekIngredients.UserId); SendMessage(notifierOperationType.Value, weekIngredients); } }
public Task RegisterChangesWatchAsync <T>(Action <ChangeStreamDocument <T> > action, ChangeStreamOperationType operationType) { return(DataContext.RegisterChangesWatchAsync(operationType, action)); }