<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-9166988</id><updated>2024-01-11T22:52:52.687+00:00</updated><title type='text'>Real BizTalk</title><subtitle type='html'>Real-life experiences gained on cutting edge BizTalk projects from the City of London.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://realbiztalk.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9166988/posts/default?alt=atom'/><link rel='alternate' type='text/html' href='http://realbiztalk.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>David Regan</name><uri>http://www.blogger.com/profile/01353209862691682987</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>13</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-9166988.post-112967899243507616</id><published>2005-10-19T00:32:00.000+01:00</published><updated>2005-10-19T01:10:28.950+01:00</updated><title type='text'>WWF and Cutting down BTS 2004 shapes</title><content type='html'>&lt;span style=&quot;font-size:85%;&quot;&gt;Have you ever wondered if there is a way to cut down the number of BizTalk shapes you need? Well there is, however this technique should only be used if you understand exactly what the effect is... Many BizTalk developers are aware of the ability to review the intermediate code that BizTalk generates in its &#39;code behind&#39;. This code is used to compile your orchestration into CLR. To simply review this code all that is needed is to right click on the orchestration and open it in notepad, at the end of the orchestration XML designer code you will find the XLANG/S code. This language is largely undocumented and really should be C# but isn’t for some unknown reason (Answers on a postcard). After reviewing the code and the documentation its possible to construct your own shapes. For example to avoid using a constructing message you would write in an expression shape:&lt;br /&gt;&lt;br /&gt;construct msgTest { msgTest = orchHelper.CreateMessage(); }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;You can combine the above with more than one shape in an expression shape: i.e: &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size:85%;&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size:85%;&quot;&gt;scope &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size:85%;&quot;&gt;{ &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size:85%;&quot;&gt;                   message SomeSchema.NACK msgNACK; &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size:85%;&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size:85%;&quot;&gt;body &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size:85%;&quot;&gt;{ &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size:85%;&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size:85%;&quot;&gt;                 construct msgNACK { msgNACK = orchHelper.CreateTestMessage(); &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size:85%;&quot;&gt;} &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size:85%;&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size:85%;&quot;&gt;exec SomeOrch.HandleNACK(msgNACK, MQOutLoc);&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size:85%;&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size:85%;&quot;&gt;} &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size:85%;&quot;&gt;e&lt;/span&gt;&lt;span style=&quot;font-size:85%;&quot;&gt;xceptions &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size:85%;&quot;&gt;{ &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size:85%;&quot;&gt;          catch (System.Exception ex1)&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size:85%;&quot;&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size:85%;&quot;&gt;          Debugger.WriteLine(ex1); } &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size:85%;&quot;&gt;} &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size:85%;&quot;&gt;} &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size:85%;&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size:85%;&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size:85%;&quot;&gt;The above expression contains a scope, construct and a start shape. I have used this method in some BTS projects to prevent rewriting NACK code every time. Unfortunately, in BTS 2004 it is not possible to have reusable shapes so the above code has to be a cut and paste job every time. This will be the same in BTS2006 but in windows workflow foundation you can create your own shapes and even use .NET in code behind, just like ASP.NET and Winforms read here for a primer ... &lt;a href=&quot;http://msdn.microsoft.com/windowsvista/building/workflow/default.aspx?pull=/library/en-us/dnlong/html/WWFIntro.asp&quot;&gt;http://msdn.microsoft.com/windowsvista/building/workflow/default.aspx?pull=/library/en-us/dnlong/html/WWFIntro.asp&lt;/a&gt; John&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-size:85%;&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-size:85%;&quot;&gt;&lt;/span&gt;&lt;span style=&quot;font-size:85%;&quot;&gt;&lt;/span&gt;&lt;span style=&quot;font-size:85%;&quot;&gt;&lt;/span&gt;&lt;span style=&quot;font-size:85%;&quot;&gt;&lt;/span&gt;&lt;span style=&quot;font-size:85%;&quot;&gt;&lt;/span&gt;&lt;span style=&quot;font-size:85%;&quot;&gt;&lt;/span&gt;</content><link rel='replies' type='application/atom+xml' href='http://realbiztalk.blogspot.com/feeds/112967899243507616/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9166988&amp;postID=112967899243507616' title='94 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9166988/posts/default/112967899243507616'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9166988/posts/default/112967899243507616'/><link rel='alternate' type='text/html' href='http://realbiztalk.blogspot.com/2005/10/wwf-and-cutting-down-bts-2004-shapes.html' title='WWF and Cutting down BTS 2004 shapes'/><author><name>Anonymous</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/blank.gif'/></author><thr:total>94</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9166988.post-112343388603809630</id><published>2005-08-07T17:49:00.000+01:00</published><updated>2005-08-07T17:58:06.043+01:00</updated><title type='text'>Assembly probing when adding pipeline components to the Toolbox</title><content type='html'>We had an issue at a customer about a month ago when a Pipeline Component was refusing to be added to the Toolbox and the error said something like &#39;You have selected an invalid Pipeline Component&#39;.&lt;br /&gt;&lt;br /&gt;The error message doesn&#39;t really give you much to go on, but one of our consultants eventually managed to work it out. It turns out that the pipeline component referenced another assembly that wasn&#39;t in the GAC and the design environment must navigate the relationships when the component is added to the Toolbox for some reason.&lt;br /&gt;&lt;br /&gt;The approach uses the standard .NET assembly probing rules, so it will look for the assembly in the same directory as the pipeline component (e.g. C:\Program Files\Microsoft BizTalk Server 2004\Pipeline Components\) and then will look in the GAC if it doesn&#39;t find it there.&lt;br /&gt;&lt;br /&gt;So if you get this spurious message when adding the pipeline component to the Toolbox, check that all other assemblies are where they should be...</content><link rel='replies' type='application/atom+xml' href='http://realbiztalk.blogspot.com/feeds/112343388603809630/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9166988&amp;postID=112343388603809630' title='15 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9166988/posts/default/112343388603809630'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9166988/posts/default/112343388603809630'/><link rel='alternate' type='text/html' href='http://realbiztalk.blogspot.com/2005/08/assembly-probing-when-adding-pipeline.html' title='Assembly probing when adding pipeline components to the Toolbox'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/18233349485719276459</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>15</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9166988.post-112340172799738405</id><published>2005-08-07T08:43:00.000+01:00</published><updated>2005-08-07T09:02:08.006+01:00</updated><title type='text'>Messages are immutable.... or are they??</title><content type='html'>David &amp; I wrote a BizTalk exam plus InfoPath exam simulator for TechEd 2005 in Orlando and travelled over in June to have some fun and get some sun . The exam consisted of 25 or so pretty hard questions on real world BizTalk stuff (150 took the exam and I think approx. 10 passed!). One of these questions was based on whether or not messages could be changed. ie: whether they are immutable.&lt;br /&gt;&lt;br /&gt;As far as orchestrations are concerned, we know that if you want to change a message, you have to clone it first and then make your ammendment. But how does it work with the rules engine? If you pass in a message to the rules engine and use some Set operations to update the message, when the message is returned to the orcehstration, the message has miracoulously been updated. Therefore, messages are immutable except for when you use the Rules Engine right?&lt;br /&gt;&lt;br /&gt;Lee Graber sat the exam (and passed by the way, although he didn&#39;t come first!). After the exam we had a chat about the message behaviour with the rules engine and he was adamant that messages are always immutable, so we had a play around and he showed us that he was in fact right, the Rules engine automatically performs the same operation by cloning the message and passing back a copy of the message with the values updated. This was easy to check by looking at the MessageId of the before and after message to confirm that it had in fact changed.&lt;br /&gt;&lt;br /&gt;This raises some interesting questions:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;What happens with .NET short-term facts? Are these cloned or just referenced as you would expect?&lt;/li&gt;&lt;li&gt;Does the cloning only occur when you use the &#39;set&#39; operations or are messages always cloned when you use the call rules shape?&lt;/li&gt;&lt;li&gt;What happens if you use .NET messages rather than XML messages?&lt;/li&gt;&lt;li&gt;What is the performance penalty associated with a set operation on an XML message?&lt;/li&gt;&lt;li&gt;Is it more performant to pass in a .NET fact to catch the set operations &lt;/li&gt;&lt;li&gt;Is the same behaviour experienced with calling the Rules Engine from the API?&lt;/li&gt;&lt;/ul&gt;If I ever get some time off from my day job, I&#39;ll have a look into these and post part 2...</content><link rel='replies' type='application/atom+xml' href='http://realbiztalk.blogspot.com/feeds/112340172799738405/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9166988&amp;postID=112340172799738405' title='106 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9166988/posts/default/112340172799738405'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9166988/posts/default/112340172799738405'/><link rel='alternate' type='text/html' href='http://realbiztalk.blogspot.com/2005/08/messages-are-immutable-or-are-they.html' title='Messages are immutable.... or are they??'/><author><name>Anonymous</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/blank.gif'/></author><thr:total>106</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9166988.post-111131510294427049</id><published>2005-03-20T10:32:00.000+00:00</published><updated>2005-03-20T10:38:22.946+00:00</updated><title type='text'>Common problem when laptop not plugged in to network</title><content type='html'>There&#39;s a common problem with BizTalk that&#39;s been around since beta days related to IP addresses. If you attempt to install BizTalk when not connected to a network, you will receive SSO errors during the configuration step.  The same problem occurs if you install whilst connected and then go away to work on your laptop in a disconnected mode. BizTalk will stop working.&lt;br /&gt;&lt;br /&gt;The solution to this is simple. Put an entry in the hosts file that refers to your machine:&lt;br /&gt;&lt;br /&gt;127.0.0.1 MACHINENAME&lt;br /&gt;&lt;br /&gt;I&#39;m sure you all know this, but just in case. I&#39;ve seen it bite someone badly during an important customer demo recently ;-)</content><link rel='replies' type='application/atom+xml' href='http://realbiztalk.blogspot.com/feeds/111131510294427049/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9166988&amp;postID=111131510294427049' title='17 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9166988/posts/default/111131510294427049'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9166988/posts/default/111131510294427049'/><link rel='alternate' type='text/html' href='http://realbiztalk.blogspot.com/2005/03/common-problem-when-laptop-not-plugged.html' title='Common problem when laptop not plugged in to network'/><author><name>Anonymous</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/blank.gif'/></author><thr:total>17</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9166988.post-110959526622823489</id><published>2005-02-28T12:54:00.000+00:00</published><updated>2005-02-28T13:10:04.543+00:00</updated><title type='text'>Performance tip: Parallel vs. Atomic sends</title><content type='html'>So, you want to send two messages at the same time and want to do it the most efficient way possible. You use a parallel shape and have two threads kicking off mutiple sends? You could do, but is there a better way?...&lt;br /&gt;&lt;br /&gt;See the diagram below with one approach on the left and one on the right...&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://photos1.blogger.com/img/159/3833/640/parallel%20vs%20atomic.jpg&quot;&gt;&lt;img style=&quot;BORDER-RIGHT: #000000 1px solid; BORDER-TOP: #000000 1px solid; MARGIN: 2px; BORDER-LEFT: #000000 1px solid; BORDER-BOTTOM: #000000 1px solid&quot; src=&quot;http://photos1.blogger.com/img/159/3833/320/parallel%20vs%20atomic.jpg&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;strong&gt;Parallel vs Atomic multiple sends&lt;/strong&gt; &lt;a href=&quot;http://www.hello.com/&quot; target=&quot;ext&quot;&gt;&lt;img style=&quot;BORDER-RIGHT: 0px; PADDING-RIGHT: 0px; BORDER-TOP: 0px; PADDING-LEFT: 0px; BACKGROUND: none transparent scroll repeat 0% 0%; PADDING-BOTTOM: 0px; BORDER-LEFT: 0px; PADDING-TOP: 0px; BORDER-BOTTOM: 0px&quot; alt=&quot;Posted by Hello&quot; src=&quot;http://photos1.blogger.com/pbh.gif&quot; align=&quot;absMiddle&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;There is a cost with spinning up the separate threads, plus an additional persistence point after each send, which means that using an atomic scope is more efficient. This is because the atomic scope batches up the sends until the end of the scope is reached. The messages are sent within the context of the atomic scope&#39;s persistence point so there&#39;s less database round trips...&lt;br /&gt;&lt;br /&gt;Try it and see....</content><link rel='replies' type='application/atom+xml' href='http://realbiztalk.blogspot.com/feeds/110959526622823489/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9166988&amp;postID=110959526622823489' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9166988/posts/default/110959526622823489'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9166988/posts/default/110959526622823489'/><link rel='alternate' type='text/html' href='http://realbiztalk.blogspot.com/2005/02/performance-tip-parallel-vs-atomic.html' title='Performance tip: Parallel vs. Atomic sends'/><author><name>Anonymous</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/blank.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9166988.post-110959381798375217</id><published>2005-02-23T12:12:00.000+00:00</published><updated>2005-02-28T12:30:17.983+00:00</updated><title type='text'>MQ Series - no need to cluster MQSAgent</title><content type='html'>The MQ Series Adapter documentation suggests that the MQSAgent should be clustered when using the MQ Series Adapter on an MQ Series cluster built on top of MSCS.&lt;br /&gt;&lt;br /&gt;This is actually not required and will not work if it&#39;s attempted. There is no need to cluster the MQSAgent component. You just need to install the MQ Series Adapter on both nodes of the cluster (as if they weren&#39;t clustered) and at runtime, it will use the local component on the active node.&lt;br /&gt;&lt;br /&gt;Hopefully they&#39;ll get around to updating the docs soon!</content><link rel='replies' type='application/atom+xml' href='http://realbiztalk.blogspot.com/feeds/110959381798375217/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9166988&amp;postID=110959381798375217' title='20 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9166988/posts/default/110959381798375217'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9166988/posts/default/110959381798375217'/><link rel='alternate' type='text/html' href='http://realbiztalk.blogspot.com/2005/02/mq-series-no-need-to-cluster-mqsagent.html' title='MQ Series - no need to cluster MQSAgent'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/18233349485719276459</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>20</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9166988.post-110847059964165214</id><published>2005-02-15T12:19:00.000+00:00</published><updated>2005-02-15T13:30:36.046+00:00</updated><title type='text'>Developing Rules</title><content type='html'>BizTalk is integrated with the Business Rules Engine (BRE). The BRE allows you to separate business policy from the flow of your orchestrations. For example, you might have a flow that routes orders for more than a certain monetary value to an expediated process. The value that this decision is made on should not be hardcoded into the orchestration. Instead the orchestration should invoke a business policy which will make the decision.&lt;br /&gt;&lt;br /&gt;The way you develop policies is as follows:-&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Develop a vocabulary of facts. Facts expose data to rules and implement actions that rules may take. Facts can be bound to .NET properties or methods, XML or databases.&lt;/li&gt;&lt;li&gt;Develop rules that reference your vocabularies. A policy consists of a set of rules and each rule is a set of predicates (i.e. logical tests) and the set of contigent actions.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;All good so far...except the way versions are managed makes it impractical to develop rules at all!&lt;/p&gt;&lt;p&gt;The problem is this. Before a rule can reference a fact in a vocabulary the vocabulary must be published. Once a vocabulary is published it cannot be changed and it is not possible to unpublish it!&lt;/p&gt;&lt;p&gt;Consequently, if you use the business rules composer as intended whenever you want to change a fact or add a new fact to your vocabulary you have to publish a new version. Moreover, your rules are bound to particular versions of your vocabularies. So, once you&#39;ve created and published your new vocabulary version you need to go through each rule and update its fact references to the new version if you intend to delete the old versions. &lt;/p&gt;&lt;p&gt;Like all software development it usually requires many versions of a fact vocabulary before you get it right. It would not be an overstatement to say you easily end up with 20-30 versions of your vocabulary before you&#39;ve got your rules working as desired.&lt;/p&gt;&lt;p&gt;So, is there an alternative. Yes - but is ain&#39;t pretty: the answer is to unpublish the vocabulary by bypassing the rule composer. But the only way to do this is to directly update the rules database.&lt;/p&gt;&lt;p&gt;The process is: &lt;/p&gt;&lt;ul&gt;&lt;li&gt;Publish your vocabulary&lt;/li&gt;&lt;li&gt;Test your rules that refer to the vocabulary&lt;/li&gt;&lt;li&gt;Open the re_vocabulary table in the BizTalkRuleEngineDb and change the nStatus field from 1 to 0 (1 = published, 0 = not published). You can identify your vocabulary by its name held in the strName field.&lt;/li&gt;&lt;li&gt;Reload the vocabulary into the rules composer and add/modify your facts.&lt;/li&gt;&lt;li&gt;Save the vocabulary and then set the nStatus field back to 1 - don&#39;t re-publish the vocabulary from the rules composer else you will get a primary key violation.&lt;/li&gt;&lt;li&gt;Reload the policies/vocabularies once more in the rules composer and retest your policy.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;You can also do the same trick with the policy. Although you don&#39;t need to publish the rules to test them using the test facilities of the rules composer, you do if you intend to test them from your orchestration. Clearly, you can find bugs in this process just as much as during your unit tests. Rather than have to create a new version of the policies just change the nStatus field in the re_ruleset table to temporarily unpublish the policy so that you can edit it.&lt;/p&gt;&lt;p&gt;One note of caution, the rules bizarrely cache the fact definitions inside the rule definition. So changing a vocabulary fact won&#39;t effect the rule that references it unless you re-reference the vocabulary item from the rule. So, although this process is fairly painless for adding new items to a vocabulary you have to be more careful with updates to facts.&lt;/p&gt;&lt;p&gt;Clearly, having to jump through hoops like this is regrettable and it can only be hoped that Microsoft do something about this in the next release of BizTalk.&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://realbiztalk.blogspot.com/feeds/110847059964165214/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9166988&amp;postID=110847059964165214' title='493 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9166988/posts/default/110847059964165214'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9166988/posts/default/110847059964165214'/><link rel='alternate' type='text/html' href='http://realbiztalk.blogspot.com/2005/02/developing-rules.html' title='Developing Rules'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/01353209862691682987</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>493</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9166988.post-110846600457956793</id><published>2005-02-15T10:44:00.000+00:00</published><updated>2005-02-15T11:13:24.586+00:00</updated><title type='text'>Business Policy &amp; Subscriptions</title><content type='html'>Here&#39;s a handy pattern which we developed to cope with a difficult requirement.&lt;br /&gt;&lt;br /&gt;I was working on a project to implement a message broker for SWIFT messages.&lt;br /&gt;&lt;br /&gt;Initially the concept was quite simple: all of the 40+ applications in a bank would route their SWIFT messages through the message broker which would decided if money laundering compliance checks needed to be carried out.&lt;br /&gt;&lt;br /&gt;Just before development started a new requirement was introduced - some of the messages would require special processing. The driver for this was that the bank was centralising one of its back office functions and wanted certain sets of messages transformed or processed so that they could be integrated with the new functionality.&lt;br /&gt;&lt;br /&gt;At first the new requirement didn&#39;t seem to complex but after some analysis we realised that not only did different subsets of message types required special processing but that different instances (i.e. messages for certain accounts or destinations) also required special processing.&lt;br /&gt;&lt;br /&gt;Now, SWIFT has over 350+ different sorts of messages so it wouldn&#39;t be practical to manage 350+ orchestrations instead the design for the original requirement was to have a common orchestration that processes untyped XML messages. The idea was that business rules would be used to extract the key data required for the routing and compliance process from the XML blob.&lt;br /&gt;&lt;br /&gt;With the introduction of the new requirement we suddenly had a more complex situation. Sometimes we would want an orchestration specific to the messages type (so that transformations and distinguished properties could be used) and sometimes we&#39;d want common processing for whole sets of messages.&lt;br /&gt;&lt;br /&gt;How could we make this all work with the BizTalk subscription model?&lt;br /&gt;&lt;br /&gt;Before I outline our solution, a quick recap on how subscription in BizTalk works.&lt;br /&gt;&lt;br /&gt;When you add an activating receive shape to an orchestration and then bind and deploy your solution you are adding a new subscription for the orchestration.&lt;br /&gt;&lt;br /&gt;Normally, your subscription consists of:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The message type (specified using the xsd namespace for your message with a # followed by the top-level element name - e.g. &lt;a href=&quot;http://mysolution#MyElement&quot;&gt;http://mysolution#MyElement&lt;/a&gt;)&lt;/li&gt;&lt;li&gt;The receive port identifier&lt;/li&gt;&lt;li&gt;Any filter predicates, i.e. tests of message context properties&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;When a message leaves the adapter framework after processing by the receive pipeline it is dumped into the message box. The BizTalk engine then looks through the subscription table and checks the promoted properties against the subscriptions. Key properties are, of course, the message type and the receive port ID.&lt;/p&gt;&lt;p&gt;Now imagine we had an architecture whereby 300+ of our SWIFT messages were to be processed by a common type agnostic orchestration whereas a small subset of messages were to be processes by type specific orchestrations. When one of the messages in the type specific subset is received it would match the subscriptions of the common orchestration and the type specific orchestration and suddenly the bank has transferred £2,000,000 when it should have been £1,000,000!&lt;/p&gt;&lt;p&gt;Moreover, in some circumstances we would want a common type agnostic orchestration to process whole sets of messages. For example, we might have the requirement that all payment and cash messages go through special processing.&lt;/p&gt;&lt;p&gt;Somehow, we need a way to control the subscription mechanism in a fine grained way.&lt;/p&gt;&lt;p&gt;The answer we came up with was to create a custom pipeline component for managing the subscription. The pipeline component&#39;s job was to invoke a subscription policy using the Business Rules Engine. The subscription policy was used to decide on an appropriate business process for the message. This decision could take into account the message type, any data in the message (e.g. priority, etc.) and could use database lookups (e.g. lookup certain accounts or destinations that required centralised processing).&lt;/p&gt;&lt;p&gt;Once the subscription policy had reached its decision it returned the name of the appropriate business process to the pipeline component. The pipeline component then simply promoted this value as a subcription property in the message context.&lt;/p&gt;&lt;p&gt;In this way orchestrations would not only subscribe to message type (if appropriate) and port then would also subscribe to the business process.&lt;/p&gt;&lt;p&gt;The common type-agnostic orchestration that handles the bulk of the messages would subscribe to the &quot;Generic&quot; business process whereas other orchestrations might subscribe to &quot;CentralisedPaymentsAndCash&quot; or somesuch. In this way different orchestrations could subscribe to the same message type (or no message type) from the same port but with different business processes.&lt;/p&gt;&lt;p&gt;This is a very generic pattern that we&#39;re sure is going to crop up time and again. Hope you find it useful!&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://realbiztalk.blogspot.com/feeds/110846600457956793/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9166988&amp;postID=110846600457956793' title='25 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9166988/posts/default/110846600457956793'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9166988/posts/default/110846600457956793'/><link rel='alternate' type='text/html' href='http://realbiztalk.blogspot.com/2005/02/business-policy-subscriptions.html' title='Business Policy &amp; Subscriptions'/><author><name>Anonymous</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/blank.gif'/></author><thr:total>25</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9166988.post-110959276456494322</id><published>2005-01-25T12:06:00.000+00:00</published><updated>2005-02-28T12:16:45.606+00:00</updated><title type='text'>Little known MQSeries feature</title><content type='html'>One of the less publicised features of the MQ Series adapter is that you can make it rollback the transaction and disable the receive location if an exception occurs in the pipeline.&lt;br /&gt;&lt;br /&gt;The reason for this is that you may not want to suspend the inbound message if processing occurs in the pipeline that is important for the handling of that message. For example, if you execute business rules in the pipleine to determine a subscription policy (see Dr. Regan&#39;s recent post), or because you&#39;re using the A4Swift adapter (lots of rules), you won&#39;t want the message suspended if the Rules Engine causes an exception due to an infrastructure problem (e.g. could not connect to DB / Rules Engine Update Service not running). You want to be alerted to the problem so it can be fixed, and then re-enable the receive location so that processing continues as if nothing ever happened.&lt;br /&gt;&lt;br /&gt;To enable this feature, set the Ordering property of the Receive Location adapter configuration to &quot;No Order With Stop&quot;.&lt;br /&gt;&lt;br /&gt;If the condition occurs the MQ Series Adapter will raise an appropriate event to the event log that can be picked up by MOM to alert an operator.&lt;br /&gt;&lt;br /&gt;It works very well and is crucial for processing financial messages that must succeed...</content><link rel='replies' type='application/atom+xml' href='http://realbiztalk.blogspot.com/feeds/110959276456494322/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9166988&amp;postID=110959276456494322' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9166988/posts/default/110959276456494322'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9166988/posts/default/110959276456494322'/><link rel='alternate' type='text/html' href='http://realbiztalk.blogspot.com/2005/01/little-known-mqseries-feature.html' title='Little known MQSeries feature'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/18233349485719276459</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9166988.post-110848651334167463</id><published>2004-12-15T20:46:00.000+00:00</published><updated>2005-02-15T17:10:47.886+00:00</updated><title type='text'>Useful retry pattern</title><content type='html'>Reading a ‘Suspended (Not Resumable)’ status for a critical $20M financial transaction is not really the best thing you can wake up to. I’ve woken up to a few in my time, and trust me: this one is particularly unpleasant…&lt;br /&gt;&lt;br /&gt;There are a number of reasons it can happen, but where orchestrations are concerned, it generally means that an exception has occurred that hasn’t been gracefully handled.&lt;br /&gt;&lt;br /&gt;Although in theory, this can happen anywhere in your orchestration, there are key points that it will happen more than most, and if you protect yourself in these scenarios, you’ll be able to sleep a little easier. Common scenarios that could generate an error are:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Calling into to the Rules Engine to execute a Policy – if the Rule Engine Update Service is not running (why does this never start on my laptop??), or the rule engine runs code that has an exception&lt;/li&gt;&lt;li&gt;Sending a message to a destination that may sometimes be unavailable (that’s pretty much all destinations!)&lt;/li&gt;&lt;li&gt;Executing some .NET code that could go wrong for an infrastructure reason (e.g. database server is down) &lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;All these scenarios are related to infrastructure problems. They’re problems that if you fix the infrastructure and resume the orchestration, then everything should continue as if nothing ever happened.&lt;br /&gt;&lt;br /&gt;In these situations, a good way of dealing with it is to execute some retry logic by gracefully putting the orchestration into a Suspended mode and allowing an administrator to resume the orchestration once the infrastructure problem has been resolved.&lt;br /&gt;&lt;br /&gt;It’s pretty simple to achieve via nested scopes. Wrap the potentially risky operation in a set of shapes that together form a reusable retry pattern:&lt;br /&gt;&lt;br /&gt;Essentially, the pattern requires that the risky operation is encapsulated within a loop shape, which in turn has a non-transactional scope with an exception handler that traps the possible error conditions. If an exception occurs, a String variable and Boolean variable is set that is then used outside the non-transactional scope to determine whether to gracefully Suspend, and to write out a meaningful reason for the suspension. The administrator will get an alert that warns that an instance has been suspended. He can then resolve the problem (e.g. start the Rules Engine Update Service) and then use HAT to resume any orchestration instances. Simple…&lt;br /&gt;&lt;br /&gt;Once I’ve worked out how to upload pictures of orchestrations, I’ll post a picture which will make it easier to understand!&lt;br /&gt;&lt;br /&gt;One extra issue is that if you’re using this pattern when sending messages and the message fails to be transported, the message to be sent will also go into a Suspended (Resumable) state. If the administrator resumes both the Orchestration service instance and the Send service instance, you will send the same message twice. To work around this problem, you can use delivery notifications and a Nack Handler to automatically clean-up the send service instances, but that’s a subject for another day…</content><link rel='replies' type='application/atom+xml' href='http://realbiztalk.blogspot.com/feeds/110848651334167463/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9166988&amp;postID=110848651334167463' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9166988/posts/default/110848651334167463'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9166988/posts/default/110848651334167463'/><link rel='alternate' type='text/html' href='http://realbiztalk.blogspot.com/2004/12/useful-retry-pattern.html' title='Useful retry pattern'/><author><name>Anonymous</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/blank.gif'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9166988.post-110959436354625440</id><published>2004-12-03T12:37:00.000+00:00</published><updated>2005-02-28T12:39:23.546+00:00</updated><title type='text'>Failover issues with MQ clusters</title><content type='html'>One issue we&#39;ve had with MQ Series in a clustered environment is that if you initiate a failover to the passive node, and then failback, MQ Series will moan about Semaphore locking issues. This is a known issue with MQ that IBM is working on with Microsoft.&lt;br /&gt;&lt;br /&gt;The solution (work around) is to always reboot the original node before failing back the resources. This seems to cure the issue!</content><link rel='replies' type='application/atom+xml' href='http://realbiztalk.blogspot.com/feeds/110959436354625440/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9166988&amp;postID=110959436354625440' title='10 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9166988/posts/default/110959436354625440'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9166988/posts/default/110959436354625440'/><link rel='alternate' type='text/html' href='http://realbiztalk.blogspot.com/2004/12/failover-issues-with-mq-clusters.html' title='Failover issues with MQ clusters'/><author><name>Anonymous</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/blank.gif'/></author><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9166988.post-110064014212254006</id><published>2004-11-16T21:19:00.000+00:00</published><updated>2004-11-17T08:27:15.396+00:00</updated><title type='text'>BAM for operational reports</title><content type='html'>When you start developing with BizTalk you envitably start with orchestrations, pipelines, schemas etc. and ignore some of the other cool features. One such feature is Business Activity Monitoring (BAM).&lt;br /&gt;&lt;br /&gt;Ian &amp;amp; I were working on a SWIFT messaging system for an investment bank and were designing the reporting system for tracking the flow of messsages. We considered the built in message body tracking facilities and considered a custom solution based on a custom application database - and then we considered BAM.&lt;br /&gt;&lt;br /&gt;We&#39;d both thought of BAM as being a management information tool, i.e. a tool for gathering aggregate data for building OLAP cubes. We hadn&#39;t previously thought of it as a tool for operational reports but it turns out that it is a scalable and flexible mechanism for capturing data.&lt;br /&gt;&lt;br /&gt;Before I discuss our approach, a quick recap of BAM. BAM is an infrastructure for capturing data into a database. It has been designed (using active and partitioned completed tables) to efficiently capture data and to allow fast queries over the data. BAM has tools for designing the data you want to capture - you define busines activities in terms of milestones and data items - and will create the requisite data tables, views, stored procedures and DTS jobs for partioning and archiving data. Moreover, the event bus service (aka the tracking host) provides a robust, asychronous system for data capture.&lt;br /&gt;&lt;br /&gt;In our SWIFT messaging system each message received resulted in 5-6 message interactions with other systems. We wanted a way to capture the flow of the messages through our system and a way of capturing the message bodies (in their native format). We decided that BAM provided the ideal infrastructure.&lt;br /&gt;&lt;br /&gt;&lt;p&gt;I created two activities: &lt;/p&gt;&lt;ul&gt;&lt;li&gt;A flow activity which defined the milestones for the message flow (e.g. received message, sent message to compliance engine, received first response, etc.) and the data items associated with the milestones.&lt;/li&gt;&lt;li&gt;a message body activity which defined the single milestone of a message body processed along with the message body as the associated data item.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;I then created two .NET classes (FlowTracker and BodyTracker) for invoking the BAM API to create, update and complete the activities. Each class had a set of methods - one for each milestone - with parameters for the data items appropriate for the milestone.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;The next job was to create a simple pipeline component for tracking the message bodies. This component was built as a decoder and encoder that could be used as either the first component in a receive pipeline or the last component in a send pipeline. The component simply used the BodyTracker to create and complete a message body activity.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;The orchestrations that process our messages use the FlowTracker to create a flow activity on receipt of the activating message and use the milestone methods to update the activity at various key points in the orchestration.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;One of the key problems to solve was how to related the flow activity to the multiple message body activities created in the pipeline. This was done by having the tracking pipeline component work in two modes.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;In a receive pipeline, the tracking component simply created the body activity using the message interchange ID. Recall, that the interchange ID is constant for all of the messages in the pipeline and is a property in the message context. When the flow activity is created by the FlowTracker constructor it uses the BAM AddRelatedActivity method to make the body activity a child activity of the flow activity. Moreover, the message interchange ID is recorded as a data item of the message received milestone. Similarly, at the other milestones in the flow where messages are received the body activities are related as children of the flow activity and the interchange IDs are recorded as data items in the flow.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;When the orchestration came to send a message it would generate a GUID and assign this as the interchange ID of the sent message. The orchestration would also record the flow activity ID as a custom property in the message context. When the tracking component in the send pipeline processed the message it would create the body activity and use the AddRelatedActivity method to make this a child of the parent flow activity. &lt;/p&gt;&lt;p&gt;Finally, if the message was sent successfully, the flow activity would record this as a milestone along with the sent message interchange ID as a milestone.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;With this infrastructure in place we had an efficient, robust and very performant mechanism for capturing both our message bodies and message flows.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Our next design decision was how to report this data. We considered a custom ASP.NET solution but decided on using SQL Reporting Services instead. SQL Reporting Services provides RAD facilites for creating reports that can be delivered in multiple formats (e.g. HTML, EXCEL, PDF etc.) and has facilities for caching, paging, resizing etc. that would all need custom development in ASP.NET. It even has facilities to produce scheduled reports that can be emailed to users.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Using SQL Reporting Services we created a top-level report that with multiple search parameters that produced a table of messsages. The operator can use this report to find messages for a particular date/time period, for different message types, from different sources, to different destinations, etc. A drill down link brings up a detailed report that shows the milestones of the flow and the associated data items and further drill down links display the original message bodies.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Using BAM we&#39;ve created an efficient operational reporting tool. In the furture we&#39;ll use the same data to create management information reports and render these with SQL Reporting Services.&lt;/p&gt;&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://realbiztalk.blogspot.com/feeds/110064014212254006/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9166988&amp;postID=110064014212254006' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9166988/posts/default/110064014212254006'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9166988/posts/default/110064014212254006'/><link rel='alternate' type='text/html' href='http://realbiztalk.blogspot.com/2004/11/bam-for-operational-reports.html' title='BAM for operational reports'/><author><name>Anonymous</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/blank.gif'/></author><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9166988.post-110053238930860268</id><published>2004-11-15T15:22:00.000+00:00</published><updated>2004-11-15T15:37:25.610+00:00</updated><title type='text'>Welcome</title><content type='html'>Hi and welcome to the real BizTalk blog.&lt;br /&gt;&lt;br /&gt;This is the blog of Cassium Technologies&#39; BizTalk consultants. Cassium is a consultancy working closely with Microsoft predominately in the City of London. We are engaged in cutting edge projects in several of the major investment banks and many of our projects rely on BizTalk Server 2004.&lt;br /&gt;&lt;br /&gt;The idea of this blog is to report on how BizTalk is used out there, in the field and give feedback on real-life experiences on mission critical projects.&lt;br /&gt;&lt;br /&gt;Hope you like it and find it useful.&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://realbiztalk.blogspot.com/feeds/110053238930860268/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9166988&amp;postID=110053238930860268' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9166988/posts/default/110053238930860268'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9166988/posts/default/110053238930860268'/><link rel='alternate' type='text/html' href='http://realbiztalk.blogspot.com/2004/11/welcome.html' title='Welcome'/><author><name>Anonymous</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/blank.gif'/></author><thr:total>1</thr:total></entry></feed>