A random collection of epiphanies, thoughts and problem solutions pertaining to .NET and BizTalk.

Sunday, November 13, 2005

StartCache: Error 0x80070002: failed to get download: 90A40409-6000-11D3-8CFE-0150048383C9

Ran into a HUGE installation problem when I attempted to install SQL Server 2005 RTM on my personal computer. I had SQL Server 2005 Beta CTP installed before. I kept getting the OWC11 installation failure message. I ended up manually install the OWC11 component with logging turned on... The log file tells me it's the infamous : 1603 problem.


Action ended 21:33:45: ProcessComponents. Return value 1.
Action 21:33:45: StartCache. Starting cache of cabinets to local installation source
Action start 21:33:45: StartCache.
StartCache: Error 0x80070002: failed to get download: 90A40409-6000-11D3-8CFE-0150048383C9
Action ended 21:33:45: StartCache. Return value 3.
Action ended 21:33:45: INSTALL. Return value 3.
Action ended 21:33:45: ExecuteAction. Return value 3.
Action 21:33:45: TheFatalError.
Action start 21:33:45: TheFatalError.


I ended up cleanning two registry keys which finally made it work:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\11.0\Delivery\90A40409-6000-11D3-8CFE-0150048383C9
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\Delivery\SourceEngine\Downloads\90A40409-6000-11D3-8CFE-0150048383C9

Hopefully it will help if you run into the same problem.

Monday, March 07, 2005

A Microsoft Distributed Transaction Coordinator problem prevented connection to the Configuration database again

When you work with a Microsoft BizTalk Server 2004 project on a Microsoft Windows Server 2003-based computer, and you deploy the assemblies to BizTalk Server 2004, you may receive the following error message from Microsoft Visual Studio .NET:


[DeploymentException] Cannot open database BizTalkMgmtDb on server [server].
[DeploymentException] Cannot open database BizTalkMgmtDb on server [server].
A Microsoft Distributed Transaction Coordinator problem prevented connection to the Configuration database.
The transaction has already been implicitly or explicitly committed or aborted


You will also receive a similar error if you run the BizTalk Deployment Wizard. KB839187 provided a solution which is pertinent but not sufficient in some scenarios. Recently, I had a new development set up that took me back to this problem and it cost me approximately 2.5 hours of productivity to figure out exactly why.




I have a mutile server BizTalk setup. BizTalk Databases and the default BizTalk host are on a dedicated Windows 2003 server box. I do my development work on laptop with Windows XP (SP2). When I try to deploy a BizTalk assembly, I ran into the problem described above. I immediately tried the workaround suggested by KB839187 which didn't work. After some research, I belive the following steps are a better overall approach to this problem.




  1. Make sure your development machine and BizTalk server (server runs BizTalk databases) can ping each other

  2. Make sure MS DTC service is up and running on both computers

  3. Modify the following registry key on both computers: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSDTC\TurnOffRpcSecurity = 1

  4. Enable the "Network Clients" for MS DTC for both computers. To do this:

    • Click through: Start | Settings | Control Panel | Administrative Tools | Component Services

    • Expand "Computers" under "Component Services" node

    • Right click on "My Computer" and click on "MSDTC" tab on "My Computer Properties" dialog

    • Click on "Security Configuration" button

    • For Windows Server 2003, check "Network Clients" checkbox as indicated in the following picture.


      For Windows XP (SP2), configure the "Security Settings" as indicated by the following picture.



  5. Restart the MS DTC services on both computers if they have not been automatically restarted.

Friday, February 18, 2005

Themize Windows Application

I am thinking about writing an article about how to themize the windows forms by using a cascading style sheet. I have a subset of functionality implemented. Here's a form that applied a nice theme called "VRust".

Thursday, February 17, 2005

How to use updategram to update multiple rows in BizTalk orchestration


