/// <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);
                }
            }
        }
Beispiel #2
0
        /// <summary>
        /// Delete a resource
        /// </summary>
        public DomainResourceBase DeleteResource(string resourceType, string id, string mimeType)
        {
            this.ThrowIfNotReady();

            FhirOperationResult result       = null;
            AuditData           audit        = null;
            IAuditorService     auditService = ApplicationContext.Current.GetService(typeof(IAuditorService)) as IAuditorService;

            try
            {
                // Setup outgoing content/
                WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.NoContent;

                // Create or update?
                var handler = FhirResourceHandlerUtil.GetResourceHandler(resourceType);
                if (handler == null)
                {
                    throw new FileNotFoundException(); // endpoint not found!
                }
                result = handler.Delete(id, TransactionMode.Commit);

                if (result == null || result.Outcome == ResultCode.Rejected)
                {
                    throw new NotSupportedException();
                }
                else if (result.Outcome == ResultCode.TypeNotAvailable)
                {
                    throw new FileNotFoundException(String.Format("Resource {0} not found", WebOperationContext.Current.IncomingRequest.UriTemplateMatch.RequestUri));
                }
                else if (result.Outcome != ResultCode.Accepted)
                {
                    throw new DataException("Delete failed");
                }

                audit = AuditUtil.CreateAuditData(result.Results);

                return(null);
            }
            catch (Exception e)
            {
                audit         = AuditUtil.CreateAuditData(null);
                audit.Outcome = OutcomeIndicator.EpicFail;
                return(this.ErrorHelper(e, result, false) as DomainResourceBase);
            }
            finally
            {
                if (auditService != null)
                {
                    auditService.SendAudit(audit);
                }
            }
        }
        /// <summary>
        /// Resolve an item
        /// </summary>
        /// <param name="sourceId"></param>
        public void Resolve(decimal sourceId)
        {
            // Get all Services
            IAuditorService             auditSvc = ApplicationContext.CurrentContext.GetService(typeof(IAuditorService)) as IAuditorService;
            IClientRegistryMergeService mergeSvc = ApplicationContext.CurrentContext.GetService(typeof(IClientRegistryMergeService)) as IClientRegistryMergeService;

            // Audit message
            AuditData auditMessage = this.ConstructAuditData(ActionType.Update, EventIdentifierType.ApplicationActivity);

            auditMessage.EventTypeCode = new CodeValue("ADM_Resolve");
            try
            {
                // Prepare merge
                VersionedDomainIdentifier resolveId = new VersionedDomainIdentifier()
                {
                    Domain     = ApplicationContext.ConfigurationService.OidRegistrar.GetOid("REG_EVT").Oid,
                    Identifier = sourceId.ToString()
                };

                // Merge
                mergeSvc.MarkResolved(resolveId);


                auditMessage.AuditableObjects.Add(new AuditableObject()
                {
                    IDTypeCode    = AuditableObjectIdType.ReportNumber,
                    LifecycleType = AuditableObjectLifecycle.Verification,
                    ObjectId      = string.Format("{0}^^^&{1}&ISO", resolveId.Identifier, resolveId.Domain),
                    Role          = AuditableObjectRole.Job,
                    Type          = AuditableObjectType.SystemObject
                });
            }
            catch (Exception e)
            {
                auditMessage.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)
                {
                    auditSvc.SendAudit(auditMessage);
                }
            }
        }
Beispiel #4
0
        /// <summary>
        /// Patient registry get identifiers query
        /// </summary>
        /// <param name="e"></param>
        /// <param name="receivedMessage"></param>
        /// <returns></returns>
        private IGraphable PatientRegistryGetIdentifiers(UnsolicitedDataEventArgs e, IReceiveResult receivedMessage)
        {
            // Setup the lists of details and issues
            List <IResultDetail> dtls = new List <IResultDetail>(receivedMessage.Details);

            // System configuration service
            ISystemConfigurationService configService = Context.GetService(typeof(ISystemConfigurationService)) as ISystemConfigurationService;

            // Localization service
            ILocalizationService locale = Context.GetService(typeof(ILocalizationService)) as ILocalizationService;

            // Data Service
            IClientRegistryDataService dataSvc = Context.GetService(typeof(IClientRegistryDataService)) as IClientRegistryDataService;

            // Do basic check and add common validation errors
            MessageUtil.ValidateTransportWrapperUv(receivedMessage.Structure as IInteraction, configService, dtls);

            // Check the request is valid
            var request = receivedMessage.Structure as PRPA_IN201309UV02;

            if (request == null)
            {
                return(null);
            }

            // Determine if the received message was interpreted properly
            bool isValid = MessageUtil.IsValid(receivedMessage);

            // set the URI
            if (request.controlActProcess != null)
            {
                request.controlActProcess.Code = request.controlActProcess.Code ?? Util.Convert <CD <String> >(PRPA_IN201302UV02.GetTriggerEvent());
            }
            if (request.Receiver.Count > 0)
            {
                request.Receiver[0].Telecom = request.Receiver[0].Telecom ?? e.ReceiveEndpoint.ToString();
            }


            // Construct the acknowledgment
            var response = new PRPA_IN201310UV02(
                new II(configService.OidRegistrar.GetOid("CR_MSGID").Oid, Guid.NewGuid().ToString()),
                DateTime.Now,
                PRPA_IN201310UV02.GetInteractionId(),
                request.ProcessingCode,
                request.ProcessingModeCode,
                AcknowledgementCondition.Never,
                MessageUtil.CreateReceiver(request.Sender),
                MessageUtil.CreateSenderUv(e.ReceiveEndpoint, configService),
                null
                );


            // Create the support classes
            AuditData audit = null;

            IheAuditUtil dataUtil = new IheAuditUtil()
            {
                Context = this.Context
            };

            // Try to execute the record
            try
            {
                // Determine if the message is valid
                if (!isValid)
                {
                    throw new MessageValidationException(locale.GetString("MSGE00A"), receivedMessage.Structure);
                }

                // Construct the canonical data structure
                GetIdentifiersQueryResponseFactory fact = new GetIdentifiersQueryResponseFactory()
                {
                    Context = this.Context
                };
                RegistryQueryRequest filter = fact.CreateFilterData(request, dtls);

                if (filter.QueryRequest == null)
                {
                    throw new MessageValidationException(locale.GetString("MSGE00A"), receivedMessage.Structure);
                }

                // Query
                var results = dataSvc.Query(filter);
                dtls.AddRange(results.Details);

                // Prepare for audit
                audit = dataUtil.CreateAuditData("ITI-45",
                                                 ActionType.Execute,
                                                 dtls.Exists(r => r.Type == ResultDetailType.Error) ? OutcomeIndicator.MinorFail : OutcomeIndicator.Success,
                                                 e,
                                                 receivedMessage,
                                                 results,
                                                 filter.QueryRequest.FindComponent(SVC.Core.ComponentModel.HealthServiceRecordSiteRoleType.AuthorOf) as HealthcareParticipant
                                                 );


                response = fact.Create(request, results, dtls) as PRPA_IN201310UV02;
            }
            catch (Exception ex)
            {
                Trace.TraceError(ex.ToString());

                // Prepare for audit
                audit = dataUtil.CreateAuditData("ITI-45", ActionType.Execute, OutcomeIndicator.EpicFail, e, receivedMessage,
                                                 new List <VersionedDomainIdentifier>(),
                                                 null
                                                 );

                dtls.Add(new ResultDetail(ResultDetailType.Error, ex.Message, ex));
                response.Acknowledgement.Add(new MARC.Everest.RMIM.UV.NE2008.MCCI_MT100300UV01.Acknowledgement(
                                                 AcknowledgementType.AcceptAcknowledgementCommitError,
                                                 new MARC.Everest.RMIM.UV.NE2008.MCCI_MT100200UV01.TargetMessage(request.Id)
                                                 ));
            }
            finally
            {
                IAuditorService auditService = Context.GetService(typeof(IAuditorService)) as IAuditorService;
                if (auditService != null)
                {
                    auditService.SendAudit(audit);
                }
            }

            // Common response parameters
            response.ProfileId     = new SET <II>(MCCI_IN000002UV01.GetProfileId());
            response.VersionCode   = HL7StandardVersionCode.Version3_Prerelease1;
            response.AcceptAckCode = AcknowledgementCondition.Never;
            response.Acknowledgement[0].AcknowledgementDetail.AddRange(MessageUtil.CreateAckDetailsUv(dtls.ToArray()));
            return(response);
        }
