If you're into Biztalk mapping, you need to check Sandro Pereira's book,
"BizTalk Mapping Patterns & Best Practices".
In 350 pages (367, but you can skip the first 15), you can learn in detail several tricks of 12 mapping patterns that will help you to be more productive (only if you want, of course).
To download the book, you have to give a valid email.
Showing posts with label Biztalk. Show all posts
Showing posts with label Biztalk. Show all posts
Thursday, September 25, 2014
Friday, May 17, 2013
Replace a schema in a map: the easy way
We had a little problem on the first day in production of an EDI project, when our partner says they have to send their orders in EFACT_D96A_ORDERS_EAN008, instead of the EFACT_D93A_ORDERS_EAN007 we tested for months.
Not a big stress. Those schemas are similar, so the change was easy.
To redo a map like this one and properly test it in the same day, was impossible. But the task was simplified in the fastest way. No XSLT knowledge needed, just basic XML and logic.
Supposing the change is in the input
1. Add the new schema or reference to the project.
2. Open the btm as xml.
3. Find and replace all references
3.1. Source Tree Root Node and Location
<SrcTree RootNode_Name="EFACT_D93A_ORDERS_EAN007">
3.2. Some on the Link elements (LinkFrom attribute).
<Link LinkID="9" LinkFrom="10" LinkTo="/*[local-name()='<Schema>']/*[local-name()='ORDERS01']/*[local-name()='E1EDK03']/*[local-name()='DATAHEADERREC']/*[local-name()='DOCNUM']" Label="" />
4. Close the xml view and open the same .btm with the regular view.
4.1. If no Map Loading Errors popped up, it’s done.
4.2. Otherwise, keep following the procedure.
5. Copy all the errors (no Ctrl+A here, just the old mouse dragging).
(1) Link from Source Tree Node with XPath: '/*[local-name()='']/*[local-name()='EFACT_D96A_ORDERS_EAN008']/*[local-name()='LINLoop1']/*[local-name()='QTY_3']/*[local-name()='C186_3']/*[local-name()='C18601']'
to Equal functoid (with FunctoidID: 30).
...
6. Close the errors screen but DO NOT save the map.
7. Locate the missing field and take note of the correct path
In this case there was no EFACT_D96A_ORDERS_EAN008/LINLoop1/QTY_3/C186_3/C18601 , but instead, EFACT_D96A_ORDERS_EAN008/LINLoop1/QTY_2/C186_2/C18601
8. Close the map (don’t save!) and open again with the xml view.
9. Replace those fields. [local -name()='QTY_3']/*[local-name()='C186_3'] to [local-name()='QTY_2']/*[local-name()='C186_2']. In case of doubt, use the FunctoidId or any additional info from the errors screen to locate the Link Id.
10. Repeat from step 4 until all the errors are gone.
Changes in Destination schema are in TrgTree instead of SrcTree, and LinkTo instead of LinkFrom.
Please note that this is only an advanced starting point. If the schema was replaced, probably it was because the previous one no longer supported the information needed. It’s very likely new fields are filled and some others have changed, including the ones used within the map. A new batch of tests will show it very quickly.
If they arrive by Direct Binding –independently of the port, from the MessageBox - use the Filter Expression.
Be careful with:
Typename
Don’t give the same name to both. Not only it is unauthorized, but also is the name by which the orchestrations will be known after deployment and so should be different for whoever is managing.
Ports types
The Orchestration 2 will try to create a port type that already exists. Delete the Operation on every port and configure to use the type from Orchestration 1. If the input message is different (source schema changed) the receive port will have a different type. The same goes for the output message (when the target schema changed) at the send port.
To redo a map like this one and properly test it in the same day, was impossible. But the task was simplified in the fastest way. No XSLT knowledge needed, just basic XML and logic.
Supposing the change is in the input
1. Add the new schema or reference to the project.
2. Open the btm as xml.
3. Find and replace all references
3.1. Source Tree Root Node and Location
<SrcTree RootNode_Name="EFACT_D93A_ORDERS_EAN007">
<Reference Location="*.EFACT_D93A_ORDERS_EAN007" />
</SrcTree> 3.2. Some on the Link elements (LinkFrom attribute).
<Link LinkID="9" LinkFrom="10" LinkTo="/*[local-name()='<Schema>']/*[local-name()='ORDERS01']/*[local-name()='E1EDK03']/*[local-name()='DATAHEADERREC']/*[local-name()='DOCNUM']" Label="" />
<Link LinkID="10" LinkFrom="/*[local-name()='<Schema>']/*[local-name()='EFACT_D93A_ORDERS_EAN007']/*[local-name()='DTM']/*[local-name()='C507']/*[local-name()='C50702']"
LinkTo="9"
Label=""
/>
<Link LinkID="11" LinkFrom="/*[local-name()='<Schema>']/*[local-name()='EFACT_D93A_ORDERS_EAN007']/*[local-name()='DTM']"
LinkTo="11"
Label=""
/>4. Close the xml view and open the same .btm with the regular view.
4.1. If no Map Loading Errors popped up, it’s done.
4.2. Otherwise, keep following the procedure.
5. Copy all the errors (no Ctrl+A here, just the old mouse dragging).
(1) Link from Source Tree Node with XPath: '/*[local-name()='
...
6. Close the errors screen but DO NOT save the map.
7. Locate the missing field and take note of the correct path
In this case there was no EFACT_D96A_ORDERS_EAN008/LINLoop1/QTY_3/C186_3/C18601 , but instead, EFACT_D96A_ORDERS_EAN008/LINLoop1/QTY_2/C186_2/C18601
8. Close the map (don’t save!) and open again with the xml view.
9. Replace those fields. [local -name()='QTY_3']/*[local-name()='C186_3'] to [local-name()='QTY_2']/*[local-name()='C186_2']. In case of doubt, use the FunctoidId or any additional info from the errors screen to locate the Link Id.
10. Repeat from step 4 until all the errors are gone.
Changes in Destination schema are in TrgTree instead of SrcTree, and LinkTo instead of LinkFrom.
Please note that this is only an advanced starting point. If the schema was replaced, probably it was because the previous one no longer supported the information needed. It’s very likely new fields are filled and some others have changed, including the ones used within the map. A new batch of tests will show it very quickly.
Extra: Two orchestrations sharing a receive port
If they enter by the same port, use the Message property to receive only one of them.If they arrive by Direct Binding –independently of the port, from the MessageBox - use the Filter Expression.
Be careful with:
Don’t give the same name to both. Not only it is unauthorized, but also is the name by which the orchestrations will be known after deployment and so should be different for whoever is managing.
The Orchestration 2 will try to create a port type that already exists. Delete the Operation on every port and configure to use the type from Orchestration 1. If the input message is different (source schema changed) the receive port will have a different type. The same goes for the output message (when the target schema changed) at the send port.
Labels:
Biztalk,
Building Stage,
XSLT
Tuesday, March 27, 2012
Copy name and value with XSLT
I run across a situation where I had to map a huge list of sibling nodes. I was required to send tuples of name (in upper case) and value.
If they were few, I would use a Table Looping like always, but this time it was a lot of fields and I was feeling lazy. Here is the solution.
<xsl:variable name="smallcase" select="'abcdefghijklmnopqrstuvwxyz'" />
<xsl:for-each select="//Data/item/*">
<xsl:variable name="smallcase" select="'abcdefghijklmnopqrstuvwxyz'" />
<xsl:variable name="uppercase" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'" />
<xsl:for-each select="//Data/item/*">
<xsl:element name="ns0:GenericDataContainerEntry">
<xsl:element name="ns0:GenericDataContainerEntryIndex">
<xsl:attribute name="value">
<xsl:value-of select="./text()" />
xsl:attribute>
<xsl:attribute name="name">
<xsl:value-of select="translate(name(.),$smallcase,$uppercase)" />
xsl:attribute>
xsl:element>
xsl:element>
xsl:for-each>
xsl:for-each>
xsl:element>
Do to all nodes
<xsl:for-each select="//Data/item/*">
Copy value
<xsl:value-of select="./text()" />Copy name
<xsl:value-of select="name(.)" />Copy name in upper case in XSLT 1.0 (found it here)
<xsl:variable name="smallcase" select="'abcdefghijklmnopqrstuvwxyz'" />
<xsl:variable name="uppercase" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'" />
<xsl:value-of select="translate(name(.),$smallcase,$uppercase)" />
Labels:
Biztalk,
Building Stage,
XSLT
Thursday, March 24, 2011
Basics - How to confirm a Biztalk update
Here are the version numbers of current Biztalk 2006 R2 as seen at Microsoft.
For other Biztalk versions you can explore another Microsoft Link.
We made an update on Biztalk to CU3 and the version seen at About was still 3.6.2149.10, referring to the SP1.

To know the specific add-ons like CU's, and hotfixes, the only place to go is Add and Remove Programs. Just remember to mark the Show Updates. checkbox.

BizTalk Server 2006 R2 | 3.6.1404.0 | |
BizTalk Server 2006 R2 SP1 | 3.6.2149.10 | January 27th, 2010 |
Cumulative Update 1 (CU1) | 3.6.2210.12 | April 12th, 2010 |
Cumulative Update 2 (CU2) | 3.6.2217.12 | June 24th, 2010 |
Cumulative Update 3 (CU3) | 3.6.2224.12 | August 30th, 2010 |
For other Biztalk versions you can explore another Microsoft Link.
We made an update on Biztalk to CU3 and the version seen at About was still 3.6.2149.10, referring to the SP1.
To know the specific add-ons like CU's, and hotfixes, the only place to go is Add and Remove Programs. Just remember to mark the Show Updates. checkbox.
Thursday, March 17, 2011
Using SAP Dates in Biztalk
Half the maps I've been doing have SAP in one side or the other. One of the biggest problems are in map transformation.
Making all those substring concatenations is ugly. Creating a functoid is the best thing to do, but in case it is needed just in a map or two, how can it be made?
dateVariable.ToString("yyyyMMdd", System.Globalization.CultureInfo.InvariantCulture);
DateTime.ParseExact(val1, "yyyyMMdd", System.Globalization.CultureInfo.InvariantCulture);
(the CultureInfo attribute is optional but recommended in both methods)
This problem appeared when I had to calculate a difference between two SAP dates. It end up by being just this:
public int DaysToPay(string val1, string val2) {
DateTime startTime = DateTime.ParseExact(val1,"yyyyMMdd", System.Globalization.CultureInfo.InvariantCulture);
DateTime endTime = DateTime.ParseExact(val2,"yyyyMMdd", System.Globalization.CultureInfo.InvariantCulture);
TimeSpan span = endTime.Subtract ( startTime );
return span.Days-1;
}
Making all those substring concatenations is ugly. Creating a functoid is the best thing to do, but in case it is needed just in a map or two, how can it be made?
Convert .NET Date to SAP using C#
dateVariable.ToString("yyyyMMdd", System.Globalization.CultureInfo.InvariantCulture);
Convert SAP Date to .NET using C#
DateTime.ParseExact(val1, "yyyyMMdd", System.Globalization.CultureInfo.InvariantCulture);
(the CultureInfo attribute is optional but recommended in both methods)
This problem appeared when I had to calculate a difference between two SAP dates. It end up by being just this:
public int DaysToPay(string val1, string val2) {
DateTime startTime = DateTime.ParseExact(val1,"yyyyMMdd", System.Globalization.CultureInfo.InvariantCulture);
DateTime endTime = DateTime.ParseExact(val2,"yyyyMMdd", System.Globalization.CultureInfo.InvariantCulture);
TimeSpan span = endTime.Subtract ( startTime );
return span.Days-1;
}
Labels:
Biztalk,
Building Stage
Friday, January 21, 2011
Untyped Messages and WCF Services in a real scenario
Context:
This project was my first big Biztalk experience. It started more than two years ago (is still in Biztalk 2006 R2) and most of the work was made based on pre-conceived ideas of what was good, what was easy, what was trustable.
The project kept on growing and at a certain point the desire to trash it all and restart was too strong. This is an example of how to slowly modify a monster-like orchestration. The images and names aren’t always the same because they are not from a case-study, they were all taken from a real project. It consisted of several orchestrations and this post was made when each one of them was in a different stage of transformation so that all situations are represented.
In this project we had to deal with a bunch of different XML files, different types, different schedules, and, worst of all, different actions on the destination server.
We could make this by using maps on the send port, but the tracking of the messages was critical so we needed to keep track of the message on every step of the journey. So, an orchestration was the choice.
To reunite everything, the receive port that collects them (from FTP, SAP idocs, etc.) is the entry of the orchestration. The Message schema in the orchestration is System.Xml.XmlDocument so all schemas are accepted with no distinction.
A Decide component help us creating the basic structure for it, with a lot of conditions of type
OriginalMessage(BTS.MessageType) == http://Company/Schemas/BusinessPartnerActivityTypes#ActivityTypes
and a two-way destination port prepared for send/receive schemas of type System.Xml.XmlDocument, we could make it by repeating a lot of components.
For each flow we make
1. Transform Xml (Received message) to original schema
FCBusinessPartnerActivityTypes = OriginalMessage;
2. Map original schema to service schema
3. Transform ServiceSchema to Xml (port schema)
XmlMessage = SMUVASActivityType;
4. Send to Service
5. Receive Response
6. And after some flows made the general picture would be something like
How to make it in a lighter way?
The first step is to remove the transformation.
1. Declare a string variable for the map, called mapName
1.1. Use an expression editor to select the map based on the message type
1.2. Use the Fully Qualified Name of the map
mapName="";
if(OriginalMessage(BTS.MessageType) == "http://Company/Schemas/OrderTypes#OrderTypes"){ mapName="Company.Biztalk.SmuasCommercialModule.Messaging.map_FCOrderTypes_to_SMUVASOrderTypes";
}
if(OriginalMessage(BTS.MessageType) == "http://Company/Schemas/OrderStatus#OrderStatus"){
mapName="Company.Biztalk.SmuasCommercialModule.Messaging.map_FCOrderStatus_to_SMUVASOrderStatus";
}
…
2. Then in a message assignment use the transform method.
mapSystemType = System.Type.GetType(mapName);
transform(XmlMessage) = mapSystemType(OriginalMessage);
3. The orchestration will be much simpler.
The next optimization is to remove the multiple actions.
At the if that defines the map, you can also define the action. Something like
if(OriginalMessage(BTS.MessageType) == "http://Company/Schemas/Banks#Banks"){
mapName="Company.Biztalk.SmuasFinancialModule.Messaging.map_FCBanks_to_SMUVASBanks"; action="http://SmuAs/Services/BackendServices/CommonBackendSyncService/ICommonBackendSyncService/SetBankList";
}
And when the request message is created, give it the correspondent action.
mapSystemType = System.Type.GetType(mapName);
transform(RequestMessage) = mapSystemType(OriginalMessage);
RequestMessage(WCF.Action)= action;
The look of the orchestration is much lighter and pleasant to work with.
Labels:
Biztalk,
Building Stage,
Links,
Orchestration,
Performance,
Ports
Using Business Rules Engine (I)
Making business rules without messages
The most common way of using business rules is by evaluating a XML message with XPath and return an XML message with more info. The problem is that most of the examples are orchestration dependents: by demanding a compiled DLL with the schemas to be used, they limit the possibilities.
In a project with many orchestrations an easy solution is to make a solution with the schemas, compile, define the rules based on that DLL, and then apply them in the remaining solutions. If it is a small project where schema and orchestration could be on the same DLL, a first compilation is needed for BRE to access the schema. Only then the orchestration can add the rule.
But, what if the message is not important in any direction? What if you just want to use the same rule in all orchestrations without referring each and every DLL?
Scenario: ten distinct schemas. One flow in and one flow out for each. The same tracking rules apply on each direction, depending only on the schema. Here I found a great way of corrupting the principles of the rules.
I recommend this blog because it was the first were I could find any comprehensible info about BRE.
Basic: Policies have versions, on each version one or more rules. By activating different versions different rules can be in use. A rule is divided in condition and actions. A straight-forward "If-Then".
Usually each orchestration has its own rule and each rule is for an orchestration, a direct match.
The trick is to make a single rule, the if always true, and the orchestration will receive information that can be used or not.
The advantage of business rules engine is the low processing time and the changeable ease (copy version, edit, publish and deploy). There are no big processing advantages in using rules this way, but the changing method is still easy and no deployments required.
Making the if always true
Like always, just use the condition 1==1 or something that obvious.
On the actions list, we’ll use an ArrayList to return a list of words.
Go to facts explorer window
Select .NET classes
Right-click and browse .NET Assemblies
Select the mscorlib library
Press OK
The library will become available.
Find ArrayList and the Add() method, and drag it to actions pane as many time as you’ll need.
Fill in with the key strings and publish the version.
Add to the orchestration variables list one of type ArrayList.
Go to Orchestration View and right click Variables folder for New Variable
At new variable define name (in this example rulesArray) and type (<.NET Class…>, mscorlib, ArrayList)
Create another variable, of type Boolean called generateAck.
Add Call Rules component and use that variable as destination for the output.
And then at a Expression editor, search for the value and do as you please. In this example, only for the flows listed we’ll generate Ack. The fixed value is the message type that the orchestration mandatorily knows.
For instance we are searching for Purchase Orders, abbreviated PO. Since the rulesArray includes that value, ANY orchestration that has Purchase Orders will set generateAcks as true and therefore record Acks, if the proper code is made.
Labels:
Biztalk,
BRE,
FAQ,
Links,
Orchestration
Thursday, January 14, 2010
Pipelines in Biztalk
Creating pipelines in ports: knowing when to use PassThru Pipelines, XML Pipelines, and when to use Custom Pipelines.
A PassThru pipeline is straightforward. On a ReceiveLocation it receives a file without further treatment, validation or field promotion. The clear text message can be captured by a Send Port with filter by Receive Port.
A XML Pipeline is more complex. It analyses the received file and determines its structure. Properties are promoted and therefore more kinds of filters become available (specially the useful namespace).
In a XML pipeline there are no limitations. The schemas can by converted, envelopes can be splitted, all options are available under the properties section. To avoid time-consuming configurations in that area – and reduce error-proneness – a Custom Pipeline should be made. It stores the configuration inside the DLL and thus can be reused in another port, or even exported to another environment without dues.
The same logic applies to SendPipelines. Usually a PassThruTransmit is enough because the message is already known in Biztalk. If a format change is needed (to Flat File i.e.) an XMLTransmit with the adequate assembler is the only option. And to place that configuration at development level, a Custom Pipeline.
Hint: For the Flat File Assembler there is no need to select a schema. According to this MSDN page If no schema is specified, run-time schema discovery is done. It was tested and confirmed. It makes development a lot easier:
by reducing the number of pipelines. There's no need for multiple assembler pipelines. Instead of one pipeline for each schema, a single pipeline can be used by the entire application.
by making them faster to upgrade. When refering schemas from external DLL's, the assembly version is required. In the past if that DLL was changed (it happens in our dev environment on a weekly basis) we had to manually correct each map and pipeline. Now the pipelines are not a problem.
A PassThru pipeline is straightforward. On a ReceiveLocation it receives a file without further treatment, validation or field promotion. The clear text message can be captured by a Send Port with filter by Receive Port.
A XML Pipeline is more complex. It analyses the received file and determines its structure. Properties are promoted and therefore more kinds of filters become available (specially the useful namespace).
In a XML pipeline there are no limitations. The schemas can by converted, envelopes can be splitted, all options are available under the properties section. To avoid time-consuming configurations in that area – and reduce error-proneness – a Custom Pipeline should be made. It stores the configuration inside the DLL and thus can be reused in another port, or even exported to another environment without dues.
The same logic applies to SendPipelines. Usually a PassThruTransmit is enough because the message is already known in Biztalk. If a format change is needed (to Flat File i.e.) an XMLTransmit with the adequate assembler is the only option. And to place that configuration at development level, a Custom Pipeline.
Hint: For the Flat File Assembler there is no need to select a schema. According to this MSDN page If no schema is specified, run-time schema discovery is done. It was tested and confirmed. It makes development a lot easier:
by reducing the number of pipelines. There's no need for multiple assembler pipelines. Instead of one pipeline for each schema, a single pipeline can be used by the entire application.
by making them faster to upgrade. When refering schemas from external DLL's, the assembly version is required. In the past if that DLL was changed (it happens in our dev environment on a weekly basis) we had to manually correct each map and pipeline. Now the pipelines are not a problem.
Labels:
Biztalk,
Building Stage,
Deployment
Tuesday, October 13, 2009
Mapping several elements to a single element
Frequently we have one block of XML that we want to split to diferent blocks. For instance, when exporting to SQL stored procedures. It is easy to do. Sometimes the opposite happens and the tables are imported from SQL: we have the information divided by several blocks on one XML and we want it grouped.
Let's imagine a simple scenario: one table included the name of a person, the other the professional information. How can we group it to a single element?

We use XSLT.
Supposing that one of the segments has all the keys, the trick is to loop that segment to read the keys and pull the information from all. This way the order of the elements is not important, the association is made by key.
This template compiles the information:
This is it. It includes attributes and elements to include a broad range of situations. More complex cases can be made from this.
Let's imagine a simple scenario: one table included the name of a person, the other the professional information. How can we group it to a single element?

We use XSLT.
Supposing that one of the segments has all the keys, the trick is to loop that segment to read the keys and pull the information from all. This way the order of the elements is not important, the association is made by key.
This template compiles the information:
<xsl:template name="NameValueTemplate">
<xsl:param name="param1" />
<xsl:for-each select="//ElementKey">
<xsl:if test="Id/text()=$param1">
<xsl:attribute name="Id">xsl:value-of select="Id/text()" /></xsl:attribute>
<xsl:element name="Name"><xsl:value-of select="Name/text()" /></xsl:element>
</xsl:if>
</xsl:for-each>
<xsl:for-each select="//ElementInfo">
<xsl:if test="$Id=$param1">
<xsl:element name="Mail"><xsl:value-of select="Mail/text()" /></xsl:element>
<xsl:element name="Job"><xsl:value-of select="Job/text()" /></xsl:element>
<xsl:element name="Phone"><xsl:value-of select="Phone/text()"/></xsl:element>
</xsl:if>
</xsl:for-each>
</xsl:template>
And this is how it is called:
<xsl:template match="/s0:Root">
<ns0:Root>
<xsl:for-each select="//ElementKey">
<xsl:element name="Element">
<xsl:call-template name="NameValueTemplate">
<xsl:with-param name="param1"><xsl:value-of select="Id/text()"/></xsl:with-param>
</xsl:call-template>
</xsl:element>
</xsl:for-each>
</ns0:Root>
</xsl:template>
This is it. It includes attributes and elements to include a broad range of situations. More complex cases can be made from this.
Labels:
Biztalk,
Building Stage
Friday, September 18, 2009
WCF service publishing wizard settings
Did you ever had to republish a web service over and over again? Is it fun to go through the wizard and add the methods one by one?
We were having that problem. The idea was to make a connection between SAP and Sharepoint through web services created by Biztalk. An RFC in SAP receives the request and returns the values to Sharepoint that will use them to create a page. To comunication was quick and stable, but I was losing my mind and time creating the services one by one. Let's see the process step by step with focus on Biztalk:
1. the new RFC is created in SAP (not my problem)
2. Biztalk imports reference with the SAP Adapter (easy)
3. build and deploy dll (too easy)
4. recreate service through Biztalk WCF Publishing Wizard
4.1 select Transport Type
4.2 enable Metadata endpoint
4.3 select Biztalk application
4.4 select "publish schemas"
4.5 rename Web Service
4.6 rename Web Method
4.7 define schema type for request and for response, enlarging both the columns to read the schema type
4.8 repeat 4.6 and 4.7 for every single RFC, old or new...
4.9 define namespace
4.10 define the same service location with overwrite
4.11 allowing anonymous access
4.12 press Create
5 update reference on client
6 do some new methods
7 test
The best way to reduce time on Biztalk is never to press the Finish button. Going back the settings are all there and you can deploy it again.
But there is a better way... I googled for this situation. On this blessed link I found the answers for all my problems. Well, at least for this one.
So, the deployment stores the configuration inside wwwroot. And more! It is understandable and can be edited!
I simply made a batch file to call the wizard with the parameter
and now my work is just with steps 4.3, 4.4, 4.6, 4.7, 4.9, 4.12. The annoying configuration of all old methods, and more than half the checkbox clicks are made for me.
Question: Shouldn't the wizard allow the loading of a xml file?
We were having that problem. The idea was to make a connection between SAP and Sharepoint through web services created by Biztalk. An RFC in SAP receives the request and returns the values to Sharepoint that will use them to create a page. To comunication was quick and stable, but I was losing my mind and time creating the services one by one. Let's see the process step by step with focus on Biztalk:
1. the new RFC is created in SAP (not my problem)
2. Biztalk imports reference with the SAP Adapter (easy)
3. build and deploy dll (too easy)
4. recreate service through Biztalk WCF Publishing Wizard
4.1 select Transport Type
4.2 enable Metadata endpoint
4.3 select Biztalk application
4.4 select "publish schemas"
4.5 rename Web Service
4.6 rename Web Method
4.7 define schema type for request and for response, enlarging both the columns to read the schema type
4.8 repeat 4.6 and 4.7 for every single RFC, old or new...
4.9 define namespace
4.10 define the same service location with overwrite
4.11 allowing anonymous access
4.12 press Create
5 update reference on client
6 do some new methods
7 test
The best way to reduce time on Biztalk is never to press the Finish button. Going back the settings are all there and you can deploy it again.
But there is a better way... I googled for this situation. On this blessed link I found the answers for all my problems. Well, at least for this one.
So, the deployment stores the configuration inside wwwroot. And more! It is understandable and can be edited!
I simply made a batch file to call the wizard with the parameter
cd C:\Program Files\Microsoft BizTalk Server 2006\
BtsWcfServicePublishingWizard -WcfServiceDescription=C:\Inetpub\wwwroot\BizTalkWcfService\App_Data\Temp\WcfServiceDescription.xml
and now my work is just with steps 4.3, 4.4, 4.6, 4.7, 4.9, 4.12. The annoying configuration of all old methods, and more than half the checkbox clicks are made for me.
Question: Shouldn't the wizard allow the loading of a xml file?
Labels:
Biztalk,
Deployment,
FAQ,
Links,
Services
Registering adapters while publishing services
The Messaging Engine failed to register the adapter for "WCF-BasicHttp" for the receive location "*/*.svc". Please verify that the receive location exists, and that the isolated adapter runs under an account that has access to the BizTalk databases.
This time the problem is not on BizTalk but on IIS. The Application Pool for this website must be running not under a predefined service, but on an account with permissions over Biztalk.
Solution:
Create a new Application Pool for Biztalk, and on the Identity Tab select Configurable and insert the login. Associate the Web Site to this new app and refresh the svc page.
Labels:
Biztalk,
Deployment,
IIS,
Services
Thursday, March 19, 2009
"Registering multiple adapter types within the same process is not a supported scenario" error
From MSDN:
Setting Up HTTP and SOAP Receive
If it is required to run both HTTP and SOAP receive functions on the same Web server, additional configuration is required to avoid the following error:
"The Messaging Engine failed to register an adapter "SOAP". Details: "Registering multiple adapter types within the same process is not a supported scenario. For e.g. HTTP and SOAP receive adapters cannot co-exist in the same process"
To avoid this error, create two separate application pools (one for HTTP adapter and one for SOAP adapter).
Note
Both application pools may use the same BizTalk Server 2004 Isolated Host User identity.
Note
The actual host configuration used should be dictated by security and isolation requirements of the production environment.
Setting Up HTTP and SOAP Receive
If it is required to run both HTTP and SOAP receive functions on the same Web server, additional configuration is required to avoid the following error:
"The Messaging Engine failed to register an adapter "SOAP". Details: "Registering multiple adapter types within the same process is not a supported scenario. For e.g. HTTP and SOAP receive adapters cannot co-exist in the same process"
To avoid this error, create two separate application pools (one for HTTP adapter and one for SOAP adapter).
Note
Both application pools may use the same BizTalk Server 2004 Isolated Host User identity.
Note
The actual host configuration used should be dictated by security and isolation requirements of the production environment.
Labels:
Biztalk
Friday, February 6, 2009
Business Rules deployment: «Database associated with deployment driver does not match the database ":" specified during product configuration»
If you ever see this dreaded error message, don't fear!
First, follow each and every step suggested here: SOLVED: The BizTalk Rules Engine Deployment Riddle.
If it still doesn't work, then find the following tables in your BizTalkMgmtDb: adm_Group, adm_OtherDatabases and adm_OtherBackupDatabases.
In the first, fill the columns RuleEngineDbServerName and RuleEngineDbName.
In the other two, add a new line with the DefaultDatabaseName = RuleEngine DB, and the other columns with your installation-specific information.
Et voilá!
First, follow each and every step suggested here: SOLVED: The BizTalk Rules Engine Deployment Riddle.
If it still doesn't work, then find the following tables in your BizTalkMgmtDb: adm_Group, adm_OtherDatabases and adm_OtherBackupDatabases.
In the first, fill the columns RuleEngineDbServerName and RuleEngineDbName.
In the other two, add a new line with the DefaultDatabaseName = RuleEngine DB, and the other columns with your installation-specific information.
Et voilá!
Labels:
Biztalk,
Business Rules
Monday, December 22, 2008
Thursday, December 18, 2008
Biztalk Performance tunning blog on MSDN
There is a useful blog about Biztalk performance tunning on MSDN:
Biztalk Performance
Biztalk Performance
Labels:
Biztalk,
Links,
Performance
Friday, December 5, 2008
Defining new filenames for send handler
How to create more ellaborated filename?
Following the list of predefined file names given on my previous post, how can you get more than what Biztalk gives you?
Solution:
You can change the SourceFileName. In the construct message block of the orchestration use something like the following:
Message_2 = Message_1;
Message_2(FILE.ReceivedFileName) = "your_value"+ToString(Message_1.id);
And then when you are defining the send port use File Name as usually: %SourceFileName%
Labels:
Archiving,
Biztalk,
FAQ,
Orchestration,
Ports
List of variables for naming files at in send handler
How to change file name
This isn't a trouble, but a useful information that should be on every biztalk programmer manual.
The name of the file generated, mainly for archiving porposes, sometimes should be more than a GUId. This is a complete list of all the variables that can be used at the send handler. This is only valid for writing files, and some of them are only available when the input comes from a file also.
Macro name | Substitute value |
---|---|
%datetime% | Coordinated Universal Time (UTC) date time in the format YYYY-MM-DDThhmmss (for example, 1997-07-12T103508). |
%datetime_bts2000% | UTC date time in the format YYYYMMDDhhmmsss, where sss means seconds and milliseconds (for example, 199707121035234 means 1997/07/12, 10:35:23 and 400 milliseconds). |
%datetime.tz% | Local date time plus time zone from GMT in the format YYYY-MM-DDThhmmssTZD, (for example, 1997-07-12T103508+800). |
%DestinationParty% | Name of the destination party. The value comes from message the context property BTS.DestinationParty. |
%DestinationPartyID% | Identifier of the destination party (GUID). The value comes from the message context property BTS.DestinationPartyID. |
%DestinationPartyQualifier% | Qualifier of the destination party. The value comes from the message context property BTS.DestinationPartyQualifier. |
%MessageID% | Globally unique identifier (GUID) of the message in BizTalk Server. The value comes directly from the message context property BTS.MessageID. |
%SourceFileName% | Name of the file from where the File adapter read the message. The file name includes extension and excludes the file path, for example, foo.xml. When substituting this property, the File adapter extracts the file name from the absolute file path stored in the FILE.ReceivedFileName context property. If the context property does not have a value, for example, if message was received on an adapter other than File adapter, then the macro will not be substituted and will remain in the file name as is (for example, C:\Drop\%SourceFileName%). |
%SourceParty% | Name of the source party from which the File adapter received the message. |
%SourcePartyID% | Identifier of the source party (GUID). The value comes from the message context property BTS.SourcePartyID. |
%SourcePartyQualifier% | Qualifier of the source party from which the File adapter received the message. |
%time% | UTC time in the format hhmmss. |
%time.tz% | Local time plus time zone from GMT in the format hhmmssTZD (for example, 124525+530). |
Thursday, December 4, 2008
Enlisting in transaction coordinator
New transaction cannot enlist in the specified transaction coordinator
This has to be made when Biztalk is installed and when a new Windows SP is installed in the server. By default and when installing Service Packs in Windows, some security rules are activated.
Those rules also affect MSDTC - Microsoft Distributed Transaction Coordenador. As the name indicates, it is responsible for coordinating transactions that span multiple resource managers, such as databases, message queues, and file systems. Basically what Biztalk wants.
Solution:
Easy setup on My Computer. Read all at MSDN
Labels:
Biztalk,
Ports,
Running Stage
Sunday, November 16, 2008
Ports and correlations
You must specify at least one already-initialized correlation set for a non-activation receive that is on a non-selfcorrelating port.
There is not a better error to start whin than this wonderful classic. This error happens to everyone all the time. When you start making an orchestration you may be thinking of this, but it will vanish from your mind before the first component is set.
Solution:
The beggining of the orchestration - usually a Receive component - must have the property Activate as True. Why isn't this a default in Biztalk? Good question...
Labels:
Biztalk,
Building Stage,
Orchestration
Subscribe to:
Posts (Atom)