Using the updategram to insert and delete are very straightforward. It's also easy to update one row of data using the updategram in BizTalk. BizTalk SQL adapter seems to be problematic when dealing with updating multiple rows of data using updategram. SQL XML states that you need to use the attribute "updg:id" to associate the records enclosed in the <updg:before> and those enclosed in <updg:after>(article here). I am pretty sure if you are reading this blog, you have tried the default schema generated by BizTalk and realized it didn't work. I have tried the following two approaches and they didn't work:


  1. Use multiple <sync> nodes to describe the updategram. It didn't work.

    <?xml version="1.0" encoding="utf-8" ?>
    <ns0:updateStatsPendingRequest xmlns:ns0="http://www.bankofamerica.com/">
    <ns0:sync>
    <ns0:before>
    <ns0:StatsPending APPLICATIONID="100010.032970" />
    </ns0:before>
    <ns0:after>
    <ns0:StatsPending APPLICATIONID="100010.032970"
    SITEID="24" ASSIGNPROCESSED="true" />
    </ns0:after>
    </ns0:sync>
    <ns0:sync>
    <ns0:before>
    <ns0:StatsPending APPLICATIONID="100010.032971" />
    </ns0:before>
    <ns0:after>
    <ns0:StatsPending APPLICATIONID="100010.032971"
    SITEID="25" ASSIGNPROCESSED="true" />
    </ns0:after>
    </ns0:sync>
    </ns0:updateStatsPendingRequest>

    Conclusion: SQL Adapter has difficulty handling multiple <sync> elements.

  2. Use the <id> attributed as suggested by SQL XML. I added the extra id attribute into the schema like this:

    <xs:attribute name="id" type="xs:string" updategram:Prefix="updg" />

    This solution fails since the generated xml document instance doesn't have the correct xml schema prefix. As described by SQL XML, the prefix for the "id", "sync", "before" and "after" should really be "updg". However, the xml instance generated by BizTalk will look like:

    <?xml version="1.0" encoding="utf-8" ?>
    <ns0:updateStatsPendingReq xmlns:ns0="http://www.bankofamerica.com/">
    <ns0:sync>
    <ns0:before>
    <ns0:StatsPending ns0:id="100010.040649" />
    <ns0:StatsPending ns0:id="100010.042313" />
    </ns0:before>
    <ns0:after>
    <ns0:StatsPending ns0:id="100010.040649"
    ns0:APPLICATIONID="100010.040649"
    ns0:SITEID="24"
    ns0:ASSIGNPROCESSED="1" />
    <ns0:StatsPending ns0:id="100010.042313"
    ns0:APPLICATIONID="100010.042313"
    ns0:SITEID="24"
    ns0:ASSIGNPROCESSED="1" />
    </ns0:after>
    </ns0:sync>
    </ns0:updateStatsPendingReq>


As you can see from the above xml instance, all of the elements and attributes are qualified with "ns0" prefix which is not what we wanted. After some research, I figured out that SQL XML need to use the "updg" prefix in order to correctly associate the records in <before> and <after> blocks. Therefore, we need to make the BizTalk to generate the document instance looks like this:

<?xml version="1.0" encoding="utf-8" ?>
<ns0:updateStatsPendingReq
xmlns:updg="urn:schemas-microsoft-com:xml-updategram"
xmlns:ns0="http://www.bankofamerica.com/">
<ns0:sync>
<ns0:before>
<ns0:StatsPending updg:id="100010.040649" />
<ns0:StatsPending updg:id="100010.042313" />
</ns0:before>
<ns0:after>
<ns0:StatsPending updg:id="100010.040649"
ns0:APPLICATIONID="100010.040649"
ns0:SITEID="24"
ns0:ASSIGNPROCESSED="1" />
<ns0:StatsPending updg:id="100010.042313"
ns0:APPLICATIONID="100010.042313"
ns0:SITEID="24"
ns0:ASSIGNPROCESSED="1" />
</ns0:after>
</ns0:sync>
</ns0:updateStatsPendingReq>

After I tweak the schemas to generate the xml instance like above, it worked!!
If you run the SQL profiler, you will see the following TSQL statements are generated:

SET XACT_ABORT ON
BEGIN TRAN
DECLARE @eip INT, @r__ int, @e__ int
SET @eip = 0

UPDATE StatsPending SET SITEID=N'24', ASSIGNPROCESSED=N'1'
WHERE (APPLICATIONID=N'100010.042313');
SELECT @e__ = @@ERROR, @r__ = @@ROWCOUNT
IF (@e__ != 0 OR @r__ != 1) SET @eip = 1
IF (@r__ > 1) RAISERROR ( N'Ambiguous update, unique identifier required', 16, 1)
ELSE IF (@r__ < 1) RAISERROR ( N'Empty update, no updatable rows found', 16, 1)

