99using Microsoft . BizTalk . Message . Interop ;
1010using Microsoft . XLANGs . RuntimeTypes ;
1111using BizTalkComponents . Utils ;
12+ using BizTalkComponents . Utilities . ComponentInstrumentation ;
13+ using System . Runtime . InteropServices ;
14+ using Microsoft . BizTalk . Streaming ;
1215
1316namespace BizTalkComponents . PipelineComponents . HttpDisassembler
1417{
18+
1519 [ System . Runtime . InteropServices . Guid ( "FE75A97A-EB7C-49AF-8778-136FA366A5F4" ) ]
1620 [ ComponentCategory ( CategoryTypes . CATID_PipelineComponent ) ]
1721 [ ComponentCategory ( CategoryTypes . CATID_DisassemblingParser ) ]
1822 public partial class HttpDisassembler : IBaseComponent , IPersistPropertyBag , IComponentUI , IDisassemblerComponent
1923 {
2024 private const string DocumentSpecNamePropertyName = "DocumentSpecName" ;
2125 private readonly Queue _outputQueue = new Queue ( ) ;
26+ private readonly ComponentInstrumentationHelper _instrumentationHelper ;
2227
28+ #if tracking
29+ public HttpDisassembler ( )
30+ {
31+ _instrumentationHelper = new ComponentInstrumentationHelper ( new AppInsightsComponentTracker ( "insert key here" ) , Name ) ;
32+ }
33+ #else
34+ public HttpDisassembler ( )
35+ {
36+ _instrumentationHelper = new ComponentInstrumentationHelper ( new TraceComponentTracker ( ) , Name ) ;
37+ }
38+ #endif
2339 [ RequiredRuntime ]
2440 [ DisplayName ( "DocumentSpecName" ) ]
2541 [ Description ( "DocumentSpec name of the schema to create an instance from." ) ]
@@ -31,11 +47,27 @@ public void Disassemble(IPipelineContext pContext, IBaseMessage pInMsg)
3147
3248 if ( ! Validate ( out errorMessage ) )
3349 {
34- throw new ArgumentException ( errorMessage ) ;
50+ var ex = new ArgumentException ( errorMessage ) ;
51+ _instrumentationHelper . TrackComponentError ( ex ) ;
52+ throw ex ;
3553 }
3654
55+ var data = pInMsg . BodyPart . GetOriginalDataStream ( ) ;
56+
57+ //Determine of the request body has any data. GET request will not have any body.
58+ var hasData = HasData ( data ) ;
59+
3760 //Get a reference to the BizTalk schema.
38- var documentSpec = ( DocumentSpec ) pContext . GetDocumentSpecByName ( DocumentSpecName ) ;
61+ DocumentSpec documentSpec ;
62+ try
63+ {
64+ documentSpec = ( DocumentSpec ) pContext . GetDocumentSpecByName ( DocumentSpecName ) ;
65+ }
66+ catch ( COMException cex )
67+ {
68+ _instrumentationHelper . TrackComponentError ( cex ) ;
69+ throw cex ;
70+ }
3971
4072 //Get a list of properties defined in the schema.
4173 var annotations = documentSpec . GetPropertyAnnotationEnumerator ( ) ;
@@ -64,13 +96,29 @@ public void Disassemble(IPipelineContext pContext, IBaseMessage pInMsg)
6496 ms . Seek ( 0 , SeekOrigin . Begin ) ;
6597
6698 var outMsg = pInMsg ;
67- outMsg . BodyPart . Data = ms ;
6899
69- //Promote message type and SchemaStrongName
70- outMsg . Context . Promote ( new ContextProperty ( SystemProperties . MessageType ) , documentSpec . DocType ) ;
71- outMsg . Context . Promote ( new ContextProperty ( SystemProperties . SchemaStrongName ) , documentSpec . DocSpecStrongName ) ;
100+ //If the request has a body it should be preserved an the query parameters should be written to it's own message part.
101+ if ( hasData )
102+ {
103+ outMsg = pInMsg ;
104+ outMsg . BodyPart . Data = pInMsg . BodyPart . Data ;
105+ outMsg . Context = PipelineUtil . CloneMessageContext ( pInMsg . Context ) ;
106+ var factory = pContext . GetMessageFactory ( ) ;
107+ var queryPart = factory . CreateMessagePart ( ) ;
108+ queryPart . Data = ms ;
109+
110+ outMsg . AddPart ( "querypart" , queryPart , false ) ;
111+ }
112+ else
113+ {
114+ outMsg . BodyPart . Data = ms ;
115+ //Promote message type and SchemaStrongName
116+ outMsg . Context . Promote ( new ContextProperty ( SystemProperties . MessageType ) , documentSpec . DocType ) ;
117+ outMsg . Context . Promote ( new ContextProperty ( SystemProperties . SchemaStrongName ) , documentSpec . DocSpecStrongName ) ;
118+ }
72119
73120 _outputQueue . Enqueue ( outMsg ) ;
121+ _instrumentationHelper . TrackComponentSuccess ( ) ;
74122
75123 }
76124
@@ -93,5 +141,23 @@ public IBaseMessage GetNext(IPipelineContext pContext)
93141
94142 return null ;
95143 }
144+
145+ private bool HasData ( Stream data )
146+ {
147+ byte [ ] buffer = new byte [ 10 ] ;
148+ const int bufferSize = 0x280 ;
149+ const int thresholdSize = 0x100000 ;
150+
151+ if ( ! data . CanSeek || ! data . CanRead )
152+ {
153+ data = new ReadOnlySeekableStream ( data , new VirtualStream ( bufferSize , thresholdSize ) , bufferSize ) ;
154+ }
155+
156+ int num = data . Read ( buffer , 0 , buffer . Length ) ;
157+ data . Seek ( 0 , SeekOrigin . Begin ) ;
158+ data . Position = 0 ;
159+
160+ return num > 0 ;
161+ }
96162 }
97163}
0 commit comments