/// <summary> /// Updates the specified storage data. /// </summary> /// <param name="storageData">The storage data.</param> /// <param name="principal">The principal.</param> /// <param name="mode">The mode.</param> /// <returns>Returns the updated model instance.</returns> public TModel Update(TModel storageData, IPrincipal principal, TransactionMode mode) { 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 preUpdateArgs = new PrePersistenceEventArgs <TModel>(storageData, principal); this.Updating?.Invoke(this, preUpdateArgs); if (preUpdateArgs.Cancel) { traceSource.TraceEvent(TraceEventType.Warning, 0, $"Pre-event handler indicates abort update for : {storageData}"); return(storageData); } using (var connection = Configuration.Provider.GetWriteConnection()) { connection.Open(); using (var tx = connection.BeginTransaction()) { try { this.traceSource.TraceEvent(TraceEventType.Verbose, 0, "UPDATE {0}", storageData); storageData = this.Update(connection, storageData, principal); if (mode == TransactionMode.Commit) { tx.Commit(); } else { tx.Rollback(); } this.Updated?.Invoke(this, new PostPersistenceEventArgs <TModel>(storageData, principal) { Mode = mode }); return(storageData); } catch (Exception e) { this.traceSource.TraceEvent(TraceEventType.Error, 0, "Error : {0}", e); tx?.Rollback(); throw new DataPersistenceException(e.Message, e); } } } }
/// <summary> /// Obsoletes the specified object /// </summary> public TData Obsolete(TData data, IPrincipal principal, TransactionMode mode) { if (data == null) { throw new ArgumentNullException(nameof(data)); } else if (data.Key == Guid.Empty) { throw new InvalidOperationException("Data missing key"); } PrePersistenceEventArgs <TData> preArgs = new PrePersistenceEventArgs <TData>(data); this.Obsoleting?.Invoke(this, preArgs); if (preArgs.Cancel) { this.m_tracer.TraceEvent(TraceEventType.Warning, 0, "Pre-Event handler indicates abort for {0}", data); return(data); } // Obsolete object using (var connection = m_configuration.Provider.GetWriteConnection()) { try { this.ThrowIfExceeded(); connection.Open(); using (IDbTransaction tx = connection.BeginTransaction()) try { //connection.Connection.Open(); this.m_tracer.TraceEvent(TraceEventType.Verbose, 0, "OBSOLETE {0}", data); data = this.Obsolete(connection, data, principal); if (mode == TransactionMode.Commit) { tx.Commit(); foreach (var itm in connection.CacheOnCommit) { ApplicationContext.Current.GetService <IDataCachingService>()?.Remove(itm.Key.Value); } } else { tx.Rollback(); } var args = new PostPersistenceEventArgs <TData>(data, principal) { Mode = mode }; this.Obsoleted?.Invoke(this, args); return(data); } catch (Exception e) { this.m_tracer.TraceEvent(TraceEventType.Error, 0, "Error : {0}", e); tx?.Rollback(); throw new DataPersistenceException(e.Message, e); } finally { } } finally { Interlocked.Decrement(ref m_currentRequests); } } }
/// <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, IPrincipal principal, TransactionMode mode) { if (data == null) { throw new ArgumentNullException(nameof(data)); } else if (data.Key == Guid.Empty) { throw new InvalidOperationException("Data missing key"); } PrePersistenceEventArgs <TData> preArgs = new PrePersistenceEventArgs <TData>(data, principal); this.Updating?.Invoke(this, preArgs); if (preArgs.Cancel) { this.m_tracer.TraceEvent(TraceEventType.Warning, 0, "Pre-Event handler indicates abort update for {0}", data); return(data); } // Persist object using (var connection = m_configuration.Provider.GetWriteConnection()) { try { this.ThrowIfExceeded(); connection.Open(); using (IDbTransaction tx = connection.BeginTransaction()) try { //connection.Connection.Open(); this.m_tracer.TraceEvent(TraceEventType.Verbose, 0, "UPDATE {0}", data); data = this.Update(connection, data, principal); 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) { ApplicationContext.Current.GetService <IDataCachingService>()?.Add(itm); } } else { tx.Rollback(); } var args = new PostPersistenceEventArgs <TData>(data, principal) { Mode = mode }; this.Updated?.Invoke(this, args); return(data); } catch (DbException e) { #if DEBUG this.m_tracer.TraceEvent(TraceEventType.Error, 0, "Error : {0} -- {1}", e, this.ObjectToString(data)); #else this.m_tracer.TraceEvent(TraceEventType.Error, 0, "Error : {0}", e.Message); #endif tx?.Rollback(); this.TranslateDbException(e); throw; } catch (Exception e) { #if DEBUG this.m_tracer.TraceEvent(TraceEventType.Error, 0, "Error : {0} -- {1}", e, this.ObjectToString(data)); #else this.m_tracer.TraceEvent(TraceEventType.Error, 0, "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 { } } finally { Interlocked.Decrement(ref m_currentRequests); } } }
/// <summary> /// Inserts the specified data /// </summary> public TData Insert(TData data, IPrincipal principal, TransactionMode mode) { if (data == null) { throw new ArgumentNullException(nameof(data)); } PrePersistenceEventArgs <TData> preArgs = new PrePersistenceEventArgs <TData>(data, principal); this.Inserting?.Invoke(this, preArgs); if (preArgs.Cancel) { this.m_tracer.TraceEvent(TraceEventType.Warning, 0, "Pre-Event handler indicates abort insert for {0}", data); return(data); } // Persist object using (var connection = m_configuration.Provider.GetWriteConnection()) { try { this.ThrowIfExceeded(); connection.Open(); using (IDbTransaction tx = connection.BeginTransaction()) try { // Disable inserting duplicate classified objects var existing = data.TryGetExisting(connection, principal, true); if (existing != null) { if (m_configuration.AutoUpdateExisting) { this.m_tracer.TraceEvent(TraceEventType.Warning, 0, "INSERT WOULD RESULT IN DUPLICATE CLASSIFIER: UPDATING INSTEAD {0}", data); data = this.Update(connection, data, principal); } else { throw new DuplicateNameException(data.Key?.ToString()); } } else { this.m_tracer.TraceEvent(TraceEventType.Verbose, 0, "INSERT {0}", data); data = this.Insert(connection, data, principal); } data.LoadState = LoadState.FullLoad; // We just persisted so it is fully loaded if (mode == TransactionMode.Commit) { tx.Commit(); foreach (var itm in connection.CacheOnCommit) { ApplicationContext.Current.GetService <IDataCachingService>()?.Add(itm); } } else { tx.Rollback(); } var args = new PostPersistenceEventArgs <TData>(data, principal) { Mode = mode }; this.Inserted?.Invoke(this, args); return(data); } catch (DbException e) { #if DEBUG this.m_tracer.TraceEvent(TraceEventType.Error, 0, "Error : {0} -- {1}", e, this.ObjectToString(data)); #else this.m_tracer.TraceEvent(TraceEventType.Error, 0, "Error : {0}", e.Message); #endif tx?.Rollback(); this.TranslateDbException(e); throw; } catch (Exception e) { this.m_tracer.TraceEvent(TraceEventType.Error, 0, "Error : {0} -- {1}", e, this.ObjectToString(data)); tx?.Rollback(); throw new DataPersistenceException(e.Message, e); } finally { } } finally { Interlocked.Decrement(ref m_currentRequests); } } }
internal void DoPersistResultMessage(object state) { // Persist a message to the database IDbConnection conn = m_configuration.CreateConnection(); AdoMessagePersistanceArgs args = state as AdoMessagePersistanceArgs; try { var mpe = new PrePersistenceEventArgs <MessageInfo>(args.MessageInfo); this.Persisting?.Invoke(this, mpe); if (mpe.Cancel) { Trace.TraceInformation("Message persistence event indicates cancel"); return; } conn.Open(); // Create the database command IDbCommand cmd = conn.CreateCommand(); try { // Setup command cmd.CommandType = CommandType.StoredProcedure; cmd.CommandText = "reg_msg"; cmd.CommandTimeout = 30; // Setup parameter for message id IDataParameter msgIdParm = cmd.CreateParameter(); msgIdParm.DbType = DbType.String; msgIdParm.Value = args.MessageInfo.Id; msgIdParm.Direction = ParameterDirection.Input; msgIdParm.ParameterName = "msg_id_in"; cmd.Parameters.Add(msgIdParm); // Setup parameter for the message body IDataParameter msgBodyParm = cmd.CreateParameter(); msgBodyParm.DbType = DbType.Binary; msgBodyParm.Value = args.MessageInfo.Body; msgBodyParm.Direction = ParameterDirection.Input; msgBodyParm.ParameterName = "msg_body_in"; cmd.Parameters.Add(msgBodyParm); // Setup parameter for msg_rsp_in IDataParameter msgRspParm = cmd.CreateParameter(); msgRspParm.DbType = DbType.String; msgRspParm.Value = String.IsNullOrEmpty(args.MessageInfo.Response) ? DBNull.Value : (object)args.MessageInfo.Response; msgRspParm.Direction = ParameterDirection.Input; msgRspParm.ParameterName = "msg_rsp_in"; cmd.Parameters.Add(msgRspParm); // Setup parameter for msg_rsp_in IDataParameter msgSrcParm = cmd.CreateParameter(); msgSrcParm.DbType = DbType.String; msgSrcParm.Value = args.MessageInfo.Source == null ? DBNull.Value : (object)args.MessageInfo.Source.ToString(); msgSrcParm.Direction = ParameterDirection.Input; msgSrcParm.ParameterName = "src_in"; cmd.Parameters.Add(msgSrcParm); // Setup parameter for msg_rsp_in IDataParameter msgDstParm = cmd.CreateParameter(); msgDstParm.DbType = DbType.String; msgDstParm.Value = args.MessageInfo.Destination == null ? DBNull.Value : (object)args.MessageInfo.Destination.ToString(); msgDstParm.Direction = ParameterDirection.Input; msgDstParm.ParameterName = "dst_in"; cmd.Parameters.Add(msgDstParm); // Execute the query without result cmd.ExecuteNonQuery(); this.Persisted?.Invoke(this, new PostPersistenceEventArgs <MessageInfo>(args.MessageInfo)); } finally { cmd.Dispose(); } } catch (Exception e) { Trace.TraceError(e.ToString()); } finally { conn.Close(); conn.Dispose(); args.MessageInfo = null; System.GC.Collect(); } }
public DiagnosticReport Insert(DiagnosticReport storageData, IPrincipal principal, TransactionMode mode) { var persistenceArgs = new PrePersistenceEventArgs <DiagnosticReport>(storageData, principal); this.Inserting?.Invoke(this, persistenceArgs); if (persistenceArgs.Cancel) { this.m_traceSource.TraceEvent(TraceEventType.Warning, 0, "Pre-persistence event cancelled the insertion"); return(persistenceArgs.Data); } try { // Send var serviceClient = new JiraServiceClient(new RestClient(this.m_configuration)); serviceClient.Authenticate(new Model.JiraAuthenticationRequest(this.m_configuration.UserName, this.m_configuration.Password)); var issue = serviceClient.CreateIssue(new Model.JiraIssueRequest() { Fields = new Model.JiraIssueFields() { Description = storageData.Note, Summary = String.Format("OpenIZ-DIAG: Issue from {0}", storageData?.Submitter?.Names?.FirstOrDefault()?.Component?.FirstOrDefault(n => n.ComponentTypeKey == NameComponentKeys.Given)?.Value), IssueType = new Model.JiraIdentifier("Bug"), Priority = new Model.JiraIdentifier("High"), Project = new Model.JiraKey(this.m_configuration.Project), Labels = new string[] { "OpenIZMobile" } } }); serviceClient.Client.Requesting += (o, e) => { e.AdditionalHeaders.Add("X-Atlassian-Token", "nocheck"); }; // Attachments List <MultipartAttachment> attachments = new List <MultipartAttachment>(); foreach (var itm in storageData.Attachments) { if (itm is DiagnosticBinaryAttachment) { var bin = itm as DiagnosticBinaryAttachment; attachments.Add(new MultipartAttachment(bin.Content, "application/x-gzip", bin.FileDescription, true)); } else { var txt = itm as DiagnosticTextAttachment; attachments.Add(new MultipartAttachment(Encoding.UTF8.GetBytes(txt.Content), "text/plain", txt.FileName, true)); } } // Attach the application information using (var ms = new MemoryStream()) { XmlSerializer xsz = new XmlSerializer(typeof(DiagnosticApplicationInfo)); xsz.Serialize(ms, storageData.ApplicationInfo); attachments.Add(new MultipartAttachment(ms.ToArray(), "text/xml", "appinfo.xml", true)); } serviceClient.CreateAttachment(issue, attachments); storageData.CorrelationId = issue.Key; storageData.Key = Guid.NewGuid(); // Invoke this.Inserted?.Invoke(this, new PostPersistenceEventArgs <DiagnosticReport>(storageData, principal)); return(storageData); } catch (Exception ex) { this.m_traceSource.TraceEvent(TraceEventType.Error, ex.HResult, "Error sending to JIRA: {0}", ex); throw; } }
/// <summary> /// Obsoletes the specified object /// </summary> public TData Obsolete(TData data, IPrincipal principal, TransactionMode mode) { if (data == null) { throw new ArgumentNullException(nameof(data)); } else if (data.Key == Guid.Empty) { throw new InvalidOperationException("Data missing key"); } PrePersistenceEventArgs <TData> preArgs = new PrePersistenceEventArgs <TData>(data); this.Obsoleting?.Invoke(this, preArgs); if (preArgs.Cancel) { this.m_tracer.TraceEvent(TraceEventType.Warning, 0, "Pre-Event handler indicates abort for {0}", data); return(data); } // Obsolete object using (var connection = new ModelDataContext(m_configuration.ReadWriteConnectionString)) { DbTransaction tx = null; try { connection.Connection.Open(); tx = connection.Transaction = connection.Connection.BeginTransaction(); // Tracer if (m_configuration.TraceSql) { connection.Log = new LinqTraceWriter(); } this.m_tracer.TraceEvent(TraceEventType.Verbose, 0, "OBSOLETE {0}", data); data = this.Obsolete(connection, data, principal); connection.SubmitChanges(); if (mode == TransactionMode.Commit) { tx.Commit(); } else { tx.Rollback(); } var args = new PostPersistenceEventArgs <TData>(data, principal) { Mode = mode }; this.Obsoleted?.Invoke(this, args); return(data); } catch (Exception e) { this.m_tracer.TraceEvent(TraceEventType.Error, 0, "Error : {0}", e); tx?.Rollback(); throw new DataPersistenceException(e.Message, e); } finally { } } }
/// <summary> /// Inserts the specified data /// </summary> public TData Insert(TData data, IPrincipal principal, TransactionMode mode) { if (data == null) { throw new ArgumentNullException(nameof(data)); } PrePersistenceEventArgs <TData> preArgs = new PrePersistenceEventArgs <TData>(data, principal); this.Inserting?.Invoke(this, preArgs); if (preArgs.Cancel) { this.m_tracer.TraceEvent(TraceEventType.Warning, 0, "Pre-Event handler indicates abort insert for {0}", data); return(data); } // Persist object using (var connection = new ModelDataContext(m_configuration.ReadWriteConnectionString)) { DbTransaction tx = null; try { connection.Connection.Open(); connection.Transaction = tx = connection.Connection.BeginTransaction(); if (m_configuration.TraceSql) { connection.Log = new LinqTraceWriter(); } // Disable inserting duplicate classified objects var existing = data.TryGetExisting(connection, principal); if (existing != null) { if (m_configuration.AutoUpdateExisting) { this.m_tracer.TraceEvent(TraceEventType.Warning, 0, "INSERT WOULD RESULT IN DUPLICATE CLASSIFIER: UPDATING INSTEAD {0}", data); data = this.Update(connection, data, principal); } else { throw new DuplicateKeyException(data); } } else { this.m_tracer.TraceEvent(TraceEventType.Verbose, 0, "INSERT {0}", data); data = this.Insert(connection, data, principal); } connection.SubmitChanges(); if (mode == TransactionMode.Commit) { tx.Commit(); } else { tx.Rollback(); } var args = new PostPersistenceEventArgs <TData>(data, principal) { Mode = mode }; this.Inserted?.Invoke(this, args); return(data); } catch (Exception e) { this.m_tracer.TraceEvent(TraceEventType.Error, 0, "Error : {0}", e); tx?.Rollback(); throw new DataPersistenceException(e.Message, e); } finally { } } }
/// <summary> /// Inserts the specified storage data. /// </summary> /// <param name="storageData">The storage data.</param> /// <param name="principal">The principal.</param> /// <param name="mode">The mode.</param> /// <returns>Returns the inserted model instance.</returns> public TModel Insert(TModel storageData, IPrincipal principal, TransactionMode mode) { if (storageData == null) { throw new ArgumentNullException(nameof(storageData), "Value cannot be null"); } var preInsertArgs = new PrePersistenceEventArgs <TModel>(storageData, principal); this.Inserting?.Invoke(this, preInsertArgs); if (preInsertArgs.Cancel) { traceSource.TraceEvent(TraceEventType.Warning, 0, $"Pre-event handler indicates abort insert for : {storageData}"); return(storageData); } using (var connection = Configuration.Provider.GetWriteConnection()) { connection.Open(); using (var transaction = connection.BeginTransaction()) { try { var existing = this.Get(connection, storageData.Key.Value, principal, false); if (existing != null) { if (Configuration.AutoUpdateExisting) { this.traceSource.TraceEvent(TraceEventType.Warning, 0, "INSERT WOULD RESULT IN DUPLICATE CLASSIFIER: UPDATING INSTEAD {0}", storageData); storageData = this.Update(connection, storageData, principal); } else { throw new DuplicateNameException(storageData.Key?.ToString()); } } else { this.traceSource.TraceEvent(TraceEventType.Verbose, 0, "INSERT {0}", storageData); storageData = this.Insert(connection, storageData, principal); } if (mode == TransactionMode.Commit) { transaction.Commit(); } else { transaction.Rollback(); } this.Inserted?.Invoke(this, new PostPersistenceEventArgs <TModel>(storageData, principal) { Mode = mode }); return(storageData); } catch (Exception e) { this.traceSource.TraceEvent(TraceEventType.Error, 0, "Error : {0}", e); transaction?.Rollback(); throw new DataPersistenceException(e.Message, e); } } } }
public DiagnosticReport Insert(DiagnosticReport storageData, IPrincipal principal, TransactionMode mode) { var persistenceArgs = new PrePersistenceEventArgs <DiagnosticReport>(storageData, principal); this.Inserting?.Invoke(this, persistenceArgs); if (persistenceArgs.Cancel) { this.m_traceSource.TraceEvent(TraceEventType.Warning, 0, "Pre-persistence event cancelled the insertion"); return(persistenceArgs.Data); } try { var issueId = Guid.NewGuid().ToString().Substring(0, 4); // Setup message MailMessage bugMessage = new MailMessage(); bugMessage.From = new MailAddress(this.m_configuration.Smtp.From, $"OpenIZ Bug on behalf of {storageData?.Submitter?.Names?.FirstOrDefault()?.Component?.FirstOrDefault(n => n.ComponentTypeKey == NameComponentKeys.Given)?.Value}"); foreach (var itm in this.m_configuration.Recipients) { bugMessage.To.Add(itm); } bugMessage.Subject = $"ISSUE #{issueId}"; bugMessage.Body = $"{storageData.Note} - Username - {storageData.LoadProperty<SecurityUser>("CreatedBy")?.UserName ?? storageData?.Submitter?.LoadProperty<SecurityUser>("SecurityUser")?.UserName}"; // Add attachments foreach (var itm in storageData.Attachments) { if (itm is DiagnosticBinaryAttachment) { var bin = itm as DiagnosticBinaryAttachment; bugMessage.Attachments.Add(new Attachment(new MemoryStream(bin.Content), itm.FileDescription ?? itm.FileName, "application/x-gzip")); } else { var txt = itm as DiagnosticTextAttachment; bugMessage.Attachments.Add(new Attachment(new MemoryStream(Encoding.UTF8.GetBytes(txt.Content)), itm.FileDescription ?? itm.FileName, "text/plain")); } } // Attach the application information using (var ms = new MemoryStream()) { XmlSerializer xsz = new XmlSerializer(typeof(DiagnosticApplicationInfo)); xsz.Serialize(ms, storageData.ApplicationInfo); bugMessage.Attachments.Add(new Attachment(new MemoryStream(ms.ToArray()), "appinfo.xml", "text/xml")); } SmtpClient smtpClient = new SmtpClient(this.m_configuration.Smtp.Server.Host, this.m_configuration.Smtp.Server.Port); smtpClient.UseDefaultCredentials = String.IsNullOrEmpty(this.m_configuration.Smtp.Username); smtpClient.EnableSsl = this.m_configuration.Smtp.Ssl; if (!(smtpClient.UseDefaultCredentials)) { smtpClient.Credentials = new NetworkCredential(this.m_configuration.Smtp.Username, this.m_configuration.Smtp.Password); } smtpClient.SendCompleted += (o, e) => { this.m_traceSource.TraceInformation("Successfully sent message to {0}", bugMessage.To); if (e.Error != null) { this.m_traceSource.TraceEvent(TraceEventType.Error, 0, e.Error.ToString()); } (o as IDisposable).Dispose(); }; this.m_traceSource.TraceInformation("Sending bug email message to {0}", bugMessage.To); smtpClient.Send(bugMessage); // Invoke this.Inserted?.Invoke(this, new PostPersistenceEventArgs <DiagnosticReport>(storageData, principal)); storageData.CorrelationId = issueId; storageData.Key = Guid.NewGuid(); return(storageData); } catch (Exception ex) { this.m_traceSource.TraceEvent(TraceEventType.Error, ex.HResult, "Error sending to JIRA: {0}", ex); throw; } }