Example #1
0
        private static int OnParse(GlobalOptions globals, object opts)
        {
            var parsedOptions = SmiCliInit.Verify <TriggerUpdatesCliOptions>(opts);

            ITriggerUpdatesSource source = parsedOptions switch
            {
                TriggerUpdatesFromMapperOptions o => new MapperSource(globals, o),
                TriggerUpdatesFromMongoOptions o => new MongoSource(globals, o),
                _ => throw new NotImplementedException($"No case for '{parsedOptions.GetType()}'")
            };

            var bootstrapper = new MicroserviceHostBootstrapper(() => new TriggerUpdatesHost(globals, source));
            int ret          = bootstrapper.Main();

            return(ret);
        }
    }
Example #2
0
        public MapperSource([NotNull] GlobalOptions globalOptions, TriggerUpdatesFromMapperOptions cliOptions)
        {
            _cliOptions    = cliOptions;
            _globalOptions = globalOptions;

            FansiImplementations.Load();

            try
            {
                var objectFactory = new MicroserviceObjectFactory();
                _swapper = objectFactory.CreateInstance <ISwapIdentifiers>(globalOptions.IdentifierMapperOptions.SwapperType, typeof(ISwapIdentifiers).Assembly);
            }
            catch (System.Exception ex)
            {
                throw new System.Exception($"Could not create IdentifierMapper Swapper with SwapperType:{globalOptions.IdentifierMapperOptions?.SwapperType ?? "Null"}", ex);
            }

            if (_swapper == null)
            {
                throw new ArgumentException("No SwapperType has been specified in GlobalOptions.IdentifierMapperOptions");
            }
        }
Example #3
0
        public void MapperSource_IntegrationTest(DatabaseType dbType)
        {
            var db = GetCleanedServer(dbType);

            DataTable dt = new DataTable();

            dt.Columns.Add("PatientID", typeof(string));
            dt.Columns.Add("StudyDescription", typeof(string));
            dt.SetDoNotReType(true);

            // We have a live table with anonymised data.  There is one person with a known ECHI 0101010101=0A0A0A0A0A
            dt.Rows.Add("0A0A0A0A0A", "CT Head");

            //There are 2 people for whome we have added temporary identifiers
            dt.Rows.Add("bbb-bbb-bbb", "CT Tail");
            dt.Rows.Add("ccc-ccc-ccc", "CT Wings");

            var liveTable = db.CreateTable("MyLiveTable", dt);

            DiscoveredTable map;

            using (var dtMap = new DataTable())
            {
                dtMap.Columns.Add("CHI");
                dtMap.Columns.Add("ECHI");

                dtMap.PrimaryKey = new [] { dtMap.Columns["CHI"] };

                dtMap.Rows.Add("0101010101", "0A0A0A0A0A");
                map = db.CreateTable("Map", dtMap);
            }

            // Import into RDMP the live table so we have a TableInfo pointer to it floating around
            Import(liveTable);

            var mapperOptions = new IdentifierMapperOptions()
            {
                MappingTableName        = map.GetFullyQualifiedName(),
                MappingConnectionString = db.Server.Builder.ConnectionString,
                SwapColumnName          = "CHI",
                ReplacementColumnName   = "ECHI",
                MappingDatabaseType     = db.Server.DatabaseType,
                SwapperType             = typeof(TableLookupWithGuidFallbackSwapper).FullName
            };

            var swapper = new TableLookupWithGuidFallbackSwapper();

            swapper.Setup(mapperOptions);

            var guidTable = swapper.GetGuidTableIfAny(mapperOptions);

            Assert.AreEqual(0, guidTable.GetRowCount(), "No temporary guids should exist yet");
            Assert.AreEqual(1, map.GetRowCount(), "We should have a mapping table with 1 entry");

            guidTable.Insert(new Dictionary <string, object>()
            {
                { "CHI", "0202020202" },
                { TableLookupWithGuidFallbackSwapper.GuidColumnName, "bbb-bbb-bbb" }
            });
            guidTable.Insert(new Dictionary <string, object>()
            {
                { "CHI", "0303030303" },
                { TableLookupWithGuidFallbackSwapper.GuidColumnName, "ccc-ccc-ccc" }
            });

            Assert.AreEqual(1, map.GetRowCount(), "We should have a mapping table with 1 entry");
            Assert.AreEqual(2, guidTable.GetRowCount(), "We should have a temporary guid for 0202020202");

            // make a fake data load into this table (create trigger and insert/update)
            var triggerImplementer = new TriggerImplementerFactory(dbType).Create(map);

            triggerImplementer.CreateTrigger(new ThrowImmediatelyCheckNotifier());

            //create a brand new mapping
            map.Insert(new Dictionary <string, object>()
            {
                { "CHI", "0303030303" },
                { "ECHI", "0C0C0C0C0C" },
                { SpecialFieldNames.ValidFrom, DateTime.Now },
                { SpecialFieldNames.DataLoadRunID, 55 },
            });

            var globals = new GlobalOptionsFactory().Load();

            var cliOptions = new TriggerUpdatesFromMapperOptions()
            {
                DateOfLastUpdate      = new DateTime(2020, 01, 01),
                LiveDatabaseFieldName = "PatientID",
                Qualifier             = '\'',
            };

            globals.UseTestValues(
                RequiresRabbit.GetConnectionFactory(),
                RequiresMongoDb.GetMongoClientSettings(),
                RequiresRelationalDb.GetRelationalDatabaseConnectionStrings(),
                ((TableRepository)RepositoryLocator.CatalogueRepository).ConnectionStringBuilder,
                ((TableRepository)RepositoryLocator.DataExportRepository).ConnectionStringBuilder);


            //make sure the identifier mapper goes to the right table
            globals.IdentifierMapperOptions.MappingConnectionString = db.Server.Builder.ConnectionString;
            globals.IdentifierMapperOptions.MappingDatabaseType     = dbType;
            globals.IdentifierMapperOptions.MappingTableName        = map.GetFullyQualifiedName();
            globals.IdentifierMapperOptions.SwapperType             = typeof(TableLookupWithGuidFallbackSwapper).FullName;

            using (var tester = new MicroserviceTester(globals.RabbitOptions, globals.CohortExtractorOptions))
            {
                tester.CreateExchange(globals.TriggerUpdatesOptions.ExchangeName, globals.UpdateValuesOptions.QueueName);

                var sourceHost = new TriggerUpdatesHost(globals, new MapperSource(globals, cliOptions));
                var destHost   = new UpdateValuesHost(globals);

                sourceHost.Start();
                tester.StopOnDispose.Add(sourceHost);

                destHost.Start();
                tester.StopOnDispose.Add(destHost);


                //wait till updater is done updating the live table
                new TestTimelineAwaiter().Await(() => destHost.Consumer.AckCount == 1);
            }

            var liveDtAfter = liveTable.GetDataTable();

            Assert.AreEqual(1, liveDtAfter.Rows.Cast <DataRow>().Count(r => (string)r["PatientID"] == "0A0A0A0A0A"), "Expected original data to still be intact");
            Assert.AreEqual(1, liveDtAfter.Rows.Cast <DataRow>().Count(r => (string)r["PatientID"] == "bbb-bbb-bbb"), "Expected unknown CHI with guid bbb to still be unknown");
            Assert.AreEqual(1, liveDtAfter.Rows.Cast <DataRow>().Count(r => (string)r["PatientID"] == "0C0C0C0C0C"), "Expected the unknown CHI ccc to be now known as 0C0C0C0C0C");
        }