コード例 #1
0
 /// <summary>
 /// Represents the bundle operation
 /// </summary>
 protected void AdtPatientRegistrationInterceptor_Bundle(object sender, DataPersistedEventArgs <Bundle> e)
 {
     foreach (var itm in e.Data.Item.Where(o => !e.Data.ExpansionKeys.Contains(o.Key.Value)).OfType <Patient>())
     {
         AdtPatientRegistrationInterceptor_Behavior(sender, new DataPersistedEventArgs <Patient>(itm, e.Principal));
     }
 }
コード例 #2
0
        /// <summary>
        /// Notify inserted
        /// </summary>
        protected override void OnInserted(object sender, DataPersistedEventArgs <Bundle> evt)
        {
            foreach (var itm in evt.Data.Item.Where(i => evt.Data.FocalObjects.Contains(i.Key.Value)))
            {
                PubSubNotifyQueueEntry queueEntry = null;

                switch (itm.BatchOperation)
                {
                case Model.DataTypes.BatchOperationType.Auto:
                case Model.DataTypes.BatchOperationType.InsertOrUpdate:
                case Model.DataTypes.BatchOperationType.Insert:
                    queueEntry = new PubSubNotifyQueueEntry(itm.GetType(), PubSubEventType.Create, itm);
                    break;

                case Model.DataTypes.BatchOperationType.Update:
                    queueEntry = new PubSubNotifyQueueEntry(itm.GetType(), PubSubEventType.Update, itm);
                    break;

                case Model.DataTypes.BatchOperationType.Delete:
                    queueEntry = new PubSubNotifyQueueEntry(itm.GetType(), PubSubEventType.Delete, itm);
                    break;
                }

                this.m_queue.Enqueue(PubSubBroker.QueueName, queueEntry);
            }
        }
コード例 #3
0
        /// <summary>
        /// Obsoletes the specified storage data.
        /// </summary>
        /// <param name="storageData">The storage data.</param>
        /// <param name="overrideAuthContext">The principal to use instead of the default.</param>
        /// <param name="mode">The mode.</param>
        /// <returns>TModel.</returns>
        public TModel Obsolete(TModel storageData, TransactionMode mode, IPrincipal overrideAuthContext = null)
        {
            if (storageData == null)
            {
                throw new ArgumentNullException(nameof(storageData), "Value cannot be null");
            }

            if (!storageData.Key.HasValue || storageData.Key == Guid.Empty)
            {
                throw new InvalidOperationException("Data missing key");
            }

            var prePersistenceEventArgs = new DataPersistingEventArgs <TModel>(storageData, overrideAuthContext);

            this.Obsoleting?.Invoke(this, prePersistenceEventArgs);

            if (prePersistenceEventArgs.Cancel)
            {
                traceSource.TraceEvent(EventLevel.Warning, $"Pre-event handler indicates abort for {storageData}");
                return(storageData);
            }

            using (var connection = Configuration.Provider.GetWriteConnection())
            {
                connection.Open();

                using (var transaction = connection.BeginTransaction())
                {
                    try
                    {
                        this.traceSource.TraceEvent(EventLevel.Verbose, $"OBSOLETE {storageData}");

                        storageData = this.Obsolete(connection, storageData);

                        if (mode == TransactionMode.Commit)
                        {
                            transaction.Commit();
                        }
                        else
                        {
                            transaction.Rollback();
                        }

                        var args = new DataPersistedEventArgs <TModel>(storageData, overrideAuthContext);

                        this.Obsoleted?.Invoke(this, args);

                        return(storageData);
                    }
                    catch (Exception e)
                    {
                        traceSource.TraceEvent(EventLevel.Error, $"Error obsoleting: {storageData}");
                        transaction.Rollback();
                        throw new DataPersistenceException(e.Message, e);
                    }
                }
            }
        }
コード例 #4
0
        /// <summary>
        /// Recheck the bundle trigger to ensure the relationships make sense
        /// </summary>
        private void RecheckBundleTrigger(object sender, DataPersistedEventArgs <Bundle> e)
        {
            foreach (var itm in e.Data.Item.OfType <ITargetedVersionedExtension>())
            {
                this.RecheckRelationship(itm, e.Mode, e.Principal);
            }

            // Remove dependent objects from cache
            foreach (var itm in e.Data.Item.OfType <IHasRelationships>())
            {
                foreach (var rel in itm.Relationships.OfType <ITargetedVersionedExtension>())
                {
                    this.RecheckRelationship(rel, e.Mode, e.Principal);
                }
            }
        }
