Exemplo n.º 1
0
        /// <summary>
        /// Internal notification logic
        /// </summary>
        private void NotifyInternal(object state)
        {
            // Get the state
            try
            {
                NotificationQueueWorkItem workItem = state as NotificationQueueWorkItem;
                ILocalizationService      locale   = this.Context.GetService(typeof(ILocalizationService)) as ILocalizationService;
                IDataPersistenceService   idps     = this.Context.GetService(typeof(IDataPersistenceService)) as IDataPersistenceService;

                if (workItem == null)
                {
                    throw new ArgumentException("workItem");
                }

                var evt = workItem.Event;

                if (idps != null)
                {
                    evt = idps.GetContainer(workItem.Event.AlternateIdentifier, true) as RegistrationEvent;
                }

                var subject = workItem.Event.FindComponent(SVC.Core.ComponentModel.HealthServiceRecordSiteRoleType.SubjectOf) as Person;
                if (subject == null)
                {
                    throw new InvalidOperationException(locale.GetString("NTFE001"));
                }

                // Now determine who will receive updates
                Trace.TraceInformation("Searching for targets for patient notification...");
                List <TargetConfiguration> targets = null;
                lock (s_syncLock)
                {
                    targets = s_configuration.Targets.FindAll(o => o.NotificationDomain.Exists(delegate(NotificationDomainConfiguration dc)
                    {
                        bool action = dc.Actions.Exists(act => (act.Action & workItem.Action) == workItem.Action);
                        bool domain = dc.Domain == "*" || subject.AlternateIdentifiers.Exists(id => id.Domain == dc.Domain);
                        return(action && domain);
                    }
                                                                                               ));
                }
                Trace.TraceInformation("{0} targets for patient notification found...");

                // Notify the targets
                foreach (var itm in targets)
                {
                    itm.Notifier.Context = this.Context;
                    itm.Notifier.Notify(workItem);
                }
            }
            catch (Exception e)
            {
                Trace.TraceError(e.ToString());
            }
        }
        /// <summary>
        /// Get one registration event
        /// </summary>
        public Core.ComponentModel.RegistrationEvent GetRegistrationEvent(decimal id)
        {
            // Get all Services
            IAuditorService         auditSvc = ApplicationContext.CurrentContext.GetService(typeof(IAuditorService)) as IAuditorService;
            IDataPersistenceService repSvc   = ApplicationContext.CurrentContext.GetService(typeof(IDataPersistenceService)) as IDataPersistenceService;

            // Audit message
            AuditData audit = this.ConstructAuditData(ActionType.Read, EventIdentifierType.Export);

            audit.EventTypeCode = new CodeValue("ADM_GetRegistrationEvent");

            try
            {
                // Result identifiers
                var retVal = repSvc.GetContainer(new VersionedDomainIdentifier()
                {
                    Domain     = ApplicationContext.ConfigurationService.OidRegistrar.GetOid("REG_EVT").Oid,
                    Identifier = id.ToString()
                }, false) as RegistrationEvent;

                // Add audit data
                if (retVal != null)
                {
                    audit.AuditableObjects.Add(new AuditableObject()
                    {
                        IDTypeCode    = AuditableObjectIdType.ReportNumber,
                        LifecycleType = AuditableObjectLifecycle.Export,
                        ObjectId      = String.Format("{0}^^^&{1}&ISO", retVal.AlternateIdentifier.Identifier, retVal.AlternateIdentifier.Domain),
                        Role          = AuditableObjectRole.MasterFile,
                        Type          = AuditableObjectType.SystemObject,
                        QueryData     = Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes("loadFast=false"))
                    });
                }
                return(retVal);
            }
            catch (Exception e)
            {
                Trace.TraceError("Could not execute GetRegistration : {0}", e.ToString());
                audit.Outcome = OutcomeIndicator.EpicFail;
#if DEBUG
                throw new FaultException(new FaultReason(e.ToString()), new FaultCode(e.GetType().Name));
#else
                throw new FaultException(new FaultReason(e.Message), new FaultCode(e.GetType().Name));
#endif
            }
            finally
            {
                if (auditSvc != null)
                {
                    auditSvc.SendAudit(audit);
                }
            }
        }