Beispiel #5
0
        /// <summary>
        /// Handle duplicates resolved message
        /// </summary>
        private IGraphable HandlePatientRegistryDuplicatesResolved(MARC.Everest.Connectors.UnsolicitedDataEventArgs e, MARC.Everest.Connectors.IReceiveResult receivedMessage)
        {
            // Setup the lists of details and issues
            List <IResultDetail> dtls = new List <IResultDetail>(receivedMessage.Details);

            // System configuration service
            ISystemConfigurationService configService = Context.GetService(typeof(ISystemConfigurationService)) as ISystemConfigurationService;

            // Localization service
            ILocalizationService locale = Context.GetService(typeof(ILocalizationService)) as ILocalizationService;

            // Data Service
            IClientRegistryDataService dataSvc = Context.GetService(typeof(IClientRegistryDataService)) as IClientRegistryDataService;

            // Do basic check and add common validation errors
            MessageUtil.ValidateTransportWrapperUv(receivedMessage.Structure as IInteraction, configService, dtls);

            // Check the request is valid
            var request = receivedMessage.Structure as PRPA_IN201304UV02;

            if (request == null)
            {
                return(null);
            }

            // Determine if the received message was interpreted properly
            bool isValid = MessageUtil.IsValid(receivedMessage);

            // set the URI
            if (request.controlActProcess != null)
            {
                request.controlActProcess.Code = request.controlActProcess.Code ?? Util.Convert <CD <String> >(PRPA_IN201302UV02.GetTriggerEvent());
            }
            if (request.Receiver.Count > 0)
            {
                request.Receiver[0].Telecom = request.Receiver[0].Telecom ?? e.ReceiveEndpoint.ToString();
            }

            // Construct the acknowledgment
            var response = new MCCI_IN000002UV01(
                new II(configService.OidRegistrar.GetOid("CR_MSGID").Oid, Guid.NewGuid().ToString()),
                DateTime.Now,
                MCCI_IN000002UV01.GetInteractionId(),
                request.ProcessingCode,
                request.ProcessingModeCode,
                MessageUtil.CreateReceiver(request.Sender),
                MessageUtil.CreateSenderUv(e.ReceiveEndpoint, configService)
                );


            // Create the support classes
            List <AuditData> audits = new List <AuditData>();

            IheAuditUtil dataUtil = new IheAuditUtil()
            {
                Context = this.Context
            };

            // Try to execute the record
            try
            {
                // Determine if the message is valid
                if (!isValid)
                {
                    throw new MessageValidationException(locale.GetString("MSGE00A"), receivedMessage.Structure);
                }

                // Construct the canonical data structure
                UvComponentUtil cu = new UvComponentUtil()
                {
                    Context = this.Context
                };
                RegistrationEvent data = cu.CreateComponents(request.controlActProcess, dtls);

                // Componentization fail?
                if (data == null || !dataUtil.ValidateIdentifiers(data, dtls))
                {
                    throw new MessageValidationException(locale.GetString("MSGE00A"), receivedMessage.Structure);
                }

                // Store
                var result = dataSvc.Merge(data, request.ProcessingCode != ProcessingID.Production ? DataPersistenceMode.Debugging : DataPersistenceMode.Production);

                if (result == null || result.VersionId == null)
                {
                    throw new Exception(locale.GetString("DTPE001"));
                }

                dtls.AddRange(result.Details);

                // prepare the delete audit
                var person = data.FindComponent(SVC.Core.ComponentModel.HealthServiceRecordSiteRoleType.SubjectOf) as Person;
                var replc  = person.FindAllComponents(SVC.Core.ComponentModel.HealthServiceRecordSiteRoleType.ReplacementOf);

                foreach (PersonRegistrationRef rplc in replc)
                {
                    audits.Add(dataUtil.CreateAuditData("ITI-44",
                                                        ActionType.Delete,
                                                        dtls.Exists(r => r.Type == ResultDetailType.Error) ? OutcomeIndicator.MinorFail : OutcomeIndicator.Success,
                                                        e,
                                                        receivedMessage,
                                                        new List <VersionedDomainIdentifier>()
                    {
                        new VersionedDomainIdentifier()
                        {
                            Domain     = rplc.AlternateIdentifiers[0].Domain,
                            Identifier = rplc.AlternateIdentifiers[0].Identifier
                        }
                    },
                                                        data.FindComponent(SVC.Core.ComponentModel.HealthServiceRecordSiteRoleType.AuthorOf) as HealthcareParticipant));
                }


                // Prepare for audit
                audits.Add(dataUtil.CreateAuditData("ITI-44",
                                                    ActionType.Update,
                                                    dtls.Exists(r => r.Type == ResultDetailType.Error) ? OutcomeIndicator.MinorFail : OutcomeIndicator.Success,
                                                    e,
                                                    receivedMessage,
                                                    new List <VersionedDomainIdentifier>()
                {
                    result.VersionId
                },
                                                    data.FindComponent(SVC.Core.ComponentModel.HealthServiceRecordSiteRoleType.AuthorOf) as HealthcareParticipant
                                                    ));

                // Add ack
                response.Acknowledgement.Add(new MARC.Everest.RMIM.UV.NE2008.MCCI_MT100200UV01.Acknowledgement(
                                                 AcknowledgementType.AcceptAcknowledgementCommitAccept,
                                                 new MARC.Everest.RMIM.UV.NE2008.MCCI_MT100200UV01.TargetMessage(request.Id)
                                                 ));
            }
            catch (Exception ex)
            {
                Trace.TraceError(ex.ToString());

                // Prepare for audit
                audits.Add(dataUtil.CreateAuditData("ITI-44", ActionType.Create, OutcomeIndicator.EpicFail, e, receivedMessage,
                                                    new List <VersionedDomainIdentifier>(),
                                                    null
                                                    ));

                dtls.Add(new ResultDetail(ResultDetailType.Error, ex.Message, ex));
                response.Acknowledgement.Add(new MARC.Everest.RMIM.UV.NE2008.MCCI_MT100200UV01.Acknowledgement(
                                                 AcknowledgementType.AcceptAcknowledgementCommitError,
                                                 new MARC.Everest.RMIM.UV.NE2008.MCCI_MT100200UV01.TargetMessage(request.Id)
                                                 ));
            }
            finally
            {
                IAuditorService auditService = Context.GetService(typeof(IAuditorService)) as IAuditorService;
                if (auditService != null)
                {
                    foreach (var aud in audits)
                    {
                        auditService.SendAudit(aud);
                    }
                }
            }

            // Common response parameters
            response.ProfileId     = new SET <II>(MCCI_IN000002UV01.GetProfileId());
            response.VersionCode   = HL7StandardVersionCode.Version3_Prerelease1;
            response.AcceptAckCode = AcknowledgementCondition.Never;
            response.Acknowledgement[0].AcknowledgementDetail.AddRange(MessageUtil.CreateAckDetailsUv(dtls.ToArray()));
            return(response);
        }