コード例 #5
0
        /// <summary>
        /// Represents when the ADT registration occurs
        /// </summary>
        protected void AdtPatientRegistrationInterceptor_Behavior(object sender, DataPersistedEventArgs <Patient> e)
        {
            ApplicationServiceContext.Current.GetService <IThreadPoolService>().QueueNonPooledWorkItem(
                (p) =>
            {
                AuthenticationContext.Current = new AuthenticationContext(AuthenticationContext.SystemPrincipal);

                Patient pat = p as Patient;
                // We want to construct an ADT message if (and only if) the guards are met and if the last ADT was not this version
                var tag = pat.LoadCollection <EntityTag>("Tags").FirstOrDefault(o => o.TagKey == TagName);

                if (tag?.Value == e.Data.VersionKey.ToString())
                {
                    return;     // No need
                }
                else if (base.ExecuteGuard(pat))
                {
                    // Perform notification
                    IMessage notificationMessage;
                    IGroup patientGroup;

                    if (tag?.Value == null)
                    {
                        // Set the tag value and send an ADMIT
                        patientGroup = notificationMessage = new ADT_A01();
                        ApplicationServiceContext.Current.GetService <ITagPersistenceService>().Save(pat.Key.Value, new EntityTag(TagName, pat.VersionKey.ToString()));
                        (notificationMessage.GetStructure("MSH") as MSH).MessageType.TriggerEvent.Value     = "A04";
                        (notificationMessage.GetStructure("MSH") as MSH).MessageType.MessageStructure.Value = "ADT_A01";
                    }
                    else if (pat.LoadCollection <EntityRelationship>("Relationships").Any(o => o.RelationshipTypeKey == EntityRelationshipTypeKeys.Replaces && o.EffectiveVersionSequenceId == pat.VersionSequence))
                    {
                        // Set the tag value and send an ADMIT
                        notificationMessage = new ADT_A39();
                        patientGroup        = (notificationMessage as ADT_A39).GetPATIENT();
                        ApplicationServiceContext.Current.GetService <ITagPersistenceService>().Save(pat.Key.Value, new EntityTag(TagName, pat.VersionKey.ToString()));
                        (notificationMessage.GetStructure("MSH") as MSH).MessageType.TriggerEvent.Value     = "A40";
                        (notificationMessage.GetStructure("MSH") as MSH).MessageType.MessageStructure.Value = "ADT_A40";

                        foreach (var mrg in pat.LoadCollection <EntityRelationship>("Relationships").Where(o => o.RelationshipTypeKey == EntityRelationshipTypeKeys.Replaces && o.EffectiveVersionSequenceId == pat.VersionSequence))
                        {
                            var seg = patientGroup.GetStructure("MRG", patientGroup.GetAll("MRG").Length) as MRG;

                            if (this.Configuration.ExportDomains.Any(o => o.DomainName == this.m_configuration.LocalAuthority.DomainName))
                            {
                                var key = seg.PriorAlternatePatientIDRepetitionsUsed;
                                seg.GetPriorAlternatePatientID(key).IDNumber.Value                           = mrg.TargetEntityKey.Value.ToString();
                                seg.GetPriorAlternatePatientID(key).IdentifierTypeCode.Value                 = "PI";
                                seg.GetPriorAlternatePatientID(key).AssigningAuthority.NamespaceID.Value     = this.m_configuration.LocalAuthority.DomainName;
                                seg.GetPriorAlternatePatientID(key).AssigningAuthority.UniversalID.Value     = this.m_configuration.LocalAuthority.Oid;
                                seg.GetPriorAlternatePatientID(key).AssigningAuthority.UniversalIDType.Value = "ISO";
                            }

                            // Alternate identifiers
                            foreach (var extrn in pat.LoadCollection <EntityIdentifier>("Identifiers"))
                            {
                                var key = seg.PriorAlternatePatientIDRepetitionsUsed;
                                if (this.Configuration.ExportDomains.Any(o => o.DomainName == extrn.LoadProperty <AssigningAuthority>("Authority").DomainName))
                                {
                                    seg.GetPriorAlternatePatientID(key).IDNumber.Value                           = extrn.Value;
                                    seg.GetPriorAlternatePatientID(key).IdentifierTypeCode.Value                 = "PT";
                                    seg.GetPriorAlternatePatientID(key).AssigningAuthority.NamespaceID.Value     = extrn.LoadProperty <AssigningAuthority>("Authority")?.DomainName;
                                    seg.GetPriorAlternatePatientID(key).AssigningAuthority.UniversalID.Value     = extrn.LoadProperty <AssigningAuthority>("Authority")?.Oid;
                                    seg.GetPriorAlternatePatientID(key).AssigningAuthority.UniversalIDType.Value = "ISO";
                                }
                            }
                        }
                    }
                    else
                    {
                        // Set the tag value and send an ADMIT
                        patientGroup = notificationMessage = new ADT_A01();
                        ApplicationServiceContext.Current.GetService <ITagPersistenceService>().Save(pat.Key.Value, new EntityTag(TagName, pat.VersionKey.ToString()));
                        (notificationMessage.GetStructure("MSH") as MSH).MessageType.TriggerEvent.Value     = "A08";
                        (notificationMessage.GetStructure("MSH") as MSH).MessageType.MessageStructure.Value = "ADT_A08";
                    }

                    if (!String.IsNullOrEmpty(this.Configuration.Version))
                    {
                        (notificationMessage.GetStructure("MSH") as MSH).VersionID.VersionID.Value = this.Configuration.Version;
                    }

                    // Add SFT
                    if (new Version(this.Configuration.Version ?? "2.5") >= new Version(2, 4))
                    {
                        (notificationMessage.GetStructure("SFT", 0) as SFT).SetDefault();
                    }

                    // Create the PID segment
                    SegmentHandlers.GetSegmentHandler("PID").Create(e.Data, patientGroup, this.Configuration.ExportDomains.ToArray());
                    SegmentHandlers.GetSegmentHandler("PD1").Create(e.Data, patientGroup, this.Configuration.ExportDomains.ToArray());
                    SegmentHandlers.GetSegmentHandler("NK1").Create(e.Data, patientGroup, this.Configuration.ExportDomains.ToArray());
                    //SegmentHandlers.GetSegmentHandler("EVN").Create(e.Data, patientGroup, this.Configuration.ExportDomains.ToArray());


                    foreach (var itm in this.Configuration.Endpoints)
                    {
                        try
                        {
                            // TODO: Create an HL7 Queue
                            (notificationMessage.GetStructure("MSH") as MSH).SetDefault(itm.ReceivingDevice, itm.ReceivingFacility, itm.SecurityToken);
                            var response = itm.GetSender().SendAndReceive(notificationMessage);

                            if (!(response.GetStructure("MSA") as MSA).AcknowledgmentCode.Value.EndsWith("A"))
                            {
                                throw new HL7Exception("Remote server rejected message");
                            }
                        }
                        catch (Exception ex)
                        {
                            this.m_tracer.TraceEvent(EventLevel.Error, "Error dispatching message {0} to {1}: {2} \r\n {3}", pat, itm.Address, ex, new PipeParser().Encode(notificationMessage));
                        }
                    }
                }
            }, e.Data
                );
        }