UPDATE StatsPending SET SITEID=N'24', ASSIGNPROCESSED=N'1'
WHERE (APPLICATIONID=N'100010.040649');
SELECT @e__ = @@ERROR, @r__ = @@ROWCOUNT
IF (@e__ != 0 OR @r__ != 1) SET @eip = 1
IF (@r__ > 1) RAISERROR ( N'Ambiguous update, unique identifier required', 16, 1)
ELSE IF (@r__ < 1) RAISERROR ( N'Empty update, no updatable rows found', 16, 1)

IF (@eip != 0) ROLLBACK ELSE COMMIT
SET XACT_ABORT OFF

The following are list of things you need to do in order to ask BizTalk to generate the "updg" prefix.




  1. Define Updategram.xsd like this:


  2. In your updategram schema's <xs:schema> element, add this line:

    xmlns:updg="urn:schemas-microsoft-com:xml-updategram"


  3. Add an <xs:import> element in your updategram schema:

    <xs:import
    schemaLocation="Updategram.xsd"
    namespace="urn:schemas-microsoft-com:xml-updategram" />


  4. Add <updg:id> attribute in <before> and <after> elements by using the following line:

    <xs:attribute ref="updg:id" />

    Your schema will look like this:


    <?xml version="1.0"?>
    <xs:schema
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns="http://www.bankofamerica.com/commercialprocesstechnology/sbui"
    xmlns:updg="urn:schemas-microsoft-com:xml-updategram"
    targetNamespace="http://www.bankofamerica.com/commercialprocesstechnology/sbui"
    attributeFormDefault="unqualified"
    elementFormDefault="qualified"
    >
    <xs:import
    schemaLocation="Updategram.xsd"
    namespace="urn:schemas-microsoft-com:xml-updategram" />
    <xs:element name="updateStatsPendingReq">
    <xs:complexType>
    <xs:sequence>
    <xs:element
    xmlns:updategram="urn:schemas-microsoft-com:xml-updategram"
    updategram:Prefix="updg" minOccurs="1" maxOccurs="unbounded" name="sync">
    <xs:complexType>
    <xs:sequence>
    <xs:element updategram:Prefix="updg" minOccurs="0" maxOccurs="unbounded" name="before">
    <xs:complexType>
    <xs:sequence>
    <xs:element minOccurs="0" maxOccurs="unbounded" name="StatsPending">
    <xs:complexType>
    <xs:attribute ref="updg:id" />
    <xs:attribute name="APPLICATIONID" type="xs:decimal" />
    </xs:complexType>
    </xs:element>
    </xs:sequence>
    </xs:complexType>
    </xs:element>
    <xs:element updategram:Prefix="updg" minOccurs="0" maxOccurs="unbounded" name="after">
    <xs:complexType>
    <xs:sequence>
    <xs:element minOccurs="0" maxOccurs="unbounded" name="StatsPending">
    <xs:complexType>
    <xs:attribute ref="updg:id" />
    <xs:attribute name="APPLICATIONID" type="xs:decimal" />
    <xs:attribute name="SITEID" type="xs:string" />
    <xs:attribute name="ASSIGNPROCESSED" type="xs:boolean" />
    </xs:complexType>
    </xs:element>
    </xs:sequence>
    </xs:complexType>
    </xs:element>
    </xs:sequence>
    </xs:complexType>
    </xs:element>
    </xs:sequence>
    </xs:complexType>
    </xs:element>
    <xs:element name="updateStatsPendingRep">
    <xs:complexType>
    <xs:sequence>
    <xs:element name="Success" />
    </xs:sequence>
    </xs:complexType>
    </xs:element>
    </xs:schema>


  5. In the message transformation shape when you construct the updategram, use a map similar to this:



Then just fire off the orchestration and watch the updategram does its work. The particular orchestration I ran was able to update approximately 1800 records in a few seconds without any problem. Email me if you need a sample project.

Wednesday, January 19, 2005

Inline XSLT Call Template


Google's Biztalk group posted this interesting problem about how to use the Inline XSLT Call Template and cumulative functoid in the map. I am quoting Jeremy's question here:



