Beispiel #1
0
        public void GivenPipelineThatChangesRequest_WhenHandlingRequest_ThenChangesRequestInPipeline()
        {
            var testHandlerA        = new TestHandler <TestRequestA>();
            var testHandlerB        = new TestHandler <TestRequestA>();
            var testMutationHandler = new TestMutationHandler();
            var testHandlerC        = new TestHandler <TestRequestB>();


            var pipeline = PipelineDefinitionBuilder <TestRequestA, TestResponse>
                           .StartWith(testHandlerA)
                           .ThenWith(testHandlerB)
                           .ThenWithMutation(testMutationHandler)
                           .ThenWith(testHandlerC)
                           .Build();

            var testRequest = new TestRequestA();

            pipeline.Handle(testRequest);

            Assert.Multiple(() =>
            {
                Assert.That(testHandlerA._request, Is.EqualTo(testRequest));
                Assert.That(testHandlerB._request, Is.EqualTo(testRequest));
                Assert.That(testMutationHandler._request, Is.EqualTo(testRequest));
                Assert.That(testHandlerC._request, Is.Not.EqualTo(testRequest));
                Assert.That(testHandlerC._request, Is.TypeOf <TestRequestB>());
            });
        }
Beispiel #2
0
        public void GivenPiplelineWithThreeStages_WhenHandlingRequest_ThenAllThreeHandlersAreCalledInOrder()
        {
            var testHandlerA = new TestHandler <TestRequestA>();
            var testHandlerB = new TestHandler <TestRequestA>();
            var testHandlerC = new TestHandler <TestRequestA>();

            var pipeline = PipelineDefinitionBuilder <TestRequestA, TestResponse>
                           .StartWith(testHandlerA)
                           .ThenWith(testHandlerB)
                           .ThenWith(testHandlerC)
                           .Build();

            var testRequest = new TestRequestA();

            pipeline.Handle(testRequest);

            var callOrder = new[]
            {
                testHandlerA,
                testHandlerB,
                testHandlerC
            }.OrderBy(x => x._timestamp)
            .ToArray();

            Assert.Multiple(() =>
            {
                Assert.That(callOrder[0], Is.EqualTo(testHandlerA));
                Assert.That(callOrder[1], Is.EqualTo(testHandlerB));
                Assert.That(callOrder[2], Is.EqualTo(testHandlerC));
            });
        }
        public async Task GivenPiplelineWithThreeStages_WhenHandlingRequest_ThenAllThreeHandlersHandleRequest()
        {
            var testHandlerA = new TestHandlerA <TestRequestA>();
            var testHandlerB = new TestHandlerB <TestRequestA>();
            var testHandlerC = new TestHandlerC <TestRequestA>();

            Dictionary <Type, Object> dictionary = new Dictionary <Type, object>
            {
                [typeof(TestHandlerA <TestRequestA>)] = testHandlerA,
                [typeof(TestHandlerB <TestRequestA>)] = testHandlerB,
                [typeof(TestHandlerC <TestRequestA>)] = testHandlerC,
            };

            PipelineDefinitionBuilder builder = new PipelineDefinitionBuilder(type => dictionary[type]);

            var pipeline = builder.StartWith <TestHandlerA <TestRequestA>, TestRequestA>()
                           .ThenWith <TestHandlerB <TestRequestA> >()
                           .ThenWith <TestHandlerC <TestRequestA> >()
                           .Build();

            var testRequest = new TestRequestA();
            await pipeline.HandleAsync(testRequest, new Context());

            Assert.Multiple(() =>
            {
                Assert.That(testHandlerA._request, Is.EqualTo(testRequest));
                Assert.That(testHandlerB._request, Is.EqualTo(testRequest));
                Assert.That(testHandlerC._request, Is.EqualTo(testRequest));
            });
        }