コード例 #6
0
 /// <summary>
 /// Notify obsoleted
 /// </summary>
 protected override void OnObsoleted(object sender, DataPersistedEventArgs <Bundle> evt)
 {
     this.OnInserted(sender, evt);
 }
コード例 #7
0
 /// <summary>
 /// Fire inserting event
 /// </summary>
 protected void FireInserted(DataPersistedEventArgs <TData> evt)
 {
     this.Inserted?.Invoke(this, evt);
 }
コード例 #8
0
        /// <summary>
        /// Obsoletes the specified object
        /// </summary>
        public TData Obsolete(TData data, TransactionMode mode, IPrincipal overrideAuthContext)
        {
            if (data == null)
            {
                throw new ArgumentNullException(nameof(data));
            }
            else if (data.Key == Guid.Empty)
            {
                throw new InvalidOperationException("Data missing key");
            }

            DataPersistingEventArgs <TData> preArgs = new DataPersistingEventArgs <TData>(data, mode, overrideAuthContext);

            this.Obsoleting?.Invoke(this, preArgs);
            if (preArgs.Cancel)
            {
                this.m_tracer.TraceEvent(EventLevel.Warning, "Pre-Event handler indicates abort for {0}", data);
                return(data);
            }

            // Obsolete object
            using (var connection = this.m_settingsProvider.GetConfiguration().Provider.GetWriteConnection())
            {
                try
                {
                    connection.Open();
                    using (IDbTransaction tx = connection.BeginTransaction())
                        try
                        {
                            //connection.Connection.Open();

                            this.m_tracer.TraceEvent(EventLevel.Verbose, "OBSOLETE {0}", data);
                            connection.EstablishProvenance(overrideAuthContext, (data as BaseEntityData)?.ObsoletedByKey);
                            data = this.Obsolete(connection, data);

                            if (mode == TransactionMode.Commit)
                            {
                                tx.Commit();
                                var cacheService = ApplicationServiceContext.Current.GetService <IDataCachingService>();
                                cacheService?.Remove(data);
                            }
                            else
                            {
                                tx.Rollback();
                            }

                            var args = new DataPersistedEventArgs <TData>(data, mode, overrideAuthContext);

                            this.Obsoleted?.Invoke(this, args);

                            return(data);
                        }
                        catch (Exception e)
                        {
                            this.m_tracer.TraceEvent(EventLevel.Error, "Error : {0}", e);
                            tx?.Rollback();
                            throw new DataPersistenceException(e.Message, e);
                        }
                    finally
                    {
                    }
                }
                finally
                {
                }
            }
        }
