/// <summary> /// Serialise a <see cref="WorkflowTrackingRecord" /> ready for persistence. /// </summary> /// <param name="workflowTrackingRecord"> /// The original <see cref="WorkflowTrackingRecord" /> to serialise. /// </param> /// <returns> /// A <see cref="SerialisableWorkflowTrackingRecord" /> containing a serialised /// copy of the <see cref="WorkflowTrackingRecord" />. /// </returns> private static SerialisableWorkflowTrackingRecord buildSerialisableWorkflowTrackingRecord(WorkflowTrackingRecord workflowTrackingRecord) { SerialisableWorkflowTrackingRecord serialisableWorkflowTrackingRecord = new SerialisableWorkflowTrackingRecord(); serialisableWorkflowTrackingRecord.Annotations.AddRange(workflowTrackingRecord.Annotations); serialisableWorkflowTrackingRecord.EventDateTime = workflowTrackingRecord.EventDateTime; serialisableWorkflowTrackingRecord.EventOrder = workflowTrackingRecord.EventOrder; serialisableWorkflowTrackingRecord.TrackingWorkflowEvent = workflowTrackingRecord.TrackingWorkflowEvent; if (workflowTrackingRecord.EventArgs != null) { serialisableWorkflowTrackingRecord.EventArgs = buildSerialisableData(workflowTrackingRecord.EventArgs); if (serialisableWorkflowTrackingRecord.EventArgs.NonSerialisable) { // if this is a termination or other exception event then // we need to get the exception details to trace what happened... Exception workflowException = null; switch (workflowTrackingRecord.TrackingWorkflowEvent) { case TrackingWorkflowEvent.Terminated: workflowException = ((TrackingWorkflowTerminatedEventArgs) workflowTrackingRecord.EventArgs).Exception; break; case TrackingWorkflowEvent.Exception: workflowException = ((TrackingWorkflowExceptionEventArgs) workflowTrackingRecord.EventArgs).Exception; break; } if (workflowException != null) { serialisableWorkflowTrackingRecord.EventArgs = buildSerialisableData(workflowException.ToString()); } } } return(serialisableWorkflowTrackingRecord); }
/// <summary> /// Inserts a batch of workflow tracking records, returning them /// as an <see cref="IDictionary{TKey,TValue}" /> indexed by their /// unique identifiers. /// </summary> /// <param name="workflowInstanceSummary"> /// A <see cref="WorkflowInstanceSummary" /> representing a workflow instance /// aInt64 with all its type information. /// </param> /// <param name="workflowTrackingRecords"> /// An <see cref="IList{T}" /> containing a batch of workflow tracking /// records to be inserted into the tracking store. /// </param> /// <returns> /// An <see cref="IDictionary{TKey,TValue}" /> containing the inserted /// records and indexed by their unique identifiers. /// </returns> protected override IDictionary <Int64, SerialisableWorkflowTrackingRecord> InsertWorkflowTrackingRecordBatch( WorkflowInstanceSummary workflowInstanceSummary, IList <SerialisableWorkflowTrackingRecord> workflowTrackingRecords) { if (workflowTrackingRecords.Count == 0 || workflowTrackingRecords.Count > WorkflowTrackingBatchSize) { throw new ArgumentOutOfRangeException("workflowTrackingRecords"); } Dictionary <Int64, SerialisableWorkflowTrackingRecord> workflowTrackingRecordsById = new Dictionary <Int64, SerialisableWorkflowTrackingRecord>(); using (OracleCommand oracleCommand = (OracleCommand)CreateCommand("WORKFLOW_TRACKING_PKG.InsertWorkflowTrackingRecord", CommandType.StoredProcedure)) { Int64[] workflowInstanceIds = new Int64[workflowTrackingRecords.Count]; Int16[] statusIds = new Int16[workflowTrackingRecords.Count]; DateTime[] eventDateTimes = new DateTime[workflowTrackingRecords.Count]; Int32[] eventOrders = new Int32[workflowTrackingRecords.Count]; String[] eventArgTypeNames = new String[workflowTrackingRecords.Count]; String[] eventArgAssemblyNames = new String[workflowTrackingRecords.Count]; Byte[][] eventArgs = new Byte[workflowTrackingRecords.Count][]; for (Int32 i = 0; i < workflowTrackingRecords.Count; i++) { SerialisableWorkflowTrackingRecord workflowTrackingRecord = workflowTrackingRecords[i]; workflowInstanceIds[i] = (Int64)workflowInstanceSummary.InternalId; statusIds[i] = (Int16)workflowTrackingRecord.TrackingWorkflowEvent; eventDateTimes[i] = workflowTrackingRecord.EventDateTime; eventOrders[i] = workflowTrackingRecord.EventOrder; if (workflowTrackingRecord.EventArgs != null) { eventArgTypeNames[i] = workflowTrackingRecord.EventArgs.Type.FullName; eventArgAssemblyNames[i] = workflowTrackingRecord.EventArgs.Type.Assembly.FullName; eventArgs[i] = workflowTrackingRecord.EventArgs.SerialisedData; } } oracleCommand.ArrayBindCount = workflowTrackingRecords.Count; AddParameter(oracleCommand, "p_WORKFLOW_INSTANCE_ID", workflowInstanceIds, AdoDbType.Int64); AddParameter(oracleCommand, "p_WORKFLOW_INSTANCE_STATUS", statusIds, AdoDbType.Int16); AddParameter(oracleCommand, "p_EVENT_DATE_TIME", eventDateTimes, AdoDbType.DateTime); AddParameter(oracleCommand, "p_EVENT_ORDER", eventOrders, AdoDbType.Int32); AddParameter(oracleCommand, "p_EVENT_ARG_TYPE_NAME", eventArgTypeNames, AdoDbType.String); AddParameter(oracleCommand, "p_EVENT_ARG_ASSEMBLY_NAME", eventArgAssemblyNames, AdoDbType.String); AddParameter(oracleCommand, "p_EVENT_ARG", eventArgs, AdoDbType.Binary); OracleParameter workflowEventId = (OracleParameter)AddParameter( oracleCommand, "p_WORKFLOW_INSTANCE_EVENT_ID", AdoDbType.Int64, ParameterDirection.Output); oracleCommand.ExecuteNonQuery(); Int64[] workflowEventIds = (Int64[])workflowEventId.Value; for (Int32 i = 0; i < workflowTrackingRecords.Count; i++) { workflowTrackingRecordsById.Add(workflowEventIds[i], workflowTrackingRecords[i]); } } return(workflowTrackingRecordsById); }
///<summary> ///Commits the list of work items by using the specified <see cref="T:System.Transactions.Transaction"></see> object. ///</summary> /// ///<param name="items">The work items to be committed.</param> ///<param name="transaction">The <see cref="T:System.Transactions.Transaction"></see> associated with the pending work.</param> public void Commit(Transaction transaction, ICollection items) { TraceHelper.Trace(); try { using (ITrackingChannelResourceAccessor resourceAccessor = CreateAccessor(resourceProvider, transaction)) { if (this.workflowInstanceSummary == null) { this.workflowInstanceSummary = resourceAccessor.InsertOrGetWorkflowInstance(buildWorkflowInstanceSummary()); } List <SerialisableActivityTrackingRecord> activityTrackingRecords = new List <SerialisableActivityTrackingRecord>(); List <SerialisableUserTrackingRecord> userTrackingRecords = new List <SerialisableUserTrackingRecord>(); List <SerialisableWorkflowChangeRecord> workflowChangeRecords = new List <SerialisableWorkflowChangeRecord>(); List <SerialisableWorkflowTrackingRecord> workflowTrackingRecords = new List <SerialisableWorkflowTrackingRecord>(); // group each type of tracking record ready for processing foreach (object itemToCommit in items) { if (!(itemToCommit is TrackingRecord)) { continue; } SerialisableActivityTrackingRecord activityTrackingRecord = itemToCommit as SerialisableActivityTrackingRecord; if (activityTrackingRecord != null) { activityTrackingRecords.Add(activityTrackingRecord); continue; } SerialisableUserTrackingRecord userTrackingRecord = itemToCommit as SerialisableUserTrackingRecord; if (userTrackingRecord != null) { userTrackingRecords.Add(userTrackingRecord); continue; } SerialisableWorkflowChangeRecord workflowChangeRecord = itemToCommit as SerialisableWorkflowChangeRecord; if (workflowChangeRecord != null) { workflowChangeRecords.Add(workflowChangeRecord); continue; } SerialisableWorkflowTrackingRecord workflowTrackingRecord = itemToCommit as SerialisableWorkflowTrackingRecord; if (workflowTrackingRecord != null) { workflowTrackingRecords.Add(workflowTrackingRecord); continue; } } // send each category of record off to the resource accessor if (activityTrackingRecords.Count > 0) { resourceAccessor.InsertTrackingRecords(this.workflowInstanceSummary, activityTrackingRecords); } if (userTrackingRecords.Count > 0) { resourceAccessor.InsertTrackingRecords(this.workflowInstanceSummary, userTrackingRecords); } if (workflowTrackingRecords.Count > 0) { resourceAccessor.InsertTrackingRecords(this.workflowInstanceSummary, workflowTrackingRecords); } if (workflowChangeRecords.Count > 0) { resourceAccessor.InsertTrackingRecords(this.workflowInstanceSummary, workflowChangeRecords); } } } catch (Exception e) { string errorMessage = RM.Get_Error_TrackingChannelException(e.ToString()); TraceHelper.Trace(errorMessage); throw new TrackingException(errorMessage, e); } }