Exemplo n.º 3
0
        /// <summary>
        /// Read a patint resource
        /// </summary>
        public SVC.Messaging.FHIR.FhirOperationResult Read(string id, string versionId)
        {
            FhirOperationResult result = new FhirOperationResult();

            result.Details = new List <IResultDetail>();
            result.Results = new List <ResourceBase>();

            // Data persistence service
            IDataPersistenceService dataPersistence = ApplicationContext.CurrentContext.GetService(typeof(IDataPersistenceService)) as IDataPersistenceService;
            var container = dataPersistence.GetContainer(new VersionedDomainIdentifier()
            {
                Domain     = this.DataDomain,
                Identifier = id,
                Version    = String.IsNullOrEmpty(versionId) ? null : versionId
            }, String.IsNullOrEmpty(versionId));


            // Container was not found
            if (container == null)
            {
                result.Outcome = ResultCode.NotAvailable;
            }
            else
            {
                var processor = FhirMessageProcessorUtil.GetComponentProcessor(container.GetType());

                // Was there a history?
                if (versionId == null)
                {
                    result.Results.Add(processor.ProcessComponent(container as IComponent, result.Details));
                }
                else if (versionId == String.Empty) // Get all versions
                {
                    while (container != null)
                    {
                        var hsrc     = container as HealthServiceRecordContainer;
                        var resource = processor.ProcessComponent(container as IComponent, result.Details);

                        if (hsrc.IsMasked) // record is masked so add a detected issue
                        {
                            result.Issues.Add(new SVC.Core.Issues.DetectedIssue()
                            {
                                MitigatedBy = ManagementType.OtherActionTaken,
                                Severity    = IssueSeverityType.Moderate,
                                Text        = String.Format("{0}/_history/{1} will not be returned as it has been masked", resource.Id, resource.VersionId),
                                Type        = IssueType.DetectedIssue
                            });
                        }
                        else
                        {
                            result.Results.Add(resource);
                        }
                        container = hsrc.FindComponent(HealthServiceRecordSiteRoleType.OlderVersionOf) as IContainer;
                    }
                }
                else // Some version
                {
                    while (container != null)
                    {
                        var hsrc     = container as HealthServiceRecordContainer;
                        var resource = processor.ProcessComponent(container as IComponent, result.Details);
                        container = hsrc.FindComponent(HealthServiceRecordSiteRoleType.ReplacementOf) as IContainer;


                        if (resource != null && resource.VersionId.ToString() != versionId)
                        {
                            continue;
                        }

                        if (hsrc.IsMasked) // record is masked so add a detected issue
                        {
                            result.Issues.Add(new SVC.Core.Issues.DetectedIssue()
                            {
                                MitigatedBy = ManagementType.OtherActionTaken,
                                Severity    = IssueSeverityType.Moderate,
                                Text        = String.Format("{0}/_history/{1} will not be returned as it has been masked", resource.Id, resource.VersionId),
                                Type        = IssueType.DetectedIssue
                            });
                        }
                        else
                        {
                            result.Results.Add(resource);
                        }
                    }
                }
                result.Outcome = ResultCode.Accepted;
            }

            result.Results.RemoveAll(o => o == null);
            return(result);
        }
        /// <summary>
        /// Get recent activity
        /// </summary>
        public RegistrationEventCollection GetRecentActivity(TimestampSet timeRange, int offset, int count, bool identifierOnly)
        {
            // Get all Services
            IAuditorService          auditSvc = ApplicationContext.CurrentContext.GetService(typeof(IAuditorService)) as IAuditorService;
            IDataRegistrationService regSvc   = ApplicationContext.CurrentContext.GetService(typeof(IDataRegistrationService)) as IDataRegistrationService;
            IDataPersistenceService  repSvc   = ApplicationContext.CurrentContext.GetService(typeof(IDataPersistenceService)) as IDataPersistenceService;

            // Audit message
            AuditData audit = this.ConstructAuditData(ActionType.Read, EventIdentifierType.Export);

            audit.EventTypeCode = new CodeValue("ADM_GetRegistrations");

            try
            {
                // Result identifiers
                VersionedDomainIdentifier[] vids = null;
                var dummyQuery = new QueryEvent();
                dummyQuery.Add(new RegistrationEvent()
                {
                    EventClassifier = RegistrationEventType.Register, EffectiveTime = timeRange
                }, "SUBJ", SVC.Core.ComponentModel.HealthServiceRecordSiteRoleType.SubjectOf, null);
                vids = regSvc.QueryRecord(dummyQuery);

                RegistrationEventCollection retVal = new RegistrationEventCollection();
                Object syncLock = new object();

                retVal.Count = vids.Length;

                // Now fetch each one asynchronously
                if (!identifierOnly)
                {
                    using (WaitThreadPool thdPool = new WaitThreadPool(Environment.ProcessorCount * 2))
                    {
                        foreach (var id in vids.Skip(offset).Take(count))
                        {
                            thdPool.QueueUserWorkItem(
                                delegate(object state)
                            {
                                try
                                {
                                    var itm = repSvc.GetContainer(state as VersionedDomainIdentifier, true);
                                    lock (syncLock)
                                        retVal.Event.Add(itm as RegistrationEvent);
                                }
                                catch (Exception e)
                                {
                                    Trace.TraceError("Could not fetch result {0} : {1}", (state as VersionedDomainIdentifier).Identifier, e.ToString());
                                }
                            }
                                , id);
                        }

                        // Wait until fetch is done
                        thdPool.WaitOne(new TimeSpan(0, 0, 30), false);
                    }
                    //retVal.Event.Sort((a, b) => b.Timestamp.CompareTo(a.Timestamp));
                    // Add audit data
                    foreach (var res in retVal.Event)
                    {
                        audit.AuditableObjects.Add(new AuditableObject()
                        {
                            IDTypeCode    = AuditableObjectIdType.ReportNumber,
                            LifecycleType = AuditableObjectLifecycle.Export,
                            ObjectId      = String.Format("{0}^^^&{1}&ISO", res.AlternateIdentifier.Identifier, res.AlternateIdentifier.Domain),
                            Role          = AuditableObjectRole.MasterFile,
                            Type          = AuditableObjectType.SystemObject,
                            QueryData     = Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes("loadFast=true"))
                        });
                    }
                }
                return(retVal);
            }
            catch (Exception e)
            {
                Trace.TraceError("Could not execute GetRegistrations : {0}", e.ToString());
                audit.Outcome = OutcomeIndicator.EpicFail;
#if DEBUG
                throw new FaultException(new FaultReason(e.ToString()), new FaultCode(e.GetType().Name));
#else
                throw new FaultException(new FaultReason(e.Message), new FaultCode(e.GetType().Name));
#endif
            }
            finally
            {
                if (auditSvc != null)
                {
                    auditSvc.SendAudit(audit);
                }
            }
        }
        /// <summary>
        /// Perform a merge
        /// </summary>
        public Core.ComponentModel.RegistrationEvent Merge(decimal[] sourceIds, decimal targetId)
        {
            // Get all Services
            IAuditorService             auditSvc = ApplicationContext.CurrentContext.GetService(typeof(IAuditorService)) as IAuditorService;
            IDataPersistenceService     repSvc   = ApplicationContext.CurrentContext.GetService(typeof(IDataPersistenceService)) as IDataPersistenceService;
            IClientRegistryMergeService mergeSvc = ApplicationContext.CurrentContext.GetService(typeof(IClientRegistryMergeService)) as IClientRegistryMergeService;

            // Audit message
            List <AuditData> auditMessages = new List <AuditData>();

            try
            {
                // Prepare merge
                List <VersionedDomainIdentifier> domainId = new List <VersionedDomainIdentifier>(sourceIds.Length);
                foreach (var srcId in sourceIds)
                {
                    domainId.Add(new VersionedDomainIdentifier()
                    {
                        Domain     = ApplicationContext.ConfigurationService.OidRegistrar.GetOid("REG_EVT").Oid,
                        Identifier = srcId.ToString()
                    });

                    var am = ConstructAuditData(ActionType.Delete, EventIdentifierType.Import);
                    am.EventTypeCode = new CodeValue("ADM_Merge");
                    am.AuditableObjects.Add(new AuditableObject()
                    {
                        IDTypeCode    = AuditableObjectIdType.ReportNumber,
                        LifecycleType = AuditableObjectLifecycle.LogicalDeletion,
                        ObjectId      = String.Format("{0}^^^&{1}&ISO", srcId, ApplicationContext.ConfigurationService.OidRegistrar.GetOid("REG_EVT").Oid),
                        Role          = AuditableObjectRole.MasterFile,
                        Type          = AuditableObjectType.SystemObject
                    });
                    auditMessages.Add(am);
                }
                VersionedDomainIdentifier survivorId = new VersionedDomainIdentifier()
                {
                    Domain     = ApplicationContext.ConfigurationService.OidRegistrar.GetOid("REG_EVT").Oid,
                    Identifier = targetId.ToString()
                };
                var updateAudit = ConstructAuditData(ActionType.Update, EventIdentifierType.Import);
                updateAudit.EventTypeCode = new CodeValue("ADM_Merge");
                updateAudit.AuditableObjects.Add(new AuditableObject()
                {
                    IDTypeCode    = AuditableObjectIdType.ReportNumber,
                    LifecycleType = AuditableObjectLifecycle.Amendment,
                    ObjectId      = String.Format("{0}^^^&{1}&ISO", survivorId.Identifier, survivorId.Domain),
                    Role          = AuditableObjectRole.MasterFile,
                    Type          = AuditableObjectType.SystemObject
                });
                auditMessages.Add(updateAudit);

                // Merge
                mergeSvc.Resolve(domainId, survivorId, DataPersistenceMode.Production);

                // Now load
                return(repSvc.GetContainer(survivorId, true) as RegistrationEvent);
            }
            catch (Exception e)
            {
                foreach (var am in auditMessages)
                {
                    am.Outcome = OutcomeIndicator.EpicFail;
                }
                Trace.TraceError("Could not execute Merge : {0}", e.ToString());
#if DEBUG
                throw new FaultException(new FaultReason(e.ToString()), new FaultCode(e.GetType().Name));
#else
                throw new FaultException(new FaultReason(e.Message), new FaultCode(e.GetType().Name));
#endif
            }
            finally
            {
                if (auditSvc != null)
                {
                    foreach (var am in auditMessages)
                    {
                        auditSvc.SendAudit(am);
                    }
                }
            }
        }
        /// <summary>
        /// Get all merge candidates
        /// </summary>
        public ConflictCollection GetConflicts(int offset, int count, bool identifierOnly)
        {
            // Get all Services
            IAuditorService             auditSvc = ApplicationContext.CurrentContext.GetService(typeof(IAuditorService)) as IAuditorService;
            IDataPersistenceService     repSvc   = ApplicationContext.CurrentContext.GetService(typeof(IDataPersistenceService)) as IDataPersistenceService;
            IClientRegistryMergeService mergeSvc = ApplicationContext.CurrentContext.GetService(typeof(IClientRegistryMergeService)) as IClientRegistryMergeService;

            // Audit message
            AuditData audit = this.ConstructAuditData(ActionType.Read, EventIdentifierType.Export);

            audit.EventTypeCode = new CodeValue("ADM_GetConflicts");
            try
            {
                // Get all with a merge
                var mergeResults = mergeSvc.GetOutstandingConflicts();

                var retVal = new ConflictCollection();
                retVal.Count = mergeResults.Count();

                // Loop and load
                foreach (var merge in mergeResults.Skip(offset).Take(count))
                {
                    // Construct the return, and load match
                    Conflict conf = new Conflict();

                    if (!identifierOnly)
                    {
                        conf.Source = repSvc.GetContainer(merge, true) as RegistrationEvent;
                        // Add audit data
                        audit.AuditableObjects.Add(new AuditableObject()
                        {
                            IDTypeCode    = AuditableObjectIdType.ReportNumber,
                            LifecycleType = AuditableObjectLifecycle.Export,
                            ObjectId      = String.Format("{0}^^^&{1}&ISO", conf.Source.AlternateIdentifier.Identifier, conf.Source.AlternateIdentifier.Domain),
                            Role          = AuditableObjectRole.MasterFile,
                            Type          = AuditableObjectType.SystemObject,
                            QueryData     = Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes("loadFast=false"))
                        });
                    }


                    // Load the matches
                    foreach (var match in mergeSvc.GetConflicts(merge))
                    {
                        if (!identifierOnly)
                        {
                            var matchRecord = repSvc.GetContainer(match, true) as RegistrationEvent;
                            conf.Match.Add(matchRecord);
                            // Add audit data
                            audit.AuditableObjects.Add(new AuditableObject()
                            {
                                IDTypeCode    = AuditableObjectIdType.ReportNumber,
                                LifecycleType = AuditableObjectLifecycle.Export,
                                ObjectId      = String.Format("{0}^^^&{1}&ISO", matchRecord.AlternateIdentifier.Identifier, matchRecord.AlternateIdentifier.Domain),
                                Role          = AuditableObjectRole.MasterFile,
                                Type          = AuditableObjectType.SystemObject,
                                QueryData     = Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes("loadFast=false"))
                            });
                        }
                        else
                        {
                            conf.Match.Add(new RegistrationEvent()
                            {
                                AlternateIdentifier = match
                            });
                        }
                    }

                    retVal.Conflict.Add(conf);
                }

                return(retVal);
            }
            catch (Exception e)
            {
                Trace.TraceError("Could not execute GetConflicts : {0}", e.ToString());
                audit.Outcome = OutcomeIndicator.EpicFail;
#if DEBUG
                throw new FaultException(new FaultReason(e.ToString()), new FaultCode(e.GetType().Name));
#else
                throw new FaultException(new FaultReason(e.Message), new FaultCode(e.GetType().Name));
#endif
            }
            finally
            {
                if (auditSvc != null)
                {
                    auditSvc.SendAudit(audit);
                }
            }
        }