コード例 #9
0
        /// <summary>
        /// Update the specified object
        /// </summary>
        /// <param name="storageData"></param>
        /// <param name="principal"></param>
        /// <param name="mode"></param>
        /// <returns></returns>
        public TData Update(TData data, TransactionMode mode, IPrincipal overrideAuthContext)
        {
            if (data == null)
            {
                throw new ArgumentNullException(nameof(data));
            }
            else if (data.Key == Guid.Empty)
            {
                throw new InvalidOperationException("Data missing key");
            }

            DataPersistingEventArgs <TData> preArgs = new DataPersistingEventArgs <TData>(data, mode, overrideAuthContext);

            this.Updating?.Invoke(this, preArgs);
            if (preArgs.Cancel)
            {
                this.m_tracer.TraceEvent(EventLevel.Warning, "Pre-Event handler indicates abort update for {0}", data);
                return(data);
            }

            // Persist object
            using (var connection = this.m_settingsProvider.GetConfiguration().Provider.GetWriteConnection())
            {
                try
                {
                    connection.Open();
                    using (IDbTransaction tx = connection.BeginTransaction())
                        try
                        {
                            //connection.Connection.Open();

                            this.m_tracer.TraceEvent(EventLevel.Verbose, "UPDATE {0}", data);

                            connection.EstablishProvenance(overrideAuthContext, (data as NonVersionedEntityData)?.UpdatedByKey ?? (data as BaseEntityData)?.CreatedByKey);
                            data           = Update(connection, data);
                            data.LoadState = LoadState.FullLoad; // We just persisted this so it is fully loaded

                            if (mode == TransactionMode.Commit)
                            {
                                tx.Commit();
                                var cacheService = ApplicationServiceContext.Current.GetService <IDataCachingService>();
                                cacheService?.Remove(data);
                            }
                            else
                            {
                                tx.Rollback();
                            }

                            var args = new DataPersistedEventArgs <TData>(data, mode, overrideAuthContext);

                            this.Updated?.Invoke(this, args);

                            return(data);
                        }
                        catch (DbException e)
                        {
#if DEBUG
                            this.m_tracer.TraceEvent(EventLevel.Error, "Error : {0} -- {1}", e, this.ObjectToString(data));
#else
                            this.m_tracer.TraceEvent(EventLevel.Error, "Error : {0}", e.Message);
#endif
                            tx?.Rollback();

                            throw new DataPersistenceException($"Error updating {data}", this.TranslateDbException(e));
                        }
                    catch (Exception e)
                    {
#if DEBUG
                        this.m_tracer.TraceEvent(EventLevel.Error, "Error : {0} -- {1}", e, this.ObjectToString(data));
#else
                        this.m_tracer.TraceEvent(EventLevel.Error, "Error : {0}", e.Message);
#endif
                        tx?.Rollback();

                        // if the exception is key not found, we want the caller to know
                        // so that a potential insert can take place
                        if (e is KeyNotFoundException)
                        {
                            throw new KeyNotFoundException($"Record {data} was not found for update", e);
                        }

                        // if the exception is anything else, we want to throw a data persistence exception
                        throw new DataPersistenceException($"Error updating {data}", e);
                    }
                    finally
                    {
                    }
                }
                finally
                {
                }
            }
        }
コード例 #10
0
        /// <summary>
        /// Inserts the specified data
        /// </summary>
        public TData Insert(TData data, TransactionMode mode, IPrincipal overrideAuthContext)
        {
            if (data == null)
            {
                throw new ArgumentNullException(nameof(data));
            }

            DataPersistingEventArgs <TData> preArgs = new DataPersistingEventArgs <TData>(data, mode, overrideAuthContext);

            this.Inserting?.Invoke(this, preArgs);
            if (preArgs.Cancel)
            {
                this.m_tracer.TraceEvent(EventLevel.Warning, "Pre-Event handler indicates abort insert for {0}", data);
                return(data);
            }

            // Persist object
            using (var connection = this.m_settingsProvider.GetConfiguration().Provider.GetWriteConnection())
            {
                try
                {
                    connection.Open();
                    using (IDbTransaction tx = connection.BeginTransaction())
                        try
                        {
                            // Disable inserting duplicate classified objects
                            connection.EstablishProvenance(overrideAuthContext, (data as BaseEntityData)?.CreatedByKey);
                            var existing = data.TryGetExisting(connection, true);
                            if (existing != null)
                            {
                                if (this.m_settingsProvider.GetConfiguration().AutoUpdateExisting)
                                {
                                    this.m_tracer.TraceEvent(EventLevel.Warning, "INSERT WOULD RESULT IN DUPLICATE CLASSIFIER: UPDATING INSTEAD {0}", data);
                                    data.Key = existing.Key;
                                    data     = this.Update(connection, data);
                                }
                                else
                                {
                                    throw new DuplicateNameException(data.Key?.ToString());
                                }
                            }
                            else
                            {
                                this.m_tracer.TraceEvent(EventLevel.Verbose, "INSERT {0}", data);
                                data = this.Insert(connection, data);
                            }
                            data.LoadState = LoadState.FullLoad; // We just persisted so it is fully loaded

                            if (mode == TransactionMode.Commit)
                            {
                                tx.Commit();
                                var cacheService = ApplicationServiceContext.Current.GetService <IDataCachingService>();
                                cacheService?.Add(data);
                            }
                            else
                            {
                                tx.Rollback();
                            }

                            var args = new DataPersistedEventArgs <TData>(data, mode, overrideAuthContext);

                            this.Inserted?.Invoke(this, args);

                            return(data);
                        }
                        catch (DbException e)
                        {
#if DEBUG
                            this.m_tracer.TraceEvent(EventLevel.Error, "Error : {0} -- {1}", e, this.ObjectToString(data));
#else
                            this.m_tracer.TraceEvent(EventLevel.Error, "Error : {0}", e.Message);
#endif
                            tx?.Rollback();

                            throw new DataPersistenceException($"Error inserting {data}", this.TranslateDbException(e));
                        }
                    catch (DataPersistenceException)
                    {
                        throw;
                    }
                    catch (Exception e)
                    {
                        this.m_tracer.TraceEvent(EventLevel.Error, "Error : {0} -- {1}", e, this.ObjectToString(data));

                        tx?.Rollback();
                        throw new DataPersistenceException(e.Message, e);
                    }
                    finally
                    {
                    }
                }
                finally
                {
                }
            }
        }
