tag:blogger.com,1999:blog-63157948333979795822024-03-09T00:55:45.156+00:00Biztalk DevelopmentA look at BizTalk Server from the sharp end. Development hints, tips and observations from a programmers perspective.Unknownnoreply@blogger.comBlogger21125tag:blogger.com,1999:blog-6315794833397979582.post-60595106908629075292010-12-04T12:47:00.002+00:002010-12-04T12:52:10.242+00:00Scope TimeoutsI had an instance recently where a scope in an orchestration would timeout pretty much instantly despite having a timeout period of 10 seconds. This was a real head-scratcher and I couldn't see where the issue was.<div>After discussing with a colleague we stumbled upon a difference in the clock time between the application server (where the orchestration runs) and the biztalk message box server. The time difference was almost 10 seconds leading to the "inst ant" timeout. A quick look in the event log indicated a problem with the NTP service and the domain controller (another story!) causing the system time to drift out. Correcting the clock fixed my timeout problem. </div>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-6315794833397979582.post-22202260321542492192010-08-04T09:44:00.003+01:002010-08-04T09:48:53.937+01:00Host Startup FailureIn my experience, the failure to start a host instance is most often caused by an error in the BizTalk config file btsntsvc.exe.config. This can be because it is not well-formed XML or the content is incorrect.<br />For example recently I had to investigate an issue with automated unit test failures which turned out to be caused by an incorrect config file update. A WCF client endpoint had been added outside of the <client> element. The error I saw in the event log was:<br /><br /><span style="font-size:85%;"><span style="font-family: courier new;">A failure occurred when executing a Windows service request.</span><br /><span style="font-family: courier new;"> </span><br /><span style="font-family: courier new;"> Service request: Start </span><br /><span style="font-family: courier new;"> </span><br /><span style="font-family: courier new;"> BizTalk host name: BizTalkServerApplication</span><br /><span style="font-family: courier new;"> Windows service name: BTSSvc$BizTalkServerApplication </span><br /><span style="font-family: courier new;"> </span><br /><span style="font-family: courier new;"> Additional error information:</span><br /><span style="font-family: courier new;"> Error code: 0xc0c0153a</span><br /><span style="font-family: courier new;"> Error source: BizTalk Server 2009</span><br /><span style="font-family: courier new;"> Error description: A BizTalk subservice has failed while executing a service request.</span><br /><span style="font-family: courier new;"> </span><br /><span style="font-family: courier new;"> Subservice: Tracking</span><br /><span style="font-family: courier new;"> Service request: Start </span><br /><span style="font-family: courier new;"> </span><br /><span style="font-family: courier new;"> Additional error information:</span><br /><span style="font-family: courier new;"> Error code: 0x80131534</span><br /><span style="font-family: courier new;"> Error source: System.Data</span><br /><span style="font-family: courier new;"> Error description: The type initializer for 'System.Data.SqlClient.SqlConnection' threw an exception.</span><br /></span>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-6315794833397979582.post-48039041984233272692009-12-17T22:24:00.001+00:002009-12-17T22:24:39.316+00:00TechEd Europe 2009<p>I had a great time at TechEd Europe in Berlin in November. Just wanted to say thanks to Stephen Kaufman, Paolo Salvatori, Markus Landler and everyone else on the BizTalk stand for their time and knowledge.</p> Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-6315794833397979582.post-71172691685758211602009-12-17T22:20:00.001+00:002009-12-17T22:20:01.436+00:00Orchestrations, Serialization and WaitHandles<p>A common pattern I use in BizTalk development is to create an orchestration with an associated C# library. The orchestration does what it does best (i.e. orchestrate the business process) and the library is where most of the underlying business logic code lives. This also allows the business logic to be called from other non-orchestration based code if required.</p> <p>In a recent scenario, the library code lent itself well to a multithreaded approach, consisting of a number of small, independent tasks which could be executed in parallel. I implemented this using a ThreadPool and used ManualResetEvent instances to enable the threads to signal when complete. The WaitHandle.WaitAll allowed the main thread to wait until all the tasks were complete before continuing. This worked fine and all my unit tests ran successfully.</p> <p>Then I tried calling it from an orchestration and got the dreaded serialization error advising that ManualResetEvent is not serializable. This was occurring when I hit a persistence point in the orchestration causing my instance of the library to be serialized, in this case unsuccessfully.</p> <p>One possible solution to this is the use of an atomic scope to prevent persistence, allowing non-serializable classes to be used. However, this is not recommended and in my case not really practical anyway given the structure of the orchestration. After considering this and other solutions, I finally settled on creating a custom notifier class that would allow the main thread to wait until all threads signalled they are complete. This would perform the same role as ManualResetEvent/WaitHandle but would be serializable. </p> <p>A simple example of this follows below. The <strong>Notifier</strong> class has just two methods: <strong>SetOne</strong> which allows each individual worker thread to signal it is complete, and <strong>Wait</strong> which enables the main thread to wait until either all worker threads are finished or a timeout period expires. This uses the static <strong>Pulse</strong> and <strong>Wait</strong> methods of the <strong>System.Threading.Monitor</strong> class to manage the signalling and waiting, providing an efficient, but serializable way to handle this pattern without resorting to a poll/sleep loop. The Notifier instance is passed to each worker thread (in much the same way as a ManualResetEvent would) allowing each thread to signal completion.</p> <pre class="code">[<span style="color: #2b91af">Serializable</span>()]<br /> <span style="color: blue">public class </span><span style="color: #2b91af">Notifier<br /> </span>{<br /> <span style="color: blue">private bool </span>m_blnAllWorkItemsCompleted = <span style="color: blue">false</span>;<br /> <span style="color: blue">private </span><span style="color: #2b91af">Int32 </span>m_i32CompletedWorkItems = 0;<br /> <span style="color: blue">private </span><span style="color: #2b91af">Int32 </span>m_i32WorkItemCount = 0;<br /> <span style="color: blue">private object </span>m_locker = <span style="color: blue">new object</span>();<br /><br /> <span style="color: blue">public </span>Notifier(<span style="color: #2b91af">Int32 </span>workItemCount)<br /> {<br /> m_i32WorkItemCount = workItemCount;<br /> }<br /><br /> <span style="color: blue">public void </span>SetOne()<br /> {<br /> <span style="color: blue">lock </span>(m_locker)<br /> {<br /> <span style="color: green">// Increment the completed work item count<br /> </span>m_i32CompletedWorkItems++;<br /><br /> <span style="color: green">// Check if all work items are complete<br /> </span><span style="color: blue">if </span>(m_i32CompletedWorkItems == m_i32WorkItemCount)<br /> {<br /> <span style="color: green">// All complete so send pulse notification to stop the wait<br /> </span>m_blnAllWorkItemsCompleted = <span style="color: blue">true</span>;<br /> <span style="color: #2b91af">Monitor</span>.Pulse(m_locker);<br /> }<br /> }<br /> }<br /><br /> <span style="color: blue">public bool </span>Wait(<span style="color: #2b91af">Int32 </span>timeout)<br /> {<br /> <span style="color: blue">lock </span>(m_locker)<br /> {<br /> <span style="color: green">// Wait until the pulse is received or the timeout period expires<br /> </span><span style="color: #2b91af">Monitor</span>.Wait(m_locker, timeout);<br /><br /> <span style="color: green">// Return an indication of whether the work was completed<br /> </span><span style="color: blue">return </span>m_blnAllWorkItemsCompleted;<br /> }<br /> }<br /> }</pre><br /><br /><pre class="code"><span style="color: blue">class </span><span style="color: #2b91af">Program<br /></span>{<br /> <span style="color: blue">const </span><span style="color: #2b91af">Int32 </span>THREAD_COUNT = 5;<br /><br /> <span style="color: blue">static void </span>Main(<span style="color: blue">string</span>[] args)<br /> {<br /> <span style="color: green">// Create a new Notifier<br /> </span><span style="color: #2b91af">Notifier </span>notifier = <span style="color: blue">new </span><span style="color: #2b91af">Notifier</span>(THREAD_COUNT);<br /><br /> <span style="color: blue">for </span>(<span style="color: blue">int </span>i = 0; i < THREAD_COUNT; i++)<br /> {<br /> <span style="color: green">// Create state to pass through to the new thread<br /> // Includes the notifier so that the thread can signal back<br /> </span><span style="color: #2b91af">ThreadState </span>state = <span style="color: blue">new </span><span style="color: #2b91af">ThreadState</span>(i, notifier);<br /><br /> <span style="color: green">// Spawn a new thread to do a single split item<br /> </span><span style="color: #2b91af">ThreadPool</span>.QueueUserWorkItem(MyThreadProc, state);<br /> }<br /><br /> <span style="color: green">// Wait for 5 seconds for all threads to complete<br /> </span><span style="color: blue">if </span>(notifier.Wait(5000))<br /> {<br /> <span style="color: #2b91af">Console</span>.WriteLine(<span style="color: #a31515">"All threads completed"</span>);<br /> }<br /> <span style="color: blue">else<br /> </span>{<br /> <span style="color: #2b91af">Console</span>.WriteLine(<span style="color: #a31515">"Notifier timed out"</span>);<br /> }<br /><br /> <span style="color: #2b91af">Console</span>.ReadLine();<br /> }<br /><br /> <span style="color: blue">private static void </span>MyThreadProc(<span style="color: blue">object </span>stateInfo)<br /> {<br /> <span style="color: green">// Get the state passed in from the main thread<br /> </span><span style="color: #2b91af">ThreadState </span>myState = (<span style="color: #2b91af">ThreadState</span>)stateInfo;<br /> <span style="color: #2b91af">Notifier </span>notifier = myState.Notifier;<br /> <span style="color: #2b91af">Int32 </span>i32Id = myState.Id;<br /><br /> <span style="color: green">// Wait for a random period to simulate work<br /> </span><span style="color: #2b91af">Thread</span>.Sleep(RandomNumber(500, 2000));<br /><br /> <span style="color: green">// Notify that the work is complete<br /> </span><span style="color: #2b91af">Console</span>.WriteLine(<span style="color: #2b91af">String</span>.Format(<span style="color: #a31515">"[{0}] thread complete."</span>, i32Id));<br /> notifier.SetOne();<br /> }<br /><br /> <span style="color: blue">private static int </span>RandomNumber(<span style="color: blue">int </span>min, <span style="color: blue">int </span>max)<br /> {<br /> <span style="color: #2b91af">Random </span>random = <span style="color: blue">new </span><span style="color: #2b91af">Random</span>();<br /> <span style="color: blue">return </span>random.Next(min, max);<br /> }<br />}<br /><br />[<span style="color: #2b91af">Serializable</span>()]<br /><span style="color: blue">class </span><span style="color: #2b91af">ThreadState<br /></span>{<br /> <span style="color: blue">public int </span>Id { <span style="color: blue">get</span>; <span style="color: blue">set</span>; }<br /> <span style="color: blue">public </span><span style="color: #2b91af">Notifier </span>Notifier { <span style="color: blue">get</span>; <span style="color: blue">set</span>; }<br /><br /> <span style="color: blue">public </span>ThreadState(<span style="color: blue">int </span>id, <span style="color: #2b91af">Notifier </span>notifier)<br /> {<br /> <span style="color: blue">this</span>.Id = id;<br /> <span style="color: blue">this</span>.Notifier = notifier;<br /> }<br />}</pre><br /><br /><p><a href="http://11011.net/software/vspaste"></a>I found <a href="http://www.albahari.com/threading/part4.aspx" target="_blank">this article</a> very helpful during my research for this code. Hope you find this useful too.</p> Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-6315794833397979582.post-38475824010511016232009-12-06T23:38:00.001+00:002009-12-06T23:38:51.588+00:00BizTalk 2009 IDE Issues<p>In my <a href="http://biztalk-dev.blogspot.com/2009/07/changing-variable-type-in-orchestration.html" target="_blank">last post</a> (too long ago but hey I’ve been busy) I stated that the BizTalk 2009 Visual Studio integration is very good. How wrong could I be! I think I may have spoken too soon.</p> <p>Over the past few months I have experienced numerous problems around project references and orchestration corruption. It’s got to the point where I have to take very regular backups of any orchestration I am working on just in case. This has been the experience of several colleagues too.</p> <p>Recently I have been testing a patch issued by the BizTalk product team to resolve some of these issues. This has been pretty good and after 3 weeks I had not had any problems, until last week. The same orchestration corruption reappeared though I have been unable to recreate it since.</p> <p>I’m currently awaiting feedback from the product team regarding this issue. Hopefully soon we’ll all have the IDE experience that we should have had when BizTalk 2009 was released.</p> Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-6315794833397979582.post-81801299347500915342009-07-11T22:50:00.001+01:002009-07-11T22:50:14.908+01:00Changing variable type in Orchestration Designer<p>In general the BizTalk 2009 Visual Studio integration is very good, however it doesn't seem very receptive to change. An annoyance I found recently in the Orchestration Designer occurred when I tried to change the type of an existing orchestration variable. This caused the project to no longer compile. The solution was to delete the variable and recreate it. This only took a few seconds but should not be necessary.</p> Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-6315794833397979582.post-6574807145829483262009-06-06T19:59:00.001+01:002009-06-06T20:00:05.636+01:00Unit Testing With XLANGMessage<p>As a rule I generally try to pass messages from BizTalk orchestrations into .NET components using the <font size="3" face="Consolas">Microsoft.XLANGs.BaseTypes.XLANGMessage</font> object. This is an abstract base class used by the orchestration engine to represent a message and provides a performant way of marshalling message content without having to resort to using an XMLDocument. For more detail on the benefits of XLANGMessage see <a href="http://www.masteringbiztalk.com/blogs/jon/PermaLink,guid,e39cd386-0e62-46c6-87b6-3625f9a80d6d.aspx" target="_blank">Jon Flanders' post on the subject</a>.</p> <p>Anyhow, whilst using XLANGMessage is a real boon for BizTalk based applications, it does raise problems when trying to write unit tests. How do I write a test for a class that uses XLANGMessage in its interface without resorting to creating an orchestration, deploying a BizTalk app, dealing with File adapters etc? </p> <p>Well the solution I have adopted is to create mock XLANGMessage and XLANGPart classes that use generics to allow a specified object type to be returned when calling the <font size="3" face="Consolas">RetrieveAs</font> method. I typically use this in conjunction with a class generated from the underlying message schema using the XSD tool. I can then write simple unit test code such as:</p> <pre class="code"><span style="color: blue">void </span>Test()<br />{<br /> <span style="color: green">// Create and populate a new message class instance.<br /> // Typically this would be done by deserializing an XML string.<br /> </span><span style="color: #2b91af">MyMessageClass </span>msg = <span style="color: blue">new </span><span style="color: #2b91af">MyMessageClass</span>();<br /><br /> <span style="color: green">// Create a new mock XLANGMessage to wrap the message<br /> </span><span style="color: #2b91af">MockXLANGMessage</span><<span style="color: #2b91af">MyMessageClass</span>> xlang <br /> = <span style="color: blue">new </span><span style="color: #2b91af">MockXLANGMessage</span><<span style="color: #2b91af">MyMessageClass</span>>(msg);<br /><br /> <span style="color: green">// Call the method on the class to be tested <br /> // passing in the mock XLANGMessage<br /> </span><span style="color: #2b91af">MyClassToBeTested</span>.DoSomething(xlang);<br />}</pre><br /><br /><p>where the class to be tested looks like:</p><br /><br /><pre class="code"><span style="color: blue">class </span><span style="color: #2b91af">MyClassToBeTested<br /></span>{ <br /> <span style="color: blue">static void </span>DoSomething(<span style="color: #2b91af">XLANGMessage </span>msg)<br /> {<br /> <span style="color: #2b91af">MyMessageClass </span>reader =<br /> (<span style="color: #2b91af">MyMessageClass</span>)msg[0].RetrieveAs(<span style="color: blue">typeof</span>(<span style="color: #2b91af">MyMessageClass</span>));<br /> } <br />}</pre><br /><br /><p>As you can see this is pretty simple code but works very effectively. But the real meat of this is the mock classes. So what do they look like? Here are simple versions which you can enhance to flesh them out if required. The key bit is the use of the generic class which provides the flexibility to wrap any class. This is utilised in the <strong>RetrieveAs</strong> implementation.</p><br /><br /><pre class="code"><span style="color: blue">public class </span><span style="color: #2b91af">MockXLANGPart</span><T> : <span style="color: #2b91af">XLANGPart<br /></span>{<br /> T m_obj;<br /><br /> <span style="color: blue">public </span>MockXLANGPart(T obj)<br /> {<br /> m_obj = obj;<br /> }<br /><br /> <span style="color: blue">public override void </span>Dispose()<br /> {<br /> }<br /><br /> <span style="color: blue">public override object </span>GetPartProperty(<span style="color: #2b91af">Type </span>propType)<br /> {<br /> <span style="color: blue">throw new </span><span style="color: #2b91af">NotImplementedException</span>();<br /> }<br /><br /> <span style="color: blue">public override </span><span style="color: #2b91af">Type </span>GetPartType()<br /> {<br /> <span style="color: blue">throw new </span><span style="color: #2b91af">NotImplementedException</span>();<br /> }<br /><br /> <span style="color: blue">public override string </span>GetXPathValue(<span style="color: blue">string </span>xpath)<br /> {<br /> <span style="color: blue">throw new </span><span style="color: #2b91af">NotImplementedException</span>();<br /> }<br /><br /> <span style="color: blue">public override void </span>LoadFrom(<span style="color: blue">object </span>source)<br /> {<br /> <span style="color: blue">throw new </span><span style="color: #2b91af">NotImplementedException</span>();<br /> }<br /><br /> <span style="color: blue">public override string </span>Name<br /> {<br /> <span style="color: blue">get </span>{ <span style="color: blue">return </span><span style="color: #a31515">"MockXLANGPart"</span>; }<br /> }<br /><br /> <span style="color: blue">public override void </span>PrefetchXPathValue(<span style="color: blue">string </span>xpath)<br /> {<br /> <span style="color: blue">throw new </span><span style="color: #2b91af">NotImplementedException</span>();<br /> }<br /><br /> <span style="color: blue">public override object </span>RetrieveAs(<span style="color: #2b91af">Type </span>t)<br /> {<br /> <span style="color: blue">if </span>(t == <span style="color: blue">typeof</span>(T))<br /> {<br /> <span style="color: blue">return </span>m_obj;<br /> }<br /><br /> <span style="color: blue">return null</span>;<br /> }<br /><br /> <span style="color: blue">public override void </span>SetPartProperty(<span style="color: #2b91af">Type </span>propType, <span style="color: blue">object </span>value)<br /> {<br /> <span style="color: blue">throw new </span><span style="color: #2b91af">NotImplementedException</span>();<br /> }<br /><br /> <span style="color: blue">public override </span>System.Xml.Schema.<span style="color: #2b91af">XmlSchema </span>XmlSchema<br /> {<br /> <span style="color: blue">get </span>{ <span style="color: blue">throw new </span><span style="color: #2b91af">NotImplementedException</span>(); }<br /> }<br /><br /> <span style="color: blue">public override </span>System.Xml.Schema.<span style="color: #2b91af">XmlSchemaCollection </span>XmlSchemaCollection<br /> {<br /> <span style="color: blue">get </span>{ <span style="color: blue">throw new </span><span style="color: #2b91af">NotImplementedException</span>(); }<br /> }<br />}<br /><br /><span style="color: blue">public class </span><span style="color: #2b91af">MockXLANGMessage</span><T> : <span style="color: #2b91af">XLANGMessage<br /></span>{<br /> <span style="color: #2b91af">List</span><<span style="color: #2b91af">MockXLANGPart</span><T>> m_parts = <span style="color: blue">new </span><span style="color: #2b91af">List</span><<span style="color: #2b91af">MockXLANGPart</span><T>>();<br /><br /> <span style="color: blue">public </span>MockXLANGMessage(T obj)<br /> {<br /> m_parts.Add(<span style="color: blue">new </span><span style="color: #2b91af">MockXLANGPart</span><T>(obj));<br /> }<br /><br /> <span style="color: blue">public override void </span>AddPart(<span style="color: blue">object </span>part, <span style="color: blue">string </span>partName)<br /> {<br /> <span style="color: blue">throw new </span><span style="color: #2b91af">NotImplementedException</span>();<br /> }<br /><br /> <span style="color: blue">public override void </span>AddPart(<span style="color: #2b91af">XLANGPart </span>part, <span style="color: blue">string </span>partName)<br /> {<br /> <span style="color: blue">throw new </span><span style="color: #2b91af">NotImplementedException</span>();<br /> }<br /><br /> <span style="color: blue">public override void </span>AddPart(<span style="color: #2b91af">XLANGPart </span>part)<br /> {<br /> <span style="color: blue">throw new </span><span style="color: #2b91af">NotImplementedException</span>();<br /> }<br /><br /> <span style="color: blue">public override int </span>Count<br /> {<br /> <span style="color: blue">get </span>{ <span style="color: blue">return </span>m_parts.Count; }<br /> }<br /><br /> <span style="color: blue">public override void </span>Dispose()<br /> {<br /> }<br /><br /> <span style="color: blue">public override </span>System.Collections.<span style="color: #2b91af">IEnumerator </span>GetEnumerator()<br /> {<br /> <span style="color: blue">return </span>m_parts.GetEnumerator();<br /> }<br /><br /> <span style="color: blue">public override object </span>GetPropertyValue(<span style="color: #2b91af">Type </span>propType)<br /> {<br /> <span style="color: blue">throw new </span><span style="color: #2b91af">NotImplementedException</span>();<br /> }<br /><br /> <span style="color: blue">public override string </span>Name<br /> {<br /> <span style="color: blue">get </span>{ <span style="color: blue">return </span><span style="color: #a31515">"MockXLANGMessage"</span>; }<br /> }<br /><br /> <span style="color: blue">public override void </span>SetPropertyValue(<span style="color: #2b91af">Type </span>propType, <span style="color: blue">object </span>value)<br /> {<br /> <span style="color: blue">throw new </span><span style="color: #2b91af">NotImplementedException</span>();<br /> }<br /><br /> <span style="color: blue">public override </span><span style="color: #2b91af">XLANGPart </span><span style="color: blue">this</span>[<span style="color: blue">int </span>partIndex]<br /> {<br /> <span style="color: blue">get </span>{ <span style="color: blue">return </span>m_parts[partIndex]; }<br /> }<br /><br /> <span style="color: blue">public override </span><span style="color: #2b91af">XLANGPart </span><span style="color: blue">this</span>[<span style="color: blue">string </span>partName]<br /> {<br /> <span style="color: blue">get </span>{ <span style="color: blue">return </span>m_parts[0]; }<br /> }<br />}</pre><br /><a href="http://11011.net/software/vspaste"></a><br /><br /><p>My thanks to Anil Prasad for putting me onto this technique.</p> Unknownnoreply@blogger.com3tag:blogger.com,1999:blog-6315794833397979582.post-53323534192076776432009-04-28T23:00:00.001+01:002009-04-28T23:00:06.794+01:00Where did I leave my HAT?<p>Following an upgrade to BizTalk 2009 you may be left wondering where the Health and Activity Tracking (HAT) Tool has disappeared to. The Start Menu group for BizTalk 2009 no longer contains a link to HAT.</p> <p>The answer lies in the BizTalk Administration Console MMC Snap-in. If you navigate to the Group Hub and select New Query you will see some new entries in the <strong>Value</strong> column such as <strong>Tracked Service Instances</strong>. This will retrieve data in the same way that the HAT queries did.</p> <p><a href="http://lh4.ggpht.com/_qTYjbNvQ0YY/Sfd8ZCNMgQI/AAAAAAAAAKE/iyTT9gIWET4/s1600-h/hat%5B3%5D.jpg"><img style="border-right: 0px; border-top: 0px; margin: 0px 10px 10px 0px; border-left: 0px; border-bottom: 0px" height="126" alt="hat" src="http://lh5.ggpht.com/_qTYjbNvQ0YY/Sfd8ZlFLGpI/AAAAAAAAAKI/eGDLOhBNXi4/hat_thumb%5B1%5D.jpg?imgmax=800" width="244" align="left" border="0" /></a> Right clicking on one of the resultset entries will offer the same options as HAT used to e.g. Message Flow, Orchestration Debugger. Navigate into one of these options presents the same interface as HAT always used to. </p> <p>In fact HAT is still there under the covers, it's just been integrated into the Admin Console rather than running as a separate application. Try looking in the Task Manager list of running processes and you'll see <em>BTSHatApp.exe</em>. </p> <p>HAT is dead...long live HAT.</p> Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-6315794833397979582.post-51160556306238516102009-04-23T20:43:00.002+01:002009-04-23T20:47:12.164+01:00How to find the BizTalk Edition installedI recently had to find the edition of an existing BizTalk installation on a test server. Initially I thought this would be a case of looking at a few Help > About dialogs in the admin tools. However, it turns out that this is stored in the registry under<br /><br /><div><div><span style="font-family: courier new;">HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\BizTalk Server\3.0\ProductEdition</span><br /><br /></div></div>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-6315794833397979582.post-30347581513121908132009-03-08T12:17:00.006+00:002009-03-08T12:55:34.640+00:00MSBTS_SendAdapter doesn't work!Just a quick post as a reminder to me (and a pointer for anyone else who happens upon this blog) to save lots of time scratching my head, looking at code that should work but doesn't.<br /><br />I wrote some code as part of a BizTalk deployment framework which was intended to create an adapter handler if one does not already exist for the specified adapter/host. The Receive handler version worked fine but the Send version gave some strange results.<br /><br />First I queried the existence of the send handler via WMI using MSBTS_SendHandler. This always returned an empty set indicating that it doesn't (even when the handler does in fact exist). When trying to create a send handler I got an error message (will update with exact text when I get a chance to look).<br /><br />Anyway, to cut a long story short it turns out that MSBTS_SendHandler2 works fine so the guidance is to use this instead. My question is though - why does MSBTS_SendHandler still exist at all? It can't be for backwards compatibility because IT DOESN'T WORK! Why not just fix MSBTS_SendHandler instead of adding MSBTS_SendHandler2? Answers on a postcard to...Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-6315794833397979582.post-72126214909205287642008-12-24T14:43:00.001+00:002008-12-24T14:43:48.214+00:00Identifying a BizTalk process<p>When using multiple BizTalk Hosts the process relating to each host can be identified using the following command line instruction:</p> <p><font face="Consolas" size="3">tasklist /SVC /FI "IMAGENAME eq btsntsvc.exe"</font></p> <p>This will display a list of BizTalk processes with the name of the Host and the PID. Note the PID for the host you are interested in. Match the correct PID with the process listed in Task Manager or the Visual Studio  Attach To Process dialog.</p> Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-6315794833397979582.post-24023150856987223262008-12-23T21:59:00.001+00:002008-12-23T21:59:34.741+00:00Resolving Schema Type Name Clashes<p>A common schema related error that may occur when building BizTalk projects that include schemas is:</p> <p><font face="Consolas" size="3">BEC2017: Node "<Schema>" - This schema file has a TypeName that collides with the RootNode TypeName of one of its root nodes. Make sure that they are different.</font></p> <p>The reason for this is quite simple - when the project is compiled, a .NET class will be generated for each top level element in your schema. If you have two schemas which share the same top level element name a clash will occur.</p> <p>This is quite a common scenario and it is not always practical (or even possible) to change the element names. The solution is to change the generated type name for the schema. To do so, select the schema in the Solution Explorer and press F4 to display the Properties window. Then change the Type Name property so that it is not the same as any of the top level elements. </p> Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-6315794833397979582.post-86726558834810203382008-12-22T19:39:00.001+00:002008-12-22T19:39:49.651+00:00Default content in Maps<p>On a couple of occasions recently I have hit upon the need to use default content in some elements of a message generated via a map. More specifically I had an orchestration which did the following:</p> <ul> <li>Defined an input and output schema that contained a standard header section</li> <li>Makes calls to external .NET components, other orchestrations and send ports</li> <li>If all works OK, a suitable response message is returned</li> <li>In the event of a failure, an exception handler is invoked which constructs a new message to send to a common error logging orchestration before creating and returning a response message to the caller</li> </ul> <p>The area of interest is the message sent to the error logging orchestration. This schema contains the standard header along with error information to be logged (for which each element defined as a distinguished field) i.e.</p> <p><font face="Consolas" size="3"><xsd:element name="exception_details"> <br />  <xsd:complexType> <br />    <xsd:sequence> <br />      <xsd:element name="<strong>type</strong>" type="xsd:string" /> <br />      <xsd:element name="<strong>description</strong>" type="xsd:string" /> <br />      <xsd:element name="<strong>error_source</strong>" type="xsd:string" /> <br />      <xsd:element name="<strong>details</strong>" type="xsd:string" /> <br />    </xsd:sequence> <br />  </xsd:complexType> <br /></xsd:element> </font></p> <p>To create an instance of this message I transform the original request (to create the standard header) and insert the error details via code in a message assignment shape.</p> <p><a href="http://lh6.ggpht.com/_qTYjbNvQ0YY/SU_s_Rqlz_I/AAAAAAAAAIA/ptQu-IkthgU/s1600-h/image%5B2%5D.png"><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="207" alt="image" src="http://lh5.ggpht.com/_qTYjbNvQ0YY/SU_s_siThSI/AAAAAAAAAIE/-oerL-j2feQ/image_thumb.png?imgmax=800" width="244" border="0" /></a> </p> <p><font face="Consolas" size="3">msgException.exception_details.description = ex.Message; <br />msgException.exception_details.details = ex.ToString(); <br />msgException.exception_details.error_source = "orch name"; <br />msgException.exception_details.type = "details here";</font></p> <p>However, in order to programmatically insert the content into these elements, the elements had to exist in the new message! If it does not I get an XPath error when trying to set the distinguished property values.</p> <p>To ensure that the elements exist I used the useful but often overlooked property of the element - <strong>Value</strong>. To find this open the Map Designer, select the target element and go to the Properties window. There you will see a Value property which can be used to set a default value for the element or <empty>. In this case <empty> was most appropriate giving message content of:</p> <p><font face="Consolas" size="3"><message> <br />    <header> <br />        ...header content omitted <br />    </header> <br />    <payload> <br />        <exception_details> <br />            <description/> <br />            <details/> <br />            <error_source/> <br />            <type/> <br />        </exception_details> <br />    </payload> <br /></message></font></p> <p>This allowed me to set the error detail programmatically as required. Voila!</p> Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-6315794833397979582.post-88796021021144187032008-12-22T18:42:00.001+00:002008-12-22T18:42:18.886+00:00How can I use Fiddler to debug BizTalk messages?<p>When using HTTP, SOAP or WCF send ports it can be incredibly useful to view the content of messages that are sent on the wire. This allows you to inspect the headers (SOAP or HTTP). <a href="http://www.fiddlertool.com/fiddler/" target="_blank">Fiddler</a> is a simple but fantastic tool to allow you to do this.</p> <p>By default, Fiddler will not trace any messages sent to endpoints by BizTalk as it does not use WinInet. However, BizTalk send ports can be configured to use a proxy allowing Fiddler to intercept them. On the Send Port tick the Use Proxy checkbox and set the Server to 127.0.0.1 and the port to 8888. For dynamic ports, set the following properties (as applicable to the adapter being used)</p> <p><font face="Consolas" color="#008000" size="3">// Debug via fiddler <br /><font color="#000000">msgSendRequest(SOAP.UseProxy) = true; <br />msgSendRequest(SOAP.ProxyAddress) = "127.0.0.1"; <br />msgSendRequest(SOAP.ProxyPort) = 8888;</font></font></p> <p>Note that this needs to be removed when Fiddler is not running since traffic directed to the proxy will not be received by anything.</p> Unknownnoreply@blogger.com1tag:blogger.com,1999:blog-6315794833397979582.post-87846032420655146612008-05-09T19:34:00.001+01:002008-05-09T19:34:43.905+01:00Fix Missing Vista Segoe UI font<p>A bit off topic here but useful nonetheless. Recently my Vista box mislaid the default system font Segoe UI and consequently fell back to the italic version of the same font. Whilst this is not a huge issue, it just looks ugly!</p> <p>Anyway after a lot of searching, the font can be replaced for free by installing <a href="http://get.live.com/wlmail/overview" target="_blank">Windows Live</a>. Worked for me!</p> Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-6315794833397979582.post-61876792966247556922008-03-04T23:20:00.001+00:002008-03-04T23:32:32.803+00:00Using the SSO database for storing configuration data<p>Single Sign-on is something that is often overlooked as being related only to Parties and for management of credentials. However, in its raw form, SSO provides a secure data store that can be used to store any information your application needs. In fact it can be used by non-BizTalk applications and doesn't have to only be for sensitive data, though this is the most typical usage.</p> <p>In order to use SSO programmatically, an API is provided for accessing data. An MMC snap-in is also supplied for administrative purposes and third-party tools also exist for this purpose. Command line based tools also exist enabling scripting support.</p> <p><strong>Adding new configuration items to SSO</strong></p> <p>Using the tools supplied out-of-the-box with BizTalk 2006 R2, it is pretty easy to create an SSO schema and populate it with some data.</p> <p>Create a schema for the configuration data. This is an XML file that look like the following:</p> <p><span class="kwrd"><</span><span class="html">sso</span><span class="kwrd">></span> <br />    <span class="kwrd"><</span><span class="html">application</span> <span class="attr">name</span><span class="kwrd">="Application Name here"</span><span class="kwrd">></span> <br />        <span class="kwrd"><</span><span class="html">description</span><span class="kwrd">></span>Description here<span class="kwrd"></</span><span class="html">description</span><span class="kwrd">></span> <br />        <span class="kwrd"><</span><span class="html">contact</span><span class="kwrd">></span>email address here<span class="kwrd"></</span><span class="html">contact</span><span class="kwrd">></span> <br />        <span class="kwrd"><</span><span class="html">appuserAccount</span><span class="kwrd">></span>domain\AppUserAccount<span class="kwrd"></</span><span class="html">appuserAccount</span><span class="kwrd">></span> <br />        <span class="kwrd"><</span><span class="html">appAdminAccount</span><span class="kwrd">></span>domain\AppAdminAccount<span class="kwrd"></</span><span class="html">appAdminAccount</span><span class="kwrd">></span> <br />        <span class="kwrd"><</span><span class="html">field</span> <span class="attr">ordinal</span><span class="kwrd">="0"</span> <span class="attr">label</span><span class="kwrd">="reserved"</span> <span class="attr">masked</span><span class="kwrd">="no"</span> <span class="kwrd">/></span> <br />        <span class="kwrd"><</span><span class="html">field</span> <span class="attr">ordinal</span><span class="kwrd">="1"</span> <span class="attr">label</span><span class="kwrd">="field name here"</span> <span class="attr">masked</span><span class="kwrd">="no"</span> <span class="kwrd">/></span> <br />        <span class="kwrd"><</span><span class="html">field</span> <span class="attr">ordinal</span><span class="kwrd">="2"</span> <span class="attr">label</span><span class="kwrd">="field name here"</span> <span class="attr">masked</span><span class="kwrd">="yes"</span> <span class="kwrd">/></span> <br />        <span class="kwrd"><</span><span class="html">flags</span> <span class="attr">groupApp</span><span class="kwrd">="no"</span> <span class="attr">configStoreApp</span><span class="kwrd">="no"</span> <span class="attr">allowTickets</span><span class="kwrd">="no"</span> <br />           <span class="attr">validateTickets</span><span class="kwrd">="yes"</span> <span class="attr">allowLocalAccounts</span><span class="kwrd">="no"</span> <span class="attr">timeoutTickets</span><span class="kwrd">="yes"</span> <br />           <span class="attr">adminAccountSame</span><span class="kwrd">="no"</span> <span class="attr">enableApp</span><span class="kwrd">="no"</span> <span class="kwrd">/></span> <br />    <span class="kwrd"></</span><span class="html">application</span><span class="kwrd">></span> <br /><span class="kwrd"></</span><span class="html">sso</span><span class="kwrd">></span></p> <p><span class="kwrd"></span><font face="Verdana">You can create as many fields as needed and multiple applications too. Note that the first field should not be used for a custom setting and is reserved for internal use.</font></p> <p><font face="Verdana">U</font>se the <strong>ssomanage.exe</strong> command line tool (in the <font face="Consolas">C:\Program Files\Common Files\Enterprise Single Sign-On\</font> folder) to create the SSO application based upon the schema. To do so use the <font face="Consolas">-createapps</font> option specifying the filename of the schema XML created above. The application has access control for user and administrators based upon groups. By default these are the “BizTalk Application Users” and “BizTalk Server Administrators” groups respectively. </p> <p><font face="Consolas" size="3">ssomanage -createapps "MySchema.xml"</font></p> <p>To populate the schema with some data, use the <strong>BTSScnSSOApplicationConfig.exe</strong> command line tool (supplied with source code) in the <strong>C:\Program Files\Microsoft BizTalk Server 2006\SDK\Common\SsoApplicationConfig</strong> folder. Run Setup.bat to compile the tool and the executable should be generated in the bin folder. </p> <p><font size="3"><font face="Consolas"><font size="2">BTSScnSSOApplicationConfig.exe -set <em>AppName</em> "ConfigProperties" "<em>paramname</em>" "<em>paramvalue</em>"</font></font></font></p> <p>To retrieve a data item</p> <p><font size="3"><font face="Consolas"><font size="2">BTSScnSSOApplicationConfig.exe -get <em>AppName</em> "ConfigProperties" "<em>paramname</em>"</font></font></font></p> <p><strong></strong></p> <p><strong>Retrieving SSO configuration values in code</strong></p> <p>Once the data is stored, it can be accessed using the API. BizTalk 2006 comes with a client DLL which can be used to create a configuration reader class. In most instances it is recommended to create a type safe version to convert data items from their name/value pairs into the correct data type.</p> <ul> <li>Add a reference to assembly Microsoft.BizTalk.InterOp.SSOClient.dll </li> <li>Create a Property Bag that implements from IPropertyBag</li> </ul> <p><font face="Consolas">public class ConfigurationPropertyBag : IPropertyBag <br />{ <br />    private HybridDictionary properties; </font></p> <p><font face="Consolas">    internal ConfigurationPropertyBag() <br />    { <br />        properties = new HybridDictionary(); <br />    } </font></p> <p><font face="Consolas">    public void Read(string propName, out object ptrVar, int errLog) <br />    { <br />        ptrVar = properties[propName]; <br />    } </font></p> <p><font face="Consolas">    public void Write(string propName, ref object ptrVar) <br />    { <br />        properties.Add(propName, ptrVar); <br />    } </font></p> <p><font face="Consolas">    public bool Contains(string key) <br />    { <br />        return properties.Contains(key); <br />    } </font></p> <p><font face="Consolas">    public void Remove(string key) <br />    { <br />        properties.Remove(key); <br />    } </font></p> <p><font face="Consolas">}</font></p> <ul> <li>Use the SSOConfigStore class to access the data using the property bag </li> </ul> <p><font face="Consolas">public static class SSOConfigHelper <br />{ </font></p> <p><font face="Consolas">    private static string idenifierGUID = "ConfigProperties"; </font></p> <p><font face="Consolas"><font color="#008000">    /// <summary> <br />    /// Read method helps get configuration data <br />    /// </summary> <br />    /// <param name="appName">The name of the affiliate application <br />    /// to represent the configuration container to access</param> <br />    /// <param name="propName">The property name to read</param> <br />    /// <returns> <br />    ///  The value of the property stored in the given affiliate <br />    /// application of this component. <br />    /// </returns> <br /></font>    public static string Read(string appName, string propName) <br />    { <br />        try <br />        { <br />            SSOConfigStore ssoStore = new SSOConfigStore(); <br />            ConfigurationPropertyBag appMgmtBag = new ConfigurationPropertyBag(); <br />            ((ISSOConfigStore) ssoStore).GetConfigInfo(appName, idenifierGUID, SSOFlag.SSO_FLAG_RUNTIME, (IPropertyBag) appMgmtBag); <br />            object propertyValue = null; <br />            appMgmtBag.Read(propName, out propertyValue, 0); <br />            return (string)propertyValue; <br />        } <br />        catch (Exception e) <br />        { <br />            System.Diagnostics.Trace.WriteLine(e.Message); <br />            throw; <br />        } <br />    } <br />}</font></p> <p>Whilst the use of these command line tools is potentially advantageous from a scripting perspective, their use on an ad-hoc basis is not ideal. An MMC snap-in now exists for managing an SSO database. <a href="http://seroter.wordpress.com/2007/09/21/biztalk-sso-configuration-data-storage-tool/">Richard Seroter</a> has written a really cool configuration tool for managing configuration data which has a handy export feature that will export the application schema as an XML file. <a href="http://seroter.wordpress.com/2008/02/28/sso-config-data-store-tool-biztalkwcf-scenario-source-code-available/" target="_blank">Source code</a> is also available.</p> Unknownnoreply@blogger.com3tag:blogger.com,1999:blog-6315794833397979582.post-22194274089744544702008-02-25T20:51:00.001+00:002008-02-25T20:51:53.719+00:00Promoting Properties that are not in a Message<p>In most instances properties are promoted from message content during the disassemble stage of a pipeline. However, in some cases it is useful to promote a property that does not relate to the content of a message. For example you may want to generate a unique identifier for a transaction and promote that into context for later use. To do so:</p> <ul> <li>Create a new property schema (or open an existing one) </li> <li>Add a new Child Field Element named with the required property name </li> <li>In the properties window, set the "Property Schema Base" property to <i>MessageContextPropertyBase.</i> This is the key to making this work. The default value is MessageDataPropertyBase indicating that the value is coming from a message </li> <li>In the orchestration or pipeline, set the new property value programmatically</li> </ul> See <a href="http://geekswithblogs.net/sthomas/archive/2004/08/27/10301.aspx" target="_blank">Stephen W Thomas's blog entry</a> for more on this. Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-6315794833397979582.post-57970593642873711942008-02-20T23:29:00.001+00:002008-02-25T20:52:48.159+00:00Dynamic SOAP Adapters<p>Following on from my <a href="http://biztalk-dev.blogspot.com/2008/02/dynamic-send-ports.html">previous post</a> concerning dynamic HTTP adapters, this time I'll extend the same concept to the SOAP adapter. Many of the techniques previously presented are still applicable but the SOAP adapter has it's own little idiosyncrasies which once explained are easy enough to overcome.</p> <p>The first issue is that of a proxy. In traditional .NET applications, when using a web service it is typical to add a web reference which, under the covers will generate a proxy to the remote service based on its WSDL definition. This is also what would happen if you add a web reference in your orchestration and use a static SOAP send port. However, for a dynamic send port we don't want to create a web reference - we'll generate the proxy manually using the wsdl.exe tool as follows:</p> <p><font face="Consolas">C:\><strong>wsdl /l:CS /o:c:\temp\wsdl </strong></font><a href="http://localhost/CalcWebService/CalcService.asmx?wsdl"><font face="Consolas"><strong>http://localhost/CalcWebService/CalcService.asmx?wsdl</strong></font></a> <br /><font face="Consolas">Microsoft (R) Web Services Description Language Utility <br />[Microsoft (R) .NET Framework, Version 2.0.50727.42] <br />Copyright (C) Microsoft Corporation. All rights reserved. <br />Writing file 'c:\temp\wsdl\CalcService.cs'.</font></p> <p>Here we have generated a proxy class from the WSDL of the web service. Add this to a new Class Library project. Ensure the resulting assembly is strong named and add it to the GAC. Note that the WebMethod to be called should have a signature as below that will accept an XML message and return one too. If an alternative method signature is required it will be necessary to update the proxy class to act as an facade between the required signature and the web service one.</p> <p><font face="Consolas">[<font color="#49bffe">WebMethod</font>] <br /><font color="#0000ff">public</font> <font color="#49bffe">XmlNode</font> MyMethod(<font color="#49bffe">XmlNode</font> Message)</font></p> <p>As with the HTTP example, we'll be invoking a dynamic adapter from an orchestration, setting adapter properties to change its behaviour at runtime. Again, add a request/response send port to the orchestration port surface and mark its type as Dynamic. The only other configuration required on the port is to specify the pipelines to be used, in this case XmlTransmit and XmlReceive. Connect up the request and response operations to the relevant send and receive shapes in the orchestration. Note that <u>the operation on the send port should have the same name as the WebMethod being called</u>.</p> <p>Prior to sending the message set the following send port properties:</p> <p><font face="Consolas"><font color="#008000">// Assign message <br /></font>msgSendRequest = msgReceiveRequest;</font> <br /> <br /><font face="Consolas"><font color="#008000">// Set base properties <br /></font>MySendPort(Microsoft.XLANGs.BaseTypes.Address) = <br />                     "</font><a href="http://localhost/CalcWebService/CalcService.asmx" ;?=";?"><font face="Consolas">http://localhost/CalcWebService/CalcService.asmx";</font></a> <br /><font face="Consolas">MySendPort (Microsoft.XLANGs.BaseTypes.TransportType) = "SOAP"; <br /> <br /><font color="#008000">// Set HTTP adapter specific properties</font> <br />msgSendRequest(BTS.SOAPAction) = "Add"; <br />msgSendRequest(SOAP.MethodName) = "Add"; <br />msgSendRequest(SOAP.AssemblyName) = "CalcTest.CalcWebServiceProxy.CalcService, <br />    CalcWebServiceProxy, Version=1.0.0.0, Culture=neutral, <br />    PublicKeyToken=b713f1108bae3109"; <br />msgSendRequest(SOAP.TypeName) = "CalcTest.CalcWebServiceProxy.CalcService";</font></p> <p>Some important points to note here:</p> <ol> <li>The TransportType is a means of informing BizTalk which adapter you want to use. If it is omitted the prefix of the Address (in this case <strong>http://</strong>) will be used to query an alias table to lookup the adapter to use. By default this will use the HTTP adapter, therefore we set the Microsoft.XLANGs.BaseTypes.TransportType property to "SOAP" to ensure that the SOAP adapter is targeted. </li> <li>The BTS.SOAPAction and the SOAP.MethodName are both set to the name of the WebMethod being invoked. </li> <li>The SOAP.AssemblyName must be populated with the details of the class name and assembly of the proxy to be used. This value takes the form <i>Namespace.ClassName</i>, <i>Fully Qualified Assembly Name</i>. Set this to the details of the proxy assembly created and GAC'd earlier. </li> <li>The SOAP.TypeName must also be set to the full name of the proxy class i.e. <i>Namespace.ClassName</i>. Not sure why this is required again but if it is not set an error occurs. </li> </ol> <p>OK, now you should be good to go. Build, deploy and (hopefully) watch those SOAP requests flying to and from your web service. Whilst it's a little more fiddly to setup that the HTTP equivalent, using a dynamic SOAP adapter is a really powerful technique for creating flexible and extensible BizTalk applications.</p> <p>Jon Fancey has taken this a step further by creating a more generic SOAP router. <a href="http://www.pluralsight.com/blogs/jfancey/archive/2007/06/07/47683.aspx" target="_blank">Check it out</a>.</p> Unknownnoreply@blogger.com14tag:blogger.com,1999:blog-6315794833397979582.post-13229210734550697122008-02-19T23:31:00.001+00:002008-02-19T23:34:16.149+00:00Dynamic Send Ports<p>Part of the project I'm currently working on involves sending XML messages to a variety of trading partners. Each partner has several products each of which could require different port settings (URL, credentials, timeout, retry strategy). Another variable is the transport type. Currently all support plain XML over HTTP but in the future SOAP may be a requirement. As we have up to 1000 different partner/product combinations to support dynamic ports seem like a logical choice.</p> <p>So how do you implement dynamic HTTP and SOAP send ports? Let's start with HTTP first as it's a little more straightforward.</p> <p>Assuming that the orchestration is in place, add a request/response send port to the port surface and mark its type as Dynamic. The only other configuration required on the port is to specify the pipelines to be used and to connect up the request and response operations to the relevant send and receive shapes in the orchestration.</p> <p><a href="http://lh3.google.com/nm157uk/R7tmxT3OtiI/AAAAAAAAAD8/_zlhAGFQCC4/dynamicsend1%5B3%5D"><img style="border-right: 0px; border-top: 0px; margin: 10px 0px; border-left: 0px; border-bottom: 0px" height="348" alt="dynamicsend1" src="http://lh5.google.com/nm157uk/R7tmxz3OtjI/AAAAAAAAAEE/eooIBWCxF1U/dynamicsend1_thumb%5B1%5D" width="644" border="0" /></a> </p> <p>Prior to the send shape (I have used the message assignment shape that builds the request message) add the following code.</p> <p><font face="Consolas"><font color="#008000">// Assign message</font> <br />msgSendRequest = msgReceiveRequest; <br /> <br /><font color="#008000">// Set base properties</font> <br />MySendPort(Microsoft.XLANGs.BaseTypes.Address) = "</font><a href="http://localhost/testpartner/test.aspx";"><font face="Consolas">http://localhost/testpartner/test.aspx";</font></a> <br /><font face="Consolas">MySendPort(Microsoft.XLANGs.BaseTypes.TransportType) = "HTTP"; <br /><font color="#008000"> <br />// Set HTTP adapter specific properties</font> <br />msgSendRequest(HTTP.AuthenticationScheme) = "Basic"; <br />msgSendRequest(HTTP.Username) = "mark"; <br />msgSendRequest(HTTP.Password) = "pwd";</font></p> <p>This code sets up the address URI and the transport type to be used. The TransportType is a means of informing BizTalk which adapter you want to use. If it is omitted the prefix of the Address (in this case <strong>http://</strong>) will be used to query an alias table to lookup the adapter to use. For some prefixes there are multiple adapters that could handle the request. For http:// it could be the HTTP, WCF-Basic or WCF-WSHttp so the TransportType property can be used to explictly choose the correct adapter. In this instance I could have omitted the TransportType since the HTTP is the default for http:// addresses.</p> <p>Next I have set some properties that are specific to the HTTP adapter. In this instance I have just configured the authentication details but there are lots of other that can be used. Typically these settings could be looked up from a database or other configuration store and set dynamically based on the request.</p> <p>And that's it! The request should then be routed to the URI configured in code above using the HTTP adapter. This is a very powerful technique to add flexibility to your application. I'll continue by demonstrating how to use the same technique for the SOAP adapter in a future post.</p> Unknownnoreply@blogger.com6tag:blogger.com,1999:blog-6315794833397979582.post-35351456053067741482008-02-18T20:07:00.001+00:002008-02-18T21:10:25.853+00:00Installation Gotchas<p>When installing BizTalk Server 2006, the process is generally pretty smooth. I have installed it a couple of times on different machines and had no problems to speak of. However, there are a few things to look out for if you do encounter problems:</p> <ul> <li>Check the event log is not full. BizTalk Server is not shy about writing to the event log so make sure that the Application log is not full and supports overwriting of events as necessary. </li> <li>Make sure you are not logged on with a Windows account that has no password. The Master Secret Server Key is generated using the password of the logged on user as a seed. </li> <li>Do not install onto a non-NTFS formatted disk. BizTalk Server does not support FAT32. </li> <li>If using a domain account, ensure that access to the domain controller is available.</li> <li>Ensure you have enough available disk space. The <a href="http://www.microsoft.com/biztalk/techinfo/2006R2/sysreqs.mspx" target="_blank">System Requirements</a> state "15 GB of available hard disk space for a complete installation including the operating system, all prerequisite software, and language packs. This does not include disk space for data storage."  </li> </ul> Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-6315794833397979582.post-29844413138439591452008-02-18T19:57:00.001+00:002008-02-18T19:57:15.250+00:00Welcome to BizTalk-Dev<p>A warm welcome to the BizTalk-Dev blog. My name is Mark and I am a Senior Developer for a mid-sized Financial Services company in the UK. I have been working with BizTalk for a few months now and hope to share a few hints, tips and observations that may be helpful.</p> Unknownnoreply@blogger.com1