Beispiel #4
0
 public PackagePipelines(PipelineDefinitionBuilder <HttpRequest, Response <AuditResponse, Error> > builder)
 {
     AuditPackages = builder.StartWith <KeyAuthorizationPipe <AuditResponse> >()
                     .ThenWithMutation <AuditMutation, AuditRequest>()
                     .ThenWith <RecordResultPipe>()
                     .ThenWith <AuditRequestCachingPipe>()
                     .ThenWith <OSSIndexPipe>()
                     .Build();
 }
Beispiel #5
0
        public static IAggregateFluent <TAgg> UnionWith <TAgg, TOther>(this IAggregateFluent <TAgg> aggregation, IRepository <TOther> other, Expression <Func <TOther, TAgg> > projection)
        {
            var otherImpl          = other as MongoRepository <TOther>;
            var pipelineDefinition = PipelineDefinitionBuilder.For <TOther>().Project(projection);

            return(aggregation.UnionWith(
                       otherImpl.Collection,
                       pipelineDefinition
                       ));
        }
Beispiel #6
0
        public void GivenOrder_WithMissingAddress_WhenHandlingOrder_ThenReturnsOrderValidationError()
        {
            var pipeline = PipelineDefinitionBuilder <Order, Response <OrderDispatched, OrderError> >
                           .StartWith(new Validation())
                           .ThenWith(new OrderDispatchedHandler())
                           .Build();

            var response = pipeline.Handle(new Order());

            Assert.That(response.Error, Is.EqualTo(OrderError.Validation));
        }
Beispiel #7
0
        public async Task CreateViewAsync <TLocal, TForeign, TOutput>(string localCollection, string foreignCollection, string viewName, Expression <Func <TLocal, object> > field, Expression <Func <TForeign, object> > foreignField, Expression <Func <TOutput, object> > outputField)
        {
            var foreign  = db.GetCollection <TForeign>(foreignCollection);
            var pipeline = PipelineDefinitionBuilder.Lookup(new EmptyPipelineDefinition <TLocal>(), foreign, field, foreignField, outputField);

            try
            {
                await db.CreateViewAsync(sessionHandle, viewName, localCollection, pipeline);
            }
            catch
            {
            }
        }
Beispiel #8
0
        //-----------------------------------------------------//

        #region Create View

        public void CreateView <TLocal, TForeign, TOutput>(string localCollection, string foreignCollection, string viewName, Expression <Func <TLocal, object> > field, Expression <Func <TForeign, object> > foreignField, Expression <Func <TOutput, object> > outputField)
        {
            var foreign = db.GetCollection <TForeign>(foreignCollection);
            //var projection = new ProjectionDefinitionBuilder().M
            var pipeline = PipelineDefinitionBuilder.Lookup(new EmptyPipelineDefinition <TLocal>(), foreign, field, foreignField, outputField);

            try
            {
                db.CreateView(sessionHandle, viewName, localCollection, pipeline);
            }
            catch
            {
            }
        }
Beispiel #9
0
        protected override async Task ExecuteAsync(CancellationToken cancellationToken)
        {
            var pipelineDefinition = PipelineDefinitionBuilder.For <ChangeStreamDocument <RecordedEventDocument> >();

            var cursor = await _events.WatchAsync(pipelineDefinition, cancellationToken : cancellationToken);

            await cursor.ForEachAsync(async csd =>
            {
                var recordedEvent = csd.FullDocument;
                var operationType = csd.OperationType;
                await BroadcastOperationAsync(operationType, recordedEvent);
            },
                                      cancellationToken
                                      );
        }
Beispiel #10
0
        public async Task GivenOrder_WithMissingAddress_WhenHandlingOrder_ThenReturnsOrderValidationError()
        {
            var pipeline = PipelineDefinitionBuilder
                           .StartWith(new Validation())
                           .ThenWith(new OrderDispatchedHandler())
                           .Build();

            var context = new Context();

            await pipeline.HandleAsync(new Order(), context);

            var response = context.GetError <OrderError>();

            Assert.That(response, Is.EqualTo(OrderError.Validation));
        }