コード例 #11
0
        /// <summary>
        /// Insert the specified audit into the database
        /// </summary>
        public AuditData Insert(AuditData storageData, TransactionMode mode, IPrincipal overrideAuthContext = null)
        {
            // Pre-event trigger
            var preEvtData = new DataPersistingEventArgs <AuditData>(storageData, overrideAuthContext);

            this.Inserting?.Invoke(this, preEvtData);
            if (preEvtData.Cancel)
            {
                this.m_traceSource.TraceEvent(EventLevel.Warning, "Pre-Event handler indicates abort insert {0}", storageData);
                return(storageData);
            }

            // Insert
            using (var context = this.m_configuration.Provider.GetWriteConnection())
            {
                IDbTransaction tx = null;
                try
                {
                    context.Open();
                    tx = context.BeginTransaction();

                    // Insert core
                    var dbAudit = this.m_mapper.MapModelInstance <AuditData, DbAuditData>(storageData);

                    var eventId = storageData.EventTypeCode;
                    if (eventId != null)
                    {
                        var existing = context.FirstOrDefault <DbAuditCode>(o => o.Code == eventId.Code && o.CodeSystem == eventId.CodeSystem);
                        if (existing == null)
                        {
                            Guid codeId = Guid.NewGuid();
                            dbAudit.EventTypeCode = codeId;
                            context.Insert(new DbAuditCode()
                            {
                                Code = eventId.Code, CodeSystem = eventId.CodeSystem, Key = codeId
                            });
                        }
                        else
                        {
                            dbAudit.EventTypeCode = existing.Key;
                        }
                    }

                    dbAudit.CreationTime = DateTime.Now;
                    storageData.Key      = Guid.NewGuid();
                    dbAudit.Key          = storageData.Key.Value;
                    context.Insert(dbAudit);

                    // Insert secondary properties
                    if (storageData.Actors != null)
                    {
                        foreach (var act in storageData.Actors)
                        {
                            var dbAct = context.FirstOrDefault <DbAuditActor>(o => o.UserName == act.UserName);
                            if (dbAct == null)
                            {
                                dbAct     = this.m_mapper.MapModelInstance <AuditActorData, DbAuditActor>(act);
                                dbAct.Key = Guid.NewGuid();
                                var roleCode = act.ActorRoleCode?.FirstOrDefault();
                                if (roleCode != null)
                                {
                                    var existing = context.FirstOrDefault <DbAuditCode>(o => o.Code == roleCode.Code && o.CodeSystem == roleCode.CodeSystem);
                                    if (existing == null)
                                    {
                                        dbAct.ActorRoleCode = Guid.NewGuid();
                                        context.Insert(new DbAuditCode()
                                        {
                                            Code = roleCode.Code, CodeSystem = roleCode.CodeSystem, Key = dbAct.ActorRoleCode
                                        });
                                    }
                                    else
                                    {
                                        dbAct.ActorRoleCode = existing.Key;
                                    }
                                }
                                context.Insert(dbAct);
                            }
                            context.Insert(new DbAuditActorAssociation()
                            {
                                TargetKey       = dbAct.Key,
                                SourceKey       = dbAudit.Key,
                                UserIsRequestor = act.UserIsRequestor,
                                AccessPoint     = act.NetworkAccessPointId,
                                Key             = Guid.NewGuid()
                            });
                        }
                    }

                    // Audit objects
                    if (storageData.AuditableObjects != null)
                    {
                        foreach (var ao in storageData.AuditableObjects)
                        {
                            var dbAo = this.m_mapper.MapModelInstance <AuditableObject, DbAuditObject>(ao);
                            dbAo.IDTypeCode    = (int)(ao.IDTypeCode ?? 0);
                            dbAo.LifecycleType = (int)(ao.LifecycleType ?? 0);
                            dbAo.Role          = (int)(ao.Role ?? 0);
                            dbAo.Type          = (int)(ao.Type);
                            dbAo.AuditId       = dbAudit.Key;
                            dbAo.Key           = Guid.NewGuid();
                            context.Insert(dbAo);
                        }
                    }

                    // metadata
                    if (storageData.Metadata != null)
                    {
                        foreach (var meta in storageData.Metadata.Where(o => !String.IsNullOrEmpty(o.Value)))
                        {
                            context.Insert(new DbAuditMetadata()
                            {
                                AuditId     = dbAudit.Key,
                                MetadataKey = (int)meta.Key,
                                Value       = meta.Value
                            });
                        }
                    }

                    if (mode == TransactionMode.Commit)
                    {
                        tx.Commit();
                    }
                    else
                    {
                        tx.Rollback();
                    }

                    var args = new DataPersistedEventArgs <AuditData>(storageData, overrideAuthContext);

                    this.Inserted?.Invoke(this, args);

                    return(storageData);
                }
                catch (Exception ex)
                {
                    tx?.Rollback();
                    throw new Exception($"Error inserting audit {storageData.Key}", ex);
                }
            }
        }