"In the following sample, I have a multiple invoice file that has 1 header record and a repeating detail record for each invoice. Can someone help me using inline xslt to sum the detail records of each invoice so that I can get the total for each invoice. I have seen how to do this just using xslt instead of the mapper, but I would like to do this within the mapper as I have other functoids that I am using. It appears I cannot get the cumulative sum functoid to sum each invoice with the scope parameter; instead it always seems to sum the entire file or nothing at all."


inbound:
<Invoices xmlns="http://www.google.com">
<Invoice>
<Header>
<Credit>-20</Credit>
</Header>
<Detail>
<Debit>10</Debit>
</Detail>
<Detail>
<Debit>9</Debit>
</Detail>
<Detail>
<Debit>1</Debit>
</Detail>
</Invoice>
<Invoice>
<Header>
<Credit>-10</Credit>
</Header>
<Detail>
<Debit>7</Debit>
</Detail>
<Detail>
<Debit>3</Debit>
</Detail>
</Invoice>
</Invoices>

outbound:
<ns0:Invoices xmlns:ns0="http://www.google.com">
<ns0:TotalFileCredit>-30</ns0:TotalFileCredit>
<ns0:TotalFileDebit>30</ns0:TotalFileDebit>
<ns0:Invoice>
<ns0:TotalInvoiceCredit>-20</ns0:TotalInvoiceCredit>
<ns0:TotalInvoiceDebit>20</ns0:TotalInvoiceDebit>
<ns0:Header>
<ns0:Credit>-20</ns0:Credit>
</ns0:Header>
<ns0:Detail>
<ns0:Debit>10</ns0:Debit>
</ns0:Detail>
<ns0:Detail>
<ns0:Debit>9</ns0:Debit>
</ns0:Detail>
<ns0:Detail>
<ns0:Debit>1</ns0:Debit>
</ns0:Detail>
</ns0:Invoice>
<ns0:Invoice>
<ns0:TotalInvoiceCredit>-10</ns0:TotalInvoiceCredit>
<ns0:TotalInvoiceDebit>10</ns0:TotalInvoiceDebit>
<ns0:Header>
<ns0:Credit>-10</ns0:Credit>
</ns0:Header>
<ns0:Detail>
<ns0:Debit>7</ns0:Debit>
</ns0:Detail>
<ns0:Detail>
<ns0:Debit>3</ns0:Debit>
</ns0:Detail>
</ns0:Invoice>
</ns0:Invoices>



Obviously the inbound and outbound xml document instances could share a same schema. Here's the schema code:


<xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns="http://www.google.com"
targetNamespace="http://www.google.com"
elementFormDefault="qualified"
attributeFormDefault="unqualified"
>
<xs:complexType name="Detail">
<xs:sequence>
<xs:element name="Debit" type="xs:int" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="Header">
<xs:sequence>
<xs:element name="Credit" type="xs:int" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="Invoice">
<xs:sequence>
<xs:element minOccurs="0" name="TotalInvoiceCredit" type="xs:int" />
<xs:element minOccurs="0" name="TotalInvoiceDebit" type="xs:int" />
<xs:element name="Header" type="Header" />
<xs:element maxOccurs="unbounded" name="Detail" type="Detail" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="Invoices">
<xs:sequence>
<xs:element minOccurs="0" name="TotalFileCredit" type="xs:int" />
<xs:element minOccurs="0" name="TotalFileDebit" type="xs:int" />
<xs:element maxOccurs="unbounded" name="Invoice" type="Invoice" />
</xs:sequence>
</xs:complexType>
<xs:element name="Invoices" type="Invoices" />
</xs:schema>


Here's the map I have used:



In the scripting functoid, I used the XSLT Call Template below:


<xsl:template name="MyXsltConcatTemplate">
<xsl:param name="param1" />
<xsl:element name="ns0:TotalInvoiceDebit"
namespace="http://www.google.com">
<xsl:value-of
select="sum(*[local-name()='Detail']/*[local-name()='Debit'])" />
</xsl:element>
</xsl:template>

We couldn't use the inline xslt here since we need to pass in a local node "Invoice" that occurs multiple times in the inbound document. You can't pass in any parameter using the inline xslt script. The inline xslt call template, however, allows you to pass in a local node and you can apply your xslt transformation within the scope of passed parameter. In this case it is "param1" and it refers to one of the "Invoice" element of the xml document.


Followers