Beispiel #6
0
        /// <summary>
        /// Create a resource
        /// </summary>
        public DomainResourceBase CreateResource(string resourceType, string mimeType, DomainResourceBase target)
        {
            this.ThrowIfNotReady();

            FhirOperationResult result = null;

            AuditData       audit        = null;
            IAuditorService auditService = ApplicationContext.Current.GetService(typeof(IAuditorService)) as IAuditorService;

            try
            {
                // Setup outgoing content

                // Create or update?
                var handler = FhirResourceHandlerUtil.GetResourceHandler(resourceType);
                if (handler == null)
                {
                    throw new FileNotFoundException(); // endpoint not found!
                }
                result = handler.Create(target, TransactionMode.Commit);
                WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.Created;

                if (result == null || result.Outcome == ResultCode.Rejected)
                {
                    throw new InvalidDataException("Resource structure is not valid");
                }
                else if (result.Outcome == ResultCode.AcceptedNonConformant)
                {
                    throw new ConstraintException("Resource not conformant");
                }
                else if (result.Outcome == ResultCode.TypeNotAvailable)
                {
                    throw new FileNotFoundException(String.Format("Resource {0} not found", WebOperationContext.Current.IncomingRequest.UriTemplateMatch.RequestUri));
                }
                else if (result.Outcome != ResultCode.Accepted)
                {
                    throw new DataException("Create failed");
                }

                audit = AuditUtil.CreateAuditData(result.Results);

                String baseUri = WebOperationContext.Current.IncomingRequest.UriTemplateMatch.BaseUri.AbsoluteUri;
                WebOperationContext.Current.OutgoingResponse.Headers.Add("Content-Location", String.Format("{0}{1}/{2}/_history/{3}", baseUri, resourceType, result.Results[0].Id, result.Results[0].VersionId));
                WebOperationContext.Current.OutgoingResponse.LastModified = result.Results[0].Timestamp;
                WebOperationContext.Current.OutgoingResponse.ETag         = result.Results[0].VersionId;


                return(result.Results[0]);
            }
            catch (Exception e)
            {
                audit         = AuditUtil.CreateAuditData(null);
                audit.Outcome = OutcomeIndicator.EpicFail;
                return(this.ErrorHelper(e, result, false) as DomainResourceBase);
            }
            finally
            {
                if (auditService != null)
                {
                    auditService.SendAudit(audit);
                }
            }
        }