Beispiel #11
0
        public void GivenValidOrder_WhenHandlingOrder_ThenOrderDispatchedIsReturned()
        {
            var pipeline = PipelineDefinitionBuilder <Order, Response <OrderDispatched, OrderError> >
                           .StartWith(new Validation())
                           .ThenWith(new OrderDispatchedHandler())
                           .Build();

            var response = pipeline.Handle(new Order
            {
                Address    = "32 north bridge",
                Amount     = 20m,
                ItemNumber = "12234BDC",
                Name       = "jordan"
            });

            Assert.That(response.Success, Is.TypeOf <OrderDispatched>());
        }
Beispiel #12
0
        public async Task GivenValidOrder_WhenHandlingOrder_ThenOrderDispatchedIsReturned()
        {
            var pipeline = PipelineDefinitionBuilder
                           .StartWith(new Validation())
                           .ThenWith(new OrderDispatchedHandler())
                           .Build();

            var request = new Order
            {
                Address    = "32 north bridge",
                Amount     = 20m,
                ItemNumber = "12234BDC",
                Name       = "jordan"
            };

            var context = new Context();
            await pipeline.HandleAsync(request, context);

            Assert.That(context.GetResponse <OrderDispatched>(), Is.TypeOf <OrderDispatched>());
        }
        public async Task GivenPiplelineWithThreeStages_WhenHandlingRequest_ThenAllThreeHandlersAreCalledInOrder()
        {
            var testHandlerA = new TestHandlerA <TestRequestA>();
            var testHandlerB = new TestHandlerB <TestRequestA>();
            var testHandlerC = new TestHandlerC <TestRequestA>();

            Dictionary <Type, Object> dictionary = new Dictionary <Type, object>
            {
                [typeof(TestHandlerA <TestRequestA>)] = testHandlerA,
                [typeof(TestHandlerB <TestRequestA>)] = testHandlerB,
                [typeof(TestHandlerC <TestRequestA>)] = testHandlerC,
            };

            PipelineDefinitionBuilder builder = new
                                                PipelineDefinitionBuilder(type => dictionary[type]);

            var pipeline = builder.StartWith <TestHandlerA <TestRequestA>, TestRequestA>()
                           .ThenWith <TestHandlerB <TestRequestA> >()
                           .ThenWith <TestHandlerC <TestRequestA> >()
                           .Build();

            var testRequest = new TestRequestA();

            await pipeline.HandleAsync(testRequest, new Context());

            var callOrder = new TestHandler <TestRequestA>[]
            {
                testHandlerA,
                testHandlerB,
                testHandlerC
            }.OrderBy(x => x._timestamp)
            .ToArray();

            Assert.Multiple(() =>
            {
                Assert.That(callOrder[0], Is.EqualTo(testHandlerA));
                Assert.That(callOrder[1], Is.EqualTo(testHandlerB));
                Assert.That(callOrder[2], Is.EqualTo(testHandlerC));
            });
        }
