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); } }
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"); } }
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"); }