/// <summary> /// Serialise a <see cref="WorkflowTrackingRecord" /> ready for persistence. This /// method deals with WorkflowTrackingRecords that contain workflow change /// details. /// </summary> /// <param name="workflowTrackingRecord"> /// The original <see cref="WorkflowTrackingRecord" /> to serialise. /// </param> /// <returns> /// Modified copy of the <see cref="WorkflowTrackingRecord" /> containing /// serialised data. /// </returns> private static SerialisableWorkflowChangeRecord buildSerialisableWorkflowChangeTrackingRecord(WorkflowTrackingRecord workflowTrackingRecord) { SerialisableWorkflowChangeRecord serialisableWorkflowChangeRecord = new SerialisableWorkflowChangeRecord(); serialisableWorkflowChangeRecord.Annotations.AddRange(workflowTrackingRecord.Annotations); serialisableWorkflowChangeRecord.EventDateTime = workflowTrackingRecord.EventDateTime; serialisableWorkflowChangeRecord.EventOrder = workflowTrackingRecord.EventOrder; serialisableWorkflowChangeRecord.TrackingWorkflowEvent = workflowTrackingRecord.TrackingWorkflowEvent; if (workflowTrackingRecord.EventArgs != null && workflowTrackingRecord.EventArgs is TrackingWorkflowChangedEventArgs) { TrackingWorkflowChangedEventArgs eventArgs = (TrackingWorkflowChangedEventArgs)workflowTrackingRecord.EventArgs; serialisableWorkflowChangeRecord.EventArgs = buildSerialisableTrackingWorkflowChangedEventArgs(eventArgs); } return(serialisableWorkflowChangeRecord); }
/// <summary> /// Inserts a batch of workflow change 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="workflowChangeRecords"> /// An <see cref="IList{T}" /> containing a batch of workflow change /// 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, SerialisableWorkflowChangeRecord> InsertWorkflowChangeRecordBatch( WorkflowInstanceSummary workflowInstanceSummary, IList <SerialisableWorkflowChangeRecord> workflowChangeRecords) { if (workflowChangeRecords.Count == 0 || workflowChangeRecords.Count > WorkflowChangeBatchSize) { throw new ArgumentOutOfRangeException("workflowChangeRecords"); } Dictionary <Int64, SerialisableWorkflowChangeRecord> workflowChangeRecordsById = new Dictionary <Int64, SerialisableWorkflowChangeRecord>(); using (OracleCommand oracleCommand = (OracleCommand)CreateCommand("WORKFLOW_TRACKING_PKG.InsertWorkflowTrackingRecord", CommandType.StoredProcedure)) { Int64[] workflowInstanceIds = new Int64[workflowChangeRecords.Count]; Int16[] statusIds = new Int16[workflowChangeRecords.Count]; DateTime[] eventDateTimes = new DateTime[workflowChangeRecords.Count]; Int32[] eventOrders = new Int32[workflowChangeRecords.Count]; String[] eventArgTypeNames = new String[workflowChangeRecords.Count]; String[] eventArgAssemblyNames = new String[workflowChangeRecords.Count]; Byte[][] eventArgs = new Byte[workflowChangeRecords.Count][]; for (Int32 i = 0; i < workflowChangeRecords.Count; i++) { SerialisableWorkflowChangeRecord workflowChangeRecord = workflowChangeRecords[i]; workflowInstanceIds[i] = (Int64)workflowInstanceSummary.InternalId; statusIds[i] = (Int16)workflowChangeRecord.TrackingWorkflowEvent; eventDateTimes[i] = workflowChangeRecord.EventDateTime; eventOrders[i] = workflowChangeRecord.EventOrder; if (workflowChangeRecord.EventArgs != null) { eventArgTypeNames[i] = workflowChangeRecord.EventArgs.Type.FullName; eventArgAssemblyNames[i] = workflowChangeRecord.EventArgs.Type.Assembly.FullName; eventArgs[i] = workflowChangeRecord.EventArgs.SerialisedData; } } oracleCommand.ArrayBindCount = workflowChangeRecords.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 < workflowChangeRecords.Count; i++) { workflowChangeRecordsById.Add(workflowEventIds[i], workflowChangeRecords[i]); } } return(workflowChangeRecordsById); }
///<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); } }