Beispiel #7
0
        /// <summary>
        /// Handles a received message
        /// </summary>
        public MARC.Everest.Interfaces.IGraphable HandleMessageReceived(object sender, UnsolicitedDataEventArgs e, MARC.Everest.Connectors.IReceiveResult receivedMessage)
        {
            // audit the error
            IAuditorService auditor = Context.GetService(typeof(IAuditorService)) as IAuditorService;
            AuditData       ad      = new AuditData(
                DateTime.Now, ActionType.Execute, OutcomeIndicator.EpicFail, EventIdentifierType.ApplicationActivity, new CodeValue(String.Format("{0}", receivedMessage.Structure))
                );

            ad.Actors.AddRange(new List <AuditActorData>(10)
            {
                new AuditActorData()
                {
                    NetworkAccessPointId = e.ReceiveEndpoint.ToString(), NetworkAccessPointType = NetworkAccessPointType.IPAddress, UserIsRequestor = false
                },
                new AuditActorData()
                {
                    NetworkAccessPointType = NetworkAccessPointType.MachineName, NetworkAccessPointId = Environment.MachineName, UserIsRequestor = false
                }
            }
                               );
            ad.AuditableObjects.Add(new AuditableObject()
            {
                IDTypeCode = AuditableObjectIdType.ReportNumber, LifecycleType = AuditableObjectLifecycle.Verification, ObjectId = (receivedMessage.Structure as IIdentifiable).Id.Root, Role = AuditableObjectRole.Subscriber, Type = AuditableObjectType.SystemObject
            });
            if (auditor != null)
            {
                auditor.SendAudit(ad);
            }

            IInteraction solicitation = receivedMessage.Structure as IInteraction;

            // get the configuration
            ISystemConfigurationService configService = Context.GetService(typeof(ISystemConfigurationService)) as ISystemConfigurationService;

            // construct a generic response
            MCCI_IN000002CA response = new MCCI_IN000002CA(
                Guid.NewGuid(),
                DateTime.Now,
                new CV <ResponseMode>(ResponseMode.Immediate),
                MCCI_IN000002CA.GetInteractionId(),
                MCCI_IN000002CA.GetProfileId(),
                ProcessingID.Debugging,
                AcknowledgementCondition.Never,
                null,
                MessageUtil.CreateSender(e.ReceiveEndpoint, configService),
                new Acknowledgement(
                    AcknowledgementType.ApplicationAcknowledgementReject,
                    new TargetMessage(
                        (receivedMessage.Structure as IIdentifiable).Id
                        )
                    )
                );

            // Add a detail
            if (solicitation.InteractionId != null && solicitation.InteractionId.Extension != receivedMessage.Structure.GetType().Name)
            {
                response.Acknowledgement.AcknowledgementDetail.Add(
                    new AcknowledgementDetail(
                        AcknowledgementDetailType.Error,
                        Util.ToWireFormat(MARC.Everest.RMIM.CA.R020402.Vocabulary.AcknowledgementDetailCode.ValueDoesNotMatchFixedValue),
                        String.Format("Interaction ID '{0}' not supported for message type '{1}'", solicitation.InteractionId.Extension, receivedMessage.Structure.GetType().Name),
                        null));
            }
            else
            {
                response.Acknowledgement.AcknowledgementDetail.Add(
                    new AcknowledgementDetail(
                        AcknowledgementDetailType.Error,
                        Util.ToWireFormat(MARC.Everest.RMIM.CA.R020402.Vocabulary.AcknowledgementDetailCode.UnsupportedInteraction),
                        "Cannot process this interaction",
                        null)
                    );
            }

            // Validation detils
            response.Acknowledgement.AcknowledgementDetail.AddRange(MessageUtil.CreateGenAckDetails(receivedMessage.Details));

            // Populate the receiver
            Sender   originalSolicitor = solicitation.GetType().GetProperty("Sender").GetValue(solicitation, null) as Sender;
            Receiver receiver          = MessageUtil.CreateReceiver(originalSolicitor);

            response.Receiver = receiver;

            return(response);
        }
        /// <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);
                }
            }
        }
