As you might have read earlier (this post), a new SQL Adapter is on its way. The features we plan to support are described there.
Further to that, some time back I had mentioned a few limitations (here), which we wouldn't be addressing.
I am happy to say that due to the TAP customer feedback received on this feature, we WILL be allowing multiple operations (i.e., INSERT, UPDATE, DELETE on the same or different Tables/Views) as well as Stored Procedure/Function invocations within the same XML message (and therefore, within the same Transaction). One thing to keep in mind though:
- The adapter will only generate the metadata for individual operations (i.e., there will be one schema for INSERT, one for UPDATE, etc, one for a Stored Procedure, etc). The user will manually have to create a schema combining all the operations which need to be a part of the same XML message/Transaction. This shouldn't be too difficult - once the individual schemas have been generated, coming up with a combined schema should take no more than a couple of minutes. This entire process will be documented.
Our current plan is to release a CTP around the end of May / beginning of June. If you plan on using the adapter, you should join the TAP program. TAP customers have a direct communication channel with the developers on the team, and can play an important role in pushing for important features (important for them) to be included in the final product. If you are interested in joining the TAP program, please leave your email address here (in a comment to this post - don't worry about spam, I promise to remove your address the moment I make a note of it).
I was recently contacted by a customer using the SAP Adapter. They were using the Adapter directly via a WCF proxy (i.e., without using BizTalk) from within an ASP.NET application. Their complaint was that the throughput was very low. On investigating further, I found that the reason was due to connections being opened and closed, as well as metadata being retrieved from SAP, for every call. All this in spite of the binding property "EnableConnectionPooling" being true. That's strange you might think, but not once you know the details of how the ASDK functions ...
In the WCF LOB ASDK, there was a need for maintaining a pool of open connections to the LOB, since opening connections to LOB systems is usually expensive. When a connection is required by a channel to a particular LOB server (as determined by the URI), with a specific set of credentials, then the appropriate connection is picked up from the pool and used; when the channel is closed, the connection is returned back to the pool.
In the current ASDK design, the connection pools are maintained at the channel factory instance. (The exact reasons of why this design was chosen - topic of another blog post). What this means is that if you have two channel factory instances, then each channel factory has its own set of connection pools. i.e., for a server A, each channel factory will have one connection pool for this server. Connections from the pools in one channel factory cannot be used by another channel factory.
Another set of objects which are cached are metadata objects. The adapters, at runtime, when receiving a message (corresponding to some LOB operation), first connect to the LOB to obtain metadata for the operation. This is required in order to understand how to parse the request message (for example - how many parameters does the function have? What are their names? etc). Once metadata is obtained from the LOB, this metadata is cached within the ASDK. There are a number of settings (exposed by the ASDK to the adapter) which determine for how long is the metadata cached, where is it cached, etc. The adapter has control over whether the ASDK should cache the metadata at an AppDomain level (i.e., "static"), or per channel factory instance. The SAP Adapter instructs the ASDK to cache the metadata per channel factory instance. (Why? Another blog post).
At this point, here's what we know - in the SAP Adapter, both, the connection pools, as well as the metadata caches, are maintained within each channel factory object. If you have two channel factories, then you will have a separate set of connection pools and metadata objects. The connection pools and metadata objects are freed up only when the channel factory object is closed.
Now, when you use the Metadata Search Browse tool (using "Add Adapter Service Reference") in your application, we generate an interface (which is the ServiceContract), as well as a client proxy. For example, if you generated the client proxy for RFC_CUSTOMER_GET, you would see a proxy class generated named RfcClient, as well as an interface named Rfc. To use the generated proxy, you would have code similar to:
RfcClient
client = new RfcClient(binding, endpointAddress);
client.Open();
client.RFC_CUSTOMER_GET();
//do work here
client.Close();
Now, here's something which you might not know - every time you create an instance of RfcClient, this causes a new channel factory to be created, and then, from that channel factory, a channel is created. When you close the RfcClient object, the channel is closed, as well as the channel factory. This leads to the connection pool being closed (i.e., all connections in the pool are closed), and the metadata objects are freed up. When you create a new instance of RfcClient, another channel factory is created, which comes with its own pool and metadata cache. Therefore, effectively, connections are not being pooled, (and neither is the metadata cache acting as a cache), since they are freed up the moment the RfcClient object is closed.
So, how do you get around this? One way would be to cache the RfcClient object, and then use that from multiple threads (for example). However, this really doesn't help. The reason being, that the RfcClient object not only represents one channel factory, but also just one channel (which ultimately maps to one LOB connection). Therefore, if you have, say, 50 threads accessing the same RfcClient object, they will all ultimately end up using the same LOB connection, which will definitely not be good for performance.
What you really want to do, is open one channel factory, cache that, and then, open and close channels at will from that channel factory. When you open a channel, a connection will be obtained from the connection pool; and when you close the channel, the connection will be released back to the pool. Plus, the metadata cache will be shared across the channels, since they are part of the same channel factory.
So, how do you this? You can't use the RfcClient proxy. Instead, you need to use the ChannelFactory<> class, and use the generated ServiceContract (which will be named Rfc if you added only RFCs in the "Add Adapter Service Reference" wizard). (You can always figure out the name of the interface, by looking up the definition of the generated proxy, and seeing which interface it implements). Thus, you need to do something like:
//do this only once
ChannelFactory<Rfc> factory = new ChannelFactory<Rfc>(binding);
factory.Open();
//cache the "factory" object somewhere.
//When you need to make a call to SAP:
Rfc channel = factory.CreateChannel(endpointAddress);
channel.RFC_CUSTOMER_GET();
((IChannel)channel).Close();
//that's all.
//When you ultimately want to free up
//all connections in the pool, and free
//up all the stored metadata,
factory.Close();
We are currently working on an Oracle EBS (aka Oracle Apps) Adapter for the next release of Adapter Pack, along with a SQL Server Adapter. The Oracle EBS adapter will be built using WCF LOB Adapter SDK. At a high-level, we are planning to have the following set of features in the adapter:
- Ability to interface with PL/SQL APIs
- Perform operations on the Interface tables/Views
- Execute Concurrent programs
- Support for Simple Data Types, UDTs, Table types, Boolean types.
Do you use XMLGateways and Business Events in your Oracle E-Business scenarios and want to see it as part of the Oracle EBS adapter? We would like to hear about any other specific features that you would like to see in the Oracle EBS adapter.
Please do let us know if you would like to enroll in the Technology Adapter Program(TAP). As part of the TAP program, you get a chance to work closely with the product team to identify features and requirements for the product, try out early drops of the adapter and help Microsoft validate the features for quality and production-readiness.
As you all know, the BizTalk® Adapter Pack was released earlier this year and includes WCF based adapters for SAP, Oracle DB and Siebel. We have recently posted a detailed presentation about the Adapter Pack on Channel 9. You can view it at http://channel9.msdn.com/ShowPost.aspx?PostID=394792. Hope you find it useful. Look forward to hearing your feedback.
As was already announced on this forum, the BizTalk Adapter Pack (BAP) was announced more than a month ago during the Office Developer Conference and became available starting March 1st. The BAP provides a robust and comprehensive out-of-the-box connectivity infrastructure to three major line-of-business (LOB) systems - SAP, Siebel, and Oracle Databases. The technology is based on the Windows Communication Foundation (WCF) LOB Adapter SDK and inherently relies on the core WCF concepts, principles, and classes implemented in the .NET Framework 3.5.
Along with the BAP, we also launched the BizTalk Adapter Pack – Office Developer Program, designed to validate the use of the BizTalk Adapter Pack as a connectivity solution in direct integration scenarios with Microsoft Office SharePoint Server (MOSS) 2007 and the Office Business Applications such as Microsoft Office Excel and Microsoft Office Word. The scope of the program is validation of six key scenarios, as depicted in the following diagram.
Customer Participation
The BAP - Office Developer Program is now open for new customer nominations. Joining this program will provide you with access to conference calls with members of the BAP development team, access to private discussion forums, and the ability to discuss and report bugs and issues directly back to the team at Microsoft.
If you would like to work closely with the product team and implement and test any of the six scenarios in your solution, please fill out the short survey and be specific in answering the questions to help us accurately evaluate your application. We will contact you shortly thereafter. If you have any questions, you can contact us via e-mail by clicking here.
You can also get additional information about this program on the SharePoint Product Team blog site.
The BizTalk SOA Customer Programs Team
As mentioned in
this post, we're developing a new SQL Adapter, which will be available in the next release of the BizTalk Adapter Pack. The list of features which we're supporting is mentioned in that blog post.
As for the features/items/etc which we've decided
NOT TO SUPPORT, they are:
- SQL Server versions prior to SQL 2005.
- The ability to perform one or more INSERT, UPDATE and DELETE operations, on one or more tables, all within the same XML message. In our current design, within a single message, you can either perform one or more INSERT, or UPDATE, or DELETE operations, all on the same TABLE or VIEW.
- The ability to have multiple transactional blocks within the same XML message. All the operations within a message all take place within the same transaction; and this is actually a distributed transaction which spans these operations on your SQL Server, as well as the operations performed by BizTalk on the MessageBox database.
If any of the above are absolutely critical to your scenarios, please get in touch with us.
EDIT: Regarding the first two points, please have a look at this post.
Quite a few customers developing custom adapters built on the WCF LOB Adapter SDK have come back to us asking for details on how to have transactional behavior while receiving messages from the LOB and submitting them to BizTalk (receive location) - for example, assume in your receive location:
- You read some data from the LOB
- You delete the data from the LOB (since you don't want to read it again)
- In IInboundHandler, you construct a message containing this data
- You return this message via the out parameter in the TryReceive function (in other words, you are submitting this message into BizTalk).
If an error occurs after step 4, you have lost the data! (since it has already been deleted from the LOB).
If your LOB supports transactions, then you can prevent this from happening - the same transaction can be used to read + delete the data from the LOB, as well as submit the message into BizTalk, and if anything fails at any point, everything is rolled back.
More information on how you can do this - read this post by Sonu Arora at
http://blogs.msdn.com/sonuarora/archive/2007/06/19/transaction-support-in-inbound-message-exchange-handler.aspx.
BizTalk® Adapter Pack Launches at Office Developers Conference
On Monday February 11th, we announced availability of the BizTalk® Adapter Pack at the Office Developer Conference. The BizTalk® Adapter Pack provides a single solution to easily and securely connect to Line of Business (LOB) data from any custom-developed .NET application, SQL Server-based business intelligence solution, or an Office Business Application (OBA). The three adapters available in this release are Siebel, SAP and Oracle DB.
The BizTalk Adapter Pack will be generally available on March 1st. Please contact your Microsoft representative for the pricing details. The Adapter Pack license is also included with BizTalk Server 2006 R2 Developer, Standard, and Enterprise editions. It is not included in the Branch edition. Customers that have already purchased BizTalk Server 2006 R2 with Software Assurance will also have access to the BizTalk Adapter Pack through the Software Assurance program.
We also announced the BizTalk Adapter Pack: Office Developer Program. This program provides participants with access to code, support and direct access to the product team for bug fixes and change requests. By working with Office developers directly we will be validate additional Office/SharePoint scenarios. If you are interested in validating your SharePoint and Office scenarios, please visit the following site to register (note that you mean need to log in using Windows Live ID to access this site).
Key Benefits
· Single infrastructure for connectivity. Whether connecting to LOB systems from custom-developed applications, SQL Server, or rich Office applications, customers can use a consistent approach to connectivity. This enables a simplified approach to interoperability that lowers total cost of ownership and reduces training requirements.
· Simple to learn. Built on top of the WCF programming model, the BizTalk® Adapter Pack is easy for .NET trained developer to begin using and building connected applications. The BizTalk Adapter Pack provides enhanced extensions to WCF that enable dynamic metadata discovery and generation – making it fast and easy to access data in corporate systems.
· Secure and reliable. The BizTalk Adapter Pack tightly integrates with the security models provided by the individual business applications, ensuring that users have access only to data which they are permitted to see.
· Improves real-time visibility to your business data. The BizTalk® Adapter Pack allows customers to access valuable corporate information when and where they can use it most productively, increasing visibility and enabling faster, better informed decision making.
-The BizTalk Adapter Pack Team
When using the SAP Adapter, while receiving an IDoc, you might see the error message "Loading property information list by namespace failed or property not found in the list" in the event log.
Cause: The SAP adapter is writing the IDoc control record fields to the BizTalk message context. However, there is no schema deployed for these context properties.
Resolution: Add the "Microsoft.Adapters.SAP.BizTalkPropertySchema" dll to the Resources section of your BizTalk application.
The post http://blogs.msdn.com/adapters/archive/2007/10/12/enablebiztalklayeredchannel-what-does-this-binding-property-do-part-1.aspx talks about this in a little more detail (of course - EnableBizTalkLayeredChannel was renamed to EnableBizTalkCompatibilityMode from the RC build onwards).
The current release of the Adapter Pack contains the SAP, Siebel and Oracle adapters (written using the WCF LOB Adapter SDK).
For the next release of the Adapter Pack, one of the adapters which we're adding is a SQL Adapter. Some of the features which we're addressing are:
- SQL 2005 and SQL 2008 datatypes (XML, VARCHAR(MAX), VARBINARY(MAX), Date, Time, DateTime2, DateTimeOffset, Geometry, Geography, HierarchyId)
- User Defined Types (UDTs - these can be defined in .NET assemblies)
- Table Parameters in Functions and Stored Procedures
- 64 bit
- Enterprise SSO
- User-defined schemas (schemas other than dbo)
- Specifying the transaction IsolationLevel to use during polling
- An ExecuteReader() operation which can be used to execute arbitrary SQL statements at runtime
- Executing any stored procedure - FOR XML is no longer required.
- Supporting multiple resultsets in the response - either from stored procedure execution, or from arbitrary SQL statements, and for both - outbound as well as polling scenarios
- Ability to specify a post poll statement for polling scenarios
- Streamed operations for reading/writing from/to VARCHAR(MAX) and VARBINARY(MAX) columns
- Dynamic Ports (i.e., specifying the Connection URI within an orchestration)
Are there any other features which you would like to see in a new SQL Adapter? Please do let us know.
We're looking for TAP customers to try out and validate the features in the new adapter. An alpha release of the adapter (having all the above features) is also currently available, so if you're interested, please do let us know and join the TAP program.
The RTM version of Siebel Adapter no longer supports the MVG operations – Associate, Dissociate and Query_*. The reason for dropping support for these operations is a memory leak in Siebel library that the adapter uses to communicate with Siebel. We are actively following up with Siebel to get this issue (SR# - 38-3489322221) resolved. In the mean time you can use the following alternate approach.
Before the adapter can be used to perform the MVG operations, users must manually obtain some information from Siebel. You can use Siebel Tools to get this information, which includes the MVG business component name and the foreign key fields in that. Below is a step by step description of how to go about finding that information.
1. Obtain the name of the Multi-Value Link based on the specific MVG field.
For example if the field is “Contact Id” in “Action” business component, the name of the MVL is “Contact”
2. From the Multi-Value Link, obtain the name of the Link
For the above example, the name of the Link is “Action/Contact”
3. From the Link, obtain the name of the Intersection Table, Inter Parent Column and Inter Child Column and the Primary ID Field. Note that if the Source Field and/or Destination Field are specified, they will be the primary keys, instead of Id, in the parent and child records.
For the above example, the name of the Intersection Table is “S_ACT_CONTACT”, Inter Parent Column is “ACTIVITY_ID”, Inter Child Column is “CON_ID” and Primary ID Field is “Primary Contact Id”. Both the Source Field and Destination Field are not specified meaning the primary key field is “Id” for either business components.
4. Now obtain a business component whose base table is the above Intersection Table. This would be the MVG business component. Note that if there are more than one, you will have to use some context to figure out the right one.
For the above example, the business component is “Action Contact”.
5. Also find the fields in the MVG business component that obtain their values from the Inter Parent Column and Inter Child Column obtained above. These will be the foreign keys for the parent and child record respectively.
For the above example, the field names are “Activity Id” and “Contact Id”
6. Now obtain a business object that contains this business component.
For the above example, the business object is “Contact”
Once we have the above information, the MVG operations can be performed by directly operating on the MVG business component using the foreign key fields. In the above example, the 3-tuple would be “Action Contact”, “Activity Id” and “Contact Id”.
1. Associate
To associate a specific record of the parent BC with a specific record of child BC, insert a record in MVG BC by setting the foreign key fields appropriately. For example if one wants to associate a record of Action with Id = “a” with a record of Contact with Id = “c”, insert a record in “Action Contact” with Activity Id set to “a” and Contact Id set to “c”.
/// <summary>
/// Associate a "Contact" record with an "Action" record
/// </summary>
/// <param name="mvg">Proxy client for the MVG business component</param>
/// <param name="activityId">Unique identifier for the "Action" record</param>
/// <param name="contactId">Unique identifier for the "Contact" record</param>
/// <returns>Id of the newly created record in MVG BC</returns>
private static string
Associate(
BusinessObjects_Contact_ActionContact_OperationClient mvg,
string activityId,
string contactId
)
{
try
{
/// Insert a record into the MVG BC after setting the
/// "Activity Id" & "Contact Id"
ActionContactInsertRecord[] insertRec = new ActionContactInsertRecord[1];
insertRec[0] = new ActionContactInsertRecord();
insertRec[0].ActivityId = activityId;
insertRec[0].ContactId = contactId;
string[] id = mvg.Insert(insertRec);
return id[0];
}
catch (Exception e)
{
Console.WriteLine("ERROR: Associate - " + e.Message);
}
return null;
}
Once a record has been associated, if you want to make this as the primary association, you need to set the Primary ID Field as well. For the above example, to make the new associated Contact record with Id = “c” as the primary association for the Action record, we will set the “Primary Contact Id” field in the Action record to “c”.
/// <summary>
/// Set the <Primary Id> field in the "Action" record to create a
/// primary "Contact" for this "Action".
/// </summary>
/// <param name="action">Proxy client for the "Action" business component</param>
/// <param name="activityId">Value of the foreign key field for the "Action" record</param>
/// <param name="contactId">Value of the foreign key field for the "Contact" record</param>
/// <returns></returns>
private static bool
SetPrimaryAssociation(
BusinessObjects_Action_Action_OperationClient action,
string activityId,
string contactId
)
{
try
{
/// Set the Primary Id field "Primary Contact Id" in "Action"
/// to the Id of Contact record
ActionUpdateRecord[] updateRec = new ActionUpdateRecord[1];
updateRec[0] = new ActionUpdateRecord();
updateRec[0].Id = activityId;
updateRec[0].PrimaryContactId = contactId;
action.Update(null, updateRec);
return true;
}
catch (Exception e)
{
Console.WriteLine("ERROR: SetPrimaryAssociation - " + e.ToString());
}
return false;
}
2. Dissociate
To dissociate a specific record of the parent BC from a specific record of child BC, delete the record from MVG BC found by using a search expression built using the 2 foreign key fields. For example if one wants to dissociate a record of Action with Id = “a” from a record of Contact with Id = “c”, delete a record from “Action Contact” using the search expression “[Activity Id] LIKE a and [Contact Id] LIKE c”.
/// <summary>
/// Dissociate a "Contact" record from an "Action" record
/// </summary>
/// <param name="mvg">Proxy client for the MVG business component</param>
/// <param name="activityId">Unique identifier for the "Action" record</param>
/// <param name="contactId">Unique identifier for the "Contact" record</param>
/// <returns>Id of the record deleted from the MVG BC</returns>
private static string
Dissociate(
BusinessObjects_Contact_ActionContact_OperationClient mvg,
string activityId,
string contactId
)
{
try
{
/// Delete the record where "Activity Id" and "Contact Id"
/// matche the specified values
string searchExpr = "[Activity Id] LIKE \"" + activityId + "\" and [Contact Id] LIKE \"" + contactId + "\"";
string[] id = mvg.Delete(null, null, searchExpr);
return id[0];
}
catch (Exception e)
{
Console.WriteLine("ERROR: Dissociate - " + e.Message);
}
return null;
}
Note that if the primary record is getting dissociated, you will need to update the Primary ID field to another associated record or if there are none, you will need to clear it. See “SetPrimaryAssociation” code sample above for how to do this.
3. Query associated
To query records of child BC that are associated with a specific record of the parent BC, query the MVG BC using a search expression built using the foreign key of parent BC. For example, if one wants to query records of Contact associated with a record of Action, whose Id = “a”, query “Action Contact” using the search expression “[Activity Id] LIKE a”
/// <summary>
/// Query the "Contact" records associated with a specific "Action"
/// record
/// </summary>
/// <param name="mvg">Proxy client for the MVG business component</param>
/// <param name="activityId">Unique identifier for the "Action" record</param>
/// <returns>Ids of the associated "Contact" records</returns>
private static List<string>
QueryAssociatedContact(
BusinessObjects_Contact_ActionContact_OperationClient mvg,
string activityId
)
{
List<string> id = new List<string>();
try
{
/// Query the MVG business component for all records where
/// "Activity Id" is set to the specified value
ActionContactQueryInputRecord queryIn = new ActionContactQueryInputRecord();
queryIn.SearchExpr = "[Activity Id] LIKE \"" + activityId + "\"";
ActionContactQueryRecord[] queryOut = mvg.Query(null, queryIn);
foreach (ActionContactQueryRecord rec in queryOut)
{
id.Add(rec.ContactId);
}
}
catch (Exception e)
{
Console.WriteLine("ERROR: Query_Contact - " + e.Message);
}
return id;
}
You must have read in the documentation that the SAP adapter does not support/honour the timeout values specified on the binding (sendTimeout, openTimeout, etc). However, at times you might yet receive timeout related exceptions from the adapter. Why?
The SAP Adapter uses the SAP RFC SDK Library to communicate with SAP. The API calls in this SDK don't support timeouts, and hence, when making a call using this API, the adapter is helpless if an API invocation ends up taking a really long time. However, in most of the code paths within the adapter, the adapter performs a bunch of steps - some of them within the adapter, while the rest involving API invocations in the RFC SDK.
Now, as mentioned above, the timeout is not honored during a single API invocation. However, in between API calls, if the adapter determines that a timeout has occurred, then it does throw a TimeoutException.
But why does it throw an ArgumentOutOfRangeException at times? That is a side effect of the internal implementation; however, the error message might be something to the tune of "Timeout must be greater than or equal to TimeSpan.Zero", indicating a timeout related exception.
If you find such exceptions common in your environment, you should increase the sendTimeout value on the SAPBinding (the default is 1 minute, which might be insufficient when sending IDocs or executing BAPIs with a large amount of data, for example).
The WCF LOB Adapter SDK (ASDK) contains a behavior named "InboundActionEndpointBehavior" which you can add to your ServiceHost in inbound scenarios. What this behavior does is, at runtime, analyzes the contract deployed, determines the Actions on the Contract, and passes those to the adapter in the StartListener() call (on the IInboundHandler interface) via the "string[] actions" parameter. This allows the adapter to determine what actions the user is listening for, and send only messages of those type.
More information on this can be found at: http://blogs.msdn.com/sonuarora/archive/2007/06/11/passing-soap-actions-to-adapter-inbound-handler-for-filtering-type-of-listeners.aspx
What do you do when the adapter is used in a Receive Location from BizTalk? The WCF Adapter allows you specify endpoint behaviors for the ServiceHost which it creates, and that's how you can plug in the InboundActionEndpointBehavior. However, this doesnt work as expected. Reason - the WCF Adapter uses an "untyped" contract for the Service, i.e., the Action/ReplyAction is specified as "*" / "*". Hence, even if you add the endpoint behavior, the "string[] actions" array just contains "*". How would a user let the adapter know what operations he is interested in?
Attached is a sample endpoint behavior which you can use. The primary difference between this behavior and the one which ships with ASDK is this - the ASDK behavior determines the list of actions from the deployed contract, and passes those to the adapter. On the other hand, the sample endpoint behavior (attached) gets the list of actions via user input. That is, while configuring your receive location, add this endpoint behavior (via the behaviors tab), and you'll see two properties: "receiveActions" and "delimiter". You need to concatenate all the actions into a single string and set it on the "receiveActions" property. Also, specify the delimiter you used in the "delimiter" property. The behavior will then split the concatenated string into a list of actions, store them in an ASDK specific class, and add this object to the Binding Parameter Collection. ASDK will then pick out the actions from there and pass them to the adapter in the StartListener call.
The attached .cs file contains comments towards the top of the file detailing how it needs to be compiled, and what entries need to be made in machine.config.
Attachment(s): Program.cs
This is in continuation to the previous post, where we discussed the differences in the XML structure used by the old SAP adapter and the new WCF SAP Adapter. In a transactional scenario, the old adapter uses the context property named 'ConnectionType'. This context property is present in the new adapter too, with a few changes, which we illustrate here.
The corresponding values for the context property ‘ConnectionType’ in the old and the new adapters are as follows:
1. OPENREUSE: Open a new connection for reuse. Equivalent in new adapter is 'OPEN'
2. REUSECONNECTION: Reuse an existing cached connection. Equivalent in new adapter is 'REUSE'.
3. REUSECLOSECONNECTION: Reuse open connection and then close it. Equivalent in new adapter is 'CLOSE'.
In addition to the above, the new adapter provides an additional value 'ABORT', which closes the connection after the current call is made despite of any exceptions that may occur. This value does not have an equivalent in the old adapter. The WCF SAP Adapter documentation discusses this context property in more detail.
The pipeline component included with the preceding post (here) has now been updated to map the old adapter's context property ‘ConnectionType’ to that of the new adapter - in addition to the XML mapping it already did - making transition from the old adapter to the new one an easy process.
We have written a custom pipeline component (code and sample projects using this pipeline component are attached) that you can use to make your BizTalk orchestrations calling RFCs and BAPIs written with Microsoft BizTalk Adapter v2.0 for mySAP Business Suite work with the new WCF SAP Adapter. All you need to do is to use custom send and receive pipelines that replace the usual XMLTransmit and XMLReceive pipelines, and plug in the new adapter in place of the old one. No other changes. The source code of the pipeline component is included so you can make changes to it if you want to.
The custom pipeline component performs the following transformations:
1. Old adapter Request XML to New adapter request XML
2. New adapter Response XML to Old adapter response XML
The result? Your orchestration and messages do not have to change at all!
The major differences between the old and new adapters’ XML structure for RFCs are as follows:
1. Namespaces:
· Old Adapter : Root element is in the namespace http://schemas.microsoft.com/BizTalk/2003 while other elements have an empty namespace
· New Adapter: Elements with depth 0 and 1 are in the namespace http://Microsoft.LobServices.Sap/2007/03/Rfc/ while elements with depth 2 and 3 are in the namespace http://Microsoft.LobServices.Sap/2007/03/Types/Rfc/
2. Name of the Root Node:
· Old Adapter: The root node is named {RFC_NAME}_Request for the request XML, and {RFC_NAME}_Response for response XML
· New Adapter: The root node is named {RFC_NAME} for the request XML, and {RFC_NAME}Response for the response XML
3. Array of Complex types:
· Old Adapter : There are multiple nodes of with the name of the parameter, each of which contain one instance of the structure as the child nodes. The name of the complex type does not appear in the XML. For example:
.
.
<ComplexParameterName>
<Element1>Value1</Element1>
<Element2>Value2</