/// <summary> /// Builds an output interchange from the message that was added by the AddDocument method. /// </summary> /// <param name="pContext">The <see cref="Microsoft.BizTalk.Component.Interop.IPipelineContext"/> that contains the current pipeline context.</param> /// <returns>The <see cref="Microsoft.BizTalk.Message.Interop.IBaseMessage"/> that contains the assembled document.</returns> IBaseMessage IAssemblerComponent.Assemble(IPipelineContext pContext) { Guard.ArgumentNotNull(pContext, "pContext"); // Write a TraceIn event indicating when execution started. var callToken = PipelineTraceManager.TraceIn(pContext.PipelineID, pContext.PipelineName, pContext.StageID, pContext.StageIndex, pContext.ComponentIndex); try { // Store a reference to IPipelineContext as soon as it's known to the component. this.pipelineContext = pContext; // The instance of the benchmark activity to measure execution time for the Assemble method. PipelineComponentBenchmarkActivity benchmarkActivity = null; // A stopwatch object will help accurately measure how long the user-defined portion of the // the Assemble method takes. Stopwatch benchmarkStopwatch = null; // If BAM instrumentation is enabled, begin the benchmark activity to indicate when Assemble phase started. if (EnableActivityTracking) { ActivityBase startedBenchmarkActivity = this.BenchmarkActivity; if (null == startedBenchmarkActivity) { startedBenchmarkActivity = BeginBenchmarkActivity(pContext, Guid.NewGuid().ToString()); } benchmarkActivity = new PipelineComponentBenchmarkActivity(startedBenchmarkActivity.ActivityID); benchmarkActivity.AssembleStarted = DateTime.UtcNow; // Start the stopwatch so that timer starts measuring elapsed time. benchmarkStopwatch = Stopwatch.StartNew(); } // Write the Start event to measure how long it takes to execute the user-defined implementation of the Assemble method. var scopeStarted = PipelineTraceManager.TraceStartScope(this.Name, callToken); // Execute the user-defined implementation of the Assemble method. IBaseMessage outputMessage = Assemble(pContext); // Once finished, write the End event along with calculated duration. PipelineTraceManager.TraceEndScope(this.Name, scopeStarted, callToken); // If BAM instrumentation is enabled, update the benchmark activity to indicate when Assemble phase completed. if (EnableActivityTracking) { // Safety check if benchmarkActivity is initialized (if not, something went wrong) if (benchmarkActivity != null) { // Safety check if benchmarkStopwatch is initialized (if not, something went wrong) if (benchmarkStopwatch != null) { // Stop the timer and record the total elapsed time spent inside Disassemble. benchmarkStopwatch.Stop(); benchmarkActivity.AssembleDurationMs = benchmarkStopwatch.Elapsed.TotalMilliseconds; } // Record the date and time when the Assemble method completed. benchmarkActivity.AssembleCompleted = DateTime.UtcNow; // Complete the benchmark activity as Assemble will be called last. PipelineEventStream.CompleteActivity(benchmarkActivity); } // We are done, check if we should stop the instance-level stopwatch used by AddDocument. if (addDocumentStopwatch != null) { addDocumentStopwatch.Stop(); } } if (outputMessage != null) { PipelineTraceManager.TraceOut(callToken, outputMessage.MessageID, outputMessage.PartCount); } else { PipelineTraceManager.TraceOut(callToken); } return(outputMessage); } catch (Exception e) { // Put component name as a source in this exception so that the error message could reflect this. e.Source = this.Name; // Trace the exception details. PipelineTraceManager.TraceError(e, EnableDetailedExceptions, callToken); // Re-throw the exception so that it can be handled by the caller. throw; } }
/// <summary> /// Gets the next message from the message set resulting from the disassembler execution. /// </summary> /// <param name="pContext">The <see cref="Microsoft.BizTalk.Component.Interop.IPipelineContext"/> for the current pipeline.</param> /// <returns>A pointer to the <see cref="Microsoft.BizTalk.Message.Interop.IBaseMessage"/> containing the next message from the disassembled document. Returns NULL if there are no more messages left.</returns> IBaseMessage IDisassemblerComponent.GetNext(IPipelineContext pContext) { Guard.ArgumentNotNull(pContext, "pContext"); // Write a TraceIn event indicating when execution started. var callToken = PipelineTraceManager.TraceIn(pContext.PipelineID, pContext.PipelineName, pContext.StageID, pContext.StageIndex, pContext.ComponentIndex); try { // The instance of the benchmark activity to measure execution time for the GetNext method. PipelineComponentBenchmarkActivity benchmarkActivity = null; // Check if we are enterting GetNext method for the first time. if (!this.getNextCalled) { this.getNextCalled = true; // If BAM instrumentation is enabled, update the GetNextStarted milestone. if (EnableActivityTracking) { benchmarkActivity = new PipelineComponentBenchmarkActivity(BenchmarkActivity.ActivityID); benchmarkActivity.GetNextStarted = DateTime.UtcNow; PipelineEventStream.UpdateActivity(benchmarkActivity); // Start the stopwatch so that timer starts measuring elapsed time. getNextStopwatch = Stopwatch.StartNew(); } } // Write the Start event to measure how long it takes to execute the user-defined implementation of the GetNext method. var scopeStarted = PipelineTraceManager.TraceStartScope(this.Name, callToken); // Execute the user-defined implementation of the GetNext method. IBaseMessage outputMessage = GetNext(pContext); // Once finished, write the End event along with calculated duration. PipelineTraceManager.TraceEndScope(this.Name, scopeStarted, callToken); if (outputMessage != null) { PipelineTraceManager.TraceOut(callToken, outputMessage.MessageID, outputMessage.PartCount); } else { // If no more messages are available and BAM instrumentation is enabled, update the GetNextCompleted milestone and complete the benchmark activity. if (EnableActivityTracking) { double getNextDurationMs = Double.NaN; // Safety check if getNextStopwatch is initialized (if not, something went wrong) if (getNextStopwatch != null) { // Stop the timer and record the total elapsed time spent inside the entire GetNext phase. getNextStopwatch.Stop(); getNextDurationMs = getNextStopwatch.Elapsed.TotalMilliseconds; } if (null == benchmarkActivity) { benchmarkActivity = new PipelineComponentBenchmarkActivity(BenchmarkActivity.ActivityID); } // Record the date and time when the last GetNext method completed. benchmarkActivity.GetNextCompleted = DateTime.UtcNow; benchmarkActivity.GetNextDurationMs = getNextDurationMs; // Complete the benchmark activity as GetNext returning no results indicates the end of cycle. PipelineEventStream.CompleteActivity(benchmarkActivity); } PipelineTraceManager.TraceOut(callToken); } return(outputMessage); } catch (Exception e) { // Put component name as a source in this exception so that the error message could reflect this. e.Source = this.Name; // Trace the exception details. PipelineTraceManager.TraceError(e, EnableDetailedExceptions, callToken); // Re-throw the exception so that it can be handled by the caller. throw; } }
/// <summary> /// Adds the document to the list of messages that are included in an interchange. /// </summary> /// <param name="pContext">The <see cref="Microsoft.BizTalk.Component.Interop.IPipelineContext"/> that contains the current pipeline context.</param> /// <param name="pInMsg">The <see cref="Microsoft.BizTalk.Message.Interop.IBaseMessage"/> that contains the document to be added to the message set.</param> void IAssemblerComponent.AddDocument(IPipelineContext pContext, IBaseMessage pInMsg) { Guard.ArgumentNotNull(pContext, "pContext"); Guard.ArgumentNotNull(pInMsg, "pInMsg"); // Write a TraceIn event indicating when execution started. var callToken = PipelineTraceManager.TraceIn(pContext.PipelineID, pContext.PipelineName, pContext.StageID, pContext.StageIndex, pContext.ComponentIndex); try { // Store a reference to IPipelineContext as soon as it's known to the component. this.pipelineContext = pContext; // The instance of the benchmark activity to measure execution time for the AddDocument method. PipelineComponentBenchmarkActivity benchmarkActivity = null; // Check if we are entering AddDocument method for the first time. if (!this.addDocumentCalled) { this.addDocumentCalled = true; // If BAM instrumentation is enabled, update the AddDocumentStarted milestone. if (EnableActivityTracking) { ActivityBase startedBenchmarkActivity = this.BenchmarkActivity; if (null == startedBenchmarkActivity) { startedBenchmarkActivity = BeginBenchmarkActivity(pContext, Guid.NewGuid().ToString()); } benchmarkActivity = new PipelineComponentBenchmarkActivity(startedBenchmarkActivity.ActivityID); benchmarkActivity.AddDocumentStarted = DateTime.UtcNow; PipelineEventStream.UpdateActivity(benchmarkActivity); // Start the stopwatch so that timer starts measuring elapsed time. addDocumentStopwatch = Stopwatch.StartNew(); } } // Write the Start event to measure how long it takes to execute the user-defined implementation of the AddDocument method. var scopeStarted = PipelineTraceManager.TraceStartScope(this.Name, callToken); // Execute the user-defined implementation of the AddDocument method. AddDocument(pContext, pInMsg); // Once finished, write the End event along with calculated duration. PipelineTraceManager.TraceEndScope(this.Name, scopeStarted, callToken); // If BAM instrumentation is enabled, update the AddDocumentCompleted milestone. if (EnableActivityTracking) { double addDocumentDurationMs = Double.NaN; // Safety check if getNextStopwatch is initialized (if not, something went wrong) if (addDocumentStopwatch != null) { // Stop the timer and record the total elapsed time spent inside the entire GetNext phase. addDocumentStopwatch.Stop(); addDocumentDurationMs = addDocumentStopwatch.Elapsed.TotalMilliseconds; // Restart the stopwatch since AddDocument is expected to be called multiple times. addDocumentStopwatch.Start(); } ActivityBase startedBenchmarkActivity = this.BenchmarkActivity; if (null == startedBenchmarkActivity) { startedBenchmarkActivity = BeginBenchmarkActivity(pContext, Guid.NewGuid().ToString()); } benchmarkActivity = new PipelineComponentBenchmarkActivity(startedBenchmarkActivity.ActivityID); benchmarkActivity.AddDocumentCompleted = DateTime.UtcNow; benchmarkActivity.AddDocumentDurationMs = addDocumentDurationMs; PipelineEventStream.UpdateActivity(benchmarkActivity); } // Write a TraceOut event indicating when execution finished. PipelineTraceManager.TraceOut(callToken); } catch (Exception e) { // Put component name as a source in this exception so that the error message could reflect this. e.Source = this.Name; // Trace the exception details. PipelineTraceManager.TraceError(e, EnableDetailedExceptions, callToken); // Re-throw the exception so that it can be handled by the caller. throw; } }
/// <summary> /// Provides the explicit implementation of the IComponent.Execute interface method. This enables wrapping the /// user implementation of the Execute method into a fully instrumented scope with tracing, exception handing and /// BAM tracking capability provided "out-of-the-box". /// </summary> /// <param name="pContext">A reference to IPipelineContext object that contains the current pipeline context.</param> /// <param name="pInMsg">A reference to IBaseMessage object that contains the message to process.</param> /// <returns>A reference to the returned IBaseMessage object which will contain the output message.</returns> IBaseMessage IComponent.Execute(IPipelineContext pContext, IBaseMessage pInMsg) { // Validate input arguments. Guard.ArgumentNotNull(pContext, "pContext"); Guard.ArgumentNotNull(pInMsg, "pInMsg"); // Trace the fact that the Execute method has been invoked. var callToken = PipelineTraceManager.TraceIn(pContext.PipelineID, pContext.PipelineName, pContext.StageID, pContext.StageIndex, pContext.ComponentIndex); try { // Store a reference to IPipelineContext as soon as it's known to the component. this.pipelineContext = pContext; // The instance of the benchmark activity to measure execution time for the Execute method. PipelineComponentBenchmarkActivity benchmarkActivity = null; // A stopwatch object will help accurately measure how long the user-defined portion of the // the Execute method takes. Stopwatch benchmarkStopwatch = null; // If BAM instrumentation is enabled, begin the benchmark activity to indicate when Execute phase started. if (EnableActivityTracking) { ActivityBase startedActivity = BeginBenchmarkActivity(pContext, pInMsg.MessageID.ToString()); benchmarkActivity = new PipelineComponentBenchmarkActivity(startedActivity.ActivityID); benchmarkActivity.ExecuteStarted = DateTime.UtcNow; // Start the stopwatch so that timer starts measuring elapsed time. benchmarkStopwatch = Stopwatch.StartNew(); } // Write the Start event to measure how long it takes to execute the user-defined implementation of the Execute method. var scopeStarted = PipelineTraceManager.TraceStartScope(this.Name, callToken); // Execute the user-defined implementation of the Execute method. IBaseMessage outputMessage = Execute(pContext, pInMsg); // Once finished, write the End event along with calculated duration. PipelineTraceManager.TraceEndScope(this.Name, scopeStarted, callToken); // If BAM instrumentation is enabled, update the benchmark activity to indicate when Disassemble phase completed. if (EnableActivityTracking) { // Safety check if benchmarkActivity is initialized (if not, something went wrong) if (benchmarkActivity != null) { // Safety check if benchmarkStopwatch is initialized (if not, something went wrong) if (benchmarkStopwatch != null) { // Stop the timer and record the total elapsed time spent inside Disassemble. benchmarkStopwatch.Stop(); benchmarkActivity.ExecuteDurationMs = benchmarkStopwatch.Elapsed.TotalMilliseconds; } // Record the date and time when the Execute method completed. benchmarkActivity.ExecuteCompleted = DateTime.UtcNow; PipelineEventStream.CompleteActivity(benchmarkActivity); } } // Check if the user-defined implementation of the Execute method returned any message. if (outputMessage != null) { // Trace the fact that the Execute method is completed and add extra data items (message ID and part count) to the trace log. PipelineTraceManager.TraceOut(callToken, outputMessage.MessageID, outputMessage.PartCount); } else { // Trace the fact that the Execute method is completed. PipelineTraceManager.TraceOut(callToken); } return(outputMessage); } catch (Exception e) { // Put component name as a source in this exception so that the error message could reflect this. e.Source = this.Name; // Trace the exception details. PipelineTraceManager.TraceError(e, EnableDetailedExceptions, callToken); // Re-throw the exception so that it can be handled by the caller. throw; } }