Exemplo n.º 1
0
        /// <summary>
        /// Enrich the registration event
        /// </summary>
        internal void EnrichRegistrationEvent(IDbConnection conn, IDbTransaction tx, RegistrationEvent hsrEvent)
        {
            decimal tryDec;
            ISystemConfigurationService configService = ApplicationContext.ConfigurationService;

            // Create a query based on the person
            Person subject = hsrEvent.FindComponent(HealthServiceRecordSiteRoleType.SubjectOf) as Person;

            if (subject.AlternateIdentifiers.Exists(o => o.Domain == configService.OidRegistrar.GetOid(ClientRegistryOids.CLIENT_CRID).Oid))
            {
                subject = new Person()
                {
                    AlternateIdentifiers = new List <DomainIdentifier>(subject.AlternateIdentifiers.FindAll(o => o.Domain == configService.OidRegistrar.GetOid(ClientRegistryOids.CLIENT_CRID).Oid)),
                    Status = StatusType.Normal
                }
            }
            ;
            else if (subject.AlternateIdentifiers.Exists(o => o is AuthorityAssignedDomainIdentifier))
            {
                subject = new Person()
                {
                    AlternateIdentifiers = new List <DomainIdentifier>(subject.AlternateIdentifiers.FindAll(o => o is AuthorityAssignedDomainIdentifier)),
                    Status = StatusType.Normal
                }
            }
            ;
            else
            {
                subject = new Person()
                {
                    AlternateIdentifiers = new List <DomainIdentifier>(subject.AlternateIdentifiers),
                    Status = StatusType.Normal
                }
            };

            QueryEvent        query = new QueryEvent();
            RegistrationEvent evt   = new RegistrationEvent();

            query.Add(evt, "SUBJ", HealthServiceRecordSiteRoleType.SubjectOf, null);
            evt.Status = StatusType.Active | StatusType.Obsolete;
            evt.Add(subject, "SUBJ", HealthServiceRecordSiteRoleType.SubjectOf, null);
            query.Add(new QueryParameters()
            {
                MatchingAlgorithm = MatchAlgorithm.Exact,
                MatchStrength     = MatchStrength.Exact
            }, "FLTR", HealthServiceRecordSiteRoleType.FilterOf, null);
            var tRecordIds = QueryRecord(query);

            if (tRecordIds.Length != 1)
            {
                throw new MissingPrimaryKeyException(ApplicationContext.LocaleService.GetString("DBCF004"));
            }
            else if (tRecordIds[0].Domain != configService.OidRegistrar.GetOid(ClientRegistryOids.REGISTRATION_EVENT).Oid)
            {
                throw new MissingPrimaryKeyException(ApplicationContext.LocaleService.GetString("DBCF005"));
            }

            tryDec = Decimal.Parse(tRecordIds[0].Identifier);
            hsrEvent.AlternateIdentifier = tRecordIds[0];
        }
        /// <summary>
        /// Find conflicts using identifiers
        /// </summary>
        public IEnumerable <SVC.Core.DataTypes.VersionedDomainIdentifier> FindIdConflicts(RegistrationEvent registration)
        {
            var registrationService = this.Context.GetService(typeof(IDataRegistrationService)) as IDataRegistrationService;

            VersionedDomainIdentifier[] pid = null;

            // Check if the person exists just via the identifier?
            // This is important because it is not necessarily a merge but an "update if exists"
            var             subject = registration.FindComponent(SVC.Core.ComponentModel.HealthServiceRecordSiteRoleType.SubjectOf) as Person;
            QueryParameters qp      = new QueryParameters()
            {
                Confidence        = 1.0f,
                MatchingAlgorithm = MatchAlgorithm.Exact,
                MatchStrength     = MatchStrength.Exact
            };

            var config = this.Context.GetService(typeof(ISystemConfigurationService)) as ISystemConfigurationService;

            List <VersionedDomainIdentifier> conflictIds = new List <VersionedDomainIdentifier>();

            foreach (var id in subject.AlternateIdentifiers)
            {
                var data = config.OidRegistrar.FindData(id.Domain);
                if (data == null || !data.Attributes.Exists(a => a.Key == "IsUniqueIdentifier" && Convert.ToBoolean(a.Value)))
                {
                    continue;
                }
                var patientQuery      = new QueryEvent();
                var registrationEvent = new RegistrationEvent();
                patientQuery.Add(registrationEvent, "SUBJ", HealthServiceRecordSiteRoleType.SubjectOf, null);
                patientQuery.Add(qp, "FLT", SVC.Core.ComponentModel.HealthServiceRecordSiteRoleType.FilterOf, null);
                registrationEvent.Add(new Person()
                {
                    AlternateIdentifiers = new List <DomainIdentifier>()
                    {
                        id
                    }
                }, "SUBJ", SVC.Core.ComponentModel.HealthServiceRecordSiteRoleType.SubjectOf, null);
                // Perform the query
                pid = registrationService.QueryRecord(patientQuery);
                foreach (var result in pid)
                {
                    if (!conflictIds.Exists(o => o.Identifier.ToString() == result.Identifier))
                    {
                        conflictIds.Add(result);
                    }
                }
            }
            return(conflictIds.ToArray());
        }
        /// <summary>
        /// Find conflicts using fuzzy match
        /// </summary>
        public IEnumerable <VersionedDomainIdentifier> FindFuzzyConflicts(RegistrationEvent registration)
        {
            var registrationService = this.Context.GetService(typeof(IDataRegistrationService)) as IDataRegistrationService;
            var persistenceService  = this.Context.GetService(typeof(IDataPersistenceService)) as IDataPersistenceService;

            var clientRegistryConfigService = this.Context.GetService(typeof(IClientRegistryConfigurationService)) as IClientRegistryConfigurationService;

            VersionedDomainIdentifier[] pid = null;

            var             subject = registration.FindComponent(SVC.Core.ComponentModel.HealthServiceRecordSiteRoleType.SubjectOf) as Person;
            QueryParameters qp      = new QueryParameters()
            {
                Confidence        = 1.0f,
                MatchingAlgorithm = MatchAlgorithm.Exact,
                MatchStrength     = MatchStrength.Exact
            };

            if (subject.Status != StatusType.Active)
            {
                return(pid);
            }

            var patientQuery      = new QueryEvent();
            var registrationEvent = new RegistrationEvent();

            patientQuery.Add(registrationEvent, "SUBJ", HealthServiceRecordSiteRoleType.SubjectOf, null);
            patientQuery.Add(qp, "FLT", SVC.Core.ComponentModel.HealthServiceRecordSiteRoleType.FilterOf, null);
            // Create merge filter for fuzzy match
            var ssubject = clientRegistryConfigService.CreateMergeFilter(subject);

            if (ssubject != null) // Minimum criteria was met
            {
                registrationEvent.Add(ssubject, "SUBJ", HealthServiceRecordSiteRoleType.SubjectOf, null);
                pid = registrationService.QueryRecord(patientQuery);
            }
            else
            {
                pid = new VersionedDomainIdentifier[0];
            }


            // Now, look for all with an assigning authority
            if (pid.Length > 0)
            {
                pid = pid.Where(o => !(o.Identifier == registration.Id.ToString() && o.Domain == ApplicationContext.ConfigurationService.OidRegistrar.GetOid(ClientRegistryOids.REGISTRATION_EVENT).Oid)).ToArray();
                // Load each match quickly and ensure that they don't already have a
                // different identifier from an assigning authority (not CR_CID) provided
                // in the registration method. For example, if John Smith, Male, 1984-05-22, 123 Main Street West is
                // registered from system X with ID 102 , and a subsequent registration message for John Smith, Male, 1984-05-22, 123 Main Street West
                // is received from system X with ID 104, it is pretty much assured they aren't the same person. If however the
                // latter message came from system Y with ID 104, then the two should be considered a match.
                ssubject.AlternateIdentifiers = new List <DomainIdentifier>();
                List <VersionedDomainIdentifier> exclude = new List <VersionedDomainIdentifier>();
                foreach (var altId in subject.AlternateIdentifiers)
                {
                    if (altId.Domain != ApplicationContext.ConfigurationService.OidRegistrar.GetOid(ClientRegistryOids.CLIENT_CRID).Oid)
                    {
                        var oidData = ApplicationContext.ConfigurationService.OidRegistrar.FindData(altId.Domain);
                        if (oidData == null ||
                            oidData.Attributes.Find(o => o.Key == "IsUniqueIdentifier").Value == null ||
                            Boolean.Parse(oidData.Attributes.Find(o => o.Key == "IsUniqueIdentifier").Value))
                        {
                            ssubject.AlternateIdentifiers.Add(new DomainIdentifier()
                            {
                                Domain = altId.Domain
                            });
                        }
                    }
                }


                foreach (var p in pid)
                {
                    var re  = persistenceService.GetContainer(p, true) as RegistrationEvent;
                    var pat = re.FindComponent(HealthServiceRecordSiteRoleType.SubjectOf) as Person;
                    if (pat.Id == subject.Id || pat.Status != StatusType.Active)  // same person
                    {
                        exclude.Add(re.AlternateIdentifier);
                    }
                    else if (pat.AlternateIdentifiers.Exists(o => ssubject.AlternateIdentifiers.Exists(r => r.Domain == o.Domain)))
                    {
                        exclude.Add(re.AlternateIdentifier);
                    }
                }

                pid = pid.Where(o => !exclude.Exists(i => i.Domain == o.Domain && i.Identifier == o.Identifier)).ToArray();
            }
            return(pid);
        }
