/// <summary> /// Starts up service and begins listening with the <see cref="Consumer"/> /// </summary> public override void Start() { FansiImplementations.Load(); IRDMPPlatformRepositoryServiceLocator repositoryLocator = Globals.RDMPOptions.GetRepositoryProvider(); var startup = new Startup(new EnvironmentInfo("netcoreapp2.2"), repositoryLocator); var toMemory = new ToMemoryCheckNotifier(); startup.DoStartup(toMemory); foreach (CheckEventArgs args in toMemory.Messages.Where(m => m.Result == CheckResult.Fail)) { Logger.Log(LogLevel.Warn, args.Ex, args.Message); } _fileMessageProducer = RabbitMqAdapter.SetupProducer(Globals.CohortExtractorOptions.ExtractFilesProducerOptions, isBatch: true); IProducerModel fileMessageInfoProducer = RabbitMqAdapter.SetupProducer(Globals.CohortExtractorOptions.ExtractFilesInfoProducerOptions, isBatch: false); InitializeExtractionSources(repositoryLocator); Consumer = new ExtractionRequestQueueConsumer(Globals.CohortExtractorOptions, _fulfiller, _auditor, _pathResolver, _fileMessageProducer, fileMessageInfoProducer); RabbitMqAdapter.StartConsumer(_consumerOptions, Consumer, isSolo: false); }
/// <summary> /// Checks that ExtractionRequestQueueConsumer publishes messages correctly according to the input message isIdentifiableExtraction value /// </summary> /// <param name="globals"></param> /// <param name="isIdentifiableExtraction"></param> /// <param name="expectedRoutingKey"></param> private static void AssertMessagePublishedWithSpecifiedKey(GlobalOptions globals, bool isIdentifiableExtraction, string expectedRoutingKey) { var fakeFulfiller = new FakeFulfiller(); var mockFileMessageProducerModel = new Mock <IProducerModel>(MockBehavior.Strict); string fileMessageRoutingKey = null; mockFileMessageProducerModel .Setup(x => x.SendMessage(It.IsAny <IMessage>(), It.IsAny <IMessageHeader>(), It.IsNotNull <string>())) .Callback((IMessage _, IMessageHeader __, string routingKey) => { fileMessageRoutingKey = routingKey; }) .Returns(new MessageHeader()); mockFileMessageProducerModel.Setup(x => x.WaitForConfirms()); var mockFileInfoMessageProducerModel = new Mock <IProducerModel>(MockBehavior.Strict); mockFileInfoMessageProducerModel .Setup(x => x.SendMessage(It.IsAny <IMessage>(), It.IsAny <IMessageHeader>(), It.IsNotNull <string>())) .Returns(new MessageHeader()); mockFileInfoMessageProducerModel.Setup(x => x.WaitForConfirms()); var msg = new ExtractionRequestMessage { JobSubmittedAt = DateTime.UtcNow, ExtractionJobIdentifier = Guid.NewGuid(), ProjectNumber = "1234", ExtractionDirectory = "1234/foo", IsIdentifiableExtraction = isIdentifiableExtraction, KeyTag = "foo", ExtractionIdentifiers = new List <string> { "foo" }, Modality = null, }; var mockDeliverArgs = Mock.Of <BasicDeliverEventArgs>(MockBehavior.Strict); mockDeliverArgs.DeliveryTag = 1; mockDeliverArgs.Body = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(msg)); mockDeliverArgs.BasicProperties = new BasicProperties { Headers = new Dictionary <string, object>() }; var header = new MessageHeader(); header.Populate(mockDeliverArgs.BasicProperties.Headers); // Have to convert these to bytes since RabbitMQ normally does that when sending mockDeliverArgs.BasicProperties.Headers["MessageGuid"] = Encoding.UTF8.GetBytes(header.MessageGuid.ToString()); mockDeliverArgs.BasicProperties.Headers["ProducerExecutableName"] = Encoding.UTF8.GetBytes(header.ProducerExecutableName); mockDeliverArgs.BasicProperties.Headers["Parents"] = Encoding.UTF8.GetBytes(string.Join("->", header.Parents)); var consumer = new ExtractionRequestQueueConsumer( globals.CohortExtractorOptions, fakeFulfiller, new NullAuditExtractions(), new DefaultProjectPathResolver(), mockFileMessageProducerModel.Object, mockFileInfoMessageProducerModel.Object); var fatalCalled = false; FatalErrorEventArgs fatalErrorEventArgs = null; consumer.OnFatal += (sender, args) => { fatalCalled = true; fatalErrorEventArgs = args; }; var mockModel = new Mock <IModel>(MockBehavior.Strict); mockModel.Setup(x => x.IsClosed).Returns(false); mockModel.Setup(x => x.BasicAck(It.IsAny <ulong>(), It.IsAny <bool>())).Verifiable(); consumer.SetModel(mockModel.Object); consumer.ProcessMessage(mockDeliverArgs); Thread.Sleep(500); // Fatal call is race-y Assert.False(fatalCalled, $"Fatal was called with {fatalErrorEventArgs}"); mockModel.Verify(x => x.BasicAck(It.IsAny <ulong>(), It.IsAny <bool>()), Times.Once); Assert.AreEqual(expectedRoutingKey, fileMessageRoutingKey); }