tag:blogger.com,1999:blog-7585103068630619362024-03-13T17:04:11.601+02:00Pinhas's BlogPinhas Kolskyhttp://www.blogger.com/profile/14144546566317745006noreply@blogger.comBlogger27125tag:blogger.com,1999:blog-758510306863061936.post-82698778248015598732010-03-05T11:24:00.001+02:002010-03-05T11:27:12.293+02:00Can I use Microsoft Entity Framework in production products?<p align="justify">My team building a monitoring administration front-end WPF application. of course, we have a lot of data stored in a database and we need to show the end-user a view from this data. I’ve been asked to choose our DAL and Entity technology and design the business-objects.</p> <p align="justify">My first decision was to use LINQ and anonymous-type in the front end. this is mainly because the application is for monitoring only and there’s no updates or insert operations.</p> <p align="justify">The next step was the data layer and the Entity technology. I don’t like writing XML by hand (who does?) and I really prefer drugging shapes from the visual studio tool box and (hopefully) auto generate code behind. so NHibernat is out of the game for me. Now, I needed to choose between LINQ to SQL and ADO.NET Entity framework which both comes with a visual studio 2008 designer.</p> <p align="justify">My first attempt was EF because it <strong>suppose</strong> to replace LINQ to SQL (is it just so?)</p> <p align="justify">Like everyone, I saw EF demos working when executing INSTER/UPDATE/DELETE stored procedures mapping exactly to a table entity, but in my case, I need a custom entity based on a table view and stored-procedure result.</p> <p align="justify">I’ve fight with EF (on VS2008) for almost all day long and it appears that EF (currently) doesn't supports out-of-the-box entity generation from SP and Views. I did find workarounds but I don’t consider workaround as a reliable solution.  </p> <p align="justify"><strong>Honestly, I find that really odd…</strong></p> <p align="justify">Every production real-world environment works with SP and view, so I just can’t understand what was the point of releasing a framework that missing basic requirements for a production use…</p> <p align="justify">For the guys in Redmond, I just have to say that there are some companies that taking your produces seriously, so please, stop with those semi-CTP frameworks. If you are <strong>releasing</strong> a product, try give another thought of productivity. Sorry to say but, currently, EF is great for ORM demos and presentations but not for real-world systems.</p> <p align="justify">Currently, I’ll use LINQ to SQL.</p> Pinhas Kolskyhttp://www.blogger.com/profile/14144546566317745006noreply@blogger.comtag:blogger.com,1999:blog-758510306863061936.post-82612052577723782902009-12-17T22:30:00.001+02:002009-12-18T09:42:25.121+02:00C# 3.5 course code samples<p>I've spend the last past week teaching 26 talented and wonderful students.</p> <p>It was a course on .Net 3.5 includes WCF, WPF, C# 3.5 features and also some important concepts that every integration-developer should follow like:</p> <ul> <li>Think XSD and not just OO </li> <li>Don’t leave an ugly WSDL behind you (because auto generated code will be as ugly as your WSDL) </li> </ul> <p>This post is for them.</p> <p>- I had a great time with you and I hope you’ll find my tips useful.</p> <p>As I promised, You can download the course code samples (all of them!) from <a href="http://inspirelearn.com/Course.Samples.zip" target="_blank">Here</a></p> Pinhas Kolskyhttp://www.blogger.com/profile/14144546566317745006noreply@blogger.comtag:blogger.com,1999:blog-758510306863061936.post-59119985181990903232009-08-25T17:38:00.001+02:002009-08-25T17:39:29.062+02:00Pnyxe - a new commenting system in my blog<p align="justify">As all of you readers can see, I’ve decided to adjust the commenting system of my blog into a bright, easy to use one. </p> <p align="justify">I’m now using the beautiful system founded by Amit monbaz (a good friend) and so-called <a href="http://www.pnyxe.com" target="_blank">Pnyxe</a></p> <p align="justify">I’m currently moving all the comments you’ve posted in Blogger to the new system, so, I’m apologize if you previously posted a comment and now you notice that its missing – I promise to show them all again within Pnyxe comments system.</p> <p align="justify">Also, I hope you’ll enjoy my new comments system. please don’t hesitate to share your thoughts with me and the other readers.</p> <p align="justify"><strong>Happy posting to everyone.</strong></p> Pinhas Kolskyhttp://www.blogger.com/profile/14144546566317745006noreply@blogger.comtag:blogger.com,1999:blog-758510306863061936.post-72747232689671425122009-04-07T22:34:00.001+02:002009-04-07T23:14:43.372+02:00My Resume<p>I’m not officially seeking for a new position but if you interested, you can follow this link to find my <a href="http://docs.google.com/View?docid=dg636jqv_1f2f46rd3&pageview=1&hgd=1&hl=en" target="_blank">Resume</a>.</p> <p>I haven't been posting for a while, but - coming really soon my next post about Microsoft WCF vs. Java SCA and what this mean in the BizTalk perspective.</p> Pinhas Kolskyhttp://www.blogger.com/profile/14144546566317745006noreply@blogger.comtag:blogger.com,1999:blog-758510306863061936.post-17124880552809051112008-12-17T21:07:00.001+02:002008-12-17T21:07:33.343+02:00Managing a BizTalk 2006 MSI deployment packages<p align="justify">One of the features of BizTalk 2006 deployment module is the ability to export and import a BizTalk Application as MSI installation package.</p> <p align="justify">In this way we can treat each application as an atomic deployment package. This means that if we need to update our application resources with a new version, we can create a new MSI version 2.0 with all new versions of the resources and then deploy them all in one managed package.</p> <p align="justify">The creation of the MSI package can be done from within the Administration Console MMC or through BTSTask.exe script. </p> <p align="justify"><a href="http://lh6.ggpht.com/_vOZ516gDDOU/SUgS2-8qUhI/AAAAAAAAAho/31OhqCZpCOs/BizTalk_MSI_MMC.PNG"><img src="http://lh6.ggpht.com/_vOZ516gDDOU/SUgS2-8qUhI/AAAAAAAAAho/31OhqCZpCOs/BizTalk_MSI_MMC.PNG" /></a> </p> <p align="justify">or with BTSTask.exe: </p> <p align="justify">ExportApp -ApplicationName:MyApp -Package:"C:\Temp\MyApp.Msi"</p> <p align="justify">To see BTSTask.exe usage:</p> <p align="justify">C:\Program Files\Microsoft BizTalk Server 2006>BTSTask.exe ExportApp -?</p> <p align="justify"><strong><u></u></strong></p> <p align="justify"><strong><u>All BizTalk Exported MSI files are always versioned ‘1.0.0.0’</u></strong></p> <p align="justify">Both BizTalk Administration console and BTSTask.exe sharing the same API to create this MSI file. The methods and classes to administrate BizTalk reside under Microsoft.BizTalk.ApplicationDeployment.Application namespace of assembly Microsoft.BizTalk.ApplicationDeployment.Engine.</p> <p align="justify">The method that actually creates the MSI package is </p> <p align="justify">CreateMsiPackage(string msiPath, ICollection<Resource> resources, ICollection<string> applicationReferences, IDictionary<string, object> requestProperties)</p> <p align="justify">Now, unfortunately by using this method, BizTalk always creates the MSI file version as 1.0.0.0 – this means that we can’t easily manage our MSI installation packages because even if we're creating MSI of version 2.0, BizTalk will export it as 1.0   </p> <p align="justify">This restriction is for some reason <strong><u>hard-coded</u></strong> and you just <strong>can't</strong> change it.</p> <p align="justify"><strong>in the following figure you can see the hard-coded msi version:</strong></p> <p align="justify"><a href="http://lh3.ggpht.com/_vOZ516gDDOU/SUgUGvfA2JI/AAAAAAAAAh4/qPzcDrabtMk/BizTalk_MSI.PNG"><img src="http://lh3.ggpht.com/_vOZ516gDDOU/SUgUGvfA2JI/AAAAAAAAAh4/qPzcDrabtMk/BizTalk_MSI.PNG" /></a> </p> <p align="justify"><strong><u>How can I change the MSI version and successfully manage my installation packages</u></strong></p> <p align="justify">One of the ways I’ve seen people handling this restriction is by simply name the generated  MSI installation Package with some Naming-Conventions like <ApplicationName>_<VerNum>.MSI</p> <p align="justify">I consider a file name as a poor way to ensure version identity, a better idea is to somehow "Patch" the MSI metadata itself to hold the correct version. in this way, I can assure that no one will accidently rename my MSI file (just think on how easy that can happen).</p> <p align="justify"><strong><u>What is BizTalk MSI installation package</u></strong></p> <p align="justify">Before I'll show you how to patch the file, it's first must be understood that an MSI file is actually a Database file. Inside the MSI there's some system table that contains a lot of data like parameters of the MSI, the name of the CAB files, the Binary stream data content of the CAB files, custom actions etc.</p> <p align="justify">The MSI Installer engine executes SQL queries against the MSI tables and by that installing and extracting the actual files. the functions required to work with MSI protocol can be reference through msi.dll unmanaged DLL under windows system directory. </p> <p align="justify">You can find the MSI database documentation on MSDN <a href="http://msdn.microsoft.com/en-us/library/aa367441(VS.85).aspx" target="_blank">here</a>:  </p> <p align="justify"><strong><u>Browse into BizTalk MSI</u></strong></p> <p align="justify">The best way to know what MSI in general (and BizTalk MSI file in particular) means is by using "Microsoft Orca".</p> <p align="justify"><a href="http://lh3.ggpht.com/_vOZ516gDDOU/SUgS22Mff2I/AAAAAAAAAhw/XR8P-PSI5ag/s720/BizTalk_MSI_Orca.PNG"><img src="http://lh3.ggpht.com/_vOZ516gDDOU/SUgS22Mff2I/AAAAAAAAAhw/XR8P-PSI5ag/s720/BizTalk_MSI_Orca.PNG" /></a> </p> <p align="justify">As you can see in the figure above, the version of the MSI is saved in '<strong>ProductVersion</strong>' cell under '<strong>Property</strong>' table. </p> <p align="justify">So, the solution to BizTalk hard-coded 1.0 version problem is to change this value inside 'Property' table. but how can we get inside the MSI tables and change this value? – one way is by using a tool like Microsoft Orca, but in this way, the developer (or administrator) must patch the file by hand and it’s a path to future mistakes. I consider it to be a good solution only if we can some-how automate the process afterwards, so some like always some C# code can do the trick.</p> <p align="justify"><strong><u>Patching BizTalk MSI file</u></strong></p> <p align="justify">BizTalk ships with a helper class to manage MSI and CAB files. The assembly name is Microsoft.BizTalk.MSIManager.dll </p> <p align="justify">This class is actually a managed code wrapper around the MSI.dll functions and mach more easy to code then PInvoke. BizTalk infrastructures API's for deployment uses this class to create and import files form BizTalkMgmtDb into an MSI installer file and vise versa.</p> <p align="justify">So, now we understand that we can't force BizTalk to export the MSI with another version then 1.0.0.0 but we can still use BizTalk helper classes to get an easy access the MSI tables and to change the information holds inside the exported MSI.</p> <p align="justify">Here's the code snippet:</p> <!--<br />{\rtf1\ansi\ansicpg\lang1024\noproof1255\uc1 \deff0{\fonttbl{\f0\fnil\fcharset177\fprq1 Courier New;}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0??;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;??\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;??\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;??\red192\green192\blue192;}??\fs20 \cf2 public\cf0 \cf2 void\cf0 UpdateMSIProps(\cf2 string\cf0 msiPath, \cf2 string\cf0 version, \cf2 string\cf0 comment)\par ?? \{\par ?? \cf10 Database\cf0 db = \cf10 Installer\cf0 .OpenDatabase(msiPath, \cf10 DatabaseOpenMode\cf0 .Transact);\par ?? \cf2 string\cf0 query = \cf13 @"UPDATE Property SET Property.Value = '"\cf0 + version + \cf13 "' WHERE Property.Property = 'ProductVersion'"\cf0 ;\par ?? \cf10 Record\cf0 rec = \cf2 null\cf0 ;\par ?? Microsoft.BizTalk.ApplicationDeployment.MSIManager.WindowsInstaller.\cf10 View\cf0 vw =\par ?? db.OpenView(query);\par ?? vw.Execute();\par ?? vw.Close();\par ?? \cf2 if\cf0 (comment != \cf2 string\cf0 .Empty)\par ?? \{\par ?? query = \cf13 @"Insert into Property (Property, Value) Values('EAITeamComment', '"\cf0 + comment + \cf13 "')"\cf0 ;\par ?? rec = \cf2 null\cf0 ;\par ?? vw = db.OpenView(query);\par ?? vw.Execute();\par ?? vw.Close();\par ?? vw.Dispose();\par ?? \}\par ?? db.Commit();\par ?? db.Close();\par ?? db.Dispose();\par ?? \}}<br />--> <div style="font-size: 8pt; background: white; color: black; font-family: courier new"> <p style="margin: 0px">        <span style="color: blue">public</span> <span style="color: blue">void</span> UpdateMSIProps(<span style="color: blue">string</span> msiPath, <span style="color: blue">string</span> version)</p> <p style="margin: 0px">        {</p> <p style="margin: 0px">            <span style="color: teal">Database</span> db = <span style="color: teal">Installer</span>.OpenDatabase(msiPath, <span style="color: teal">DatabaseOpenMode</span>.Transact);</p> <p style="margin: 0px">            <span style="color: blue">string</span> query = <span style="color: maroon">@"UPDATE Property SET Property.Value = '"</span> + version + <span style="color: maroon">"' WHERE Property.Property = 'ProductVersion'"</span>;</p> <p style="margin: 0px">            <span style="color: teal">Record</span> rec = <span style="color: blue">null</span>;</p> <p style="margin: 0px">            Microsoft.BizTalk.ApplicationDeployment.MSIManager.WindowsInstaller.<span style="color: teal">View</span> vw =</p> <p style="margin: 0px">            db.OpenView(query);</p> <p style="margin: 0px">            vw.Execute();</p> <p style="margin: 0px">            vw.Close();</p> <p style="margin: 0px">            </p> <p style="margin: 0px">            db.Commit();</p> <p style="margin: 0px">            db.Close();</p> <p style="margin: 0px">            db.Dispose();</p> <p style="margin: 0px">        }</p> </div> <p align="justify">I also guess you’ll probably want to automate following steps as a script:</p> <ul> <li> <div align="justify">BTSTask.exe -AddResource </div> </li> <li> <div align="justify">BTSTask.exe -ExportApp </div> </li> <li> <div align="justify">Patch MSI </div> </li> <li> <div align="justify">Move MSI to the destination MSI's folder. </div> </li> </ul> <p align="justify"><strong><u>Conclusion</u></strong></p> <p align="justify">Although BizTalk can export Application from BizTalkMgmtDb into a MSI installer package, it’s also forces this package to be of version 1.0.0.0</p> <p align="justify">we simply can't do much with that because it's hard-coded with BizTalk deployment API but we does can take the newly generated MSI and 'Patch' the correct table with our desired version.</p> <p align="justify">In this way we can handle our MSI versioning in the correct way.</p> <p></p> <p></p> <p></p> <p>Thanks’ to <strong>Moti Feldman</strong> for helping me with this issue.</p> Pinhas Kolskyhttp://www.blogger.com/profile/14144546566317745006noreply@blogger.comtag:blogger.com,1999:blog-758510306863061936.post-49266799079556664092008-09-24T23:03:00.000+02:002008-09-24T23:05:02.718+02:00BizTalk 2006 MMC snap-in limitation<p align="justify">No doubt BizTalk 2006 MMC snap-in is a great move forward since the days of BizTalk 2004 Explorer Add-in. although, the GUI itself suffers sometimes from a problem or another. I think the mostly common problems are missing features or incomplete implementation. one example is when you try to start application. you can right click on the BizTalk application name and choose start. in this case, BizTalk administration console consider the activity to be under one 'transaction' so if one orchestration in one application fails in the start process - all other orchestrations, send-ports etc. in the whole application will automatically rollback to the previous state.</p> <p align="justify">The reason is that under the surface the GUI is using <a title="Microsoft.BizTalk.ExplorerOM.BtsCatalogExplorer Class" href="http://msdn2.microsoft.com/aa963345.aspx">Microsoft.BizTalk.ExplorerOM.BtsCatalogExplorer</a> class (please note that it's actually also make use of <a title="Group Class" href="http://msdn2.microsoft.com/aa963018.aspx">Microsoft.BizTalk.ApplicationDeployment.Group</a> class - but I'll ignore that for the moment). when you creates instance of this class and make some changes to send-port etc. the change will not reflect to BizTalkMgmtDb until a call to the <a title="BtsCatalogExplorer.SaveChanges Method" href="http://msdn2.microsoft.com/aa957197.aspx">SaveChanges</a>() method.</p> <p align="justify">If I could select all the applications in the BizTalk Group and choose them to start (a great feature that for some unknown reason is forbidden and you can start only exactly <u><strong>one</strong></u> application at a time ) the pseudo code in the MMC is something like this:</p><!--<br />{\rtf1\ansi\ansicpg\lang1024\noproof1255\uc1 \deff0{\fonttbl{\f0\fnil\fcharset177\fprq1 Courier New;}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0??;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;??\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;??\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;??\red192\green192\blue192;}??\fs20 Microsoft.BizTalk.ExplorerOM.\cf10 BtsCatalogExplorer\cf0 explorer = \cf2 new\cf0 Microsoft.BizTalk.ExplorerOM.\cf10 BtsCatalogExplorer\cf0 ();\par ?? explorer.ConnectionString = \cf13 @"Data Source="\cf0 + dbServerName + \cf13 ";Initial Catalog=BizTalkMgmtDb;Integrated Security=True"\cf0 ;\par ?? \par ?? \cf2 try\par ??\cf0 \{\par ?? \cf2 foreach\cf0 (Microsoft.BizTalk.ExplorerOM.\cf10 Application\cf0 app \cf2 in\cf0 explorer.Applications)\par ?? \{\par ?? app.Start(Microsoft.BizTalk.ExplorerOM.\cf10 ApplicationStartOption\cf0 .StartAll);\par ?? \}\par ??\par ?? explorer.SaveChanges();\par ?? \}\par ?? \cf2 catch\cf0 (\cf10 Exception\cf0 ex)\par ?? \{\par ?? \cf2 throw\cf0 ex;\par ?? \}}<br />--> <div style="font-size: 8pt; background: white; color: black; font-family: courier new"><pre style="margin: 0px">Microsoft.BizTalk.ExplorerOM.<span style="color: teal">BtsCatalogExplorer</span> e = <span style="color: blue">new</span> Microsoft.BizTalk.ExplorerOM.<span style="color: teal">BtsCatalogExplorer</span>();</pre><pre style="margin: 0px"> e.ConnectionString = <span style="color: maroon">@"Data Source="</span> + dbServerName + <span style="color: maroon">";Initial Catalog=BizTalkMgmtDb;Integrated Security=True"</span>;</pre><pre style="margin: 0px"> </pre><pre style="margin: 0px"> <span style="color: blue">try</span></pre><pre style="margin: 0px"> {</pre><pre style="margin: 0px"> <span style="color: blue">foreach</span> (Microsoft.BizTalk.ExplorerOM.<span style="color: teal">Application</span> app <span style="color: blue">in</span> e.Applications)</pre><pre style="margin: 0px"> {</pre><pre style="margin: 0px"> app.Start(Microsoft.BizTalk.ExplorerOM.<span style="color: teal">ApplicationStartOption</span>.StartAll);</pre><pre style="margin: 0px"> }</pre><pre style="margin: 0px"> </pre><pre style="margin: 0px"> e.SaveChanges();</pre><pre style="margin: 0px"> }</pre><pre style="margin: 0px"> <span style="color: blue">catch</span> (<span style="color: teal">Exception</span> ex)</pre><pre style="margin: 0px"> {</pre><pre style="margin: 0px"> <span style="color: blue">throw</span> ex;</pre><pre style="margin: 0px"> }</pre></div><br /><p align="justify">As you can see, all successfully started applications state has not been saved because that one application failed. </p><br /><p align="justify"><strong>I think it's need to be like this:</strong></p><br /><div style="font-size: 8pt; background: white; color: black; font-family: courier new"><pre style="margin: 0px"> <span style="color: blue">foreach</span> (Microsoft.BizTalk.ExplorerOM.<span style="color: teal">Application</span> app <span style="color: blue">in</span> e.Applications)</pre><pre style="margin: 0px"> {</pre><pre style="margin: 0px"> <span style="color: blue">try</span></pre><pre style="margin: 0px"> {</pre><pre style="margin: 0px"> app.Start(Microsoft.BizTalk.ExplorerOM.<span style="color: teal">ApplicationStartOption</span>.StartAll);</pre><pre style="margin: 0px"> }</pre><pre style="margin: 0px"> <span style="color: blue">catch</span> (<span style="color: teal">Exception</span> ex)</pre><pre style="margin: 0px"> {</pre><pre style="margin: 0px"> <span style="color: blue">bool</span> whatToDo = AskTheUserWhatToDo();</pre><pre style="margin: 0px"> </pre><pre style="margin: 0px"> <span style="color: blue">if</span> (whatToDo)</pre><pre style="margin: 0px"> <span style="color: blue">throw</span> ex;</pre><pre style="margin: 0px"> }</pre><pre style="margin: 0px"> }</pre><pre style="margin: 0px"> </pre><pre style="margin: 0px"> e.SaveChanges();</pre></div><br /><p align="justify">As an insight, the semi-unfriendly BizTalk 2006 Administration console GUI is <strong>not a direct effect of BizTalk deployment API's architecture</strong> - it's more like a half implementation in the MMC snap-in. </p> Pinhas Kolskyhttp://www.blogger.com/profile/14144546566317745006noreply@blogger.comtag:blogger.com,1999:blog-758510306863061936.post-4456350668147843372008-08-26T02:01:00.001+03:002008-08-26T02:15:03.391+03:00Unexpected disappearance of messages after executing BizTalk pipeline component<p align="justify">Here's another 'mysteries' behavior in BizTalk pipeline components:</p> <p align="justify">If you're promoting a context property that only was 'GAC'd but haven't successfully deployed into BizTalkMgmtDb (by adding the BizTalkAssembly as a resource in BizTalk management console), at runtime the pipeline component will search the context schema generated class (see <a href="http://pinhask.blogspot.com/2008/01/biztalk-context-property-class.html">here</a>) in the machine GAC and will promote the value as expected, <strong>BUT</strong> at the end of the <a title="IComponent.Execute Method" href="http://msdn2.microsoft.com/aa956978.aspx">Execute (IPipelineContext pContext, IBaseMessage pInMsg)</a> method, BizTalk will 'freeze' <strong>like no message was submitted</strong> into the message-box by the pipeline. also there's <strong>no error messages</strong> in the event viewer. this is happens even if the promoted property is not used as the subscriber parameter. </p> <p align="justify">It's not surprising that for a well working context property you must first deploy the property schema. the strange thing here is one, the way BizTalk pipeline components promoting values which is without any validation inside BizTalkMgmtDb schema tables. second, the unexpected disappearance of the message without any clue in the event viewer.</p> <p align="justify">I guess this is one of the problems with the two management repositories of BizTalk artifacts: GAC and BizTalkMgmtDb database. for example: when you're looking for a <a title="IDocumentSpec Interface" href="http://msdn2.microsoft.com/aa963272.aspx">IDocumentSpec</a> object using <a title="IPipelineContext.GetDocumentSpecByName Method" href="http://msdn2.microsoft.com/aa957002.aspx">GetDocumentSpecByName</a> method - BizTalk will fetch the schema by executing a query against the database. but when working with a context property, in the pipeline perspective, even if it uses the previously generated schema class to get the name and namespace, the purpose is to add the value into the context property list with <a title="IBaseMessageContext.Promote Method" href="http://msdn2.microsoft.com/aa957547.aspx">IBaseMessageContext.Promote</a> method, so the pipeline is not looking inside the database to actually validate the context property existence and the pipeline assumes the developer is knowing what he is doing (yeah, right...). the problem is that afterwards, the pipeline is submits the message into the message box and then the routing engine is looking for a subscriber by executing T-SQL stored-procedure against the database, so you must have the context property inside the database tables.</p> <p align="justify">Maybe in the next version we'll not have to manage artifacts in two places - till then, just be aware to deploy all the property schemas before running any pipeline component that uses them.</p> Pinhas Kolskyhttp://www.blogger.com/profile/14144546566317745006noreply@blogger.comtag:blogger.com,1999:blog-758510306863061936.post-72771344377386965342008-07-30T00:02:00.001+03:002008-07-30T00:04:10.829+03:00Expert Days Conference 2008<p align="justify">Expert Days Conference 2008 arranged by E4D-Solutions and Microsoft Israel. In this year, there's more then 20 .NET Framework Experts in a week of extreme Courses (All the sessions are in the Hebrew language).</p> <p align="justify">I'm giving two sessions:</p> <ul> <li> <div align="justify"><strong>The far side of the moon</strong>: <strong>How to use BizTalk and avoid known issues</strong></div></li></ul> <p align="justify">this session will help advanced BizTalk developers and project managers<strong> </strong>to avoid 'mysterious' problems and will show how to develop a clean workarounds to BizTalk known issues into a successful BizTalk solution.</p> <ul> <li> <div align="justify"><strong>Advanced WCF integrated with BizTalk Adapter Pack</strong></div></li></ul> <p align="justify">in this session, a deep dive into the WCF LOB adapter SDK (ASDK) for advanced .NET integration developers.</p> <p align="justify"><strong>So, for all of you Israelis readers - hope to see you there.</strong></p> Pinhas Kolskyhttp://www.blogger.com/profile/14144546566317745006noreply@blogger.comtag:blogger.com,1999:blog-758510306863061936.post-69774099333376896192008-06-22T23:01:00.001+03:002008-06-22T23:01:18.161+03:00Processing soap envelope within BizTalk Server<p align="justify">BizTalk parsing engine supports envelope schemas. This means that if the incoming message is marked as envelope schema, the parsing engine will parse the message and will dispatch the body content of the envelope as the message body part. <p align="justify">The most common scenario is when BizTalk receives SOAP Envelop. It's little known that Microsoft supplies soap envelope XSD schema as part of BizTalk system schemas. The schema name is BTS.soap_envelope_1__1 and is deployed inside Microsoft.BizTalk.GlobalPropertySchemas.dll under BizTalk.System BTS application. <p><a href="http://lh6.ggpht.com/Pinhask/SF6fRhshUTI/AAAAAAAAAbk/21bEi2sHNUY/soapEnvelopeXsd.PNG"><img src="http://lh6.ggpht.com/Pinhask/SF6fRhshUTI/AAAAAAAAAbk/21bEi2sHNUY/soapEnvelopeXsd.PNG"></a></p> <p align="justify">When schema is marked as Envelope (is_envelope="yes"), the engine is looking for the body_xpath annotation. This value is the actual data section and will be assigned as the message part. The value of body_xpath attribute is saved in dbo.bt_DocumentSpec table of BizTalkMgmtDb database. In the disassembling process the engine is extracting the value by using <a title="IDocumentSpec.GetBodyPath Method" href="http://msdn2.microsoft.com/aa956981.aspx">IDocumentSpec.GetBodyPath()</a> under <a title="Microsoft.BizTalk.Component.Interop Namespace" href="http://msdn2.microsoft.com/aa958858.aspx">Microsoft.BizTalk.Component.Interop</a> namespace.</p> <p><a href="http://lh5.ggpht.com/Pinhask/SF6fRs2IWJI/AAAAAAAAAbc/In56XyEtXEs/soapEnvelopeDocSpec.PNG"><img src="http://lh5.ggpht.com/Pinhask/SF6fRs2IWJI/AAAAAAAAAbc/In56XyEtXEs/soapEnvelopeDocSpec.PNG"></a></p> <p align="justify">Then the engine performing denormalize process by extracting message data from the body element. At the end of the process, BTS.MessageType context property is set to the message type of actual content of the soap:Body section. <p><a href="http://lh3.ggpht.com/Pinhask/SF6fR6UtxUI/AAAAAAAAAbs/plqq9CR53AM/XmlDasmReader.CreateReader.PNG"><img src="http://lh3.ggpht.com/Pinhask/SF6fR6UtxUI/AAAAAAAAAbs/plqq9CR53AM/XmlDasmReader.CreateReader.PNG"></a></p> <p><a href="http://lh3.ggpht.com/Pinhask/SF6fSFkYL2I/AAAAAAAAAb0/7LfsENU7hwE/XmlDasmReader.Denormalize.PNG?imgmax=512"><img src="http://lh3.ggpht.com/Pinhask/SF6fSFkYL2I/AAAAAAAAAb0/7LfsENU7hwE/XmlDasmReader.Denormalize.PNG"></a></p> <p align="justify"><strong><u>How do I start an Orchestration with soap:envelope message type</u></strong></p> <p align="justify">Normally, Orchestration subscription includes value for BTS.MessageType context property, this mean you can't start orchestration with the soap envelope message type because the XmlDisassembler Component will discard the soap:Envelope content and the messaging engine will only get the soap:Body content – so at the end of the process, BTS.MessageType context property will be set to the actual message type of content under soap:Body section and the orchestration will never start with the type soap:Envelope. <p align="justify">In case you need to process the entire soap:Envelope inside orchestration: <ul> <li> <div align="justify">Use PassThruReceive pipeline.</div> <li> <div align="justify">Define message of type BTS.soap_envelope_1__1 message inside the orchestration (Message Type > schemas > from referenced assembly > Microsoft.BizTalk.GlobalPropertySchemas).</div> <li> <div align="justify">Use Xml Document as the incoming message.</div> <li> <div align="justify">Assign the incoming Xml Document message to the BTS.soap_envelope_1__1 message.</div></li></ul> <p align="justify"><a href="http://lh5.ggpht.com/Pinhask/SF6kzDG2ZzI/AAAAAAAAAb8/oU-jIBc_QI4/BTS.soap_envelope_1__1.PNG" target="_blank"><img src="http://lh5.ggpht.com/Pinhask/SF6kzDG2ZzI/AAAAAAAAAb8/oU-jIBc_QI4/BTS.soap_envelope_1__1.PNG"></a> </p> <p align="justify"><a href="http://lh6.ggpht.com/Pinhask/SF6m4QZqgwI/AAAAAAAAAcE/Lyx7Fr4KBTw/ProcessSoapEnvOrchestration.PNG?" target="_blank"><img src="http://lh6.ggpht.com/Pinhask/SF6m4QZqgwI/AAAAAAAAAcE/Lyx7Fr4KBTw/ProcessSoapEnvOrchestration.PNG"></a> </p> <p align="justify"><strong><u>Which custom pipeline component I need to develop for extracting the soap:Body section</u></strong></p> <p align="justify">If you need to receive message that is wrapped by a soap envelope and you're using the XmlDisassembler pipeline component - there's no need to develop further components for extracting the body element because the engine will automatically dispatch the soap:Body as the message part. <p align="justify"><strong><u>What about soap:Header and soap:Fault section</u></strong> <p align="justify">The automatic dispatch is only for the soap:Body section and the other section are discarded. so if you also need to process the soap:Header section you have to write a custom pipeline component for this task.</p> Pinhas Kolskyhttp://www.blogger.com/profile/14144546566317745006noreply@blogger.comtag:blogger.com,1999:blog-758510306863061936.post-31916334546346005232008-06-21T23:04:00.001+03:002008-06-21T23:06:08.198+03:00Dependency in BizTalk Assembly<p align="justify">When you deploy BizTalk assembly you must ensure that any referenced assembly is also deployed. Actually, BizTalk is enforcing that by not letting you applying adding resource action without deploying all its references. <p align="justify">When removing resource BizTalk doesn't uninstalling the actual assembly from the GAC, so, any application would work regardless to missing registration of the assembly in BizTalk database. <p align="justify">On the other hand, BizTalk is forcing dependencies when trying to delete (or modify) any resource that has other depended artifact in BizTalk. This means that if one application uses pipeline component or map from referenced BizTalk Application, BizTalk explorer object model (<a title="Microsoft.BizTalk.ExplorerOM Namespace" href="http://msdn2.microsoft.com/aa958862.aspx">Microsoft.BizTalk.ExplorerOM</a>) will throw an exception when trying to remove the assembly containing the pipeline component or map as long you'll not reset the pipeline to the default passthrough pipeline components (or some pipeline from other deployed assembly) and remove the mapping from the port. <p align="justify">The very same behavior is happens when it come to BizTalk resources. Any attempt to remove assembly that referenced by other assembly inside any BizTalk application will throw exception by BizTalk ApplicationDeployment API's. (<a title="Microsoft.BizTalk.ApplicationDeployment Namespace" href="http://msdn2.microsoft.com/aa958850.aspx">Microsoft.BizTalk.ApplicationDeployment</a>) <p align="justify"><strong><u>How does BizTalk detects references assemblies</u></strong> <p align="justify">BizTalk is actually uses <a title="System.Reflection Namespace" href="http://msdn2.microsoft.com/136wx94f.aspx">System.Reflection</a> to detect references. Each <a title="Assembly Class" href="http://msdn2.microsoft.com/xbe1wdx9.aspx">System.Reflection.Assembly</a> object has References member of type List that contains the fully-qualified name. Inside BizTalk any resource has <a href="http://msdn.microsoft.com/en-us/microsoft.biztalk.applicationdeployment.resource.luid.aspx" target="_blank">Resource.Luid</a> property, when deleting (or modifying) assembly ApplicationDeployment API's loads each resource as an <a title="Assembly Class" href="http://msdn2.microsoft.com/xbe1wdx9.aspx">System.Reflection.Assembly</a> object and checks the References member for this Luid. If BizTalk finds equal Luid an exception will be thrown. <p align="justify">Because of this reason, updating infrastructure artifacts is quite headache. The Process must be in the following order: <ul> <li> <div align="justify">Removing all referenced Applications. </div> <li> <div align="justify">Remove infrastructures old version. </div> <li> <div align="justify">Deploy infrastructures new version. </div> <li> <div align="justify">Deploy all high level referenced Application.</div></li></ul> <p align="justify"><strong><u>Where can I search for BizTalk assembly for checking its referenced Assemblies</u></strong> <p align="justify">There are three places which BizTalk assembly can be found for checking its referenced assemblies: <ul> <li> <div align="justify">Local server where the assembly location specified by the sourceLocation property – this approach </div> <li> <div align="justify">Remote server where the sourceLocation property specifies assembly on the local machine - this is the most bad option because you must be sure the assembly is the very same as the one on the remote computer. Unfortunately this is the actual way BizTalk Administration Console is using – see below. </div> <li> <div align="justify">Local server on the GAC – this is the best option because it checks the actual running assembly.</div></li></ul> <p align="justify"><strong><u>How can I detect references in BizTalk assemblies</u></strong> <p align="justify">BizTalk 2006 MMC offers GUI for detecting references in BizTalk assemblies. Despite this, the MMC is running in a client mode, on a remote computer so, the GUI is not checking the remote machine GAC. As I wrote, this checking is Reflection based so; the BizTalk MMC must load the assembly into memory before being able to search for Luid equality – which is not possible from remote computer. <p align="justify">The way BizTalk MMC handles this issue is by using the property annotations list that each BizTalk resource contains: <p align="justify">Each Resource has <a title="Resource.Properties Property" href="http://msdn2.microsoft.com/aa960314.aspx">Resource.Properties</a> property of IDictionary<string,Object> type. the entry in this dictionary which points to the resource path is 'SourceLocation' so, BizTalk Administration console uses this entity for the parameters needed by <a title="Assembly..::.Load Method " href="http://msdn2.microsoft.com/3te3zcz1.aspx">System.Reflection.Assembly.Load</a> method. By this, if the local machine contains the assembly on the same path as in the remote computer – BizTalk Administration console can load it into memory and search for references. <p align="justify"><a href="http://lh5.ggpht.com/Pinhask/SFt6vQ60mRI/AAAAAAAAAZ0/7tHkE5cVaYk/SourceLocation.PNG" target="_blank"><img src="http://lh5.ggpht.com/Pinhask/SFt6vQ60mRI/AAAAAAAAAZ0/7tHkE5cVaYk/SourceLocation.PNG"></a> <p align="justify">In the following, BizTalk administration console MMC was find the assembly in the path specified under the sourceLocation, so check for dependencies was preformed. <p align="justify"><a href="http://lh5.ggpht.com/Pinhask/SFt6vIjVh9I/AAAAAAAAAZk/HPmKF6-PnQg/DependencyFound.PNG" target="_blank"><img src="http://lh5.ggpht.com/Pinhask/SFt6vIjVh9I/AAAAAAAAAZk/HPmKF6-PnQg/DependencyFound.PNG"></a> <p align="justify">If the Administration Console can't find the assembly in the location specified in sourceLocation – the <a href="http://msdn2.microsoft.com/3te3zcz1.aspx">System.Reflection.Assembly.Load</a> method failed and <strong><u>no further check is preformed</u></strong>. <p align="justify"><img src="http://lh3.ggpht.com/Pinhask/SFt6vXSaSEI/AAAAAAAAAZs/hNZE-HQFrgQ/NoDependencyFound.PNG"> <p align="justify">In this insight, it would be much more advisable to run the check on the local server GAC. Unfortunately, BizTalk 2006 administration console is MMC snap-in and was designed to run on a remote computer so it does not support this approach.</p> <p align="justify">The first step for extracting BizTalk Assembly from the GAC is by finding the path to the assmebly. this can be done by using the GetAssemblyPath(string assemblyDisplayName) static method of the GAC class under Microsoft.BizTalk.Gac namespace. you can find this namespace in Microsoft.BizTalk.Deployment.dll</p> <p align="justify">The second step is to load the assembly. this can be done by using Microsoft.BizTalk.Deployment.Assembly namespace. use AssemblyBase property of the BtsAssemblyManager class.</p> <p align="justify">Here's the code snippet: </p><!--<br />{\rtf1\ansi\ansicpg\lang1024\noproof1255\uc1 \deff0{\fonttbl{\f0\fnil\fcharset177\fprq1 Courier New;}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0??;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;??\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;??\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;??\red192\green192\blue192;}??\fs20 \cf2 public\cf0 \cf10 List\cf0 <\cf2 string\cf0 > CheckDependencies(\cf2 string\cf0 btsAssemblyLuid, \cf2 string\cf0 btsSqlServerName)\par ?? \{\par ?? \cf10 List\cf0 <\cf2 string\cf0 > dependeciesArr = \cf2 new\cf0 \cf10 List\cf0 <\cf2 string\cf0 >();\par ??\par ?? \cf2 string\cf0 [] btsAssemblyProps = btsAssemblyLuid.Split(\cf13 ','\cf0 );\par ?? \cf2 string\cf0 btsAssemblyName = btsAssemblyProps[0];\par ?? \cf2 string\cf0 btsAssemblyVersion = btsAssemblyProps[1].Remove(1, \cf13 "Version="\cf0 .Length).Trim();\par ?? \cf2 string\cf0 btsAssemblyCulture = btsAssemblyProps[2].Remove(1, \cf13 "Culture="\cf0 .Length).Trim();\par ?? \cf2 string\cf0 btsAssemblyKey = btsAssemblyProps[3].Remove(1, \cf13 "PublicKeyToken="\cf0 .Length).Trim();\par ??\par ?? \cf2 string\cf0 btsAssemblyPath = Microsoft.BizTalk.Gac.\cf10 Gac\cf0 .GetAssemblyPath(btsAssemblyName);\par ?? Microsoft.BizTalk.Deployment.Assembly.\cf10 BtsAssemblyManager\cf0 mgr = \cf2 new\cf0 Microsoft.BizTalk.Deployment.Assembly.\cf10 BtsAssemblyManager\cf0 (btsAssemblyPath, \cf2 null\cf0 );\par ??\par ?? Microsoft.BizTalk.MetaDataOM.\cf10 IAssemblyBase\cf0 assembly = mgr.AssemblyBase;\par ??\par ?? Microsoft.BizTalk.ApplicationDeployment.\cf10 Group\cf0 group = \cf2 new\cf0 Microsoft.BizTalk.ApplicationDeployment.\cf10 Group\cf0 ();\par ?? group.DBName = \cf13 "BizTalkMgmtDb"\cf0 ;\par ?? group.DBServer = btsSqlServerName;\par ??\par ?? \cf2 foreach\cf0 (Microsoft.BizTalk.ApplicationDeployment.\cf10 Application\cf0 app \cf2 in\cf0 group.Applications)\par ?? \{\par ?? \cf2 foreach\cf0 (Microsoft.BizTalk.ApplicationDeployment.\cf10 Resource\cf0 res \cf2 in\cf0 app.ResourceCollection)\par ?? \{\par ?? \cf2 if\cf0 (res.ResourceType.Equals(\cf13 "System.BizTalk:BizTalkAssembly"\cf0 ) || res.ResourceType.Equals(\cf13 "System.BizTalk:Assembly"\cf0 ))\par ?? \{\par ?? \cf2 string\cf0 [] props = res.Luid.Split(\cf13 ','\cf0 );\par ?? \cf2 string\cf0 name = props[0];\par ?? \cf2 string\cf0 version = props[1].Remove(1, \cf13 "Version="\cf0 .Length).Trim();\par ?? \cf2 string\cf0 culture = props[2].Remove(1, \cf13 "Culture="\cf0 .Length).Trim();\par ?? \cf2 string\cf0 key = props[3].Remove(1, \cf13 "PublicKeyToken="\cf0 .Length).Trim();\par ??\par ?? \cf2 string\cf0 path = Microsoft.BizTalk.Gac.\cf10 Gac\cf0 .GetAssemblyPath(name);\par ?? Microsoft.BizTalk.Deployment.Assembly.\cf10 BtsAssemblyManager\cf0 manager = \cf2 new\cf0 Microsoft.BizTalk.Deployment.Assembly.\cf10 BtsAssemblyManager\cf0 (path, \cf2 null\cf0 );\par ?? \cf10 Array\cf0 references = manager.AssemblyBase.References \cf2 as\cf0 \cf10 Array\cf0 ;\par ??\par ?? \cf2 foreach\cf0 (\cf2 string\cf0 refName \cf2 in\cf0 references)\par ?? \{\par ?? \cf2 if\cf0 (assembly.DisplayName.Equals(refName))\par ?? \{\par ?? dependeciesArr.Add(app.Name + \cf13 " : "\cf0 + res.Luid);\par ?? \}\par ?? \}\par ?? \}\par ?? \}\par ?? \}\par ??\par ?? \cf2 return\cf0 dependeciesArr;\par ?? \}}<br />--> <div style="font-size: 8pt; background: white; color: black; font-family: courier new"><pre style="margin: 0px"><span style="color: blue">public</span> <span style="color: teal">List</span><<span style="color: blue">string</span>> CheckDependencies(<span style="color: blue">string</span> btsAssemblyLuid, <span style="color: blue">string</span> btsSqlServerName)</pre><pre style="margin: 0px">{</pre><pre style="margin: 0px"> <span style="color: teal">List</span><<span style="color: blue">string</span>> dependeciesArr = <span style="color: blue">new</span> <span style="color: teal">List</span><<span style="color: blue">string</span>>();</pre><pre style="margin: 0px"> </pre><pre style="margin: 0px"> <span style="color: blue">string</span>[] btsAssemblyProps = btsAssemblyLuid.Split(<span style="color: maroon">','</span>);</pre><pre style="margin: 0px"> <span style="color: blue">string</span> btsAssemblyName = btsAssemblyProps[0];</pre><pre style="margin: 0px"> <span style="color: blue">string</span> btsAssemblyVersion = btsAssemblyProps[1].Remove(1, <span style="color: maroon">"Version="</span>.Length).Trim();</pre><pre style="margin: 0px"> <span style="color: blue">string</span> btsAssemblyCulture = btsAssemblyProps[2].Remove(1, <span style="color: maroon">"Culture="</span>.Length).Trim();</pre><pre style="margin: 0px"> <span style="color: blue">string</span> btsAssemblyKey = btsAssemblyProps[3].Remove(1, <span style="color: maroon">"PublicKeyToken="</span>.Length).Trim();</pre><pre style="margin: 0px"> </pre><pre style="margin: 0px"> <span style="color: blue">string</span> btsAssemblyPath = Microsoft.BizTalk.Gac.<span style="color: teal">Gac</span>.GetAssemblyPath(btsAssemblyName);</pre><pre style="margin: 0px"> Microsoft.BizTalk.Deployment.Assembly.<span style="color: teal">BtsAssemblyManager</span> mgr = <span style="color: blue">new </span>Microsoft.BizTalk.Deployment.Assembly.<span style="color: teal">BtsAssemblyManager</span>(btsAssemblyPath, <span style="color: blue">null</span>);</pre><pre style="margin: 0px"> </pre><pre style="margin: 0px"> Microsoft.BizTalk.MetaDataOM.<span style="color: teal">IAssemblyBase</span> assembly = mgr.AssemblyBase;</pre><pre style="margin: 0px"> </pre><pre style="margin: 0px"> Microsoft.BizTalk.ApplicationDeployment.<span style="color: teal">Group</span> group = <span style="color: blue">new</span> Microsoft.BizTalk.ApplicationDeployment.<span style="color: teal">Group</span>();</pre><pre style="margin: 0px"> group.DBName = <span style="color: maroon">"BizTalkMgmtDb"</span>;</pre><pre style="margin: 0px"> group.DBServer = btsSqlServerName;</pre><pre style="margin: 0px"> </pre><pre style="margin: 0px"> <span style="color: blue">foreach</span> (Microsoft.BizTalk.ApplicationDeployment.<span style="color: teal">Application</span> app <span style="color: blue">in</span> group.Applications)</pre><pre style="margin: 0px"> {</pre><pre style="margin: 0px"> <span style="color: blue">foreach</span> (Microsoft.BizTalk.ApplicationDeployment.<span style="color: teal">Resource</span> res <span style="color: blue">in</span> app.ResourceCollection)</pre><pre style="margin: 0px"> {</pre><pre style="margin: 0px"> <span style="color: blue">if</span> (res.ResourceType.Equals(<span style="color: maroon">"System.BizTalk:BizTalkAssembly"</span>) || res.ResourceType.Equals(<span style="color: maroon">"System.BizTalk:Assembly"</span>))</pre><pre style="margin: 0px"> {</pre><pre style="margin: 0px"> <span style="color: blue">string</span>[] props = res.Luid.Split(<span style="color: maroon">','</span>);</pre><pre style="margin: 0px"> <span style="color: blue">string</span> name = props[0];</pre><pre style="margin: 0px"> <span style="color: blue">string</span> version = props[1].Remove(1, <span style="color: maroon">"Version="</span>.Length).Trim();</pre><pre style="margin: 0px"> <span style="color: blue">string</span> culture = props[2].Remove(1, <span style="color: maroon">"Culture="</span>.Length).Trim();</pre><pre style="margin: 0px"> <span style="color: blue">string</span> key = props[3].Remove(1, <span style="color: maroon">"PublicKeyToken="</span>.Length).Trim();</pre><pre style="margin: 0px"> </pre><pre style="margin: 0px"> <span style="color: blue">string</span> path = Microsoft.BizTalk.Gac.<span style="color: teal">Gac</span>.GetAssemblyPath(name);</pre><pre style="margin: 0px"> Microsoft.BizTalk.Deployment.Assembly.<span style="color: teal">BtsAssemblyManager</span> manager = <span style="color: blue">new</span> Microsoft.BizTalk.Deployment.Assembly.<span style="color: teal">BtsAssemblyManager</span>(path, <span style="color: blue">null</span>);</pre><pre style="margin: 0px"> <span style="color: teal">Array</span> references = manager.AssemblyBase.References <span style="color: blue">as</span> <span style="color: teal">Array</span>;</pre><pre style="margin: 0px"> </pre><pre style="margin: 0px"> <span style="color: blue">foreach</span> (<span style="color: blue">string</span> refName <span style="color: blue">in</span> references)</pre><pre style="margin: 0px"> {</pre><pre style="margin: 0px"> <span style="color: blue">if</span> (assembly.DisplayName.Equals(refName))</pre><pre style="margin: 0px"> {</pre><pre style="margin: 0px"> dependeciesArr.Add(app.Name + <span style="color: maroon">" : "</span> + res.Luid);</pre><pre style="margin: 0px"> }</pre><pre style="margin: 0px"> }</pre><pre style="margin: 0px"> }</pre><pre style="margin: 0px"> }</pre><pre style="margin: 0px"> }</pre><pre style="margin: 0px"> </pre><pre style="margin: 0px"> <span style="color: blue">return</span> dependeciesArr;</pre><pre style="margin: 0px">}</pre><pre style="margin: 0px"> </pre></div> Pinhas Kolskyhttp://www.blogger.com/profile/14144546566317745006noreply@blogger.comtag:blogger.com,1999:blog-758510306863061936.post-44124291976606894012008-05-30T13:10:00.001+03:002008-05-30T13:10:37.301+03:00Microsoft ESB Guidance - Message flow : Part I<p align="justify">The ESB Guidance are set of tools that extends BizTalk from regular EAI 'Hub-and-Spoke' Broker, into the <a title="ESB Guidance - Hello SOA world!" href="pinhask.blogspot.com/2008/01/esb-guidance-hello-soa-world.html">'SOA' world</a>. One of the first thing you need to know about the guidance is that there's (almost) no magic or new stand alone feature in there - the guidance takes you beyond 'EAI' by understanding BizTalk 2006 architecture and leading BizTalk features to the wanted results.</p> <p align="justify">The main components are:</p> <ul> <li> <div align="justify">Itinerary On/Off ramps - Extends BizTalk Messaging and BizTalk Adapter framework.</div> <li> <div align="justify">Core services (Agents) - Extends BizTalk Orchestration.</div> <li> <div align="justify">Exception management - Extends BizTalk Error report (For Orchestrations) and ACK/NACK notification (For pipelines)</div> <li> <div align="justify">Web services - Extends BizTalk transformation API and ExplorerOM API</div></li></ul> <p align="justify">In the following, slides from the session I gave together with Daniel Ben Zikry at 'SOA open day' ,Microsoft - Israel.</p> <p align="justify">BizTalk Server 2006 was designed to fully encapsulate the End-Point native technology and the broker Routing engine. this was done by separating the Messaging engine from the Adapter layer and the EPM. in this strategy, the communication with the End-Point and the translation of the incoming bytes into something BizTalk can handle with - is under the responsibility of the adapter and the Message engine is route the message to the destination without worry about protocols ,specifications or programing languages.</p> <p align="justify"><a title="BizTalk 2006" href="http://lh4.ggpht.com/Pinhask/SD3VOSrdTbI/AAAAAAAAAYk/vV8hWn5szAo/ESBMsgFlowBTS2006.jpg"><img src="http://lh4.ggpht.com/Pinhask/SD3VOSrdTbI/AAAAAAAAAYk/vV8hWn5szAo/ESBMsgFlowBTS2006.jpg"></a> </p> <p align="justify">Unfortunately all the above is not so simple, BizTalk Routing Engine is working in pub/sub pattern and the topics are <strong><u>Promoted Properties</u></strong>. the broker has no idea what to do with the incoming stream unless it came with instructions as metadata. the instructions are the Topic that all subscribers are listening to. in BizTalk routing engine, the Topic is a key/value entry in the message context that signed as "propPromoted" - a promoted property.</p> <p align="justify">The component in the layer that promote those properties is the Adapter - and each adapter promote it's own properties. so you can't really be sure the message that submitted through <strong>SOAP</strong> adapter is routed in the very same way as a message submitted by <strong>MQSeries</strong> adapter - unless the routing is defined by a common promoted property. this architecture leads to tight coupling between service provider and client endpoint technology. In 'SOA' term, the service is an atomic unit of functionality that has no limit to the client protocol, this problem traditionally handled by a Logical Port that contains physical port. each physical port has one adapter to work against one endpoint technology. the topic for all subscribers was the logical port. the disadvantage with this solution is that the only way to active and consume the service is through this logical port, which means, not all other messages submitted into the MessageBox from any other logical ports. so, the real solution is to use <strong><u>ESB Routing context property</u></strong> and use them as topics for all subscriptions.</p> <p align="justify">This is exactly what happened within the ESB Guidance. All routing inside the ESB are done by common ESB Routing properties. The layer between the Adapter framework and the Message Engine is the ESB Pipelines. this means that the message is submitted into the adapter and after this the message is moved to the next layer and only then - <strong>absolutely isolated from the adapter and the endpoint</strong> - the routing properties are initialized.</p> <p align="justify"><a title="BizTalk 2006 with ESB Guidance" href="http://lh4.ggpht.com/Pinhask/SD3VPSrdTcI/AAAAAAAAAYs/5VPIsyLm-y8/ESBMsgFlowBTS2006Extend.jpg"><img src="http://lh4.ggpht.com/Pinhask/SD3VPSrdTcI/AAAAAAAAAYs/5VPIsyLm-y8/ESBMsgFlowBTS2006Extend.jpg"></a></p> Pinhas Kolskyhttp://www.blogger.com/profile/14144546566317745006noreply@blogger.comtag:blogger.com,1999:blog-758510306863061936.post-63224106257144208492008-05-18T23:55:00.001+03:002008-05-19T00:07:13.699+03:00xsl:for-each statement with BizTalk mapper<p align="justify">Honestly, I'm not a big fan of the XSL mapper editor shipped with BizTalk extensions for VS2005. likewise with the xsl and C# functions visual representation called functoids. Personally, I find writing the XSL code to transform between one XML to another as easy approach and more easy tuning then fighting with the editor until it generates the appropriate code.</p> <p align="justify">One common scenario is generating xsl:for-each loop in the XSL stylesheet. I stopped counting the times people asked me how to to obtain this with the mapper. The task is easy when you write the xsl code by yourself but much more complicated when you're trying to generate it with the mapper. </p> <ul> <li> <div align="justify"><strong><u>unbounded element to another unbounded element.</u></strong></div></li></ul> <p align="justify">The basic scenario is transforming from one repeating element to another. consider the following:</p> <p><strong><u>Source Schema:</u></strong></p> <p><a href="http://lh5.ggpht.com/Pinhask/SDB7efTjdiI/AAAAAAAAAV4/geKU8nHIVp8/Demo.Mapping.Foreach.1.jpg"><img src="http://lh5.ggpht.com/Pinhask/SDB7efTjdiI/AAAAAAAAAV4/geKU8nHIVp8/Demo.Mapping.Foreach.1.jpg"></a> </p> <p><strong><u>Destination Schema:</u></strong></p> <p><a href="http://lh6.ggpht.com/Pinhask/SDB7fvTjdjI/AAAAAAAAAWA/nRBd7T8Ders/Demo.Mapping.Foreach.2.jpg"><img src="http://lh6.ggpht.com/Pinhask/SDB7fvTjdjI/AAAAAAAAAWA/nRBd7T8Ders/Demo.Mapping.Foreach.2.jpg"></a> </p> <p><strong><u>XSL Code:</u></strong></p> <p><a href="http://lh5.ggpht.com/Pinhask/SDB7hfTjdkI/AAAAAAAAAWI/xisAt2Q_HQc/Demo.Mapping.Foreach.xsl.4.jpg"><img src="http://lh5.ggpht.com/Pinhask/SDB7hfTjdkI/AAAAAAAAAWI/xisAt2Q_HQc/Demo.Mapping.Foreach.xsl.4.jpg"></a> </p> <p><u><strong>BizTalk Mapper:</strong></u></p> <p><a href="http://lh4.ggpht.com/Pinhask/SDCIYPTjdtI/AAAAAAAAAXo/wWGB5LMIxJk/Demo.Mapping.Foreach.map.3.jpg"><img src="http://lh4.ggpht.com/Pinhask/SDCIYPTjdtI/AAAAAAAAAXo/wWGB5LMIxJk/Demo.Mapping.Foreach.map.3.jpg"></a> </p> <p align="justify">As you can see, to create the above XSL, all you have to do is to drug the source elements to the destination. this is because both source and destination elements are unbounded, so the mapper 'understand' and generating xsl:for-each statement.</p> <ul> <li> <div align="justify"><strong><u>Unbounded element with maxOccurs="1" child and unbounded child:</u></strong></div></li></ul> <p>consider the following:</p> <p><strong><u>Source Schema:</u></strong></p> <p><a href="http://lh6.ggpht.com/Pinhask/SDB7ivTjdlI/AAAAAAAAAWQ/s0SKoWOOo-g/Demo.Mapping.Foreach.sample2.1.jpg"><img src="http://lh6.ggpht.com/Pinhask/SDB7ivTjdlI/AAAAAAAAAWQ/s0SKoWOOo-g/Demo.Mapping.Foreach.sample2.1.jpg"></a> </p> <p><strong><u>Destination Schema:</u></strong></p> <p><a href="http://lh6.ggpht.com/Pinhask/SDB7jvTjdmI/AAAAAAAAAWY/ngYGs0-0rCk/Demo.Mapping.Foreach.sample2.2.jpg"><img src="http://lh6.ggpht.com/Pinhask/SDB7jvTjdmI/AAAAAAAAAWY/ngYGs0-0rCk/Demo.Mapping.Foreach.sample2.2.jpg"></a> </p> <p><u><strong>Input XML:</strong></u></p><!--<br />{\rtf1\ansi\ansicpg\lang1024\noproof1255\uc1 \deff0{\fonttbl{\f0\fnil\fcharset177\fprq1 Courier New;}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0??;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;??\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;??\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;??\red192\green192\blue192;}??\fs20 \cf2 <\cf13 ns0:Root\cf2 \cf6 xmlns:ns0\cf2 =\cf0 "\cf2 http://Pinhas_Kolsky.Demos.Mapping.Looping.Schema1\cf0 "\cf2 >\par ?? <\cf13 Record1\cf2 >\par ?? <\cf13 Record\cf2 >\par ?? <\cf13 Record2\cf2 >\par ?? <\cf13 TargetField1\cf2 >\cf0 1\cf2 </\cf13 TargetField1\cf2 >\par ?? <\cf13 TargetField1\cf2 >\cf0 2\cf2 </\cf13 TargetField1\cf2 >\par ?? </\cf13 Record2\cf2 >\par ?? <\cf13 Record2\cf2 >\par ?? <\cf13 TargetField1\cf2 >\cf0 3\cf2 </\cf13 TargetField1\cf2 >\par ?? <\cf13 TargetField1\cf2 >\cf0 4\cf2 </\cf13 TargetField1\cf2 >\par ?? </\cf13 Record2\cf2 >\par ?? </\cf13 Record\cf2 >\par ?? </\cf13 Record1\cf2 >\par ?? <\cf13 Record1\cf2 >\par ?? <\cf13 Record\cf2 >\par ?? <\cf13 Record2\cf2 >\par ?? <\cf13 TargetField1\cf2 >\cf0 5\cf2 </\cf13 TargetField1\cf2 >\par ?? <\cf13 TargetField1\cf2 >\cf0 6\cf2 </\cf13 TargetField1\cf2 >\par ?? </\cf13 Record2\cf2 >\par ?? </\cf13 Record\cf2 >\par ?? </\cf13 Record1\cf2 >\par ??</\cf13 ns0:Root\cf2 >}<br />--> <div style="font-size: 8pt; background: white; color: black; font-family: courier new"> <p style="margin: 0px"><span style="color: blue"><</span><span style="color: maroon">ns0:Root</span><span style="color: blue"> </span><span style="color: red">xmlns:ns0</span><span style="color: blue">=</span>"<span style="color: blue">http://Pinhas_Kolsky.Demos.Mapping.Looping.Schema1</span>"<span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue"> <</span><span style="color: maroon">Record1</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue"> <</span><span style="color: maroon">Record</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue"> <</span><span style="color: maroon">Record2</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue"> <</span><span style="color: maroon">TargetField1</span><span style="color: blue">></span>1<span style="color: blue"></</span><span style="color: maroon">TargetField1</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue"> <</span><span style="color: maroon">TargetField1</span><span style="color: blue">></span>2<span style="color: blue"></</span><span style="color: maroon">TargetField1</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue"> </</span><span style="color: maroon">Record2</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue"> <</span><span style="color: maroon">Record2</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue"> <</span><span style="color: maroon">TargetField1</span><span style="color: blue">></span>3<span style="color: blue"></</span><span style="color: maroon">TargetField1</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue"> <</span><span style="color: maroon">TargetField1</span><span style="color: blue">></span>4<span style="color: blue"></</span><span style="color: maroon">TargetField1</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue"> </</span><span style="color: maroon">Record2</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue"> </</span><span style="color: maroon">Record</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue"> </</span><span style="color: maroon">Record1</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue"> <</span><span style="color: maroon">Record1</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue"> <</span><span style="color: maroon">Record</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue"> <</span><span style="color: maroon">Record2</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue"> <</span><span style="color: maroon">TargetField1</span><span style="color: blue">></span>5<span style="color: blue"></</span><span style="color: maroon">TargetField1</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue"> <</span><span style="color: maroon">TargetField1</span><span style="color: blue">></span>6<span style="color: blue"></</span><span style="color: maroon">TargetField1</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue"> </</span><span style="color: maroon">Record2</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue"> </</span><span style="color: maroon">Record</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue"> </</span><span style="color: maroon">Record1</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue"></</span><span style="color: maroon">ns0:Root</span><span style="color: blue">></span></p></div> <p>in this case, you cannot drug the elements like in the basic scenario:</p> <p><u><strong>BizTalk Mapper:</strong></u></p> <p><a href="http://lh6.ggpht.com/Pinhask/SDB7kvTjdnI/AAAAAAAAAWg/i5UytxFG7is/Demo.Mapping.Foreach.map.sample2.3.jpg"><img src="http://lh6.ggpht.com/Pinhask/SDB7kvTjdnI/AAAAAAAAAWg/i5UytxFG7is/Demo.Mapping.Foreach.map.sample2.3.jpg"></a> </p> <p align="justify">BizTalk mapper can 'guess' how to build the for-each statement only in the basic scenario, in the case above, the mapper will generate the first child of the unbounded destination element more then once:</p> <p><strong><u>XSL Code:</u></strong></p> <p><img src="http://lh5.ggpht.com/Pinhask/SDB7mfTjdoI/AAAAAAAAAWo/s-eHoX1WyGk/Demo.Mapping.Foreach.map.sample2.xsl.4.jpg"> </p> <p><u><strong>Output XML (Not valid):</strong></u></p><!--<br />{\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset177\fprq1 Courier New;}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0??;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;??\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;??\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;??\red192\green192\blue192;}??\fs20 \cf2 <\cf13 ns0:Root\cf2 \cf6 xmlns:ns0\cf2 =\cf0 "\cf2 http://Pinhas_Kolsky.Demos.Mapping.Looping.Schema2\cf0 "\cf2 >\par ?? <\cf13 LoopRecord1\cf2 >\par ?? <\cf13 Record\cf2 >\par ?? <\cf13 LoopRecord2\cf2 >\par ?? <\cf13 DestField1\cf2 >\cf0 1\cf2 </\cf13 DestField1\cf2 >\par ?? <\cf13 DestField2\cf2 >\cf0 2\cf2 </\cf13 DestField2\cf2 >\par ?? </\cf13 LoopRecord2\cf2 >\par ?? <\cf13 LoopRecord2\cf2 >\par ?? <\cf13 DestField1\cf2 >\cf0 3\cf2 </\cf13 DestField1\cf2 >\par ?? <\cf13 DestField2\cf2 >\cf0 4\cf2 </\cf13 DestField2\cf2 >\par ?? </\cf13 LoopRecord2\cf2 >\par ?? </\cf13 Record\cf2 >\par ?? <\cf13 Record\cf2 >\par ?? <\cf13 LoopRecord2\cf2 >\par ?? <\cf13 DestField1\cf2 >\cf0 5\cf2 </\cf13 DestField1\cf2 >\par ?? <\cf13 DestField2\cf2 >\cf0 6\cf2 </\cf13 DestField2\cf2 >\par ?? </\cf13 LoopRecord2\cf2 >\par ?? </\cf13 Record\cf2 >\par ?? </\cf13 LoopRecord1\cf2 >\par ??</\cf13 ns0:Root\cf2 >}<br />--> <div style="font-size: 8pt; background: white; color: black; font-family: courier new"> <p style="margin: 0px"><span style="color: blue"><</span><span style="color: maroon">ns0:Root</span><span style="color: blue"> </span><span style="color: red">xmlns:ns0</span><span style="color: blue">=</span>"<span style="color: blue">http://Pinhas_Kolsky.Demos.Mapping.Looping.Schema2</span>"<span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue"> <</span><span style="color: maroon">LoopRecord1</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue"> <</span><span style="color: maroon">Record</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue"> <</span><span style="color: maroon">LoopRecord2</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue"> <</span><span style="color: maroon">DestField1</span><span style="color: blue">></span>1<span style="color: blue"></</span><span style="color: maroon">DestField1</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue"> <</span><span style="color: maroon">DestField2</span><span style="color: blue">></span>2<span style="color: blue"></</span><span style="color: maroon">DestField2</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue"> </</span><span style="color: maroon">LoopRecord2</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue"> <</span><span style="color: maroon">LoopRecord2</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue"> <</span><span style="color: maroon">DestField1</span><span style="color: blue">></span>3<span style="color: blue"></</span><span style="color: maroon">DestField1</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue"> <</span><span style="color: maroon">DestField2</span><span style="color: blue">></span>4<span style="color: blue"></</span><span style="color: maroon">DestField2</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue"> </</span><span style="color: maroon">LoopRecord2</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue"> </</span><span style="color: maroon">Record</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue"> <</span><span style="color: maroon">Record</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue"> <</span><span style="color: maroon">LoopRecord2</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue"> <</span><span style="color: maroon">DestField1</span><span style="color: blue">></span>5<span style="color: blue"></</span><span style="color: maroon">DestField1</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue"> <</span><span style="color: maroon">DestField2</span><span style="color: blue">></span>6<span style="color: blue"></</span><span style="color: maroon">DestField2</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue"> </</span><span style="color: maroon">LoopRecord2</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue"> </</span><span style="color: maroon">Record</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue"> </</span><span style="color: maroon">LoopRecord1</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue"></</span><span style="color: maroon">ns0:Root</span><span style="color: blue">></span></p></div> <p>As you can see, the element 'Record' was created twice.</p> <p><strong>In this case you must use the looping functiod:</strong></p> <p><u><strong>BizTalk Mapper:</strong></u></p> <p><img src="http://lh4.ggpht.com/Pinhask/SDB7nPTjdpI/AAAAAAAAAWw/3ORKbE5hllA/Demo.Mapping.Foreach.map.sample2.map.7.jpg"> </p> <p><u><strong>XSL Code:</strong></u></p> <p><a href="http://lh5.ggpht.com/Pinhask/SDB7rfTjdsI/AAAAAAAAAXI/zCxHOYsmbGE/Demo.Mapping.Foreach.map.sample2.xsl.8.jpg"><img src="http://lh5.ggpht.com/Pinhask/SDB7rfTjdsI/AAAAAAAAAXI/zCxHOYsmbGE/Demo.Mapping.Foreach.map.sample2.xsl.8.jpg"></a> </p> <p><u><strong>Output XML (valid):</strong></u></p><!--<br />{\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset177\fprq1 Courier New;}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0??;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;??\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;??\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;??\red192\green192\blue192;}??\fs20 \cf2 <\cf13 ns0:Root\cf2 \cf6 xmlns:ns0\cf2 =\cf0 "\cf2 http://Pinhas_Kolsky.Demos.Mapping.Looping.Schema2\cf0 "\cf2 >\par ?? <\cf13 LoopRecord1\cf2 >\par ?? <\cf13 Record\cf2 >\par ?? <\cf13 LoopRecord2\cf2 >\par ?? <\cf13 DestField1\cf2 >\cf0 1\cf2 </\cf13 DestField1\cf2 >\par ?? <\cf13 DestField2\cf2 >\cf0 2\cf2 </\cf13 DestField2\cf2 >\par ?? </\cf13 LoopRecord2\cf2 >\par ?? <\cf13 LoopRecord2\cf2 >\par ?? <\cf13 DestField1\cf2 >\cf0 3\cf2 </\cf13 DestField1\cf2 >\par ?? <\cf13 DestField2\cf2 >\cf0 4\cf2 </\cf13 DestField2\cf2 >\par ?? </\cf13 LoopRecord2\cf2 >\par ?? </\cf13 Record\cf2 >\par ?? </\cf13 LoopRecord1\cf2 >\par ?? <\cf13 LoopRecord1\cf2 >\par ?? <\cf13 Record\cf2 >\par ?? <\cf13 LoopRecord2\cf2 >\par ?? <\cf13 DestField1\cf2 >\cf0 5\cf2 </\cf13 DestField1\cf2 >\par ?? <\cf13 DestField2\cf2 >\cf0 6\cf2 </\cf13 DestField2\cf2 >\par ?? </\cf13 LoopRecord2\cf2 >\par ?? </\cf13 Record\cf2 >\par ?? </\cf13 LoopRecord1\cf2 >\par ??</\cf13 ns0:Root\cf2 >}<br />--> <div style="font-size: 8pt; background: white; color: black; font-family: courier new"> <p style="margin: 0px"><span style="color: blue"><</span><span style="color: maroon">ns0:Root</span><span style="color: blue"> </span><span style="color: red">xmlns:ns0</span><span style="color: blue">=</span>"<span style="color: blue">http://Pinhas_Kolsky.Demos.Mapping.Looping.Schema2</span>"<span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue"> <</span><span style="color: maroon">LoopRecord1</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue"> <</span><span style="color: maroon">Record</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue"> <</span><span style="color: maroon">LoopRecord2</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue"> <</span><span style="color: maroon">DestField1</span><span style="color: blue">></span>1<span style="color: blue"></</span><span style="color: maroon">DestField1</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue"> <</span><span style="color: maroon">DestField2</span><span style="color: blue">></span>2<span style="color: blue"></</span><span style="color: maroon">DestField2</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue"> </</span><span style="color: maroon">LoopRecord2</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue"> <</span><span style="color: maroon">LoopRecord2</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue"> <</span><span style="color: maroon">DestField1</span><span style="color: blue">></span>3<span style="color: blue"></</span><span style="color: maroon">DestField1</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue"> <</span><span style="color: maroon">DestField2</span><span style="color: blue">></span>4<span style="color: blue"></</span><span style="color: maroon">DestField2</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue"> </</span><span style="color: maroon">LoopRecord2</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue"> </</span><span style="color: maroon">Record</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue"> </</span><span style="color: maroon">LoopRecord1</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue"> <</span><span style="color: maroon">LoopRecord1</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue"> <</span><span style="color: maroon">Record</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue"> <</span><span style="color: maroon">LoopRecord2</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue"> <</span><span style="color: maroon">DestField1</span><span style="color: blue">></span>5<span style="color: blue"></</span><span style="color: maroon">DestField1</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue"> <</span><span style="color: maroon">DestField2</span><span style="color: blue">></span>6<span style="color: blue"></</span><span style="color: maroon">DestField2</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue"> </</span><span style="color: maroon">LoopRecord2</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue"> </</span><span style="color: maroon">Record</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue"> </</span><span style="color: maroon">LoopRecord1</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue"></</span><span style="color: maroon">ns0:Root</span><span style="color: blue">></span></p></div> <p align="justify">It's impotent to notice that when the mapper is not automatically creates the XSL by drugging the elements, you can't use both - looping functiod for the parent and drugging unbounded to unbounded. this will generate only the first xsl:for-each. you can see this in the following:</p> <p><u><strong>BizTalk Mapper:</strong></u></p> <p><a href="http://lh3.ggpht.com/Pinhask/SDB7n_TjdqI/AAAAAAAAAW4/XqbG5CUKsJk/Demo.Mapping.Foreach.map.sample2.map.5.jpg"><img src="http://lh3.ggpht.com/Pinhask/SDB7n_TjdqI/AAAAAAAAAW4/XqbG5CUKsJk/Demo.Mapping.Foreach.map.sample2.map.5.jpg"></a> </p> <p><u><strong>XSL Code:</strong></u></p> <p><a href="http://lh5.ggpht.com/Pinhask/SDB7pfTjdrI/AAAAAAAAAXA/z3qLgvRVVEQ/Demo.Mapping.Foreach.map.sample2.xsl.6.jpg"><img src="http://lh5.ggpht.com/Pinhask/SDB7pfTjdrI/AAAAAAAAAXA/z3qLgvRVVEQ/Demo.Mapping.Foreach.map.sample2.xsl.6.jpg"></a> </p> <p><u><strong>Output XML (Not valid):</strong></u></p><!--<br />{\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset177\fprq1 Courier New;}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0??;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;??\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;??\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;??\red192\green192\blue192;}??\fs20 \cf2 <\cf13 ns0:Root\cf2 \cf6 xmlns:ns0\cf2 =\cf0 "\cf2 http://Pinhas_Kolsky.Demos.Mapping.Looping.Schema2\cf0 "\cf2 >\par ?? <\cf13 LoopRecord1\cf2 >\par ?? <\cf13 Record\cf2 >\par ?? <\cf13 LoopRecord2\cf2 >\par ?? <\cf13 DestField1\cf2 >\cf0 1\cf2 </\cf13 DestField1\cf2 >\par ?? <\cf13 DestField2\cf2 >\cf0 2\cf2 </\cf13 DestField2\cf2 >\par ?? </\cf13 LoopRecord2\cf2 >\par ?? </\cf13 Record\cf2 >\par ?? </\cf13 LoopRecord1\cf2 >\par ?? <\cf13 LoopRecord1\cf2 >\par ?? <\cf13 Record\cf2 >\par ?? <\cf13 LoopRecord2\cf2 >\par ?? <\cf13 DestField1\cf2 >\cf0 5\cf2 </\cf13 DestField1\cf2 >\par ?? <\cf13 DestField2\cf2 >\cf0 6\cf2 </\cf13 DestField2\cf2 >\par ?? </\cf13 LoopRecord2\cf2 >\par ?? </\cf13 Record\cf2 >\par ?? </\cf13 LoopRecord1\cf2 >\par ??</\cf13 ns0:Root\cf2 >}<br />--> <div style="font-size: 8pt; background: white; color: black; font-family: courier new"> <p style="margin: 0px"><span style="color: blue"><</span><span style="color: maroon">ns0:Root</span><span style="color: blue"> </span><span style="color: red">xmlns:ns0</span><span style="color: blue">=</span>"<span style="color: blue">http://Pinhas_Kolsky.Demos.Mapping.Looping.Schema2</span>"<span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue"> <</span><span style="color: maroon">LoopRecord1</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue"> <</span><span style="color: maroon">Record</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue"> <</span><span style="color: maroon">LoopRecord2</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue"> <</span><span style="color: maroon">DestField1</span><span style="color: blue">></span>1<span style="color: blue"></</span><span style="color: maroon">DestField1</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue"> <</span><span style="color: maroon">DestField2</span><span style="color: blue">></span>2<span style="color: blue"></</span><span style="color: maroon">DestField2</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue"> </</span><span style="color: maroon">LoopRecord2</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue"> </</span><span style="color: maroon">Record</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue"> </</span><span style="color: maroon">LoopRecord1</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue"> <</span><span style="color: maroon">LoopRecord1</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue"> <</span><span style="color: maroon">Record</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue"> <</span><span style="color: maroon">LoopRecord2</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue"> <</span><span style="color: maroon">DestField1</span><span style="color: blue">></span>5<span style="color: blue"></</span><span style="color: maroon">DestField1</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue"> <</span><span style="color: maroon">DestField2</span><span style="color: blue">></span>6<span style="color: blue"></</span><span style="color: maroon">DestField2</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue"> </</span><span style="color: maroon">LoopRecord2</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue"> </</span><span style="color: maroon">Record</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue"> </</span><span style="color: maroon">LoopRecord1</span><span style="color: blue">></span></p> <p style="margin: 0px"><span style="color: blue"></</span><span style="color: maroon">ns0:Root</span><span style="color: blue">></span></p></div> <p align="justify"><strong><u>Conclusions:</u></strong> <strong>generating xsl:for-each statement with BizTalk mapper:</strong></p> <ul> <li> <div align="justify">In a simple scenario you can generate xsl:for-each by drugging the source unbounded element to the destination unbounded element.</div></li> <li> <div align="justify">When you need to add more logic to the code (like creating maxOccurs="1" element inside the looping) you must use looping functoid.</div></li> <li> <div align="justify">In a case when a looping functoid is necessary, you must use one looping functoid for each unbounded element. </div></li></ul> Pinhas Kolskyhttp://www.blogger.com/profile/14144546566317745006noreply@blogger.comtag:blogger.com,1999:blog-758510306863061936.post-28052478625154385832008-05-01T23:51:00.001+03:002008-05-01T23:59:16.230+03:00BizTalk project namespace and schema-type namespace duplication issue<p>When adding web reference to a C# project in Visual Studio, VS generates a class named Reference.cs. this class is the C# code of the XSD types of the web service. BizTalk installation includes extensions to visual studio that additionally creates classes for BizTalk artifacts that will be used by the BizTalk messaging engine. <p>When you create XSD schema - VS will generate cs file with the schema as a CLR object. the naming convention for this file is <schemaName>.xsd.cs <p>When you add a Web reference to the project - VS will create three classes: <ol> <li>Reference.map.cs <li>Reference.odx.cs <li>Reference.xsd.cs</li></ol> <p>In a future post I'll write about those classes in great details. <p>The namespace and the CLR class name of the auto-generated classes is depends on some factors: <p><strong><u>For web reference:</u></strong> <ul> <li>The class namespace is the project default namespace (by default it's Visual Studio Project filename ) + dot sign (.) + the name of the web reference. <li>The class name is a factor of the WSDL artifact.</li></ul> <p><strong><u>For XSD schema:</u></strong> <ul> <li>The class namespace is the schema-type namespace <li>The class name is the schema-type name.</li></ul> <p><strong>This naming convention is auto-generated and you can't control or change it.</strong> <p>Another thing to know is that for the Compiler perspective, the default namespace for all artifacts in the project is default namespace (by default it's the VS project filename). <p><strong><u>All the above leads us to this:</u></strong> <p>What if the default namespace (the project filename) is equals to the XSD schema-type namespace?</p> <p><a title="Schema-type namespace equals to the project default namespace" href="http://lh3.ggpht.com/Pinhask/SBoLkBp8tNI/AAAAAAAAARM/A6WBaJX3oNs/3.jpg"><img src="http://lh3.ggpht.com/Pinhask/SBoLkBp8tNI/AAAAAAAAARM/A6WBaJX3oNs/3.jpg"></a> </p> <p><a title="Project default namespace" href="http://lh3.ggpht.com/Pinhask/SBootBp8tTI/AAAAAAAAAS8/S-QTo6_e-qY/5.jpg"><img src="http://lh3.ggpht.com/Pinhask/SBootBp8tTI/AAAAAAAAAS8/S-QTo6_e-qY/5.jpg"></a> </p> <p>In a regular situation it's all right but in case you adding web reference to the project, VS will generate the namespace for the Reference.odx.cs classes in the form of <ProjName>.<WebRefName> so if the name of the project file is Test.Schemas it will look like: Test.Schemas.<nameOfWebRef> <p>In the sample below Test.Schemas is a <strong><u>namespace</u></strong>. <p><a title="Web-Ref namespace is the combination of the project defualt namespace + 'dot' sign + Web-Ref name" href="http://lh4.ggpht.com/Pinhask/SBoQtRp8tRI/AAAAAAAAASU/QMxv3OOBnok/1.jpg"><img src="http://lh4.ggpht.com/Pinhask/SBoQtRp8tRI/AAAAAAAAASU/QMxv3OOBnok/1.jpg"></a> <p>When VS generates the XSD schema class it will generate it in the form of <schemaNS>.<schemaName> <p>in the sample below Test.Schemas is the <strong><u>class namespace</u> </strong>and Teat is the <strong><u>class name</u></strong>; explicit: Test.Schemas.Test <p><a title="The class namespace is the schema-type namespace and the class name is the schema-type name" href="http://lh4.ggpht.com/Pinhask/SBoLnRp8tPI/AAAAAAAAARc/_yVbW7OolfM/4.jpg"><img src="http://lh4.ggpht.com/Pinhask/SBoLnRp8tPI/AAAAAAAAARc/_yVbW7OolfM/4.jpg"></a> <p>When the compiler tries to compile the project it will translate the word 'Test' in namespace of the web reference file Reference.odx.cs as the class that represents the XSD schema-type, because the schema has the same namespace as the project default namespace – by default the VS project name. <p> <a title="Web-Ref namespace first word 'Test' is recognized by the compiler as the Schema class Test.Schemas.Test" href="http://lh5.ggpht.com/Pinhask/SBoQuhp8tSI/AAAAAAAAASc/75FItsSrxWg/2.jpg"><img src="http://lh5.ggpht.com/Pinhask/SBoQuhp8tSI/AAAAAAAAASc/75FItsSrxWg/2.jpg"></a> <p>This process will cause the following error: <p><strong>error CS0426: The type name '<Name>' does not exist in the type.</strong> <p>The error means that the XSD generated class 'Test' does not contains member with the name 'Schemas'. this is completely true because 'Test.Schemas' is only a <strong><u>namespace</u></strong> – copied from the project namespace. <p>To fix the error, all we have to do is to change the schema name or the schema namespace. additionally, we can change the project default-namespace and then import the web reference. <p>Be aware that to change the web reference namespace you need to remove them and adding them again. <p><strong>The insights of all of this:</strong> if your project default namespace is composed of two words separated by a dot (.) sign: <ul> <li>Unless you have a web reference in your BizTalk project – you can name the schema namespace just like the VS project file including 'dot' sign, you can also name the schema-type name as the first word in the Project filename. <li>If you need to include a web reference in the project change the schema-type namespace to be different from the project namespace. additionally; you can name the schema-type name different from the first word in the project namespace.</li></ul> Pinhas Kolskyhttp://www.blogger.com/profile/14144546566317745006noreply@blogger.comtag:blogger.com,1999:blog-758510306863061936.post-91912272413973114742008-04-28T23:15:00.001+03:002008-04-28T23:15:33.025+03:00BizTalk UTF-8 codepage<p>I guess it's only me but after working a lot with BizTalk and WMQ, it was so clear to me that UTF-8 codepage is 1208. so today when working with the SAP adapter against Hebrew records we set value of the BizTalk Code Page as 1208 . the correct value is actually 65001. </p> <p>I also find <a href="http://msdn2.microsoft.com/en-us/library/aa562108.aspx">this</a> about the SAP Adapter: <a href="http://msdn2.microsoft.com/en-us/library/aa562108.aspx">http://msdn2.microsoft.com/en-us/library/aa562108.aspx</a></p> <p>With Service Pack 1 installed, you must specify the appropriate encoding on any new and existing SAP receive port while receiving the IDoc. For example, if you need to receive Japanese characters, you may want to consider setting BizTalk Code Page as 65001, which is UTF-8 encoding. <p>Finally, look inside the UTF8Encoding class:</p> <p> <a title="UTF8_CODEPAGE" href="http://lh3.ggpht.com/Pinhask/SBYuGBp8tII/AAAAAAAAAPA/QXPfalza5NY/UTF8Encoding_Codepage.jpg"><img src="http://lh3.ggpht.com/Pinhask/SBYuGBp8tII/AAAAAAAAAPA/QXPfalza5NY/UTF8Encoding_Codepage.jpg"></a></p> <p>So for all of you out there: <ul> <li><strong>For IBM products (like WebSphere MQ) <strong>UTF-8 codepage is <strong>1208</strong></strong>.</strong> <li><strong>For widows based products UTF-8 codepage is 65001. </strong></li></ul> <p>thanks to Amir Cohen for that.</p> Pinhas Kolskyhttp://www.blogger.com/profile/14144546566317745006noreply@blogger.comtag:blogger.com,1999:blog-758510306863061936.post-58624158327213588852008-04-01T00:09:00.001+02:002008-04-01T00:09:29.955+02:00Dynamic Send Port - Host instance limitation<p>In a previous post, I wrote about the importance of choosing the right Host instances for a peacefully working 'real-world' BizTalk solution. Although this is right for all BizTalk artifacts, unfortunately there's one exception: Dynamic Send Ports.</p> <p align="justify">The analogy behind Dynamic ports is a wish to provide BizTalk the flexibility of 'SOA' - a way to create an atomic service that has no intension with the End-Point protocol/technology. the Dynamic ports are the way BizTalk server is combining it's Orchestration engine with the Adapter framework layer. in runtime - the orchestration will inform the adapter engine with the information about the destination Protocol and URI and the adapter engine will ship the message to that location using the right Adapter instance.</p> <p align="justify">This magic become possible thanks to the <strong>Microsoft.XLANG.BaseTypes.Address</strong> class who derived from <strong>PortPropertyBase</strong> class under Microsoft.XLANG.BaseTypes.dll.</p> <p align="justify">When passing those's parameters to the port, the Adapter engine is checking the value of Address to be associated with the adapter prefixes table. for example the following will cause the FILE adapter to handle the sending process:</p> <p align="justify"><a href="http://lh5.google.com/Pinhask/R_FVyeTyY4I/AAAAAAAAANE/gk6HqFStAPM/DynamicPortAddress.bmp"><img src="http://lh5.google.com/Pinhask/R_FVyeTyY4I/AAAAAAAAANE/gk6HqFStAPM/DynamicPortAddress.bmp"></a> </p> <p align="justify">The ability to "late-bind" the Adapter instance to associate with the Send process actually forces us to disallow any Host Instance configuration at design-time - the adapter can be In-Process Host like the FILE or WCF Adapter and equally can be Isolated Host like SOAP Adapter.</p> <p align="justify">The BizTalk team choose to handle the Host-Instance resolving is to use the<strong> default Host Instance</strong> configured for the Adapter. because of this most unacceptable design, use can find your process running under BizTalkApplicationHost and BizTalkApplicationIsolatedHost instances. so eventually, <strong><u>this means we can't use Dynamic Ports in most of our BizTalk Solutions!.</u></strong></p> <p align="justify">After all this, I've been surprised to find that in the newly published ESB Guidance (v1.0), the Agent who responsible of routing (Delivery agent) was implemented using a Dynamic Send Port.</p> <p align="justify">Just imagine what will happen if <strong><u>ALL of the specific Adapter of the entire ESB</u></strong> are running on the same Host Instance. So, I really can't understand this design, more then that - I encourage you <strong>NOT </strong>to use the default Delivery Agent in a real ESB environment.</p> <p align="justify">Let's just hope that the team will fix this behavior and there will be a way of choosing the correct Host Instance within Dynamic Send port - then we'll can enjoy the benefits of 'SOA' with BizTalk solutions. </p> Pinhas Kolskyhttp://www.blogger.com/profile/14144546566317745006noreply@blogger.comtag:blogger.com,1999:blog-758510306863061936.post-35727163931811553822008-03-31T22:39:00.001+02:002008-03-31T22:39:01.489+02:0070-235 Exam: Developing Business Process and Integration Solutions Using Microsoft BizTalk Server<a href="http://lh5.google.com/Pinhask/R_C5buTyY3I/AAAAAAAAAMM/4AeTZ7DPhKo/MCTS%28rgb%29_511.png"><img src="http://lh5.google.com/Pinhask/R_C5buTyY3I/AAAAAAAAAMM/4AeTZ7DPhKo/MCTS(rgb)_511.png"></a> <p align="justify">Just passed Microsoft MCTS 70-235 exam. I can tell you that the preparations you have to take for this exam are very different from other Microsoft exam because there's almost no references from Microsoft (except MSDN).</p> <p align="justify">It's seems that the team is checking the candidate knowledge about various of BTS-related technologies such as BAM and BRE, so in the single question in the exam with some code - you don't really need to know what you're coding, you need to identify the correct object to use (It's a question about invoking BRE policy).</p> <p align="justify">If you're going to take the exam I can assist you with those tips:</p> <ul> <li> <div align="justify">Spend time on the samples that ships with BizTalk and the Walk-through scenarios - spastically the BRE and BAM stuff. - Pay attention to the <strong><u>order of the actions</u></strong> you perform in those's sample.</div></li> <li> <div align="justify">Choose the right answer even if it's seems so clear (remember that no one is trying to fool you)</div></li> <li> <div align="justify">Read the <u><strong>documentation in the MSDN</strong></u> - this way you'll know that for example "BizTalk Editor" is the way Microsoft is calling the Schema Editor in Visual-Studio 2005 BizTalk 2006 extensions.</div></li> <li> <div align="justify">Prepare yourself with BizTalk references other then Microsoft (I read "Professional BizTalk Server 2006" from Wrox).</div></li></ul> Pinhas Kolskyhttp://www.blogger.com/profile/14144546566317745006noreply@blogger.comtag:blogger.com,1999:blog-758510306863061936.post-62988065755974489672008-03-24T23:39:00.001+02:002008-03-24T23:42:24.960+02:00BizTalk Host-Instances selection<p align="justify">Choosing the right Host-Instance for BizTalk artifact (like a send port) is one of the basics to a successful project. This is one of the points where development and test/prod environment are so different.</p> <p align="justify"><strong><u>Scenario 1:</u></strong></p> <p align="justify">All BizTalk Host-Instances queues have a table under MsgBobDb with the prefix:<HostName>Q. when the adapter is committing a message into BizTalk MsgBox it means that the message was committed into this queue. afterwards a process of de-queue will be fired. just imagine what will happened if you have two services one is batch process with thousands of messages, and the second is on-line. the first process will flow the queue and the second on-line process will suffer from badly performance (and not like Message queuing like WMQ and MSMQ there's no way to configure priority within BizTalk queuing).</p> <p align="justify"><strong><u>Scenario 2:</u></strong></p> <p align="justify">If I have two BizTalk Servers with one MsgBox (this usually increase performance), I need to run a Receive Location or Send Port on one of those Servers - the only way is to create separated Host Instances - one on each server and then to configure the port to be hosted within the correct Host Instance.</p> <p align="justify"><strong><u>Scenario 3:</u></strong></p> <p align="justify">We need to collect files from a directory, then we need to send the content of the files to a web-service. The web-service processing is taking a long time - mach more then collecting the files from a file-system directory. the results of this is that while BizTalk is busy to commit the incoming messages into the MsgBox the Send process is waiting. also, if the incoming messages are very big - the processing is likely to use a lot of the BTSNTSvc process free memory and the sending process will wait to this memory to be freed before processing.</p> <p align="justify"><strong><u>Scenario 4:</u></strong></p> <p align="justify">The Send Port must run under specific user to grand access permissions.</p> Pinhas Kolskyhttp://www.blogger.com/profile/14144546566317745006noreply@blogger.comtag:blogger.com,1999:blog-758510306863061936.post-86273842020317815992008-03-10T18:55:00.004+02:002008-03-11T19:30:05.983+02:00Microsoft.BizTalk.ParsingEngine.FFReader ReadToFollowing Issue<p><span style="font-size:100%;">Have you ever worked with Microsoft.BizTalk.ParsingEngine.FFReader object to parse Flat-File contant in Pipeline component? be aware not to use ReadToFollowing() method within this object.</span></p><p><span style="font-size:100%;">I've wrote a custom PPLC to parse and modify Flat File. Hers the Code snippet:</span> </p><div style="BACKGROUND: white;font-family:Courier New;font-size:8pt;color:black;" ><p style="MARGIN: 0px"> <span style="color:green;">//Get the messge stream</span><br /></p><p style="MARGIN: 0px"> <span style="color:teal;">Stream</span> inStream = inMsg.BodyPart.GetOriginalDataStream();</p><br /><p style="MARGIN: 0px"> <span style="color:green;">//Get FFDocumentSpec and parse content from FF to XML with FF Anotation</span><br /></p><p style="MARGIN: 0px"> <span style="color:teal;">IFFDocumentSpec</span> docSpec = (<span style="color:teal;">IFFDocumentSpec</span>)context.GetDocumentSpecByName(<span style="color:maroon;">"MyPoject.Schemas.MySchema_FF"</span>);</p><br /><p style="MARGIN: 0px"> <span style="color:green;">//Prepare Stream reader</span><br /></p><p style="MARGIN: 0px"> <span style="color:teal;">StreamReader</span> streamReader = <span style="color:blue;">new</span> <span style="color:teal;">StreamReader</span>(inStream);</p><br /><p style="MARGIN: 0px"> Microsoft.BizTalk.ParsingEngine.<span style="color:teal;">DataReader</span> dataReader = <span style="color:blue;">new</span> Microsoft.BizTalk.ParsingEngine.<span style="color:teal;">DataReader</span>(streamReader);</p><br /><p style="MARGIN: 0px"> <span style="color:green;">//start parsing the message</span><br /></p><p style="MARGIN: 0px"> reader = (Microsoft.BizTalk.ParsingEngine.<span style="color:teal;">FFReader</span>)docSpec.Parse(dataReader);</p><br /><p style="MARGIN: 0px"> <span style="color:green;">//start reading the message</span><br /></p><p style="MARGIN: 0px"> reader.ReadToFollowing(<span style="color:maroon;">"nodeName"</span>, "<span style="color:maroon;"><a href="http://node.namespace/">http://node.Namespace</a>"</span>);</p></div><p><span style="font-size:100%;">The FFReader class is derived from System.Xml.XmlReader I read the content of the stream</span> with the System.Xml.XmlReader.ReadToFollowing(String) method. and was very surprised to run into some NullReferenceException runtime exception. The Exception was thrown at ReadToFollowing() method.</p><p>After checking all the member initialization, I decided to search a little deeper inside the framework.</p><p>I find out that FFReader doesn't implements it's own ReadToFollowing() method so, the method is executing as in the base XmlReader Class.</p><p>The FFReader doesn't initializing the 'TableName' object and this member is remaining Null.</p><p><img style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://lh4.google.com/Pinhask/R9ay7WBYV2I/AAAAAAAAALs/Yngt4WBYv-o/FFReader_Issue_QuickWatch.bmp" border="0" /></p><p></p><p>Unfortunatlly, the base XmlReader uses this object in the ReadToFollowing() method so it was cousing NullReferenceException.</p><p><img style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://lh5.google.com/Pinhask/R9axTmBYV0I/AAAAAAAAALY/wzMFNyPCafk/FFReader_Issue_TableName.bmp" border="0" /></p><p><strong><u>Conclusion:</u></strong> manually create your own ReadToFollowing() method and don't use the one under FFReader.</p><div style="BACKGROUND: white;font-family:Courier New;font-size:8pt;color:black;" ><p style="MARGIN: 0px"> <span style="color:blue;">public</span> <span style="color:blue;">bool</span> ReadToFollowing(<span style="color:blue;">string</span> localName, <span style="color:blue;">string</span> namespaceURI, <span style="color:teal;">FFReader</span> reader)<br /></p><p style="MARGIN: 0px"> {<br /></p><p style="MARGIN: 0px"> <span style="color:blue;">while</span> (reader.Read())<br /></p><p style="MARGIN: 0px"> {<br /></p><p style="MARGIN: 0px"> <span style="color:blue;">if</span> (reader.Name.Equals(localName) && reader.NamespaceURI.Equals(namespaceURI))<br /></p><p style="MARGIN: 0px"> <span style="color:blue;">return</span> <span style="color:blue;">true</span>;<br /></p><p style="MARGIN: 0px"> }<br /></p><p style="MARGIN: 0px"> <span style="color:blue;">return</span> <span style="color:blue;">false</span>;<br /></p><p style="MARGIN: 0px"> }</p><br /></div>Pinhas Kolskyhttp://www.blogger.com/profile/14144546566317745006noreply@blogger.comtag:blogger.com,1999:blog-758510306863061936.post-56003355020355456292008-02-18T11:24:00.004+02:002008-02-18T11:29:31.442+02:00Arrays in BizTalk Orchestration - Part I<p>I really don’t know why but I often hear from BizTalk developers that XLANG/s does not support arrays. The truth is that arrays in BizTalk orchestration are not an issue at all. XLANG/s does fully support arrays. More than that, XLANG/s fully supports indexing within arrays.</p><p>Here's some links:</p><p><strong>"BizTalk Server can consume one dimensional and jagged arrays exposed by Web services that are not BizTalk Web services"</strong> (Support for consuming arrays exposed by Web services) <a href="http://msdn2.microsoft.com/en-us/library/aa561724.aspx">http://msdn2.microsoft.com/en-us/library/aa561724.aspx</a></p><p><strong>"XLANG/s supports single-dimensional arrays, but does not support array literals"</strong> <a href="http://technet.microsoft.com/en-us/library/aa560334.aspx">http://technet.microsoft.com/en-us/library/aa560334.aspx</a></p><p><strong>How to Consume Web Service Arrays</strong>: <a href="http://msdn2.microsoft.com/en-us/library/aa559325.aspx">http://msdn2.microsoft.com/en-us/library/aa559325.aspx</a></p><p>I suppose the reason to this mistaken is because of the following downfalls:</p><ol><li>You can’t declare typed array (like string[]) variable in the Orchestration editor.</li><li>You can’t initialize typed array using 'new' keyword (arr = new string[4] is not valid)</li><li>XLANG/s considers Array as primitive and not as an object. This means you can’t use useful methods and properties like Length (arr.Length is not recognized)</li></ol><p>On the other hand, BizTalk 2006 was designed with Xml web services in mind – this means that every serializable object is accessible from inside BizTalk orchestration. If you need to consume a web service that returns array, BizTalk will serialize the web message part into the appropriate CLR object and not just into general System.Array object.</p>Pinhas Kolskyhttp://www.blogger.com/profile/14144546566317745006noreply@blogger.comtag:blogger.com,1999:blog-758510306863061936.post-60803416639063301422008-02-17T19:06:00.003+02:002008-02-17T19:49:04.711+02:00A Great new integration blogAlex Linder is one of the integration consultants in our company and a very good friend.<br />He is one of the fewest people I know with a lot knowledge and experience of many integration technologies.<br />In the past last years he is examining products like Microsoft BizTalk Server, WebSphere Message-Broker and WebSphere MQ to the very edge.<br /><br />Now he sharing his investigations and tips in his great new blog: <a href="http://linderalex.blogspot.com/">http://linderalex.blogspot.com/</a><br /><br /><strong>It's a great place for all you integration experts so stay tunes – I'm sure I would!<br /></strong><br />Congratulations Alex.Pinhas Kolskyhttp://www.blogger.com/profile/14144546566317745006noreply@blogger.comtag:blogger.com,1999:blog-758510306863061936.post-41119588296044216752008-02-03T18:37:00.000+02:002008-02-03T20:34:28.037+02:00Publishing BizTalk Orchestration as WCF serviceSome issue I encountered when publishing BizTalk Orchestration as WCF service.<br /><br />After the wizard finished, I tried to browse to the svc file and got the following error:<br /><br /><strong>Type 'System.ServiceModel.Activation.HttpHandler' cannot be instantiated under a partially trusted security policy (AllowPartiallyTrustedCallersAttribute is not present on the target assembly).<br /></strong><br />It seems that WCF can't initiate itself with less then full trust policy. To solve this edit the service web.config under <system.web> section with the following entry:<br /><br /><trust level="Full"><br /><br />By this you'll grand the service full trust security policy.<br /><br />Another error is: <strong>Receive location for address ".svc" not found. (The BizTalk receive location may be disabled.)</strong><br /></u><br />This one means that the target Receive Location in BizTalk administration is not existing (you didn't check the option in the wizard) or it's not enabled.Pinhas Kolskyhttp://www.blogger.com/profile/14144546566317745006noreply@blogger.comtag:blogger.com,1999:blog-758510306863061936.post-66810066076691710832008-01-21T22:25:00.001+02:002008-01-29T18:42:02.740+02:00BizTalk Context Property Class Generator - BTSPscGen.exe<p>When working with BizTalk Pipeline components, it’s a common requirement to work with context property values.</p><p>The context property key is actually XML element defined in the Property Schema, and is a combination of the name and namespace of the XML element. </p><p>To read a context property value, you use the Read method on the context object of IBaseMessage:</p><div style="BACKGROUND: white;font-family:courier new;font-size:8pt;color:black;" ><p style="MARGIN: 0px"><span style="color:blue;">object</span> Read(<span style="color:blue;">string</span> strName, <span style="color:blue;">string</span> strNamespace);</p></div><br /><p>Now, because its so easy to make mistakes with the name and namespace (just like all other string value in your code) its very advisable to save those values as constants. Something like that:</p><div style="BACKGROUND: white;font-family:courier new;font-size:10pt;color:black;" ><div style="BACKGROUND: white;font-family:courier new;font-size:10pt;color:black;" ><div style="BACKGROUND: white;font-family:courier new;font-size:10pt;color:black;" ><div style="BACKGROUND: white;font-family:courier new;font-size:8pt;color:black;" ><p style="MARGIN: 0px"><span style="color:blue;">const</span> <span style="color:blue;">string</span> EPMRRCORRELATIONTOKEN_NAME = <span style="color:maroon;">"EpmRRCorrelationToken"</span>;</p><p style="MARGIN: 0px"><span style="color:blue;">const</span> <span style="color:blue;">string</span> EPMRRCORRELATIONTOKEN_NAMESPACE = <span style="color:maroon;">"http://schemas.microsoft.com/BizTalk/2003/system-properties"</span>;</p><br /><p style="MARGIN: 0px"></p><p style="MARGIN: 0px"><span style="color:blue;">public</span> <span style="color:teal;">IBaseMessage</span> Execute(<span style="color:teal;">IPipelineContext</span> context, <span style="color:teal;">IBaseMessage</span> inMsg)</p><p style="MARGIN: 0px">{</p><p style="MARGIN: 0px"><span style="color:blue;">object</span> epmObj = inMsg.Context.Read(EPMRRCORRELATIONTOKEN_NAME, EPMRRCORRELATIONTOKEN_NAMESPACE)</p><br /><p style="MARGIN: 0px"><span style="color:blue;">if</span> (epm != <span style="color:blue;">null</span>)</p><p style="MARGIN: 0px">{</p><p style="MARGIN: 0px"><span style="color:green;">//Do Something here </span></p><p style="MARGIN: 0px">}<br /></p><p style="MARGIN: 0px"><span style="color:blue;">return</span> outMsg;</p><p style="MARGIN: 0px">}</p></div><br /><p style="MARGIN: 0px">More elegant way is to use the classes in Microsoft.BizTalk.GlobalPropertySchemas.dll</p></div><br /><p style="MARGIN: 0px"><span style="color:blue;">public</span> <span style="color:teal;">IBaseMessage</span> Execute(<span style="color:teal;">IPipelineContext</span> context, <span style="color:teal;">IBaseMessage</span> inMsg)</p></div></div><div style="FONT-SIZE: 8pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: courier new"><p style="MARGIN: 0px">{</p><p style="MARGIN: 0px">BTS.EpmRRCorrelationToken epm = <span style="color:blue;">new</span> BTS.EpmRRCorrelationToken();<br /></p><p style="MARGIN: 0px"><span style="color:blue;">object</span> epmObj = inMsg.Context.Read(epm.Name.Name, epm.Name.Namespace);<br /></p><p style="MARGIN: 0px"><span style="color:blue;">if</span> (epm != <span style="color:blue;">null</span>)</p><p style="MARGIN: 0px">{</p><p style="MARGIN: 0px"><span style="color:green;">//Do Something here </span></p><p style="MARGIN: 0px">}</p><p style="MARGIN: 0px">}</p></div><br /><p>You can see the benefits of the second approach with Reflector:</p><p><a title="Property schema element class" href="http://lh4.google.com/Pinhask/R5T1ok1xBAI/AAAAAAAAAI0/MstPzZUQ1NE/empRrCorrelationToken.jpg"><img height="239" alt="Property schema element class" src="http://lh4.google.com/Pinhask/R5T1ok1xBAI/AAAAAAAAAI0/MstPzZUQ1NE/empRrCorrelationToken.jpg?imgmax=640" width="640" /></a> </p><br /><ul><li>The class has Type property that is the CLR object type of the context property value.<br /><li>System.Xml.XmlQualifiedName object (that have some useful method itself) include the name and namespace values.</li></ul><p>To me it's seemes that the above is the most appropriate way, so, if you want to create your own GlobalPropertySchemas.dll follow thoes steps:</p><ol><li>Create a new BizTalk project</li><li>Create a folder with the appropriate Name (ex. ESB)</li><li>Add a new property schema (ex. ESBProperties)</li><li>Add the context-properties (ex. ServiceName).</li><li>complie</li></ol><p>the results are generated classes for each context-property (ex. ESB.ServiceName)</p><p>For educational proposes, I once wrote a utility that takes a user defined BizTalk schema property and generates this class for every element so you could see what happens behind scene. also, you can extend this tool and create more "smart" classes for your own GlobalPropertySchemas.dll</p><p>So, go ahead and start using your own GlobalPropertySchemas.dll in the very same way that BizTalk artifacts are using property schema elements from inside code.</p><p>BTSPscGen.exe source-code can be download form: <a href="http://pinhask.googlepages.com/BTSProperySchemaClassGen_Source.rar">http://pinhask.googlepages.com/BTSProperySchemaClassGen_Source.rar</a></p><p>Enjoy!. </p>Pinhas Kolskyhttp://www.blogger.com/profile/14144546566317745006noreply@blogger.comtag:blogger.com,1999:blog-758510306863061936.post-65907365731650869532008-01-20T19:46:00.000+02:002008-01-21T10:23:32.387+02:00BizTalk Host instance and Windows NT Services limit issue<span style="font-size:100%;">When developing SOA/ESB solutions, you should NOT use the same Host instance for more then one service. the reason is because all messages will be writen into the same table (queue), so if one service is consumed intensively, the other services will experience latency.<br /><br />To avoid this, it's a known best-practice with BizTalk solutions, to create at least 3 Hosts instances per service:</span><br /><ul><li><span style="font-size:100%;">Orchestrations Host</span></li><li><span style="font-size:100%;">Receive Ports Handler</span></li><li><span style="font-size:100%;">Send Handler</span></li></ul><p><span style="font-size:100%;">An important and little known issue is the limit number of host instances that can be defined on a single machine.</span></p><p><span style="font-size:100%;">Every host instance in BizTalk is implemented as a Window NT Service with the prefix 'BizTalk Service BizTalk Group : <servicename>'HostName'<hostname>. </span></p><p><span style="font-size:100%;">Now, services can run under one of two Accounts:</span></p><ul><li><span style="font-size:100%;">User Account</span></li><li><span style="font-size:100%;">LocalSystem</span></li></ul><p><span style="font-size:100%;">Windows can host unlimited number of services running under LocalSystem, but By Default, has a limit number of services running under User Account (from my experience with Windows 2003 Server it's between 23 to 25, based on the service memory usage).<br /><br />If you reach this limit, the host instance won't start and you'll get the following error massage:<br /><br /><strong>1053 The <servicename>service failed to start due to the following error: The service did not respond to the start or control request in a timely fashion.<br /></strong><br />The only solution is to decrease the memory for each desktop on the computer.</span></p><p><span style="font-size:100%;"><strong>In the following I'll show you how to set this key in the system registery: </strong><br /><u><br /></u></span><span style="font-size:100%;">Run regedit.exe and browse to:<br /><br />HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\SubSystems\Windows<br /><br />Find the key 'SharedSection=1024,3072,<strong>512</strong>'<br /><br />The third value (512) is the desktop heap for each desktop that is associated with a "noninteractive" window station. this value can be decreased down to 128.<br /><br />More information can be found on </span><a href="http://support.microsoft.com/kb/184802/en-us"><span style="font-size:100%;">http://support.microsoft.com/kb/184802/en-us</span></a><span style="font-size:100%;"> (cause 2).<br /><br /></span><span style="font-size:100%;"><strong><u>Very important:<br /></u></strong><br />Please <strong>DON’T</strong> do this on production environment before a <strong>VERY CARFUL</strong> test – this key can <strong>affected and harm the system very badly</strong>. So please <strong>check if it suitable for your system before running and applying it</strong>.</span></p>Pinhas Kolskyhttp://www.blogger.com/profile/14144546566317745006noreply@blogger.comtag:blogger.com,1999:blog-758510306863061936.post-5052166627128533832008-01-12T20:55:00.001+02:002008-01-13T22:39:56.076+02:00The ESB Guidance – hello ‘SOA’ world<p><strong>Introduction to BizTalk solutions architectures</strong>. <p>Almost all IT professionals are familiar with the benefits Service Oriented Architecture (‘SOA’) approach is offering, therefore the term ‘ESB’ is not a buzz word any more. <p>As a BizTalk developer the architecture you often use is known as ‘Hub-And-Spoke’. This means we’re using BizTalk as a middleware application (known as a ‘Broker’) between of all other applications. When app A needs to interact with app B, it will submit the request to the broker application. The broker then will make the preparations needed to redirect the request to app B (one example is transformation) and then route the message into app B and vice versa. <p>Enterprise Service Bus ('ESB') extend of the traditional EAI and MOM broker with some capabilities like: <ul><li>Web Service standards <li>Integration with rang of protocols and technologies. <li>metadata registry</li></ul><p>As a rule of thumb, ESB is the gate into the ‘SOA’ world. <p>It means you don’t develop ‘<strong>Application</strong>’ anymore; from now on it is about ‘<strong>Services</strong>’. <p></p>If you’re new with ‘SOA’ you can learn about it <a href="http://www.microsoft.com/biztalk/solutions/soa/overview.mspx">here.</a><br />Also, you can find an overview of BizTalk Server based 'ESB' <a href="http://www.microsoft.com/biztalk/solutions/soa/esb.mspx">here.</a><br /><p>Now, because of BizTalk ‘Hub-And-Spoke’ nature, developing ESB solution based on BizTalk Server require massive development of infrastructures, The ESB guidance is Microsoft way of achieving it in the fastest way by integrating and relaying on common Microsoft technologies.</p>Pinhas Kolskyhttp://www.blogger.com/profile/14144546566317745006noreply@blogger.comtag:blogger.com,1999:blog-758510306863061936.post-40911691597584914682008-01-06T23:05:00.000+02:002008-01-06T23:06:40.765+02:00Microsoft ESB Guidance is here<p>Microsoft finally released the toolkit for developing ESB solutions based on BizTalk Server.<br />if you're a BizTalk developer and 'ESB' is your second name [the first one is probably 'SOA' :-) ] this set of powerful tools was designed exactly for you. It can make your life match more happier and save you a lot of coding time.</p><p>you can find the ESB Guidance on the MSDN <a href="http://msdn2.microsoft.com/en-us/library/bb931189.aspx">Here</a></p><p>In the next few posts I'll give you a deep dive into this new exciting tools and framework.</p>Pinhas Kolskyhttp://www.blogger.com/profile/14144546566317745006noreply@blogger.com