Beispiel #14
0
        public void GivenPiplelineWithThreeStages_WhenHandlingRequest_ThenAllThreeHandlersHandleRequest()
        {
            var testHandlerA = new TestHandler <TestRequestA>();
            var testHandlerB = new TestHandler <TestRequestA>();
            var testHandlerC = new TestHandler <TestRequestA>();

            var pipeline = PipelineDefinitionBuilder <TestRequestA, TestResponse>
                           .StartWith(testHandlerA)
                           .ThenWith(testHandlerB)
                           .ThenWith(testHandlerC)
                           .Build();

            var testRequest = new TestRequestA();

            pipeline.Handle(testRequest);
            Assert.Multiple(() =>
            {
                Assert.That(testHandlerA._request, Is.EqualTo(testRequest));
                Assert.That(testHandlerB._request, Is.EqualTo(testRequest));
                Assert.That(testHandlerC._request, Is.EqualTo(testRequest));
            });
        }
        public async Task GivenPipelineThatChangesRequest_WhenHandlingRequest_ThenChangesRequestInPipeline()
        {
            var testHandlerA        = new TestHandlerA <TestRequestA>();
            var testHandlerB        = new TestHandlerB <TestRequestA>();
            var testMutationHandler = new TestMutationHandler();
            var testHandlerC        = new TestHandlerC <TestRequestB>();

            Dictionary <Type, Object> dictionary = new Dictionary <Type, object>
            {
                [typeof(TestHandlerA <TestRequestA>)] = testHandlerA,
                [typeof(TestHandlerB <TestRequestA>)] = testHandlerB,
                [typeof(TestHandlerC <TestRequestB>)] = testHandlerC,
                [typeof(TestMutationHandler)]         = testMutationHandler,
            };

            PipelineDefinitionBuilder builder = new
                                                PipelineDefinitionBuilder(type => dictionary[type]);


            var pipeline = builder.StartWith <TestHandlerA <TestRequestA>, TestRequestA> ()
                           .ThenWith <TestHandlerB <TestRequestA> >()
                           .ThenWithMutation <TestMutationHandler, TestRequestB>()
                           .ThenWith <TestHandlerC <TestRequestB> >()
                           .Build();

            var testRequest = new TestRequestA();

            await pipeline.HandleAsync(testRequest, new Context());

            Assert.Multiple(() =>
            {
                Assert.That(testHandlerA._request, Is.EqualTo(testRequest));
                Assert.That(testHandlerB._request, Is.EqualTo(testRequest));
                Assert.That(testMutationHandler._request, Is.EqualTo(testRequest));
                Assert.That(testHandlerC._request, Is.Not.EqualTo(testRequest));
                Assert.That(testHandlerC._request, Is.TypeOf <TestRequestB>());
            });
        }
Beispiel #16
0
 public TenantPipelines(PipelineDefinitionBuilder <HttpRequest, Response <TenantOverview, Error> > builder)
 {
     _builder = builder;
 }
 public KeyPiplines(PipelineDefinitionBuilder <HttpRequest, Response <Key, Error> > builder)
 {
     _builder = builder;
 }