Exemplo n.º 4
0
        /// <summary>
        /// Notify the operation
        /// </summary>
        public void Notify(NotificationQueueWorkItem workItem)
        {
            // configuration service
            ISystemConfigurationService config = this.Context.GetService(typeof(ISystemConfigurationService)) as ISystemConfigurationService;
            ILocalizationService        locale = this.Context.GetService(typeof(ILocalizationService)) as ILocalizationService;

            // Common message bits we need to update
            IMessage notificationMessage = null;
            MSH      msh = null;
            PID      pid = null;
            EVN      evn = null;
            PV1      pv1 = null;
            MRG      mrg = null;

            // Identify the work item action
            switch (workItem.Action)
            {
            case MARC.HI.EHRS.CR.Notification.PixPdq.Configuration.ActionType.Create:
            {
                ADT_A01 message = new ADT_A01();
                msh = message.MSH;
                pid = message.PID;
                evn = message.EVN;
                pv1 = message.PV1;
                notificationMessage = message;
                msh.MessageType.TriggerEvent.Value = "A04";

                break;
            }

            case MARC.HI.EHRS.CR.Notification.PixPdq.Configuration.ActionType.DuplicatesResolved:
            {
                ADT_A39 message = new ADT_A39();
                msh = message.MSH;
                msh.MessageType.TriggerEvent.Value = "A40";
                pid = message.GetPATIENT(0).PID;
                evn = message.EVN;
                pv1 = message.GetPATIENT(0).PV1;
                mrg = message.GetPATIENT(0).MRG;
                notificationMessage = message;
                break;
            };

            case MARC.HI.EHRS.CR.Notification.PixPdq.Configuration.ActionType.Update:
            {
                ADT_A01 message = new ADT_A01();
                msh = message.MSH;
                pid = message.PID;
                evn = message.EVN;
                pv1 = message.PV1;
                notificationMessage = message;
                msh.MessageType.TriggerEvent.Value = "A08";
                break;
            }
            }

            // Populate the MSH header first
            this.UpdateMSH(msh, config);

            // Populate the EVN segment
            evn.EventTypeCode.Value = workItem.Event.Mode.ToString();
            evn.RecordedDateTime.TimeOfAnEvent.Value = (TS)workItem.Event.Timestamp;

            // Populate the PID segment
            Person subject = workItem.Event.FindComponent(SVC.Core.ComponentModel.HealthServiceRecordSiteRoleType.SubjectOf) as Person;

            this.UpdatePID(subject, pid, config);
            pv1.PatientClass.Value = "I";

            // Populate MRG
            if (mrg != null)
            {
                var registration = this.Context.GetService(typeof(IDataRegistrationService)) as IDataRegistrationService;
                var persistence  = this.Context.GetService(typeof(IDataPersistenceService)) as IDataPersistenceService;
                var replacements = subject.FindAllComponents(SVC.Core.ComponentModel.HealthServiceRecordSiteRoleType.ReplacementOf);

                foreach (PersonRegistrationRef rplc in replacements)
                {
                    // First, need to de-persist the identifiers
                    QueryParameters qp = new QueryParameters()
                    {
                        Confidence        = 1.0f,
                        MatchingAlgorithm = MatchAlgorithm.Exact,
                        MatchStrength     = MatchStrength.Exact
                    };
                    var queryEvent   = new QueryEvent();
                    var patientQuery = new RegistrationEvent();
                    queryEvent.Add(qp, "FLT", SVC.Core.ComponentModel.HealthServiceRecordSiteRoleType.FilterOf, null);
                    patientQuery.Add(new Person()
                    {
                        AlternateIdentifiers = rplc.AlternateIdentifiers
                    }, "SUBJ", SVC.Core.ComponentModel.HealthServiceRecordSiteRoleType.SubjectOf, null);
                    queryEvent.Add(patientQuery, "SUBJ", SVC.Core.ComponentModel.HealthServiceRecordSiteRoleType.SubjectOf, null);
                    // Perform the query
                    var patientIdentifiers = registration.QueryRecord(queryEvent);
                    if (patientIdentifiers.Length == 0)
                    {
                        throw new InvalidOperationException();
                    }
                    var replacedPerson = (persistence.GetContainer(patientIdentifiers[0], true) as RegistrationEvent).FindComponent(SVC.Core.ComponentModel.HealthServiceRecordSiteRoleType.SubjectOf) as Person;

                    foreach (var ii in replacedPerson.AlternateIdentifiers.FindAll(o => this.Target.NotificationDomain.Exists(d => d.Domain == o.Domain)))
                    {
                        var cx = mrg.GetPriorPatientIdentifierList(mrg.PriorAlternatePatientIDRepetitionsUsed);
                        cx.ID.Value = ii.Identifier;
                        if (String.IsNullOrEmpty(ii.AssigningAuthority))
                        {
                            cx.AssigningAuthority.NamespaceID.Value = config.OidRegistrar.FindData(ii.Domain).Attributes.Find(o => o.Key == "AssigningAuthorityName").Value;
                        }
                        else
                        {
                            cx.AssigningAuthority.NamespaceID.Value = ii.AssigningAuthority;
                        }
                        cx.AssigningAuthority.UniversalID.Value     = ii.Domain;
                        cx.AssigningAuthority.UniversalIDType.Value = "ISO";
                    }
                }
            }

            // Send
            var queueItem = new Hl7MessageQueue.MessageQueueWorkItem(this.Target, notificationMessage);

            if (!queueItem.TrySend())
            {
                Trace.TraceWarning(locale.GetString("NTFW005"));
                Hl7MessageQueue.Current.EnqueueMessageItem(queueItem);
            }
        }
        /// <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);
                }
            }
        }
