/// <summary> /// Serialise a <see cref="ActivityTrackingRecord" /> ready for persistence. /// </summary> /// <param name="activityTrackingRecord"> /// The original <see cref="ActivityTrackingRecord" /> to serialise. /// </param> /// <returns> /// Modified copy of the <see cref="ActivityTrackingRecord" /> containing /// the serialised data. /// </returns> private static SerialisableActivityTrackingRecord buildSerialisableActivityTrackingRecord(ActivityTrackingRecord activityTrackingRecord) { SerialisableActivityTrackingRecord serialisableActivityTrackingRecord = new SerialisableActivityTrackingRecord(); serialisableActivityTrackingRecord.ActivityType = activityTrackingRecord.ActivityType; serialisableActivityTrackingRecord.Annotations.AddRange(activityTrackingRecord.Annotations); serialisableActivityTrackingRecord.ContextGuid = activityTrackingRecord.ContextGuid; serialisableActivityTrackingRecord.EventDateTime = activityTrackingRecord.EventDateTime; serialisableActivityTrackingRecord.EventOrder = activityTrackingRecord.EventOrder; serialisableActivityTrackingRecord.ExecutionStatus = activityTrackingRecord.ExecutionStatus; serialisableActivityTrackingRecord.ParentContextGuid = activityTrackingRecord.ParentContextGuid; serialisableActivityTrackingRecord.QualifiedName = activityTrackingRecord.QualifiedName; if (activityTrackingRecord.Body != null) { for (int i = 0; i < activityTrackingRecord.Body.Count; i++) { serialisableActivityTrackingRecord.Body.Add(buildSerialisableTrackingDataItem(activityTrackingRecord.Body[i])); } } if (activityTrackingRecord.EventArgs != null) { serialisableActivityTrackingRecord.EventArgs = buildSerialisableData(activityTrackingRecord.EventArgs); } return(serialisableActivityTrackingRecord); }
/// <summary> /// Inserts a batch of activity 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="activityTrackingRecords"> /// An <see cref="IList{T}" /> containing a batch of activity 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, SerialisableActivityTrackingRecord> InsertActivityTrackingRecordBatch( WorkflowInstanceSummary workflowInstanceSummary, IList <SerialisableActivityTrackingRecord> activityTrackingRecords) { if (activityTrackingRecords.Count == 0 || activityTrackingRecords.Count > ActivityTrackingBatchSize) { throw new ArgumentOutOfRangeException("activityTrackingRecords"); } Dictionary <Int64, SerialisableActivityTrackingRecord> activityTrackingRecordsById = new Dictionary <Int64, SerialisableActivityTrackingRecord>(); using (OracleCommand oracleCommand = (OracleCommand)CreateCommand("WORKFLOW_TRACKING_PKG.InsertActivityTrackingRecord", CommandType.StoredProcedure)) { Int64[] workflowInstanceIds = new Int64[activityTrackingRecords.Count]; Int64?[] activityInstanceIds = new Int64?[activityTrackingRecords.Count]; String[] activityIdentifiers = new String[activityTrackingRecords.Count]; String[] qualifiedNames = new String[activityTrackingRecords.Count]; Guid[] contextGuids = new Guid[activityTrackingRecords.Count]; Guid[] parentContextGuids = new Guid[activityTrackingRecords.Count]; Int16[] executionStates = new Int16[activityTrackingRecords.Count]; DateTime[] eventDateTimes = new DateTime[activityTrackingRecords.Count]; Int32[] eventOrders = new Int32[activityTrackingRecords.Count]; for (Int32 i = 0; i < activityTrackingRecords.Count; i++) { SerialisableActivityTrackingRecord activityTrackingRecord = activityTrackingRecords[i]; workflowInstanceIds[i] = (Int64)workflowInstanceSummary.InternalId; activityIdentifiers[i] = BuildActivityIdentifier(activityTrackingRecord); activityInstanceIds[i] = FindActivityInstanceInternalId(activityIdentifiers[i]); qualifiedNames[i] = activityTrackingRecord.QualifiedName; contextGuids[i] = activityTrackingRecord.ContextGuid; parentContextGuids[i] = activityTrackingRecord.ParentContextGuid; executionStates[i] = (Int16)activityTrackingRecord.ExecutionStatus; eventDateTimes[i] = activityTrackingRecord.EventDateTime; eventOrders[i] = activityTrackingRecord.EventOrder; } oracleCommand.ArrayBindCount = activityTrackingRecords.Count; AddParameter(oracleCommand, "p_WORKFLOW_INSTANCE_ID", workflowInstanceIds, AdoDbType.Int64); OracleParameter activityInstanceId = (OracleParameter)AddParameter( oracleCommand, "p_ACTIVITY_INSTANCE_ID", activityInstanceIds, AdoDbType.Int64, ParameterDirection.InputOutput); AddParameter(oracleCommand, "p_QUALIFIED_NAME", qualifiedNames, AdoDbType.String); AddParameter(oracleCommand, "p_CONTEXT_GUID", contextGuids, AdoDbType.Guid); AddParameter(oracleCommand, "p_PARENT_CONTEXT_GUID", parentContextGuids, AdoDbType.Guid); AddParameter(oracleCommand, "p_ACTIVITY_STATUS_ID", executionStates, AdoDbType.Int16); AddParameter(oracleCommand, "p_EVENT_DATE_TIME", eventDateTimes, AdoDbType.DateTime); AddParameter(oracleCommand, "p_EVENT_ORDER", eventOrders, AdoDbType.Int32); OracleParameter activityStatusEventId = (OracleParameter)AddParameter( oracleCommand, "p_ACTIVITY_STATUS_EVENT_ID", AdoDbType.Int64, ParameterDirection.Output); oracleCommand.ExecuteNonQuery(); Int64[] populatedActivityInstanceIds = (Int64[])activityInstanceId.Value; Int64[] activityStatusEventIds = (Int64[])activityStatusEventId.Value; for (Int32 i = 0; i < activityTrackingRecords.Count; i++) { if (activityTrackingRecords[i].ExecutionStatus == ActivityExecutionStatus.Closed) { RemoveActivityInstanceInternalId(activityIdentifiers[i]); } else { UpdateActivityInstanceInternalId(activityIdentifiers[i], populatedActivityInstanceIds[i]); } activityTrackingRecordsById.Add(activityStatusEventIds[i], activityTrackingRecords[i]); } } return(activityTrackingRecordsById); }
///<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); } }