コード例 #12
0
        /// <summary>
        /// Insert the specified audit into the database
        /// </summary>
        public AuditData Insert(AuditData storageData, TransactionMode mode, IPrincipal overrideAuthContext = null)
        {
            // Pre-event trigger
            var preEvtData = new DataPersistingEventArgs <AuditData>(storageData, mode, overrideAuthContext);

            this.Inserting?.Invoke(this, preEvtData);
            if (preEvtData.Cancel)
            {
                this.m_traceSource.TraceEvent(EventLevel.Warning, "Pre-Event handler indicates abort insert {0}", storageData);
                return(storageData);
            }

            // Insert
            using (var context = this.m_configuration.Provider.GetWriteConnection())
            {
                IDbTransaction tx = null;
                try
                {
                    context.Open();
                    tx = context.BeginTransaction();

                    // Insert core
                    var dbAudit = this.m_mapper.MapModelInstance <AuditData, DbAuditData>(storageData);

                    var eventId = storageData.EventTypeCode;
                    if (eventId != null)
                    {
                        dbAudit.EventTypeCode = this.GetOrCreateAuditCode(context, eventId).Key;
                    }

                    dbAudit.CreationTime = DateTimeOffset.Now;
                    storageData.Key      = Guid.NewGuid();
                    dbAudit.Key          = storageData.Key.Value;
                    context.Insert(dbAudit);

                    // Insert secondary properties
                    if (storageData.Actors != null)
                    {
                        foreach (var act in storageData.Actors)
                        {
                            var roleCode = this.GetOrCreateAuditCode(context, act.ActorRoleCode.FirstOrDefault());

                            DbAuditActor dbAct = null;
                            if (roleCode != null)
                            {
                                dbAct = context.FirstOrDefault <DbAuditActor>(o => o.UserName == act.UserName && o.ActorRoleCode == roleCode.Key);
                            }
                            else
                            {
                                dbAct = context.FirstOrDefault <DbAuditActor>(o => o.UserName == act.UserName && o.ActorRoleCode == Guid.Empty);
                            }

                            if (dbAct == null)
                            {
                                dbAct = this.m_mapper.MapModelInstance <AuditActorData, DbAuditActor>(act);
                                dbAct.ActorRoleCode = roleCode?.Key ?? Guid.Empty;
                                dbAct = context.Insert(dbAct);
                            }
                            context.Insert(new DbAuditActorAssociation()
                            {
                                TargetKey       = dbAct.Key,
                                SourceKey       = dbAudit.Key,
                                UserIsRequestor = act.UserIsRequestor,
                                AccessPoint     = act.NetworkAccessPointId
                            });
                        }
                    }

                    // Audit objects
                    if (storageData.AuditableObjects != null)
                    {
                        foreach (var ao in storageData.AuditableObjects)
                        {
                            var dbAo = this.m_mapper.MapModelInstance <AuditableObject, DbAuditObject>(ao);
                            dbAo.IDTypeCode    = (int)(ao.IDTypeCode ?? 0);
                            dbAo.LifecycleType = (int)(ao.LifecycleType ?? 0);
                            dbAo.Role          = (int)(ao.Role ?? 0);
                            dbAo.Type          = (int)(ao.Type);
                            dbAo.AuditId       = dbAudit.Key;

                            if (ao.CustomIdTypeCode != null)
                            {
                                var code = this.GetOrCreateAuditCode(context, ao.CustomIdTypeCode);
                                dbAo.CustomIdType = code.Key;
                            }

                            dbAo = context.Insert(dbAo);

                            if (ao.ObjectData?.Count > 0)
                            {
                                foreach (var od in ao.ObjectData)
                                {
                                    context.Insert(new DbAuditObjectData()
                                    {
                                        Name     = od.Key,
                                        Value    = od.Value,
                                        ObjectId = dbAo.Key
                                    });
                                }
                            }
                        }
                    }

                    // metadata
                    if (storageData.Metadata != null)
                    {
                        foreach (var meta in storageData.Metadata.Where(o => !String.IsNullOrEmpty(o.Value) && o.Key != AuditMetadataKey.CorrelationToken))
                        {
                            var kv = context.FirstOrDefault <DbAuditMetadataValue>(o => o.Value == meta.Value);
                            if (kv == null)
                            {
                                kv = context.Insert(new DbAuditMetadataValue()
                                {
                                    // TODO: Make this a common extension function (to trim)
                                    Value = meta.Value.Substring(0, meta.Value.Length > 256 ? 256 : meta.Value.Length)
                                });
                            }

                            context.Insert(new DbAuditMetadata()
                            {
                                AuditId     = dbAudit.Key,
                                MetadataKey = (int)meta.Key,
                                ValueId     = kv.Key
                            });
                        }
                    }

                    if (mode == TransactionMode.Commit)
                    {
                        tx.Commit();
                    }
                    else
                    {
                        tx.Rollback();
                    }

                    var args = new DataPersistedEventArgs <AuditData>(storageData, mode, overrideAuthContext);

                    this.Inserted?.Invoke(this, args);

                    return(storageData);
                }
                catch (Exception ex)
                {
                    tx?.Rollback();
                    throw new Exception($"Error inserting audit {storageData.Key}", ex);
                }
            }
        }