Beispiel #11
0
        /// <summary>
        /// Handle a PIX query
        /// </summary>
        private IMessage HandlePixQuery(NHapi.Model.V25.Message.QBP_Q21 request, Hl7MessageReceivedEventArgs evt)
        {
            // Get config
            var config      = this.Context.GetService(typeof(ISystemConfigurationService)) as ISystemConfigurationService;
            var locale      = this.Context.GetService(typeof(ILocalizationService)) as ILocalizationService;
            var dataService = this.Context.GetService(typeof(IClientRegistryDataService)) as IClientRegistryDataService;

            // Create a details array
            List <IResultDetail> dtls = new List <IResultDetail>();

            // Validate the inbound message
            MessageUtil.Validate((IMessage)request, config, dtls, this.Context);

            IMessage response = null;

            // Control
            if (request == null)
            {
                return(null);
            }

            // Construct appropriate audit
            AuditData audit = null;

            // Data controller
            AuditUtil auditUtil = new AuditUtil()
            {
                Context = this.Context
            };

            //DataUtil dataUtil = new DataUtil() { Context = this.Context };

            try
            {
                // Create Query Data
                ComponentUtility cu = new ComponentUtility()
                {
                    Context = this.Context
                };
                DeComponentUtility dcu = new DeComponentUtility()
                {
                    Context = this.Context
                };
                var data = cu.CreateQueryComponents(request, dtls);

                if (data == null)
                {
                    throw new InvalidOperationException(locale.GetString("MSGE00A"));
                }


                RegistryQueryResult result = dataService.Query(data);
                dtls.AddRange(result.Details);

                // Update locations?
                foreach (var dtl in dtls)
                {
                    if (dtl is PatientNotFoundResultDetail)
                    {
                        dtl.Location = "QPD^1^3^1^1";
                    }
                    else if (dtl is UnrecognizedPatientDomainResultDetail)
                    {
                        dtl.Location = "QPD^1^3^1^4";
                    }
                    else if (dtl is UnrecognizedTargetDomainResultDetail)
                    {
                        dtl.Location = "QPD^1^4^";
                    }
                }


                audit = auditUtil.CreateAuditData("ITI-9", ActionType.Execute, OutcomeIndicator.Success, evt, result);

                // Now process the result
                response = dcu.CreateRSP_K23(result, dtls);
                //var r = dcu.CreateRSP_K23(null, null);
                // Copy QPD
                try
                {
                    (response as NHapi.Model.V25.Message.RSP_K23).QPD.MessageQueryName.Identifier.Value = request.QPD.MessageQueryName.Identifier.Value;
                    Terser reqTerser = new Terser(request),
                           rspTerser = new Terser(response);
                    rspTerser.Set("/QPD-1", reqTerser.Get("/QPD-1"));
                    rspTerser.Set("/QPD-2", reqTerser.Get("/QPD-2"));
                    rspTerser.Set("/QPD-3-1", reqTerser.Get("/QPD-3-1"));
                    rspTerser.Set("/QPD-3-4-1", reqTerser.Get("/QPD-3-4-1"));
                    rspTerser.Set("/QPD-3-4-2", reqTerser.Get("/QPD-3-4-2"));
                    rspTerser.Set("/QPD-3-4-3", reqTerser.Get("/QPD-3-4-3"));
                    rspTerser.Set("/QPD-4-1", reqTerser.Get("/QPD-4-1"));
                    rspTerser.Set("/QPD-4-4-1", reqTerser.Get("/QPD-4-4-1"));
                    rspTerser.Set("/QPD-4-4-2", reqTerser.Get("/QPD-4-4-2"));
                    rspTerser.Set("/QPD-4-4-3", reqTerser.Get("/QPD-4-4-3"));
                }
                catch (Exception e)
                {
                    Trace.TraceError(e.ToString());
                }
                //MessageUtil.((response as NHapi.Model.V25.Message.RSP_K23).QPD, request.QPD);

                MessageUtil.UpdateMSH(new NHapi.Base.Util.Terser(response), request, config);
            }
            catch (Exception e)
            {
                Trace.TraceError(e.ToString());
                if (!dtls.Exists(o => o is UnrecognizedPatientDomainResultDetail || o is UnrecognizedTargetDomainResultDetail || o.Message == e.Message || o.Exception == e))
                {
                    dtls.Add(new ResultDetail(ResultDetailType.Error, e.Message, e));
                }
                response = MessageUtil.CreateNack(request, dtls, this.Context, typeof(RSP_K23));
                Terser errTerser = new Terser(response);
                // HACK: Fix the generic ACK with a real ACK for this message
                errTerser.Set("/MSH-9-2", "K23");
                errTerser.Set("/MSH-9-3", "RSP_K23");
                errTerser.Set("/QAK-2", "AE");
                errTerser.Set("/MSA-1", "AE");
                errTerser.Set("/QAK-1", request.QPD.QueryTag.Value);
                audit = auditUtil.CreateAuditData("ITI-9", ActionType.Execute, OutcomeIndicator.EpicFail, evt, new List <VersionedDomainIdentifier>());
            }
            finally
            {
                IAuditorService auditSvc = this.Context.GetService(typeof(IAuditorService)) as IAuditorService;
                if (auditSvc != null)
                {
                    auditSvc.SendAudit(audit);
                }
            }

            return(response);
        }
Beispiel #12
0
        /// <summary>
        /// Handle a PIX admission
        /// </summary>
        private IMessage HandlePixAdmit(NHapi.Model.V231.Message.ADT_A01 request, Hl7MessageReceivedEventArgs evt)
        {
            // Get config
            var config      = this.Context.GetService(typeof(ISystemConfigurationService)) as ISystemConfigurationService;
            var locale      = this.Context.GetService(typeof(ILocalizationService)) as ILocalizationService;
            var dataService = this.Context.GetService(typeof(IClientRegistryDataService)) as IClientRegistryDataService;
            // Create a details array
            List <IResultDetail> dtls = new List <IResultDetail>();

            // Validate the inbound message
            MessageUtil.Validate((IMessage)request, config, dtls, this.Context);

            IMessage response = null;

            // Control
            if (request == null)
            {
                return(null);
            }

            // Data controller
            AuditUtil auditUtil = new AuditUtil()
            {
                Context = this.Context
            };
            //DataUtil dataUtil = new DataUtil() { Context = this.Context };

            // Construct appropriate audit
            AuditData audit = null;

            try
            {
                // Create Query Data
                ComponentUtility cu = new ComponentUtility()
                {
                    Context = this.Context
                };
                DeComponentUtility dcu = new DeComponentUtility()
                {
                    Context = this.Context
                };
                var data = cu.CreateComponents(request, dtls);
                if (data == null)
                {
                    throw new InvalidOperationException(locale.GetString("MSGE00A"));
                }

                var result = dataService.Register(data, request.MSH.ProcessingID.ProcessingID.Value == "P" ? DataPersistenceMode.Production : DataPersistenceMode.Debugging);
                if (result == null || result.VersionId == null)
                {
                    throw new InvalidOperationException(locale.GetString("DTPE001"));
                }

                dtls.AddRange(result.Details);

                audit = auditUtil.CreateAuditData("ITI-8", result.VersionId.UpdateMode == UpdateModeType.Update ? ActionType.Update : ActionType.Create, OutcomeIndicator.Success, evt, new List <VersionedDomainIdentifier>()
                {
                    result.VersionId
                });

                // Now process the result
                response = MessageUtil.CreateNack(request, dtls, this.Context, typeof(NHapi.Model.V231.Message.ACK));
                MessageUtil.UpdateMSH(new NHapi.Base.Util.Terser(response), request, config);
                (response as NHapi.Model.V231.Message.ACK).MSH.MessageType.TriggerEvent.Value = request.MSH.MessageType.TriggerEvent.Value;
                (response as NHapi.Model.V231.Message.ACK).MSH.MessageType.MessageType.Value  = "ACK";
            }
            catch (Exception e)
            {
                Trace.TraceError(e.ToString());
                if (!dtls.Exists(o => o.Message == e.Message || o.Exception == e))
                {
                    dtls.Add(new ResultDetail(ResultDetailType.Error, e.Message, e));
                }
                response = MessageUtil.CreateNack(request, dtls, this.Context, typeof(NHapi.Model.V231.Message.ACK));
                audit    = auditUtil.CreateAuditData("ITI-8", ActionType.Create, OutcomeIndicator.EpicFail, evt, new List <VersionedDomainIdentifier>());
            }
            finally
            {
                IAuditorService auditSvc = this.Context.GetService(typeof(IAuditorService)) as IAuditorService;
                if (auditSvc != null)
                {
                    auditSvc.SendAudit(audit);
                }
            }
            return(response);
        }