Exemplo n.º 6
0
        /// <summary>
        /// Create a patient registry duplicates resolved message
        /// </summary>
        private Everest.Interfaces.IInteraction CreatePatientRegistryDuplicatesResolvedMessage(Core.ComponentModel.RegistrationEvent registrationEvent, TargetConfiguration configuration)
        {
            // Construct the return value
            PRPA_IN201304UV02 retVal = new PRPA_IN201304UV02(
                Guid.NewGuid(),
                DateTime.Now,
                PRPA_IN201304UV02.GetInteractionId(),
                ProcessingID.Production,
                "T",
                AcknowledgementCondition.Always);

            // Construct the sending node
            retVal.VersionCode = HL7StandardVersionCode.Version3_Prerelease1;
            retVal.Sender      = CreateSenderNode();
            retVal.Receiver.Add(CreateReceiverNode(configuration));

            // Construct the control act process
            retVal.controlActProcess = new Everest.RMIM.UV.NE2008.MFMI_MT700701UV01.ControlActProcess <Everest.RMIM.UV.NE2008.PRPA_MT201303UV02.Patient, object>("EVN");

            // Get the subjects and components
            var subject      = registrationEvent.FindComponent(SVC.Core.ComponentModel.HealthServiceRecordSiteRoleType.SubjectOf) as Person;
            var providerOrg  = subject.FindComponent(SVC.Core.ComponentModel.HealthServiceRecordSiteRoleType.PlaceOfEntry | SVC.Core.ComponentModel.HealthServiceRecordSiteRoleType.InformantTo) as HealthcareParticipant;
            var custodian    = registrationEvent.FindComponent(SVC.Core.ComponentModel.HealthServiceRecordSiteRoleType.PlaceOfRecord | SVC.Core.ComponentModel.HealthServiceRecordSiteRoleType.ResponsibleFor);
            var replacements = subject.FindAllComponents(SVC.Core.ComponentModel.HealthServiceRecordSiteRoleType.ReplacementOf);

            // Create the person
            List <DomainIdentifier> identifiers = new List <DomainIdentifier>(subject.AlternateIdentifiers.FindAll(o => configuration.NotificationDomain.Exists(d => d.Domain.Equals(o.Domain))));
            var eventRegistration = new Everest.RMIM.UV.NE2008.MFMI_MT700701UV01.Subject1 <Everest.RMIM.UV.NE2008.PRPA_MT201303UV02.Patient, object>(false,
                                                                                                                                                     new Everest.RMIM.UV.NE2008.MFMI_MT700701UV01.RegistrationEvent <Everest.RMIM.UV.NE2008.PRPA_MT201303UV02.Patient, object>(
                                                                                                                                                         ActStatus.Active,
                                                                                                                                                         new Everest.RMIM.UV.NE2008.MFMI_MT700701UV01.Subject2 <Everest.RMIM.UV.NE2008.PRPA_MT201303UV02.Patient>(
                                                                                                                                                             new Everest.RMIM.UV.NE2008.PRPA_MT201303UV02.Patient(
                                                                                                                                                                 CreateIISet(identifiers),
                                                                                                                                                                 RoleStatus.Active,
                                                                                                                                                                 CreatePerson(subject, new TargetConfiguration(String.Empty, null, configuration.Notifier.GetType().Name, null)),
                                                                                                                                                                 providerOrg == null ? null : CreateProviderOrganization(providerOrg)
                                                                                                                                                                 )
                                                                                                                                                             )
                                                                                                                                                         )
                                                                                                                                                     );

            // Get person data
            var personData = eventRegistration.RegistrationEvent.Subject1.registeredRole.PatientEntityChoiceSubject as Everest.RMIM.UV.NE2008.PRPA_MT201303UV02.Person;

            personData.AsOtherIDs.Clear();
            retVal.controlActProcess.Subject.Add(eventRegistration);

            // TODO: Replacement of compatibility mode for other XDS registries
            // Replacement
            var registration = this.Context.GetService(typeof(IDataRegistrationService)) as IDataRegistrationService;
            var persistence  = this.Context.GetService(typeof(IDataPersistenceService)) as IDataPersistenceService;

            foreach (PersonRegistrationRef rplc in replacements)
            {
                // First, need to de-persist the identifiers
                QueryParameters qp = new QueryParameters()
                {
                    Confidence        = 1.0f,
                    MatchingAlgorithm = MatchAlgorithm.Exact,
                    MatchStrength     = MatchStrength.Exact
                };
                var patientQuery           = new QueryEvent();
                RegistrationEvent regEvent = new RegistrationEvent()
                {
                };
                patientQuery.Add(regEvent, "SUBJ", SVC.Core.ComponentModel.HealthServiceRecordSiteRoleType.SubjectOf, null);
                patientQuery.Add(qp, "FLT", SVC.Core.ComponentModel.HealthServiceRecordSiteRoleType.FilterOf, null);
                regEvent.Add(new Person()
                {
                    AlternateIdentifiers = rplc.AlternateIdentifiers
                }, "SUBJ", SVC.Core.ComponentModel.HealthServiceRecordSiteRoleType.SubjectOf, null);
                // Perform the query
                var pid = registration.QueryRecord(patientQuery);
                if (pid.Length == 0)
                {
                    throw new InvalidOperationException();
                }
                var replacedPerson = (persistence.GetContainer(pid[0], true) as RegistrationEvent).FindComponent(SVC.Core.ComponentModel.HealthServiceRecordSiteRoleType.SubjectOf) as Person;

                var ids = CreateIISet(replacedPerson.AlternateIdentifiers.FindAll(o => configuration.NotificationDomain.Exists(d => d.Domain == o.Domain)));
                if (ids.Count == 0)
                {
                    ; // TODO: Trace log
                }
                else
                {
                    eventRegistration.RegistrationEvent.ReplacementOf.Add(new Everest.RMIM.UV.NE2008.MFMI_MT700701UV01.ReplacementOf(
                                                                              new Everest.RMIM.UV.NE2008.MFMI_MT700701UV01.PriorRegistration(
                                                                                  null,
                                                                                  ActStatus.Obsolete,
                                                                                  new Everest.RMIM.UV.NE2008.MFMI_MT700701UV01.Subject3(
                                                                                      new Everest.RMIM.UV.NE2008.MFMI_MT700701UV01.PriorRegisteredRole(
                                                                                          ids
                                                                                          )
                                                                                      ),
                                                                                  null
                                                                                  )
                                                                              ));
                }
            }

            if (eventRegistration.RegistrationEvent.ReplacementOf.Count == 0)
            {
                throw new InvalidOperationException("Nothing to do");
            }

            // Custodian?
            eventRegistration.RegistrationEvent.Custodian = CreateCustodian(registrationEvent, configuration);

            return(retVal);
        }