コード例 #13
0
        /// <summary>
        /// Update the specified container
        /// </summary>
        /// <param name="data">The data to be updated</param>
        /// <param name="principal">The principal for authorization</param>
        /// <param name="mode">The mode of operation</param>
        /// <returns>The updated model</returns>
        public TModel Update(TModel data, TransactionMode mode, IPrincipal principal)
        {
            if (data == null)
            {
                throw new ArgumentNullException(nameof(data));
            }
            else if (data.Key == Guid.Empty)
            {
                throw new InvalidOperationException("Data missing key");
            }

            DataPersistingEventArgs <TModel> preArgs = new DataPersistingEventArgs <TModel>(data, mode, principal);

            this.Updating?.Invoke(this, preArgs);
            if (preArgs.Cancel)
            {
                this.m_tracer.TraceWarning("Pre-Event handler indicates abort update for {0}", data);
                return(data);
            }

            // Persist object
            using (var connection = AdoAuditPersistenceService.GetConfiguration().Provider.GetWriteConnection())
            {
                connection.Open();
                using (IDbTransaction tx = connection.BeginTransaction())
                    try
                    {
                        //connection.Connection.Open();
                        connection.EstablishProvenance(principal, (data as NonVersionedEntityData)?.UpdatedByKey ?? (data as BaseEntityData)?.CreatedByKey);

                        this.m_tracer.TraceVerbose("UPDATE {0}", data);

                        data = this.UpdateInternal(connection, data, principal);
                        connection.AddCacheCommit(data);
                        data.LoadState = LoadState.FullLoad; // We just persisted this so it is fully loaded

                        if (mode == TransactionMode.Commit)
                        {
                            tx.Commit();
                            foreach (var itm in connection.CacheOnCommit)
                            {
                                ApplicationServiceContext.Current.GetService <IDataCachingService>()?.Add(itm);
                            }
                        }
                        else
                        {
                            tx.Rollback();
                        }

                        var args = new DataPersistedEventArgs <TModel>(data, mode, principal);

                        this.Updated?.Invoke(this, args);

                        return(data);
                    }
                    catch (DbException e)
                    {
#if DEBUG
                        this.m_tracer.TraceError("Error : {0} -- {1}", e, this.ObjectToString(data));
#else
                        this.m_tracer.TraceError("Error : {0}", e.Message);
#endif
                        tx?.Rollback();

                        this.TranslateDbException(e);
                        throw;
                    }
                catch (Exception e)
                {
#if DEBUG
                    this.m_tracer.TraceError("Error : {0} -- {1}", e, this.ObjectToString(data));
#else
                    this.m_tracer.TraceError("Error : {0}", e.Message);
#endif
                    tx?.Rollback();

                    // if the exception is key not found, we want the caller to know
                    // so that a potential insert can take place
                    if (e is KeyNotFoundException)
                    {
                        throw new KeyNotFoundException(e.Message, e);
                    }

                    // if the exception is anything else, we want to throw a data persistence exception
                    throw new DataPersistenceException(e.Message, e);
                }
                finally
                {
                }
            }
        }