Beispiel #13
0
        /// <summary>
        /// Handle the PIX merge request
        /// </summary>
        private IMessage HandlePixMerge(NHapi.Model.V231.Message.ADT_A39 request, Hl7MessageReceivedEventArgs evt)
        {
            // Get config
            var config      = this.Context.GetService(typeof(ISystemConfigurationService)) as ISystemConfigurationService;
            var locale      = this.Context.GetService(typeof(ILocalizationService)) as ILocalizationService;
            var dataService = this.Context.GetService(typeof(IClientRegistryDataService)) as IClientRegistryDataService;

            // Create a details array
            List <IResultDetail> dtls = new List <IResultDetail>();

            // Validate the inbound message
            MessageUtil.Validate((IMessage)request, config, dtls, this.Context);

            IMessage response = null;

            // Control
            if (request == null)
            {
                return(null);
            }

            // Data controller
            //DataUtil dataUtil = new DataUtil() { Context = this.Context };
            AuditUtil auditUtil = new AuditUtil()
            {
                Context = this.Context
            };

            // Construct appropriate audit
            List <AuditData> audit = new List <AuditData>();

            try
            {
                // Create Query Data
                ComponentUtility cu = new ComponentUtility()
                {
                    Context = this.Context
                };
                DeComponentUtility dcu = new DeComponentUtility()
                {
                    Context = this.Context
                };
                var data = cu.CreateComponents(request, dtls);
                if (data == null)
                {
                    throw new InvalidOperationException(locale.GetString("MSGE00A"));
                }

                // Merge
                var result = dataService.Merge(data, request.MSH.ProcessingID.ProcessingID.Value == "P" ? DataPersistenceMode.Production : DataPersistenceMode.Debugging);

                if (result == null || result.VersionId == null)
                {
                    throw new InvalidOperationException(locale.GetString("DTPE001"));
                }

                List <VersionedDomainIdentifier> deletedRecordIds = new List <VersionedDomainIdentifier>(),
                                                 updatedRecordIds = new List <VersionedDomainIdentifier>();

                // Subjects
                var oidData = config.OidRegistrar.GetOid("CR_CID").Oid;
                foreach (Person subj in data.FindAllComponents(SVC.Core.ComponentModel.HealthServiceRecordSiteRoleType.SubjectOf))
                {
                    PersonRegistrationRef replcd = subj.FindComponent(SVC.Core.ComponentModel.HealthServiceRecordSiteRoleType.ReplacementOf) as PersonRegistrationRef;
                    deletedRecordIds.Add(new VersionedDomainIdentifier()
                    {
                        Identifier = replcd.Id.ToString(),
                        Domain     = oidData
                    });
                    updatedRecordIds.Add(new VersionedDomainIdentifier()
                    {
                        Identifier = subj.Id.ToString(),
                        Domain     = oidData
                    });
                }

                // Now audit
                audit.Add(auditUtil.CreateAuditData("ITI-8", ActionType.Delete, OutcomeIndicator.Success, evt, deletedRecordIds));
                audit.Add(auditUtil.CreateAuditData("ITI-8", ActionType.Update, OutcomeIndicator.Success, evt, updatedRecordIds));
                // Now process the result
                response = MessageUtil.CreateNack(request, dtls, this.Context, typeof(NHapi.Model.V231.Message.ACK));
                MessageUtil.UpdateMSH(new NHapi.Base.Util.Terser(response), request, config);
                (response as NHapi.Model.V231.Message.ACK).MSH.MessageType.TriggerEvent.Value = request.MSH.MessageType.TriggerEvent.Value;
                (response as NHapi.Model.V231.Message.ACK).MSH.MessageType.MessageType.Value  = "ACK";
            }
            catch (Exception e)
            {
                Trace.TraceError(e.ToString());
                if (!dtls.Exists(o => o.Message == e.Message || o.Exception == e))
                {
                    dtls.Add(new ResultDetail(ResultDetailType.Error, e.Message, e));
                }
                response = MessageUtil.CreateNack(request, dtls, this.Context, typeof(NHapi.Model.V231.Message.ACK));
                audit.Add(auditUtil.CreateAuditData("ITI-8", ActionType.Delete, OutcomeIndicator.EpicFail, evt, new List <VersionedDomainIdentifier>()));
            }
            finally
            {
                IAuditorService auditSvc = this.Context.GetService(typeof(IAuditorService)) as IAuditorService;
                if (auditSvc != null)
                {
                    foreach (var aud in audit)
                    {
                        auditSvc.SendAudit(aud);
                    }
                }
            }
            return(response);
        }