Exemplo n.º 7
0
        /// <summary>
        /// Store a container
        /// </summary>
        public VersionedDomainIdentifier StoreContainer(System.ComponentModel.IContainer storageData, DataPersistenceMode mode)
        {
            if (m_disposed)
            {
                throw new ObjectDisposedException("DatabasePersistenceService");
            }

            // Merge
            IEnumerable <VersionedDomainIdentifier> pid = null;
            var regEvent = storageData as RegistrationEvent;

            if (this.m_clientRegistryMerge != null && regEvent != null)
            {
                bool fuzzy = false;
                pid = this.m_clientRegistryMerge.FindIdConflicts(regEvent);


                // Do we have a match?
                if (pid.Count() == 0)                                                            // if we didn't find any id conflicts go to fuzzy mode
                {
                    if (this.m_clientRegistryConfiguration.Configuration.Registration.AutoMerge) // we have to do this now :(
                    {
                        fuzzy = true;
                        pid   = this.m_clientRegistryMerge.FindFuzzyConflicts(regEvent);
                        if (pid.Count() == 1)
                        {
                            regEvent.AlternateIdentifier = pid.First();
                            Trace.TraceInformation("Matched with {0} records (fuzzy={1}, autoOn={2}, updateEx={3})",
                                                   pid.Count(), fuzzy, this.m_clientRegistryConfiguration.Configuration.Registration.AutoMerge,
                                                   this.m_clientRegistryConfiguration.Configuration.Registration.UpdateIfExists);
                            return(this.UpdateContainer(regEvent, mode));
                        }
                    }
                }
                else if (this.m_clientRegistryConfiguration.Configuration.Registration.UpdateIfExists)
                {
                    // Update
                    if (pid.Count() == 1)
                    {
                        Trace.TraceInformation("Updating record {0} because it matched by identifier", regEvent.Id);
                        regEvent.AlternateIdentifier = pid.First();
                        return(this.UpdateContainer(regEvent, mode));
                    }
                }
            }
            else
            {
                pid = new List <VersionedDomainIdentifier>();
            }

            //// do a sanity check, have we already persisted this record?
            if (!ValidationSettings.AllowDuplicateRecords)
            {
                var duplicateQuery = new QueryEvent();
                duplicateQuery.Add((storageData as ICloneable).Clone() as HealthServiceRecordContainer, "SUBJ", HealthServiceRecordSiteRoleType.SubjectOf, null);
                duplicateQuery.Add(new QueryParameters()
                {
                    MatchStrength     = Core.ComponentModel.MatchStrength.Exact,
                    MatchingAlgorithm = MatchAlgorithm.Exact
                }, "FLT", HealthServiceRecordSiteRoleType.FilterOf, null);
                var storedRecords = QueryRecord(duplicateQuery as IComponent);
                if (storedRecords.Length != 0)
                {
                    throw new DuplicateNameException(ApplicationContext.LocaleService.GetString("DTPE004"));
                }
            }

            // Get the persister
            IComponentPersister persister = GetPersister(storageData.GetType());

            if (persister != null)
            {
                IDbTransaction tx   = null;
                IDbConnection  conn = null;
                try
                {
                    conn = DatabasePersistenceService.ConnectionManager.GetConnection();
                    tx   = conn.BeginTransaction();

                    var retVal = persister.Persist(conn, tx, storageData as IComponent, false);

                    // Set the mode
                    if (m_configuration.OverridePersistenceMode.HasValue)
                    {
                        mode = m_configuration.OverridePersistenceMode.Value;
                    }

                    // Commit or rollback
                    if (mode == DataPersistenceMode.Production)
                    {
                        tx.Commit();
                        tx = null;

                        // Notify that reconciliation is required and mark merge candidates
                        if (pid.Count() > 0)
                        {
                            this.m_clientRegistryMerge.MarkConflicts(retVal, pid);
                            if (this.m_notificationService != null && pid.Count() != 0)
                            {
                                var list = new List <VersionedDomainIdentifier>(pid)
                                {
                                    retVal
                                };
                                this.m_notificationService.NotifyReconciliationRequired(list);
                            }
                        }
                        else if (this.m_clientRegistryMerge != null)
                        {
                            this.m_threadPool.QueueUserWorkItem(this.MarkConflictsAsync, retVal);
                        }

                        // Notify register
                        if (this.m_notificationService != null && storageData is RegistrationEvent)
                        {
                            this.m_notificationService.NotifyRegister(storageData as RegistrationEvent);
                        }
                    }
                    else
                    {
                        tx.Rollback();
                    }

                    return(retVal);
                }
                catch (Exception e)
                {
                    if (tx != null)
                    {
                        tx.Rollback();
                    }
                    throw;
                }
                finally
                {
                    if (tx != null)
                    {
                        tx.Dispose();
                    }
                    if (conn != null)
                    {
                        DatabasePersistenceService.ConnectionManager.ReleaseConnection(conn);
                        conn = null;
                    }
                }
            }
            else
            {
                Trace.TraceError("Can't find a persistence handler for type '{0}'", storageData.GetType().Name);
                throw new DataException(String.Format("Can't persist type '{0}'", storageData.GetType().Name));
            }
        }