/// <summary> /// Start the service /// </summary> /// <returns></returns> public bool Start() { this.Starting?.Invoke(this, EventArgs.Empty); this.m_repositoryListeners = new List <IDisposable>(); ApplicationServiceContext.Current.Started += (o, e) => { using (AuthenticationContext.EnterSystemContext()) { try { // Hook up the listeners for existing foreach (var psd in this.m_pubSubManager.FindSubscription(x => x.IsActive == true)) { this.PubSubSubscribed(this, new Event.DataPersistedEventArgs <PubSubSubscriptionDefinition>(psd, TransactionMode.Commit, AuthenticationContext.SystemPrincipal)); } } catch (Exception ex) { this.m_tracer.TraceWarning("Cannot wire up subscription broker - {0}", ex); } } }; this.m_repositoryListeners.Add(this.m_serviceManager.CreateInjected <BundleRepositoryListener>()); this.Started?.Invoke(this, EventArgs.Empty); return(true); }
public void Setup() { // Force load of the DLL var p = FbCharset.Ascii; TestApplicationContext.TestAssembly = typeof(TestOrganizationResourceHandler).Assembly; TestApplicationContext.Initialize(TestContext.CurrentContext.TestDirectory); m_serviceManager = ApplicationServiceContext.Current.GetService <IServiceManager>(); var testConfiguration = new FhirServiceConfigurationSection { Resources = new List <string> { "Immunization", "Patient", "Encounter", "Practitioner" }, MessageHandlers = new List <TypeReferenceConfiguration> { new TypeReferenceConfiguration(typeof(ImmunizationResourceHandler)) } }; using (AuthenticationContext.EnterSystemContext()) { FhirResourceHandlerUtil.Initialize(testConfiguration, m_serviceManager); ExtensionUtil.Initialize(testConfiguration); } }
public void ClassSetup() { TestApplicationContext.TestAssembly = typeof(AdoIdentityProviderTest).Assembly; TestApplicationContext.Initialize(TestContext.CurrentContext.TestDirectory); AuthenticationContext.EnterSystemContext(); }
public void ClassSetup() { AuthenticationContext.EnterSystemContext(); IIdentityProviderService identityProvider = ApplicationServiceContext.Current.GetService <IIdentityProviderService>(); var identity = identityProvider.CreateIdentity(nameof(SecurityRolePersistenceServiceTest), "password", AuthenticationContext.Current.Principal); // Give this identity the administrative functions group IRoleProviderService roleProvider = ApplicationServiceContext.Current.GetService <IRoleProviderService>(); roleProvider.AddUsersToRoles(new string[] { identity.Name }, new string[] { "ADMINISTRATORS" }, AuthenticationContext.Current.Principal); // Authorize s_authorization = identityProvider.Authenticate(nameof(SecurityRolePersistenceServiceTest), "password"); IDataPersistenceService <SecurityPolicy> policyService = ApplicationServiceContext.Current.GetService <IDataPersistenceService <SecurityPolicy> >(); s_chickenCostumePolicy = new SecurityPolicy() { Name = "Allow wearing of chicken costume", Oid = "2.3.23.543.25.2" }; s_chickenCostumePolicy = policyService.Insert(s_chickenCostumePolicy, TransactionMode.Commit, s_authorization); }
public void Setup() { TestApplicationContext.TestAssembly = typeof(TestOrganizationResourceHandler).Assembly; TestApplicationContext.Initialize(TestContext.CurrentContext.TestDirectory); m_serviceManager = ApplicationServiceContext.Current.GetService <IServiceManager>(); TestApplicationContext.Current.AddBusinessRule <Core.Model.Roles.Patient>(typeof(SamplePatientBusinessRulesService)); var testConfiguration = new FhirServiceConfigurationSection { Resources = new List <string> { "Patient" }, MessageHandlers = new List <TypeReferenceConfiguration> { new TypeReferenceConfiguration(typeof(PatientResourceHandler)) } }; using (AuthenticationContext.EnterSystemContext()) { FhirResourceHandlerUtil.Initialize(testConfiguration, m_serviceManager); ExtensionUtil.Initialize(testConfiguration); } }
/// <summary> /// Map the object to model /// </summary> public IdentifiedData MapToModel(Resource resourceInstance) { using (AuthenticationContext.EnterSystemContext()) // All queries under the mapping process are performed by the SYSTEM { var retVal = this.MapToModel((TFhirResource)resourceInstance); // Append the notice that this is a source model switch (retVal) { case IResourceCollection irc: irc.AddAnnotationToAll(SanteDBConstants.NoDynamicLoadAnnotation); break; case ITargetedAssociation tra: (tra.TargetEntity as IdentifiedData)?.AddAnnotation(SanteDBConstants.NoDynamicLoadAnnotation); (tra.SourceEntity as IdentifiedData)?.AddAnnotation(SanteDBConstants.NoDynamicLoadAnnotation); break; default: retVal.AddAnnotation(SanteDBConstants.NoDynamicLoadAnnotation); break; } return(retVal); } }
public void TestParseAndQBPMessage() { using (AuthenticationContext.EnterSystemContext()) { var msg = TestUtil.GetMessage("QBP_COMPLEX_PRE"); var response = this.m_serviceManager.CreateInjected <AdtMessageHandler>().HandleMessage(new Hl7MessageReceivedEventArgs(msg, new Uri("test://"), new Uri("test://"), DateTime.Now)); var patient = ApplicationServiceContext.Current.GetService <IDataPersistenceService <Patient> >().Query(o => o.Identifiers.Any(i => i.Value == "HL7-9"), AuthenticationContext.Current.Principal).SingleOrDefault(); Assert.IsNotNull(patient); msg = TestUtil.GetMessage("QBP_AND_PRE"); this.m_serviceManager.CreateInjected <AdtMessageHandler>().HandleMessage(new Hl7MessageReceivedEventArgs(msg, new Uri("test://"), new Uri("test://"), DateTime.Now)); patient = ApplicationServiceContext.Current.GetService <IDataPersistenceService <Patient> >().Query(o => o.Identifiers.Any(i => i.Value == "HL7-10"), AuthenticationContext.Current.Principal).SingleOrDefault(); Assert.IsNotNull(patient); msg = TestUtil.GetMessage("QBP_COMPLEX"); var message = this.m_serviceManager.CreateInjected <QbpMessageHandler>().HandleMessage(new Hl7MessageReceivedEventArgs(msg, new Uri("test://"), new Uri("test://"), DateTime.Now)); var messageStr = TestUtil.ToString(message); Assert.AreEqual("1", (message.GetStructure("QAK") as QAK).HitCount.Value); Assert.AreEqual("SMITH", ((message.GetStructure("QUERY_RESPONSE") as AbstractGroup).GetStructure("PID") as PID).GetMotherSMaidenName(0).FamilyName.Surname.Value); Assert.AreNotEqual("JENNY", ((message.GetStructure("QUERY_RESPONSE") as AbstractGroup).GetStructure("PID") as PID).GetPatientName(0).GivenName.Value); Assert.AreEqual("AA", (message.GetStructure("MSA") as MSA).AcknowledgmentCode.Value); Assert.AreEqual("OK", (message.GetStructure("QAK") as QAK).QueryResponseStatus.Value); Assert.AreEqual("K22", (message.GetStructure("MSH") as MSH).MessageType.TriggerEvent.Value); // OR MESSAGE SHOULD CATCH TWO PATIENTS msg = TestUtil.GetMessage("QBP_OR"); message = this.m_serviceManager.CreateInjected <QbpMessageHandler>().HandleMessage(new Hl7MessageReceivedEventArgs(msg, new Uri("test://"), new Uri("test://"), DateTime.Now)); messageStr = TestUtil.ToString(message); Assert.AreEqual("2", (message.GetStructure("QAK") as QAK).HitCount.Value); Assert.AreEqual("AA", (message.GetStructure("MSA") as MSA).AcknowledgmentCode.Value); Assert.AreEqual("OK", (message.GetStructure("QAK") as QAK).QueryResponseStatus.Value); Assert.AreEqual("K22", (message.GetStructure("MSH") as MSH).MessageType.TriggerEvent.Value); } }
/// <summary> /// Loads all definitions from the applet manager service /// </summary> private void LoadAllDefinitions() { using (AuthenticationContext.EnterSystemContext()) { this.m_tracer.TraceInfo("(Re)Loading all BIS Definitions from Applets"); // We only want to clear those assets which can be defined in applets this.m_definitionCache.Remove(typeof(BiReportDefinition)); this.m_definitionCache.Remove(typeof(BiQueryDefinition)); this.m_definitionCache.Remove(typeof(BiParameterDefinition)); var solutions = this.m_solutionManagerService?.Solutions.ToList(); // Doesn't have a solution manager if (solutions == null) { this.ProcessApplet(this.m_appletManager.Applets); } else { solutions.Add(new Core.Applets.Model.AppletSolution() { Meta = new Core.Applets.Model.AppletInfo() { Id = String.Empty } }); foreach (var s in solutions) { var appletCollection = this.m_solutionManagerService.GetApplets(s.Meta.Id); this.ProcessApplet(appletCollection); } } } }
public void TestUpdateAdt() { using (AuthenticationContext.EnterSystemContext()) { var msg = TestUtil.GetMessage("ADT_SIMPLE"); var message = this.m_serviceManager.CreateInjected <AdtMessageHandler>().HandleMessage(new Hl7MessageReceivedEventArgs(msg, new Uri("test://"), new Uri("test://"), DateTime.Now)); var messageStr = TestUtil.ToString(message); Assert.AreEqual("CA", (message.GetStructure("MSA") as MSA).AcknowledgmentCode.Value); var patientOriginal = ApplicationServiceContext.Current.GetService <IDataPersistenceService <Patient> >().Query(o => o.Identifiers.Any(i => i.Value == "HL7-1"), AuthenticationContext.Current.Principal).SingleOrDefault(); Assert.NotNull(patientOriginal); msg = TestUtil.GetMessage("ADT_UPDATE"); message = this.m_serviceManager.CreateInjected <AdtMessageHandler>().HandleMessage(new Hl7MessageReceivedEventArgs(msg, new Uri("test://"), new Uri("test://"), DateTime.Now)); messageStr = TestUtil.ToString(message); Assert.AreEqual("CA", (message.GetStructure("MSA") as MSA).AcknowledgmentCode.Value); // Ensure that the patient actually was persisted var patientNew = ApplicationServiceContext.Current.GetService <IDataPersistenceService <Patient> >().Query(o => o.Identifiers.Any(i => i.Value == "HL7-1"), AuthenticationContext.Current.Principal).SingleOrDefault(); Assert.IsNotNull(patientNew); Assert.AreEqual(1, patientNew.Names.Count); Assert.AreEqual("JOHNSTON", patientNew.Names.First().Component.First(o => o.ComponentTypeKey == NameComponentKeys.Family).Value); Assert.AreEqual("ROBERTA", patientNew.Names.First().Component.First(o => o.ComponentTypeKey == NameComponentKeys.Given).Value); } }
/// <summary> /// Run the backup /// </summary> public void Run(object sender, EventArgs e, object[] parameters) { using (AuthenticationContext.EnterSystemContext()) { try { ApplicationServiceContext.Current.GetService <ITickleService>().SendTickle(new Tickler.Tickle(Guid.Empty, Tickler.TickleType.Toast | Tickler.TickleType.Task, Strings.locale_backupStarted)); this.m_jobStateManager.SetState(this, JobStateType.Running); var backupService = ApplicationServiceContext.Current.GetService <IBackupService>(); var maxBackups = Int32.Parse(ApplicationServiceContext.Current.GetService <IConfigurationManager>().GetAppSetting("autoBackup.max") ?? "5"); // First attempt to backup backupService.Backup(BackupMedia.Private, ApplicationContext.Current.Configuration.GetSection <SecurityConfigurationSection>().DeviceName); // Now are there more backups than we like to retain? foreach (var descriptor in backupService.GetBackups(BackupMedia.Private).Skip(maxBackups)) { this.m_tracer.TraceInfo("Retention of backups from backup job will remove {0}", descriptor); backupService.RemoveBackup(BackupMedia.Private, descriptor); } this.m_jobStateManager.SetState(this, JobStateType.Completed); ApplicationServiceContext.Current.GetService <ITickleService>().SendTickle(new Tickler.Tickle(Guid.Empty, Tickler.TickleType.Toast | Tickler.TickleType.Task, Strings.locale_backupCompleted)); } catch (Exception ex) { this.m_tracer.TraceError("Error running backup job: {0}", ex); this.m_jobStateManager.SetState(this, JobStateType.Aborted); this.m_jobStateManager.SetProgress(this, ex.Message, 0.0f); } } }
public void Setup() { // Force load of the DLL var p = FbCharset.Ascii; TestApplicationContext.TestAssembly = typeof(TestRelatedPersonResourceHandler).Assembly; TestApplicationContext.Initialize(TestContext.CurrentContext.TestDirectory); this.m_serviceManager = ApplicationServiceContext.Current.GetService <IServiceManager>(); var testConfiguration = new FhirServiceConfigurationSection { Resources = new List <string> { "Encounter", "Bundle", "Patient", "Organization" }, OperationHandlers = new List <TypeReferenceConfiguration>(), ExtensionHandlers = new List <TypeReferenceConfiguration>(), ProfileHandlers = new List <TypeReferenceConfiguration>(), MessageHandlers = new List <TypeReferenceConfiguration> { new TypeReferenceConfiguration(typeof(EncounterResourceHandler)), new TypeReferenceConfiguration(typeof(BundleResourceHandler)), new TypeReferenceConfiguration(typeof(PatientResourceHandler)) } }; using (AuthenticationContext.EnterSystemContext()) { FhirResourceHandlerUtil.Initialize(testConfiguration, this.m_serviceManager); ExtensionUtil.Initialize(testConfiguration); } }
/// <summary> /// Run the specified job /// </summary> public void Run(object sender, EventArgs e, object[] parameters) { try { using (AuthenticationContext.EnterSystemContext()) { this.m_stateManager.SetState(this, JobStateType.Running); var clear = parameters.Length > 0 ? (bool?)parameters[0] : false; this.m_tracer.TraceInfo("Starting batch run of MDM Matching "); if (clear.GetValueOrDefault()) { this.m_tracer.TraceVerbose("Batch instruction indicates clear of all links"); this.m_mergeService.ClearGlobalIgnoreFlags(); this.m_mergeService.ClearGlobalMergeCanadidates(); } else { this.m_mergeService.ClearGlobalMergeCanadidates(); } this.m_mergeService.DetectGlobalMergeCandidates(); this.m_stateManager.SetState(this, JobStateType.Completed); } } catch (Exception ex) { this.m_stateManager.SetState(this, JobStateType.Aborted); this.m_stateManager.SetProgress(this, ex.Message, 0.0f); this.m_tracer.TraceError("Could not run MDM Matching Job: {0}", ex); } }
public void Setup() { TestApplicationContext.TestAssembly = typeof(TestRelatedPersonResourceHandler).Assembly; TestApplicationContext.Initialize(TestContext.CurrentContext.TestDirectory); this.m_serviceManager = ApplicationServiceContext.Current.GetService <IServiceManager>(); var testConfiguration = new FhirServiceConfigurationSection { Resources = new List <string> { "Patient" }, OperationHandlers = new List <TypeReferenceConfiguration>(), ExtensionHandlers = new List <TypeReferenceConfiguration>(), ProfileHandlers = new List <TypeReferenceConfiguration>(), MessageHandlers = new List <TypeReferenceConfiguration> { new TypeReferenceConfiguration(typeof(BirthPlaceExtension)) } }; using (AuthenticationContext.EnterSystemContext()) { FhirResourceHandlerUtil.Initialize(testConfiguration, this.m_serviceManager); ExtensionUtil.Initialize(testConfiguration); } }
/// <summary> /// Run the specified job /// </summary> public void Run(object sender, EventArgs e, object[] parameters) { var biProvider = ApplicationServiceContext.Current.GetService <IBiDataSource>(); // Global default var biRepository = ApplicationServiceContext.Current.GetService <IBiMetadataRepository>(); // Global default var serviceManager = ApplicationServiceContext.Current.GetService <IServiceManager>(); // try { this.m_tracer.TraceInfo("Starting refresh of defined BI materialized views"); this.m_cancel = false; this.m_stateManager.SetState(this, JobStateType.Running); // TODO: Refactor on new enhanced persistence layer definition using (AuthenticationContext.EnterSystemContext()) { var definitions = biRepository.Query <BiQueryDefinition>(o => o.MetaData.Status != BiDefinitionStatus.Deprecated && o.MetaData.Status != BiDefinitionStatus.Obsolete, 0, 100).ToArray(); int i = 0; foreach (var itm in definitions) { if (parameters.Length > 0 && !String.IsNullOrEmpty(parameters[0]?.ToString()) && parameters[0]?.Equals(itm.Id) != true) { continue; } this.m_stateManager.SetProgress(this, $"Refreshing {itm.Name ?? itm.Id}", ((float)i++ / (float)definitions.Length)); var dataSource = biProvider; var queryDefinition = BiUtils.ResolveRefs(itm) as BiQueryDefinition; var providerType = queryDefinition.DataSources.FirstOrDefault()?.ProviderType; if (providerType != null) { dataSource = serviceManager.CreateInjected(providerType) as IBiDataSource; } dataSource.RefreshMaterializedView(itm); if (this.m_cancel) { this.m_stateManager.SetState(this, JobStateType.Cancelled); return; } } } this.m_stateManager.SetState(this, JobStateType.Completed); } catch (Exception ex) { this.m_stateManager.SetState(this, JobStateType.Aborted); this.m_stateManager.SetProgress(this, ex.Message, 0.0f); this.m_cancel = false; this.m_tracer.TraceError("Error processing BI materialized views: {0}", ex.Message); throw new Exception("Error running BI refresh job", ex); } finally { this.m_cancel = false; } }
/// <summary> /// Gets the specified sub object /// </summary> public object Get(Type scopingType, object scopingKey, object key) { var matcher = ApplicationServiceContext.Current.GetService <IRecordMatchingService>(); if (matcher == null) { throw new InvalidOperationException("No matching service configuration"); } // Match report factory var matchReportFactory = ApplicationServiceContext.Current.GetService <IMatchReportFactory>(); if (matchReportFactory == null) { throw new InvalidOperationException("No match report factory"); } // Configuration provider var matchConfiguration = ApplicationServiceContext.Current.GetService <IRecordMatchingConfigurationService>(); if (matchConfiguration == null) { throw new InvalidOperationException("No match configuration factory"); } // Validate parameters if (scopingKey is Guid objectAKey && key is Guid objectBKey) { var repository = ApplicationServiceContext.Current.GetService(typeof(IRepositoryService <>).MakeGenericType(scopingType)) as IRepositoryService; // Produce a match report using (AuthenticationContext.EnterSystemContext()) { IdentifiedData recordA = repository.Get(objectAKey), recordB = repository.Get(objectBKey); if (recordA == null || recordB == null) { throw new KeyNotFoundException($"Source or target not found"); } var configId = RestOperationContext.Current.IncomingRequest.QueryString["_configuration"]; IEnumerable <IRecordMatchingConfiguration> matchConfigurations = matchConfiguration.Configurations.Where(o => o.AppliesTo.Contains(scopingType) && o.Metadata.State == MatchConfigurationStatus.Active); if (!String.IsNullOrEmpty(configId)) { matchConfigurations = matchConfiguration.Configurations.Where(o => o.AppliesTo.Contains(scopingType) && o.Id == configId).Union(matchConfigurations); } if (matchConfiguration == null) { throw new InvalidOperationException("No configuration for type exists"); } // Match result var matchResult = matchConfigurations.SelectMany(c => matcher.Classify(recordA, new IdentifiedData[] { recordB }, c.Id)); return(matchReportFactory.CreateMatchReport(scopingType, recordA, matchResult)); } }
/// <summary> /// Notification has been queued /// </summary> private void NotificationQueued(DispatcherMessageEnqueuedInfo e) { if (e.QueueName == QueueName) { using (AuthenticationContext.EnterSystemContext()) { Object queueObject = null; while ((queueObject = this.m_queue.Dequeue(QueueName)) is DispatcherQueueEntry dq && dq.Body is PubSubNotifyQueueEntry evtData) { try { foreach (var dsptchr in this.GetDispatchers(evtData.EventType, evtData.Data)) { switch (evtData.EventType) { case PubSubEventType.Create: dsptchr.NotifyCreated(evtData.Data as IdentifiedData); break; case PubSubEventType.Delete: dsptchr.NotifyObsoleted(evtData.Data as IdentifiedData); break; case PubSubEventType.Update: dsptchr.NotifyUpdated(evtData.Data as IdentifiedData); break; case PubSubEventType.Merge: { if (evtData.Data is ParameterCollection pc && pc.TryGet("survivor", out IdentifiedData survivor) && pc.TryGet("linkedDuplicates", out Bundle duplicates)) { dsptchr.NotifyMerged(survivor, duplicates.Item); } break; } case PubSubEventType.UnMerge: { if (evtData.Data is ParameterCollection pc && pc.TryGet("survivor", out IdentifiedData survivor) && pc.TryGet("linkedDuplicates", out Bundle duplicates)) { dsptchr.NotifyUnMerged(survivor, duplicates.Item); } break; } } } } catch (Exception ex) { this.m_tracer.TraceError("Error dispatching notification from PubSub broker: {0}", ex); this.m_queue.Enqueue($"{QueueName}.dead", evtData); } } } } }
/// <summary> /// This test registers a new patient and ensures that parent repository calls are intercepted /// </summary> // TODO: This test should only be enabled if we decide to call upstream repositories to have masters // [Test(Description = "Case 0: Chained / Upstream Calls")] public void TestMdmInterceptsParentTypes() { using (AuthenticationContext.EnterSystemContext()) { var patientUnderTest = new Patient() { DateOfBirth = DateTime.Parse("1983-01-10"), Names = new List <EntityName>() { new EntityName(NameUseKeys.Legal, "MDM", "Test Subject 0") }, Identifiers = new List <EntityIdentifier>() { new EntityIdentifier(this.m_testAuthority, "MDM-00") }, GenderConceptKey = Guid.Parse("F4E3A6BB-612E-46B2-9F77-FF844D971198") }; var savedLocal = this.m_patientRepository.Insert(patientUnderTest); // Assert -> A local is returned from the patient repository with a key and version id Assert.IsNotNull(savedLocal.Key); Assert.IsNotNull(savedLocal.VersionKey); // Assert -> A query by identifier should result in a master being returned var queriedMaster = this.m_patientRepository.Find(o => o.Identifiers.Any(i => i.Value == "MDM-00")).FirstOrDefault(); Assert.AreEqual("M", queriedMaster.GetTag("$mdm.type")); Assert.AreEqual("true", queriedMaster.GetTag("$generated")); Assert.AreEqual(1, queriedMaster.Names.Count); Assert.AreEqual(2, queriedMaster.Identifiers.Count); // Assert -> A fetch by ID from master should return master var fetchMaster = this.m_patientRepository.Get(queriedMaster.Key.Value); Assert.AreEqual(queriedMaster.Key, fetchMaster.Key); // Assert -> A fetch by ID for local should return local var fetchLocal = this.m_patientRepository.Get(savedLocal.Key.Value); Assert.AreEqual(1, fetchLocal.Names.Count); Assert.AreEqual(1, fetchLocal.Identifiers.Count); Assert.IsNull(fetchLocal.GetTag("$mdm.type")); // Assert -> Call to IRepositoryService<Person> behaves the same way var queriedPersonMaster = this.m_personRepository.Find(o => o.Identifiers.Any(i => i.Value == "MDM-00")).FirstOrDefault(); Assert.AreEqual("M", queriedMaster.GetTag("$mdm.type")); Assert.AreEqual("true", queriedMaster.GetTag("$generated")); Assert.AreEqual(1, queriedMaster.Names.Count); Assert.AreEqual(2, queriedMaster.Identifiers.Count); // Assert -> Call to IRepositoryService<Entity> behaves the same way var queryEntityMaster = this.m_entityRepository.Find(o => o.Identifiers.Any(i => i.Value == "MDM-00")).FirstOrDefault(); Assert.AreEqual("M", queriedMaster.GetTag("$mdm.type")); Assert.AreEqual("true", queriedMaster.GetTag("$generated")); Assert.AreEqual(1, queriedMaster.Names.Count); Assert.AreEqual(2, queriedMaster.Identifiers.Count); } }
public void TestMerge() { var entityRepository = ApplicationServiceContext.Current.GetService <IRepositoryService <Entity> >(); var patientRepository = ApplicationServiceContext.Current.GetService <IRepositoryService <Patient> >(); // Register first patient using (AuthenticationContext.EnterSystemContext()) { var msg = TestUtil.GetMessage("ADT_MRG_PRE1"); var result = this.m_serviceManager.CreateInjected <AdtMessageHandler>().HandleMessage(new Hl7MessageReceivedEventArgs(msg, new Uri("test://"), new Uri("test://"), DateTime.Now)); var resultStr = TestUtil.ToString(result); Assert.IsTrue(resultStr.Contains("|CA")); Assert.AreEqual(1, patientRepository.Find(o => o.Identifiers.Any(id => id.Value == "RJ-439")).Count()); var patientA = patientRepository.Find(o => o.Identifiers.Any(id => id.Value == "RJ-439")).SingleOrDefault(); // Register second patient msg = TestUtil.GetMessage("ADT_MRG_PRE2"); result = this.m_serviceManager.CreateInjected <AdtMessageHandler>().HandleMessage(new Hl7MessageReceivedEventArgs(msg, new Uri("test://"), new Uri("test://"), DateTime.Now)); resultStr = TestUtil.ToString(result); Assert.IsTrue(resultStr.Contains("|CA")); Assert.AreEqual(1, patientRepository.Find(o => o.Identifiers.Any(id => id.Value == "RJ-999")).Count()); var patientB = patientRepository.Find(o => o.Identifiers.Any(id => id.Value == "RJ-999")).SingleOrDefault(); // There are 2 patients var patients = ApplicationServiceContext.Current.GetService <IDataPersistenceService <Patient> >().Query(o => o.Identifiers.Any(i => i.Value == "RJ-439" || i.Value == "RJ-999"), AuthenticationContext.Current.Principal); Assert.AreEqual(2, patients.Count()); msg = TestUtil.GetMessage("ADT_MRG"); result = this.m_serviceManager.CreateInjected <AdtMessageHandler>().HandleMessage(new Hl7MessageReceivedEventArgs(msg, new Uri("test://"), new Uri("test://"), DateTime.Now)); resultStr = TestUtil.ToString(result); Assert.IsTrue(resultStr.Contains("|CA")); // Validate QBP appropriately redirects as described in 3.6.2.1.2 msg = TestUtil.GetMessage("ADT_MRG_POST"); result = this.m_serviceManager.CreateInjected <QbpMessageHandler>().HandleMessage(new Hl7MessageReceivedEventArgs(msg, new Uri("test://"), new Uri("test://"), DateTime.Now)); resultStr = TestUtil.ToString(result); Assert.IsTrue(resultStr.Contains("|AA")); Assert.IsTrue(resultStr.Contains("RJ-439"), "Missing Patient A identifier"); Assert.IsTrue(resultStr.Contains("RJ-999"), "Missing Patient B identifier"); Assert.IsTrue(resultStr.Contains(patientA.Key.ToString()), "Missing Master Key for Patient A"); Assert.IsFalse(resultStr.Contains(patientB.Key.ToString()), "Should not have Master Key for Patient B"); // Validate -> Query for RJ-439 resolves to patient var afterMergeA = patientRepository.Find(o => o.Identifiers.Any(id => id.Value == "RJ-439")).SingleOrDefault(); Assert.AreEqual(patientA.Key, afterMergeA.Key); // Remains unchanged (Patient A => After Merge A) // Validate -> Query for RJ-999 resolves to same patient var afterMergeB = patientRepository.Find(o => o.Identifiers.Any(id => id.Value == "RJ-999")).SingleOrDefault(); Assert.AreNotEqual(patientB.Key, afterMergeB.Key); // (Patient B no longer equals Merge B since it was merged into A) Assert.AreEqual(patientA.Key, afterMergeB.Key); // Patient B => Patient A var oldMaster = entityRepository.Get(patientB.Key.Value); oldMaster.LoadProperty(o => o.StatusConcept); Assert.AreEqual(StatusKeys.Inactive, oldMaster.StatusConceptKey); // Old Master is obsolete } }
/// <summary> /// Perform actual invokation on all objects /// </summary> public TBinding Invoke <TBinding>(string triggerName, TBinding data) where TBinding : IdentifiedData { lock (this.m_lock) { using (AuthenticationContext.EnterSystemContext()) { if (data == default(TBinding)) { return(data); } var callList = this.GetCallList(data.GetType(), triggerName); callList = callList.Union(this.GetCallList <TBinding>(triggerName), this.m_javascriptComparer).ToList(); var retVal = data; if (callList.Count() > 0) { dynamic viewModel = JavascriptUtils.ToViewModel(retVal); foreach (var c in callList) { try { // There is a guard so let's execute it if (c.Guard == null || QueryExpressionParser.BuildLinqExpression <TBinding>(c.Guard).Compile()(data)) { viewModel = c.Callback.DynamicInvoke(viewModel); } } catch (JavaScriptException e) { this.m_tracer.TraceError("JS ERROR: Error running {0} for {1} @ {2}:{3} \r\n Javascript Stack: {4} \r\n C# Stack: {5}", triggerName, data, e.Location.Source, e.LineNumber, e.CallStack, e); throw new JsBusinessRuleException($"Error running business rule {c.Id} - {triggerName} for {data}", e); } catch (TargetInvocationException e) when(e.InnerException is JavaScriptException je) { this.m_tracer.TraceError("JS ERROR: Error running {0} for {1} @ {2}:{3} \r\n Javascript Stack: {4} \r\n C# Stack: {5}", triggerName, data, je.Location.Source, je.LineNumber, je.CallStack, e); throw new JsBusinessRuleException($"Error running business rule {c.Id} - {triggerName} for {data}", je); } catch (Exception e) { this.m_tracer.TraceError("Error running {0} for {1} : {2}", triggerName, data, e); throw new JsBusinessRuleException($"Error running business rule {c.Id} - {triggerName} for {data}", e); } } retVal = (TBinding)JavascriptUtils.ToModel(viewModel).CopyAnnotations(retVal); } return(retVal); } } }
#pragma warning restore CS0067 /// <summary> /// Create new audit repository service /// </summary> public AdoAuditRepositoryService(IConfigurationManager configurationManager, IDataCachingService dataCachingService, IBiMetadataRepository biMetadataRepository, IConceptRepositoryService conceptRepository, IAdhocCacheService adhocCacheService = null) { this.m_configuration = configurationManager.GetSection <AdoAuditConfigurationSection>(); this.m_adhocCache = adhocCacheService; this.m_dataCachingService = dataCachingService; this.m_conceptRepository = conceptRepository; try { this.m_configuration.Provider.UpgradeSchema("SanteDB.Persistence.Audit.ADO"); ApplicationServiceContext.Current.Started += (o, e) => { using (AuthenticationContext.EnterSystemContext()) { // Add audits as a BI data source biMetadataRepository .Insert(new BiDataSourceDefinition() { IsSystemObject = true, ConnectionString = this.m_configuration.ReadonlyConnectionString, MetaData = new BiMetadata() { Version = typeof(AdoAuditRepositoryService).Assembly.GetName().Version.ToString(), Status = BiDefinitionStatus.Active, Demands = new List <string>() { PermissionPolicyIdentifiers.AccessAuditLog } }, Id = "org.santedb.bi.dataSource.audit", Name = "audit", ProviderType = typeof(OrmBiDataProvider) }); } }; this.m_mapper = new ModelMapper(typeof(AdoAuditRepositoryService).Assembly.GetManifestResourceStream("SanteDB.Persistence.Auditing.ADO.Data.Map.ModelMap.xml")); this.m_builder = new QueryBuilder(this.m_mapper, this.m_configuration.Provider); } catch (ModelMapValidationException e) { this.m_traceSource.TraceError("Error validing map: {0}", e.Message); foreach (var i in e.ValidationDetails) { this.m_traceSource.TraceError("{0}:{1} @ {2}", i.Level, i.Message, i.Location); } throw; } }
/// <summary> /// Get all dispatchers and subscriptions /// </summary> protected IEnumerable <IPubSubDispatcher> GetDispatchers(PubSubEventType eventType, Object data) { using (AuthenticationContext.EnterSystemContext()) { var resourceName = data.GetType().GetSerializationName(); var subscriptions = this.m_pubSubManager .FindSubscription(o => o.ResourceTypeName == resourceName && o.IsActive && (o.NotBefore == null || o.NotBefore < DateTimeOffset.Now) && (o.NotAfter == null || o.NotAfter > DateTimeOffset.Now)) .Where(o => o.Event.HasFlag(eventType)) .Where(s => { // Attempt to compile the filter criteria into an executable function if (!this.m_filterCriteria.TryGetValue(s.Key.Value, out Func <Object, bool> fn)) { Expression dynFn = null; var parameter = Expression.Parameter(data.GetType()); foreach (var itm in s.Filter) { var fFn = QueryExpressionParser.BuildLinqExpression(data.GetType(), NameValueCollection.ParseQueryString(itm), "p", forceLoad: true, lazyExpandVariables: true); if (dynFn is LambdaExpression le) { dynFn = Expression.Lambda( Expression.And( Expression.Invoke(le, parameter), Expression.Invoke(fFn, parameter) ), parameter); } else { dynFn = fFn; } } if (dynFn == null) { dynFn = Expression.Lambda(Expression.Constant(true), parameter); } parameter = Expression.Parameter(typeof(object)); fn = Expression.Lambda(Expression.Invoke(dynFn, Expression.Convert(parameter, data.GetType())), parameter).Compile() as Func <Object, bool>; this.m_filterCriteria.TryAdd(s.Key.Value, fn); } return(fn(data)); }); // Now we want to filter by channel, since the channel is really what we're interested in foreach (var chnl in subscriptions.GroupBy(o => o.ChannelKey)) { var channelDef = this.m_pubSubManager.GetChannel(chnl.Key); var factory = DispatcherFactoryUtil.FindDispatcherFactoryById(channelDef.DispatcherFactoryId); yield return(factory.CreateDispatcher(chnl.Key, new Uri(channelDef.Endpoint), channelDef.Settings.ToDictionary(o => o.Name, o => o.Value))); } } }
/// <summary> /// Performs an identifier based match /// </summary> private IEnumerable <IRecordMatchResult <T> > PerformIdentityMatch <T>(T entity, IEnumerable <Guid> ignoreKeys, IRecordMatchingDiagnosticSession collector) where T : IdentifiedData { if (!(entity is IHasIdentifiers identifiers)) { throw new InvalidOperationException($"Cannot perform identity match on {typeof(T)}"); } try { collector?.LogStartStage("blocking"); // Identifiers in which entity has the unique authority var uqIdentifiers = identifiers.Identifiers.OfType <IExternalIdentifier>().Where(o => this.m_uniqueAuthorities.Contains(o.Authority?.Key ?? Guid.Empty)); if (uqIdentifiers?.Any(i => i.Authority == null) == true) { throw new InvalidOperationException("Some identifiers are missing authorities, cannot perform identity match"); } if (uqIdentifiers?.Any() != true) { return(new List <IRecordMatchResult <T> >()); } else { try { collector?.LogStartAction("block-identity"); // TODO: Build this using Expression trees rather than relying on the parsing methods NameValueCollection nvc = new NameValueCollection(); foreach (var itm in uqIdentifiers) { nvc.Add($"identifier[{itm.Authority.Key}].value", itm.Value); } var filterExpression = QueryExpressionParser.BuildLinqExpression <T>(nvc); // Now we want to filter returning the masters using (AuthenticationContext.EnterSystemContext()) { var repository = ApplicationServiceContext.Current.GetService <IRepositoryService <T> >(); var results = repository.Find(filterExpression).Where(o => !ignoreKeys.Contains(o.Key.Value)).Select(o => new MdmIdentityMatchResult <T>(entity, o, "$identity")); collector?.LogSample(filterExpression.ToString(), results.Count()); return(results); } } finally { collector?.LogEndAction(); } } } finally { collector?.LogEnd(); } }
/// <summary> /// Validate the data object if validation is available /// </summary> public List <DetectedIssue> Validate <TBinding>(TBinding data) where TBinding : IdentifiedData { lock (this.m_lock) { using (AuthenticationContext.EnterSystemContext()) { var callList = this.GetCallList(data.GetType(), "Validate").Union(this.GetCallList <TBinding>("Validate"), this.m_javascriptComparer).Distinct(); var retVal = new List <DetectedIssue>(); var vmData = JavascriptUtils.ToViewModel(data); foreach (var c in callList) { try { object[] issues = null; issues = c.Callback.DynamicInvoke(vmData) as object[]; retVal.AddRange(issues.Cast <IDictionary <String, Object> >().Select(o => new DetectedIssue() { Text = o.ContainsKey("text") ? o["text"]?.ToString() : null, Priority = o.ContainsKey("priority") ? (DetectedIssuePriorityType)(int)(double)o["priority"] : DetectedIssuePriorityType.Information, TypeKey = o.ContainsKey("type") ? Guid.Parse(o["type"].ToString()) : DetectedIssueKeys.BusinessRuleViolationIssue })); } catch (JavaScriptException e) { this.m_tracer.TraceError("Error validating {0} (rule: {1}) : {2}", data, c.Id, e); return(new List <DetectedIssue>() { new DetectedIssue() { Priority = DetectedIssuePriorityType.Error, Text = $"Error validating {data} (rule: {c.Id}) - {e.Message} @ {e.LineNumber}" } }); } catch (Exception e) { this.m_tracer.TraceError("Error validating {0} (rule: {1}) : {2}", data, c.Id, e); return(new List <DetectedIssue>() { new DetectedIssue() { Priority = DetectedIssuePriorityType.Error, Text = $"Error validating {data} (rule: {c.Id}) - {e.Message}" } }); } } return(retVal); } } }
/// <summary> /// Create the specified authority /// </summary> public static void CreateAuthority(string nsid, string oid, string url, string applicationName, byte[] deviceSecret) { // Create the test harness device / application var securityDevService = ApplicationServiceContext.Current.GetService <IRepositoryService <SecurityDevice> >(); var securityAppService = ApplicationServiceContext.Current.GetService <IRepositoryService <SecurityApplication> >(); var metadataService = ApplicationServiceContext.Current.GetService <IAssigningAuthorityRepositoryService>(); using (AuthenticationContext.EnterSystemContext()) { var pubId = $"{applicationName}|TEST"; var device = securityDevService.Find(o => o.Name == pubId).FirstOrDefault(); if (device == null) { device = new SecurityDevice { DeviceSecret = BitConverter.ToString(deviceSecret).Replace("-", ""), Name = $"{applicationName}|TEST" }; device.AddPolicy(PermissionPolicyIdentifiers.LoginAsService); device = securityDevService.Insert(device); } // Application var app = securityAppService.Find(o => o.Name == applicationName).FirstOrDefault(); if (app == null) { app = new SecurityApplication { Name = applicationName, ApplicationSecret = BitConverter.ToString(deviceSecret).Replace("-", "") }; app.AddPolicy(PermissionPolicyIdentifiers.LoginAsService); app.AddPolicy(PermissionPolicyIdentifiers.UnrestrictedClinicalData); app.AddPolicy(PermissionPolicyIdentifiers.UnrestrictedMetadata); app = securityAppService.Insert(app); } // Create AA var aa = metadataService.Get(nsid); if (aa == null) { aa = new AssigningAuthority(nsid, nsid, oid) { AssigningApplicationKey = app.Key, IsUnique = true, Url = url }; metadataService.Insert(aa); } } }
/// <summary> /// Public constructor for promise /// </summary> public JsPromiseProvider(Action <JsPromiseCallback, JsPromiseCallback> asyncFunc) { this.m_tracer.TraceVerbose("Creating async promise on thread pool"); var threadPool = (IThreadPoolService)ApplicationServiceContext.Current.GetService(typeof(IThreadPoolService)); if (s_syncObject == null) { s_syncObject = new object(); } var tsync = s_syncObject; Action <Object> workerCallback = (o) => { using (AuthenticationContext.EnterSystemContext()) { try { var worker = o as Action <JsPromiseCallback, JsPromiseCallback>; lock (tsync) { worker((f) => { this.m_asyncResult = f; this.m_thenCallback?.Invoke(f); }, (r) => { this.m_asyncReject = r; this.m_catchCallback?.Invoke(r); }); } this.m_completed = true; this.m_completeEvent.Set(); } catch (Exception e) { this.m_tracer.TraceError("Error in Promise: {0}", e); this.m_completeEvent.Set(); } } }; if (threadPool != null) { threadPool.QueueUserWorkItem(workerCallback, asyncFunc); } else { workerCallback.BeginInvoke(asyncFunc, null, null); } }
public void Setup() { TestApplicationContext.TestAssembly = typeof(TestRelatedPersonResourceHandler).Assembly; TestApplicationContext.Initialize(TestContext.CurrentContext.TestDirectory); this.m_serviceManager = ApplicationServiceContext.Current.GetService <IServiceManager>(); var testConfiguration = new FhirServiceConfigurationSection { Resources = new List <string> { "Patient", "Practitioner", "Observation" } }; TestUtil.CreateAuthority("TEST", "1.2.3.4", "http://santedb.org/fhir/test", "TEST_HARNESS", this.AUTH); using (AuthenticationContext.EnterSystemContext()) { FhirResourceHandlerUtil.Initialize(testConfiguration, this.m_serviceManager); ExtensionUtil.Initialize(testConfiguration); //add practitioner to be used as performer var practitioner = TestUtil.GetFhirMessage("ObservationPerformer") as Practitioner; var practitionerResourceHandler = FhirResourceHandlerUtil.GetResourceHandler(ResourceType.Practitioner); // create the practitioner using the resource handler this.m_practitioner = (Practitioner)practitionerResourceHandler.Create(practitioner, TransactionMode.Commit); //add patient to be used subject var patient = TestUtil.GetFhirMessage("ObservationSubject") as Patient; var patientResourceHandler = FhirResourceHandlerUtil.GetResourceHandler(ResourceType.Patient); // create the patient using the resource handler this.m_patient = (Patient)patientResourceHandler.Create(patient, TransactionMode.Commit); //add a general observation to be used for multiple tests var observation = TestUtil.GetFhirMessage("SetupObservation") as Observation; observation.Subject = new ResourceReference($"urn:uuid:{this.m_patient.Id}"); observation.Performer.Add(new ResourceReference($"urn:uuid:{this.m_practitioner.Id}")); var observationResourceHandler = FhirResourceHandlerUtil.GetResourceHandler(ResourceType.Observation); this.m_observation = (Observation)observationResourceHandler.Create(observation, TransactionMode.Commit); } }
public void TestErrorLocation() { using (AuthenticationContext.EnterSystemContext()) { var msg = TestUtil.GetMessage("ADT_INV_GC"); var errmsg = this.m_serviceManager.CreateInjected <AdtMessageHandler>().HandleMessage(new Hl7MessageReceivedEventArgs(msg, new Uri("test://"), new Uri("test://"), DateTime.Now)); var ack = errmsg as ACK; Assert.AreNotEqual(0, ack.ERRRepetitionsUsed); Assert.AreEqual("204", ack.GetERR(0).HL7ErrorCode.Identifier.Value); Assert.AreEqual("8", ack.GetERR(0).GetErrorLocation(0).FieldPosition.Value); Assert.AreEqual("PID", ack.GetERR(0).GetErrorLocation(0).SegmentID.Value); Assert.AreEqual("1", ack.GetERR(0).GetErrorLocation(0).SegmentSequence.Value); } }
/// <summary> /// Install data directory contents /// </summary> public void InstallDataDirectory(EventHandler <ProgressChangedEventArgs> fileProgress = null) { using (AuthenticationContext.EnterSystemContext()) { try { String dataDirectory = Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), "data"); this.m_traceSource.TraceEvent(EventLevel.Verbose, "Scanning Directory {0} for datasets", dataDirectory); XmlSerializer xsz = XmlModelSerializerFactory.Current.CreateSerializer(typeof(Dataset)); var datasetFiles = Directory.GetFiles(dataDirectory, "*.dataset"); datasetFiles = datasetFiles.OrderBy(o => Path.GetFileName(o)).ToArray(); int i = 0; // Perform migrations foreach (var f in datasetFiles) { try { var logFile = Path.ChangeExtension(f, "completed"); if (File.Exists(logFile)) { continue; // skip } using (var fs = File.OpenRead(f)) { var ds = xsz.Deserialize(fs) as Dataset; fileProgress?.Invoke(this, new ProgressChangedEventArgs(++i / (float)datasetFiles.Length, ds.Id)); this.m_traceSource.TraceEvent(EventLevel.Informational, "Installing {0}...", Path.GetFileName(f)); this.InstallDataset(ds); } File.Move(f, logFile); } catch (Exception ex) { this.m_traceSource.TraceEvent(EventLevel.Error, "Error applying {0}: {1}", f, ex); throw; } } } finally { this.m_traceSource.TraceEvent(EventLevel.Verbose, "Un-binding event handler"); ApplicationServiceContext.Current.Started -= this.m_persistenceHandler; } } }
public void TestCrossReference() { using (AuthenticationContext.EnterSystemContext()) { var msg = TestUtil.GetMessage("QBP_XREF_PRE"); var result = this.m_serviceManager.CreateInjected <AdtMessageHandler>().HandleMessage(new Hl7MessageReceivedEventArgs(msg, new Uri("test://"), new Uri("test://"), DateTime.Now)); Assert.AreEqual("CA", (result.GetStructure("MSA") as MSA).AcknowledgmentCode.Value); var patient = ApplicationServiceContext.Current.GetService <IRepositoryService <Patient> >().Find(o => o.Identifiers.Any(i => i.Value == "HL7-4")).SingleOrDefault(); Assert.IsNotNull(patient); msg = TestUtil.GetMessage("QBP_XREF"); var message = this.m_serviceManager.CreateInjected <QbpMessageHandler>().HandleMessage(new Hl7MessageReceivedEventArgs(msg, new Uri("test://"), new Uri("test://"), DateTime.Now)); var messageStr = TestUtil.ToString(message); // TODO : Assert that id is present Assert.IsTrue(((message.GetStructure("QUERY_RESPONSE") as AbstractGroup).GetStructure("PID") as PID).GetPatientIdentifierList().Any(i => i.IDNumber.Value == patient.Key.ToString() && i.AssigningAuthority.NamespaceID.Value == "KEY")); Assert.AreEqual("AA", (message.GetStructure("MSA") as MSA).AcknowledgmentCode.Value); Assert.AreEqual("OK", (message.GetStructure("QAK") as QAK).QueryResponseStatus.Value); Assert.AreEqual("K23", (message.GetStructure("MSH") as MSH).MessageType.TriggerEvent.Value); } }
/// <summary> /// Invoke the operation /// </summary> public object Invoke(Type scopingType, object scopingKey, ParameterCollection parameters) { if (parameters.TryGet("input", out String inputIdString) && Guid.TryParse(inputIdString, out Guid inputId)) { // Matching is run on system context // Load the configuration var config = this.m_configService?.GetConfiguration(scopingKey.ToString()); if (config == null) { throw new KeyNotFoundException($"{scopingKey} not found"); } // Get the target input var inputObject = config.AppliesTo.Select(o => { using (AuthenticationContext.EnterSystemContext()) // The input should be in system concept since the privacy service may block our identity domains based on policy { var repo = ApplicationServiceContext.Current.GetService(typeof(IRepositoryService <>).MakeGenericType(o)) as IRepositoryService; if (repo != null) { return(repo.Get(inputId)); } else { return(null); } } }).OfType <IdentifiedData>().FirstOrDefault(); if (inputObject == null) { throw new KeyNotFoundException($"{inputId} not found or not applicable for {scopingKey}"); } // Run the configuration var mergeService = ApplicationServiceContext.Current.GetService(typeof(IRecordMergingService <>).MakeGenericType(inputObject.GetType())) as IRecordMergingService; var repoService = ApplicationServiceContext.Current.GetService(typeof(IRepositoryService <>).MakeGenericType(inputObject.GetType())) as IRepositoryService; IEnumerable <IdentifiedData> blocks = null; var diagnosticSession = this.m_matchingService.CreateDiagnosticSession(); if (parameters.TryGet("targets", out String[] knownDuplicates) && knownDuplicates.Length > 0)