Beispiel #18
0
        private static Task StartRadioFeeder(RadioCastServer radioCastServer, MongoWrapper mongoWrapper)
        {
            var userCollection = mongoWrapper.Database.GetCollection <Models.Musician>(nameof(Models.User));

            var songSortBuilder = new SortDefinitionBuilder <ProjectedMusicianSong>();
            var songSort        = songSortBuilder
                                  .Descending(nameof(ProjectedMusicianSong.Score));

            var userFilterBuilder = new FilterDefinitionBuilder <Models.Musician>();
            var userFilter        = userFilterBuilder.And
                                    (
                GeneralUtils.NotDeactivated(userFilterBuilder),
                userFilterBuilder.AnyEq("_t", nameof(Models.Musician))
                                    );

            var songFilterBuilder = new FilterDefinitionBuilder <ProjectedMusicianSong>();
            var songFilter        = songFilterBuilder.And
                                    (
                GeneralUtils.NotDeactivated(songFilterBuilder, s => s.Song),
                songFilterBuilder.Eq(s => s.Song.RadioAuthorized, true),
                songFilterBuilder.Eq(s => s.Song.Original, true)
                                    );

            var projectionBuilder = new ProjectionDefinitionBuilder <Models.Musician>();
            var projection        = projectionBuilder.Include(m => m.FullName).Include(m => m.Songs);

            var fsBucket = new GridFSBucket <ObjectId>(mongoWrapper.Database);

            var trackHistory = new List <(IAudioSource, ProjectedMusicianSong)>();

            var onTrackChangedTE = new ManualResetEvent(true);

            radioCastServer.OnTrackChanged += async(s, e) =>
            {
                List <(IAudioSource, ProjectedMusicianSong)> myTrackHistory;
                lock (trackHistory)
                {
                    myTrackHistory = trackHistory.ToList();
                }

                RadioInfoController.CurrentSong = myTrackHistory.Where(th => th.Item1.Equals(e.NewTrack)).Select(th => th.Item2).LastOrDefault();
                LOGGER.Info("Now playing: {}", JsonConvert.SerializeObject(RadioInfoController.CurrentSong));

                onTrackChangedTE.Set();

                if (e.OldTrack == null)
                {
                    return;
                }

                var oldTrack      = myTrackHistory.Where(th => th.Item1.Equals(e.OldTrack)).Select(th => th.Item2).LastOrDefault();
                var oldMusicianId = oldTrack._id;
                var oldTrackId    = oldTrack.Song._id;

                var musSongFilterBuilder = new FilterDefinitionBuilder <Models.Musician>();

                var musSongFilter = musSongFilterBuilder.And
                                    (
                    musSongFilterBuilder.Eq(m => m._id, oldMusicianId),
                    musSongFilterBuilder.ElemMatch(m => m.Songs, sg => sg._id == oldTrackId)
                                    );
                var musSongUpdate = new UpdateDefinitionBuilder <Models.Musician>()
                                    .Inc($"{nameof(Models.Musician.Songs)}.$.{nameof(Song.TimesPlayedRadio)}", 1);

                await userCollection.UpdateOneAsync(musSongFilter, musSongUpdate);

                // Remove oldest, only keep 5 in history
                if (myTrackHistory.Count > 5)
                {
                    lock (trackHistory)
                    {
                        trackHistory.RemoveAt(0);
                    }
                }
            };

            return(Task.Run(async() =>
            {
                while (true)
                {
                    List <(IAudioSource, ProjectedMusicianSong)> myTrackHistory;
                    lock (trackHistory)
                    {
                        myTrackHistory = trackHistory.ToList();
                    }

                    var lookupStageRandomArr = $@"
                    {{
                        $lookup:
                        {{
                            from: ""randomNumbers"",
                            pipeline:
                            [
                                {{ $sample: {{ size: 2 }} }}
                            ],
                            as: ""RandomArr""
                        }}
                    }}
                    ";

                    // OK Vezes totais que a música foi tocada * 0.5
                    // OK Vezes totais que a música foi tocada na rádio * -1
                    // OK Se música está presente na lista das últimas 5 tocadas, -100
                    // OK Se o autor da música está presente na lista das últimas 5 tocadas, -50
                    // OK Pontuação aleatória para cada música, entre - 10 e + 10
                    // OK Número de dias desde o cadastramento da música * -1
                    // OK   Há uma chance de 5% de multiplicar a pontuação resultante por -1 (efeito nostalgia)

                    var scoreStage = $@"
                    {{
                        $addFields:
                        {{
                            ""Score"":
                            {{
                                $add:
                                [
                                    {{
                                        $multiply: [ ""$Song.timesPlayed"", 0.5 ]
                                    }},
                                    {{
                                        $multiply: [ ""$Song.timesPlayedRadio"", -1 ]
                                    }},
                                    {{
                                        $cond:
                                        {{
                                            if:
                                            {{
                                                $in: [ ""$_id"", [ {myTrackHistory.Select(th => $"ObjectId(\"{th.Item2._id.ToString()}\")").DefaultIfEmpty("").Aggregate((s1, s2) => $"{s1.TrimEnd(',')},{s2.TrimEnd(',')},").TrimEnd(',')} ] ]
                                            }},
                                            then: -50,
                                            else: 0
                                        }}
                                    }},
                                    {{
                                        $cond:
                                        {{
                                            if:
                                            {{
                                                $in: [ ""$Song._id"", [ {myTrackHistory.Select(th => $"ObjectId(\"{th.Item2.Song._id.ToString()}\")").DefaultIfEmpty("").Aggregate((s1, s2) => $"{s1.TrimEnd(',')},{s2.TrimEnd(',')},").TrimEnd(',')} ] ]
                                            }},
                                            then: -100,
                                            else: 0
                                        }}
                                    }},
                                    {{
                                        $add:
                                        [ 
                                            {{
                                                $multiply:
                                                [
                                                    {{ $toDecimal: {{ $arrayElemAt: [""$RandomArr.decimal"", 0] }} }},
                                                    21
                                                ]
                                            }}, 
                                            -10
                                        ]
                                    }},
                                    {{
                                        $multiply:
                                        [
                                            {{
                                                $divide:
                                                [
                                                    {{
                                                        $subtract:
                                                        [
                                                            {{ $toDate: ""{DateTime.UtcNow.ToString("o")}"" }},
                                                            {{ $toDate: ""$Song._id"" }}
                                                        ]
                                                    }},
                                                    NumberLong(""86400000"")
                                                ]
                                            }},
                                            {{
                                                $cond:
                                                {{
                                                    if:
                                                    {{
                                                        $gt:
                                                        [
                                                            {{ $toDecimal: {{ $arrayElemAt: [""$RandomArr.decimal"", 1] }} }},
                                                            NumberDecimal(""0.1"")
                                                        ]
                                                    }},
                                                    then: -1,
                                                    else: 1
                                                }}
                                            }}
                                        ]
                                    }}
                                ]
                            }}
                        }}
                    }}";

                    LOGGER.Info("Score stage generated MongoDB query: {}", scoreStage);

                    var pipeline = PipelineDefinitionBuilder
                                   .For <Models.Musician>()
                                   .Match(userFilter)
                                   .Unwind(m => m.Songs, new AggregateUnwindOptions <Models.Musician>
                    {
                        PreserveNullAndEmptyArrays = false,
                        IncludeArrayIndex = null,
                    })
                                   .Project(m => new ProjectedMusicianSong
                    {
                        _id = m._id,
                        Song = (Song)m.Songs,
                        Score = 1,
                    })
                                   .Match(songFilter)
                                   .AppendStage <Musician, ProjectedMusicianSong, ProjectedMusicianSong>(lookupStageRandomArr)
                                   .AppendStage <Musician, ProjectedMusicianSong, ProjectedMusicianSong>(scoreStage)
                                   .Sort(songSort)
                                   .Limit(1);

                    if (LOGGER.IsDebugEnabled)
                    {
                        LOGGER.Debug("Pipeline generated MongoDB query for song: {}", pipeline.ToString());
                    }

                    var findTask = userCollection.AggregateAsync(pipeline, new AggregateOptions
                    {
                        AllowDiskUse = true,
                        BatchSize = 1,
                        UseCursor = true,
                        Comment = "Radio Aggregate Query",
                        TranslationOptions = new ExpressionTranslationOptions
                        {
                            StringTranslationMode = AggregateStringTranslationMode.CodePoints
                        }
                    });

                    var findResult = await findTask;
                    var firstSong = findResult.SingleOrDefault();
                    // If no songs, wait a minute before checking again
                    // Mostly not to strain the CPU on development environments
                    if (firstSong?.Song == null)
                    {
                        Thread.Sleep(TimeSpan.FromMinutes(1));
                        continue;
                    }
                    LOGGER.Info("Next selected song: {}", JsonConvert.SerializeObject(firstSong));
                    var audioRef = firstSong.Song.AudioReference;
                    var gridId = audioRef._id;
                    var fileStreamTask = fsBucket.OpenDownloadStreamAsync(gridId, new GridFSDownloadOptions
                    {
                        Seekable = true,
                        CheckMD5 = false,
                    });
                    var audioSource = new Mp3FileAudioSource(await fileStreamTask, firstSong.Song.Name);
                    // Wait for the radio to need more songs before we add the track we have on our hands
                    while (radioCastServer.TrackCount > 1)
                    {
                        onTrackChangedTE.WaitOne();
                        onTrackChangedTE.Reset();
                    }
                    lock (trackHistory)
                    {
                        trackHistory.Add((audioSource, firstSong));
                    }
                    radioCastServer.AddTrack(audioSource);
                }
            }));
        }
 public UserPipelines(PipelineDefinitionBuilder <HttpRequest, Response <User, Error> > builder)
 {
     _builder = builder;
 }