/// <summary> /// Insert audit data /// </summary> public AuditData Insert(AuditData audit) { var conn = this.CreateConnection(); using (conn.Lock()) { try { if (!conn.IsInTransaction) { conn.BeginTransaction(); } // Insert core var dbAudit = this.m_mapper.MapModelInstance <AuditData, DbAuditData>(audit); if (audit.EventTypeCode != null) { var auditCode = this.GetOrCreateAuditCode(conn, audit.EventTypeCode); dbAudit.EventTypeCode = auditCode.Id; } dbAudit.CreationTime = DateTime.Now; audit.Key = Guid.NewGuid(); dbAudit.Id = audit.Key.Value.ToByteArray(); conn.Insert(dbAudit); // Insert secondary properties if (audit.Actors != null) { foreach (var act in audit.Actors) { var roleCode = this.GetOrCreateAuditCode(conn, act.ActorRoleCode.FirstOrDefault()); DbAuditActor dbAct = null; if (roleCode != null) { dbAct = conn.Table <DbAuditActor>().Where(o => o.UserName == act.UserName && o.ActorRoleCode == roleCode.Id).FirstOrDefault(); } else { dbAct = conn.Table <DbAuditActor>().Where(o => o.UserName == act.UserName && o.ActorRoleCode == null).FirstOrDefault(); } if (dbAct == null) { dbAct = this.m_mapper.MapModelInstance <AuditActorData, DbAuditActor>(act); dbAct.Id = Guid.NewGuid().ToByteArray(); dbAct.ActorRoleCode = roleCode?.Id; conn.Insert(dbAct); } conn.Insert(new DbAuditActorAssociation() { TargetUuid = dbAct.Id, SourceUuid = dbAudit.Id, Id = Guid.NewGuid().ToByteArray(), AccessPoint = act.NetworkAccessPointId, UserIsRequestor = act.UserIsRequestor }); } } // Audit objects if (audit.AuditableObjects != null) { foreach (var ao in audit.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.Id; dbAo.NameData = ao.NameData; dbAo.QueryData = ao.QueryData ?? (ao.ObjectData != null ? String.Join(";", ao.ObjectData.Select(o => $"{o.Key}")) : null); dbAo.Id = Guid.NewGuid().ToByteArray(); conn.Insert(dbAo); } } // metadata if (audit.Metadata != null) { foreach (var meta in audit.Metadata) { conn.Insert(new DbAuditMetadata() { Id = Guid.NewGuid().ToByteArray(), AuditId = dbAudit.Id, MetadataKey = (int)meta.Key, Value = meta.Value }); } } conn.Commit(); return(audit); } catch (SQLiteException e) { this.m_tracer.TraceError("Error inserting audit ({1}): {0}", e, conn); throw; } catch (Exception ex) { conn.Rollback(); this.m_tracer.TraceError("Error inserting audit: {0}", ex); throw new Exception($"Error inserting audit {audit.ActionCode}", ex); } } }
/// <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); } } }