Beispiel #14
0
        /// <summary>
        /// Fired whenever a message is available for processing
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void connector_MessageAvailable(object sender, UnsolicitedDataEventArgs e)
        {
            // Audit service
            IAuditorService auditService = Context.GetService(typeof(IAuditorService)) as IAuditorService;

            #region Setup Audit
            AuditData audit = new AuditData(
                DateTime.Now, ActionType.Execute,
                OutcomeIndicator.Success,
                EventIdentifierType.ApplicationActivity,
                new AuditCode("GEN", null)
                );
            audit.Actors.Add(new AuditActorData()
            {
                NetworkAccessPointId   = Environment.MachineName,
                NetworkAccessPointType = NetworkAccessPointType.MachineName,
                UserIdentifier         = String.Format("{0}\\{1}", Environment.UserDomainName, Environment.UserName)
            });
            audit.Actors.Add(new AuditActorData()
            {
                UserIsRequestor        = true,
                NetworkAccessPointId   = e.SolicitorEndpoint.ToString(),
                NetworkAccessPointType = NetworkAccessPointType.IPAddress,
                UserIdentifier         = e.SolicitorEndpoint.ToString()
            });
            audit.AuditableObjects.Add(new AuditableObject()
            {
                IDTypeCode    = AuditableObjectIdType.Uri,
                LifecycleType = AuditableObjectLifecycle.Access,
                Role          = AuditableObjectRole.DataRepository,
                ObjectId      = e.ReceiveEndpoint.ToString(),
                Type          = AuditableObjectType.SystemObject
            });
            #endregion

            try
            {
                // Find a receiver capable of processing this
                var            wcfConnector = (sender as IListenWaitConnector);
                IReceiveResult rcvResult    = wcfConnector.Receive();

                // get the persistence service from the context
                IMessagePersistenceService persistenceService = Context.GetService(typeof(IMessagePersistenceService)) as IMessagePersistenceService;

                // Were we able to process the message
                Assembly messageTypeAssembly = null;
                if (rcvResult.Structure != null)
                {
                    messageTypeAssembly = rcvResult.Structure.GetType().Assembly;
                }

                // Find the configuration section that handles the specified revision
                var curRevision = m_configuration.Revisions.Find(o => o.Listeners.Exists(l => l.ConnectionString == wcfConnector.ConnectionString));
                if (curRevision == null)
                {
                    Trace.TraceError("This service does not seem to have support for the version of message being used");
                    throw new UninterpretableMessageException("This service doesn't support this standard", rcvResult);
                }

                // Do we have a handler for this message interaction? Cast as an interaction
                // and attempt to find the handler configuration
                IInteraction interactionStructure          = rcvResult.Structure as IInteraction;
                MessageHandlerConfiguration receiverConfig = null;
                if (interactionStructure != null && interactionStructure.InteractionId != null &&
                    !String.IsNullOrEmpty(interactionStructure.InteractionId.Extension))
                {
                    receiverConfig = curRevision.MessageHandlers.Find(o => o.Interactions.Exists(i => i.Id == interactionStructure.InteractionId.Extension));
                }
                else
                {
                    Trace.TraceWarning("Interaction is missing InteractionId attribute! Assuming default");
                    // Set interaction id
                    var intId = interactionStructure.GetType().GetMethod("GetInteractionId", BindingFlags.Static | BindingFlags.Public);
                    if (intId == null)
                    {
                        throw new InvalidOperationException("Cannot find the GetInteractionId method, cannot determine interaction");
                    }
                    interactionStructure.InteractionId = intId.Invoke(null, null) as II;
                }

                // Message identifier missing?
                if (interactionStructure.Id == null)
                {
                    interactionStructure.Id = Guid.NewGuid();
                    Trace.TraceWarning("Interaction is missing id. Generated token {0}...", interactionStructure.Id.Root);
                }

                IEverestMessageReceiver currentHandler = null, defaultHandler = null;

                var defaultHandlerConfig = curRevision.MessageHandlers.Find(o => o.Interactions.Exists(i => i.Id == "*"));
                receiverConfig = receiverConfig ?? defaultHandlerConfig; // find a handler

                // Receiver configuration
                if (receiverConfig == null)
                {
                    throw new InvalidOperationException("Cannot find appropriate handler this message");
                }
                else
                {
                    var          messageState = Core.Services.MessageState.New;
                    IInteraction response     = null;

                    InteractionConfiguration interactionConfig = receiverConfig.Interactions.Find(o => o.Id == interactionStructure.InteractionId.Extension);
                    if (interactionConfig != null && interactionConfig.Disclosure)
                    {
                        persistenceService = null;
                    }

                    // check with persistence
                    if (persistenceService != null)
                    {
                        messageState = persistenceService.GetMessageState(String.Format(curRevision.MessageIdentifierFormat, interactionStructure.Id.Root, interactionStructure.Id.Extension));
                    }

                    switch (messageState)
                    {
                    case Core.Services.MessageState.New:

                        // Persist the message
                        if (persistenceService != null)
                        {
                            MemoryStream ms = new MemoryStream();
                            try
                            {
                                WriteMessageToStream(sender as IFormattedConnector, interactionStructure, ms);
                                persistenceService.PersistMessage(String.Format(curRevision.MessageIdentifierFormat, interactionStructure.Id.Root, interactionStructure.Id.Extension), ms);
                            }
                            finally
                            {
                                ms.Dispose();
                            }
                        }

                        currentHandler = receiverConfig.Handler;
                        defaultHandler = defaultHandlerConfig.Handler;
                        response       = currentHandler.HandleMessageReceived(sender, e, rcvResult) as IInteraction;
                        if (persistenceService != null)
                        {
                            MemoryStream ms = new MemoryStream();
                            try
                            {
                                WriteMessageToStream(sender as IFormattedConnector, response, ms);
                                persistenceService.PersistResultMessage(String.Format(curRevision.MessageIdentifierFormat, response.Id.Root, response.Id.Extension), String.Format(curRevision.MessageIdentifierFormat, interactionStructure.Id.Root, interactionStructure.Id.Extension), ms);
                            }
                            finally
                            {
                                ms.Dispose();
                            }
                        }

                        break;

                    case Core.Services.MessageState.Complete:
                        var rms         = persistenceService.GetMessageResponseMessage(String.Format(curRevision.MessageIdentifierFormat, interactionStructure.Id.Root, interactionStructure.Id.Extension));
                        var parseResult = (sender as IFormattedConnector).Formatter.Parse(rms);
                        response = parseResult.Structure as IInteraction;
                        break;

                    case Core.Services.MessageState.Active:
                        throw new ApplicationException("Message is already being processed");
                    }
                    // Send back
                    IListenWaitRespondConnector ilwConnector = sender as IListenWaitRespondConnector;
                    if (ilwConnector == null) // no need to send something back
                    {
                        auditService.SendAudit(audit);
                        return;
                    }
                    else
                    {
                        // Invalid message delegate
                        var invalidMessageDelegate = new EventHandler <MessageEventArgs>(delegate(object sndr, MessageEventArgs mea)
                        {
                            audit.Outcome            = OutcomeIndicator.MinorFail;
                            InvalidMessageResult res = new InvalidMessageResult()
                            {
                                Code      = mea.Code,
                                Details   = mea.Details,
                                Structure = rcvResult.Structure
                            };
                            if (defaultHandler != null)
                            {
                                mea.Alternate = response;
                            }
                            Trace.TraceWarning("Returning a default message because Everest was unable to serialize the response correctly. Error was {0}", mea.Code);
                            Trace.Indent();
                            foreach (IResultDetail dtl in mea.Details)
                            {
                                Trace.TraceWarning("{0} : {1} : {2}", dtl.Type, dtl.Message, dtl.Location);
                            }
                            Trace.Unindent();
                            mea.Alternate = response;
                        });
                        ilwConnector.InvalidResponse += invalidMessageDelegate;

                        try
                        {
                            // Create headers
                            var wcfResult = rcvResult as WcfReceiveResult;
                            if (wcfResult != null && wcfResult.Headers != null)
                            {
                                var rcvrInfo = receiverConfig.Interactions.Find(o => o.Id == interactionStructure.InteractionId.Extension);
                                if (rcvrInfo != null)
                                {
                                    wcfResult.ResponseHeaders = CreateResponseHeaders(rcvrInfo.ResponseHeaders, wcfResult.Headers.MessageVersion);
                                }
                                if (wcfResult.ResponseHeaders != null)
                                {
                                    wcfResult.ResponseHeaders.RelatesTo = wcfResult.Headers.MessageId;
                                }
                            }
                            ISendResult sndResult = ilwConnector.Send(response, rcvResult);
                            if (sndResult.Code != ResultCode.Accepted &&
                                sndResult.Code != ResultCode.AcceptedNonConformant)
                            {
                                Trace.TraceError("Cannot send response back to the solicitor : {0}", sndResult.Code);
                                Trace.Indent();
                                foreach (IResultDetail dtl in sndResult.Details ?? new IResultDetail[0])
                                {
                                    Trace.TraceError("{0}: {1} : {2}", dtl.Type, dtl.Message, dtl.Location);
                                }
                                Trace.Unindent();
                            }
                        }
                        finally
                        {
                            if (auditService != null)
                            {
                                auditService.SendAudit(audit);
                            }
                            // Remove the invalid message delegate
                            ilwConnector.InvalidResponse -= invalidMessageDelegate;
                        }
                    }
                }
            }
            catch (System.Exception ex)
            {
                #region Audit Failure
                audit.Outcome = OutcomeIndicator.EpicFail;

                if (auditService != null)
                {
                    auditService.SendAudit(audit);
                }
                #endregion

                Trace.TraceError(ex.ToString());
                throw;
            }
        }