コード例 #14
0
        /// <summary>
        /// Obsolete the specified key data
        /// </summary>
        /// <param name="storageData">The storage data to be obsoleted</param>
        /// <param name="principal">The principal to use to obsolete</param>
        /// <param name="mode">The mode of obsoletion</param>
        /// <returns>The obsoleted record</returns>
        public TModel Obsolete(TModel data, TransactionMode mode, IPrincipal principal)
        {
            if (data == null)
            {
                throw new ArgumentNullException(nameof(data));
            }
            else if (data.Key == Guid.Empty)
            {
                throw new InvalidOperationException("Data missing key");
            }

            DataPersistingEventArgs <TModel> preArgs = new DataPersistingEventArgs <TModel>(data, mode, principal);

            this.Obsoleting?.Invoke(this, preArgs);
            if (preArgs.Cancel)
            {
                this.m_tracer.TraceWarning("Pre-Event handler indicates abort for {0}", data);
                return(data);
            }

            // Obsolete object
            using (var connection = AdoAuditPersistenceService.GetConfiguration().Provider.GetWriteConnection())
            {
                connection.Open();
                using (IDbTransaction tx = connection.BeginTransaction())
                    try
                    {
                        //connection.Connection.Open();

                        this.m_tracer.TraceVerbose("OBSOLETE {0}", data);
                        connection.EstablishProvenance(principal, (data as NonVersionedEntityData)?.ObsoletedByKey ?? (data as BaseEntityData)?.ObsoletedByKey);

                        data = this.ObsoleteInternal(connection, data, principal);
                        connection.AddCacheCommit(data);
                        if (mode == TransactionMode.Commit)
                        {
                            tx.Commit();
                            foreach (var itm in connection.CacheOnCommit)
                            {
                                ApplicationServiceContext.Current.GetService <IDataCachingService>()?.Remove(itm.Key.Value);
                            }
                        }
                        else
                        {
                            tx.Rollback();
                        }

                        var args = new DataPersistedEventArgs <TModel>(data, mode, principal);

                        this.Obsoleted?.Invoke(this, args);

                        return(data);
                    }
                    catch (Exception e)
                    {
                        this.m_tracer.TraceError("Error : {0}", e);
                        tx?.Rollback();
                        throw new DataPersistenceException(e.Message, e);
                    }
                finally
                {
                }
            }
        }
コード例 #15
0
        /// <summary>
        /// Insert the specified storage data
        /// </summary>
        /// <param name="data">The storage data to be inserted</param>
        /// <param name="principal">The authentication context</param>
        /// <param name="mode">The transaction control mode</param>
        /// <returns>The inserted data</returns>
        public TModel Insert(TModel data, TransactionMode mode, IPrincipal principal)
        {
            if (data == null)
            {
                throw new ArgumentNullException(nameof(data));
            }

            DataPersistingEventArgs <TModel> preArgs = new DataPersistingEventArgs <TModel>(data, mode, principal);

            this.Inserting?.Invoke(this, preArgs);
            if (preArgs.Cancel)
            {
                this.m_tracer.TraceWarning("Pre-Event handler indicates abort insert for {0}", data);
                return(data);
            }

            // Persist object
            using (var connection = AdoAuditPersistenceService.GetConfiguration().Provider.GetWriteConnection())
            {
                connection.Open();
                using (IDbTransaction tx = connection.BeginTransaction())
                    try
                    {
                        connection.EstablishProvenance(principal, (data as NonVersionedEntityData)?.CreatedByKey ?? (data as BaseEntityData)?.CreatedByKey);
                        // Disable inserting duplicate classified objects
                        var existing = data.TryGetExisting(connection, principal, true);
                        if (existing != null)
                        {
                            throw new DuplicateNameException(data.Key?.ToString());
                        }
                        else
                        {
                            this.m_tracer.TraceVerbose("INSERT {0}", data);
                            data = this.InsertInternal(connection, data, principal);
                            connection.AddCacheCommit(data);
                        }
                        data.LoadState = LoadState.FullLoad; // We just persisted so it is fully loaded

                        if (mode == TransactionMode.Commit)
                        {
                            tx.Commit();
                            foreach (var itm in connection.CacheOnCommit)
                            {
                                ApplicationServiceContext.Current.GetService <IDataCachingService>()?.Add(itm);
                            }
                        }
                        else
                        {
                            tx.Rollback();
                        }

                        var args = new DataPersistedEventArgs <TModel>(data, mode, principal);

                        this.Inserted?.Invoke(this, args);

                        return(data);
                    }
                    catch (DbException e)
                    {
#if DEBUG
                        this.m_tracer.TraceError("Error : {0} -- {1}", e, this.ObjectToString(data));
#else
                        this.m_tracer.TraceError("Error : {0}", e.Message);
#endif
                        tx?.Rollback();

                        this.TranslateDbException(e);
                        throw;
                    }
                catch (Exception e)
                {
                    this.m_tracer.TraceError("Error : {0} -- {1}", e, this.ObjectToString(data));

                    tx?.Rollback();
                    throw new DataPersistenceException(e.Message, e);
                }
            }
        }
コード例 #16
0
 /// <summary>
 /// Re-check relationships to ensure that they are properly in the database
 /// </summary>
 private void RecheckRelationshipTrigger(object sender, DataPersistedEventArgs <EntityRelationship> e)
 {
     this.RecheckRelationship(e.Data, e.Mode, e.Principal);
     this.m_dataCachingService.Remove(e.Data);
 }