Beispiel #15
0
        /// <summary>
        /// Handle the pdq query
        /// </summary>
        private IMessage HandlePdqQuery(QBP_Q21 request, Hl7MessageReceivedEventArgs evt)
        {
            // Get config
            var config      = this.Context.GetService(typeof(ISystemConfigurationService)) as ISystemConfigurationService;
            var locale      = this.Context.GetService(typeof(ILocalizationService)) as ILocalizationService;
            var dataService = this.Context.GetService(typeof(IClientRegistryDataService)) as IClientRegistryDataService;

            // Create a details array
            List <IResultDetail> dtls = new List <IResultDetail>();

            // Validate the inbound message
            MessageUtil.Validate((IMessage)request, config, dtls, this.Context);

            IMessage response = null;

            // Control
            if (request == null)
            {
                return(null);
            }


            // Data controller
            //DataUtil dataUtil = new DataUtil() { Context = this.Context };
            AuditUtil auditUtil = new AuditUtil()
            {
                Context = this.Context
            };
            // Construct appropriate audit
            AuditData audit = null;

            try
            {
                // Create Query Data
                ComponentUtility cu = new ComponentUtility()
                {
                    Context = this.Context
                };
                DeComponentUtility dcu = new DeComponentUtility()
                {
                    Context = this.Context
                };
                var data = cu.CreateQueryComponentsPdq(request, dtls);
                if (data == null)
                {
                    Trace.TraceError("{0} problems mapping message:", dtls.Count);
                    foreach (var itm in dtls)
                    {
                        Trace.TraceError($"\t{itm.Type} : {itm.Message}");
                    }
                    throw new InvalidOperationException();// locale?.GetString("MSGE00A") ?? "Could not process components");
                }

                // Is this a continue or new query?
                RegistryQueryResult result = dataService.Query(data);

                audit = auditUtil.CreateAuditData("ITI-21", ActionType.Execute, OutcomeIndicator.Success, evt, result);

                // Now process the result
                response = dcu.CreateRSP_K21(result, data, dtls);
                //MessageUtil.CopyQPD((response as RSP_K21).QPD, request.QPD, data);
                MessageUtil.UpdateMSH(new NHapi.Base.Util.Terser(response), request, config);
                Terser ters = new Terser(response);
                ters.Set("/MSH-9-2", "K22");
            }
            catch (Exception e)
            {
                Trace.TraceError(e.ToString());


                if (!dtls.Exists(o => o.Message == e.Message || o.Exception == e))
                {
                    if (dtls.Count == 0)
                    {
                        dtls.Add(new ResultDetail(ResultDetailType.Error, e.Message, e));
                    }
                }
                // HACK: Only one error allowed in nHAPI for some reason :
                // TODO: Fix NHapi
                dtls.RemoveAll(o => o.Type != ResultDetailType.Error);
                while (dtls.Count > 1)
                {
                    dtls.RemoveAt(1);
                }
                response = MessageUtil.CreateNack(request, dtls, this.Context, typeof(RSP_K21));

                Terser errTerser = new Terser(response);
                // HACK: Fix the generic ACK with a real ACK for this message
                errTerser.Set("/MSH-9-2", "K22");
                errTerser.Set("/MSH-9-3", "RSP_K21");
                errTerser.Set("/QAK-2", "AE");
                errTerser.Set("/MSA-1", "AE");
                errTerser.Set("/QAK-1", request.QPD.QueryTag.Value);
                audit = auditUtil.CreateAuditData("ITI-21", ActionType.Execute, OutcomeIndicator.EpicFail, evt, new List <VersionedDomainIdentifier>());
            }
            finally
            {
                IAuditorService auditSvc = this.Context.GetService(typeof(IAuditorService)) as IAuditorService;
                if (auditSvc != null)
                {
                    auditSvc.SendAudit(audit);
                }
            }

            return(response);
        }