<b:schemaInfo http: BizTalk schema_type="property" xmlns:b="<b:fieldInfo http: BizTalk xmlns:b="<b:fieldInfo http: BizTalk xmlns:b="

I’ve recently had to go through the process of having to find out how to achieve this so
hopefully I can save other people a lot of time when it comes to creating their custom adapters.


The Socket Adapter sample provided with the Biztalk Adapter Wizard does not support Dynamic Port Binding out of the box, so as an illustrative exercise I have prepared a walkthrough to show how to make it work with Dynamic Ports.


You have two options:


OPTION 1  – Work through the code yourself (Recommended)


Familiarise yourself with the Pre-requisites.


1) Read Christof Claessens excellent article that touches on dynamic send port binding. It’s located at
http://weblogs.asp.net/christof_claessens/archive/2004/06/18.aspx
There is a section that explains how you can use Dynamic Port Binding with the out of the box FTP adapter
2) Work through creating the sample Socket Adapter using the
“Developing a BizTalk Server 2004 Socket Adapter with the Adapter Wizard.doc” that’s located in the “BTSAW11.zip”, available for download from
http://www.gotdotnet.com/Community/UserSamples/Details.aspx?SampleGuid=c95217fc-4f9f-4fec-9d68-1aa9456b6ca0
Make sure that you can get it working before continuing.


Make adapter “message context properties” visible to an Orchestration


1) Add a new BizTalk project to the BizTalk Socket Adapter Solution called “SocketPropertySchema”
2) Add a the following Property Schema as “PropertySchema.xsd” to your SocketPropertySchema project


<?xml version=”1.0″ encoding=”utf-16″?>
<xs:schema xmlns=”
http://schemas.unisys.com/BizTalk/Adapters/SocketAdapter” xmlns:b=”http://schemas.microsoft.com/BizTalk/2003” targetNamespace=”http://schemas.unisys.com/BizTalk/Adapters/SocketAdapter” xmlns:xs=”http://www.w3.org/2001/XMLSchema“>
  <xs:annotation>
    <xs:appinfo>
      <b:schemaInfo schema_type=”property” xmlns:b=”
http://schemas.microsoft.com/BizTalk/2003” />
    </xs:appinfo>
  </xs:annotation>
  <xs:element name=”RemoteHostName” type=”xs:string”>
    <xs:annotation>
      <xs:appinfo>
        <b:fieldInfo propSchFieldBase=”MessageContextPropertyBase” xmlns:b=”
http://schemas.microsoft.com/BizTalk/2003” propertyGuid=”1a0116b8-e2c7-4da2-9f43-414686d38005″ />
      </xs:appinfo>
    </xs:annotation>
  </xs:element>
  <xs:element name=”RemotePortNr” type=”xs:int”>
    <xs:annotation>
      <xs:appinfo>
        <b:fieldInfo propSchFieldBase=”MessageContextPropertyBase” xmlns:b=”
http://schemas.microsoft.com/BizTalk/2003” propertyGuid=”7a8a8133-4aff-4af4-8ae9-62f8ef056d87″ />
      </xs:appinfo>
    </xs:annotation>
  </xs:element>
</xs:schema>


NOTE –  the propSchFieldBase=”MessageContextPropertyBase” xmlns:b=”http://schemas.microsoft.com/BizTalk/2003” attributes have to be manually added if you need to add new elements.
The schema editor does not add them.


NOTE – the xmlns and targetNamespace attributes were set to the same value as the PropertyNamespace value that was found in the SocketAdapter.reg that is provided in the sample adapter solution directory.


3) If it wasn’t already set make sure you set the build action of PropertySchema.xsd to “compile”.


4) Assign a strong name to the project “SocketAdapterTester.snk” otherwise you wont be able deploy it to BizTalk.


5) Build and Deploy the SocketPropertySchema project


6) Reference the SocketPropertySchema  from the SocketAdapterTester project


Once you have completed this task the message context properties will be available for setting in an orchestration message construct shape , just like in Christoph’s example for the FTP adapter.


You’ll be able to set them in a similar manner to the examples below (the actual property names my differ slightly but will start with “Socket”)


msgServerOrder(SocketAdapterPropertySchema.PropertySchema.RemoteHostName) = “biztalktest”;
msgServerOrder(SocketAdapterPropertySchema.PropertySchema.RemotePortNr) = 8999;


Modify the Sample Socket Adapter Code to enable it to access the new message context properties


Unfortunately the adapter code in its current format doesn’t automatically “know” that these are the values to use.
In fact there is no real relationship between the elements set up in the Transmit Location.xsd and the PropertySchema.xsd files.


So we have to modify the socket adapter code to deal with this new data.


The following is merely an illustration i.e. it reflects the key points in order to make the adapter support Dynamic Port Binding.
I have probably skipped over a number of vital error handling routines so ensure that you add the necessary error trapping routines in your
production code.



1. Modify the following code snippet located in the SocketTransmitAdapterBatch.cs .


Old Code


remote_host.PortNr = config.RemotePortNr;
remote_host.TimeOut = SocketAdapterProperties.Timeout*1000;


New Code


if (null != config)
{
    //It’s a static port
    remote_host.ServerName = config.RemoteHostName;                                     
    remote_host.PortNr = config.RemotePortNr;
}
else
{
    //It’s a dynamic port. No properties are available if it’s Dynamic so we have to get them from Message Context
    remote_host.ServerName = msg.Message.Context.Read (“RemoteHostName”,”
http://schemas.unisys.com/BizTalk/Adapters/SocketAdapter”).ToString();
    remote_host.PortNr = Convert.ToInt32(msg.Message.Context.Read(“RemotePortNr”,”
http://schemas.unisys.com/BizTalk/Adapters/SocketAdapter“));
}


Stop the Biztalk Server and any send ports. Rebuild the Solution (sometimes WMI has a hold on the assemblies . Use sysinternals handle.exe to determine this)
Now all that is left is for you to test your adapter by modifying the existing sample orchestration.


Modifying The “SocketAdapterTester” Project to use Dynamic Port Binding


Now that we have added Dynamic support to our adapter we can modify an existing orchestration to use a Dynamic Solicit Response Send Port.


1. Undeploy the existing “SocketAdapterTester”  assembly from your Biztalk server.
2. Open up the OrchSocketClient.odx , delete the “psrSolRspSocketClient” port from the orchestration
3. Add a new Configured Port with the following values


Name:    portSendDynamic
portType :   portTypeDynamic
Pattern :    Request Response
Direction:  Send Receive
Port Binding :  Dynamic
Receive Pipeline: XmlReceive
Send Pipeline:  XmlReceive


4. In Orchestration Properties add a new message called “msgServerOrder2” of same type as “msgServerOrder”


5. Add a Construct Message Shape immediately under the rcvFromFile Receive Shape. Name it “Create msgServerOrder2” . Set the Messages Constructed property to msgServerOrder2
6. Drag a Message Assignment Shape into the Construct Message shape.Name it “from msgServerOrder”
set the expression to :


msgServerOrder2 = msgServerOrder;



7. Drag another Message Assignment Shape into the Construct Message shape.Name it “Set Context”
set the expression to : (replace biztalktest with your machine name. )



msgServerOrder2(SocketAdapterPropertySchema.PropertySchema.RemoteHostName)=”biztalktest”;
msgServerOrder2(SocketAdapterPropertySchema.PropertySchema.RemotePortNr)=8999;


NOTE – Exact Message context properties name may differ slightly from what’s outline above , depending on the namespace assigned to the PropertySchema.xsd file.
You should be able to locate the values as they will more than likely start with “Socket”.
8. Drag an Expression shape immediately below the Construct Message Shape and before the sndToSocket shape , name it “Set Dynamic Port”
Set the expression to : (change biztalktest to your machine name)



portSendDynamic(Microsoft.XLANGs.BaseTypes.Address)=”Socket://biztalktest/8999″;


9. Modify the sndToSocket Shape and set its Message property to msgServerOrder2 instead of msgServerOrder.
10. Re-connect the sndToSocket and rcvFromSocket shapes to the portSendDynamic port.
11. Stop the Biztalk Server Host and any send ports that may be using the adapter.
You may need to close down Server Administration and Biztalk Explorer as sometimes they seem to keep hold of the assemblies.(use handle to find any locked assemblies)
12. Rebuild the solution. If there are any build issues then revisit the previous steps.
13. Re-Start the BizTalk host
14. Deploy the modified “SocketAdapterTester” Project.
15. As part of the standard Socket Adapter walkthrough you will have created two file locations called rcvFromFile and sndToFile
Make sure they have provided the necessary read / write permissions to allow Biztalk to access them.
17. Bind and Start the “SocketAdapterTester.OrchSocketClient” and “SocketAdapterTester.OrchSocketServer” Orchestrations
NOTE – The orchestration “SocketAdapterTester.OrchSocketClient” should have already pre-bound its send port to the auto-generated dynamic port)
NOTE – With the exception of the new Dynamic port , bind all other ports as per the Socket Adapter Walkthrough.
18. Start the socket listener client as per the socket adapter walkthrough
19. Drop the following Xml sample instance into the “rcvFromFile” file receive location.


<ns0:ServerPO xmlns:ns0=”http://SocketAdapterTester.POSchema“>
  <Manufacturer>Unisys</Manufacturer>
  <Type>ES 7000 Orion 560</Type>
  <NrOfProcessors>32</NrOfProcessors>
  <AmountOfRam>64 GB</AmountOfRam>
  <Quantity>12</Quantity>
</ns0:ServerPO>



20. The xml file should be processed just like it was in with the Static Send Port.


OPTION 2 – Use my sample code (based upon the original socket adapter sample code.)


NOTE – this sample is hard coded to work from a specific directory location on the C drive.
For convenience , I have added assembly-binding files, send and receive locations and also have strong named the assemblies.
But the following step-by-step instructions apply ONLY to the default solution location.
You’ll need to modify the assembly binding file and the adapter registry file if you decide to use a different file location.


1. If you have previously used the SocketSample adapter code provided with the BizTalk Adapter Wizard , you MUST ensure that you have removed
the adapter and any old send and receive ports prior to using this sample code. Otherwise you will have problems re-registering and re-adding the adapter.
1. Download the source code from
http://www.appsolutions.co.uk/samples/SocketSample.zip
2. Extract the zip file to your C drive. It will create a “SocketSample” folder on the C drive.
3. Open the “C:\SocketSample\BizTalk Server Socket Adapter Sample\BizTalk Socket Adapter.sln” solution.
4. In the SocketRecvListener project modify the SocketRecvListener.cs to replace the machine name “biztalktest” with your machine name.
NOTE – You can optionally change the port and uri values but I would recommend leaving them as they are, otherwise you will have to change your assembly binding files to make the sample work properly.
5. Build the entire solution.
6. Run the C:\SocketSample\BizTalk Server Socket Adapter Sample\SocketAdapter.reg to import the necessary adapter registry details
7. Add the adapter using Biztalk Server Administration>>Adapters>>New>>Adapter. Once done you must stop the Biztalk host.
8. Set the Send Handler Properties on the adapter. Set MaxBufferSize to 49152 and Timeout to 20.
9. Deploy the SocketAdapterPropertySchema and SocketAdapterTester Biztalk projects (in that order).
10.Modify the C:\SocketSample\AssemblyBinding\SocketBinding.xml. Replace any occurrences of “biztalktest” with your machine name.
10. Once that is done you can import this assembly-binding file (SocketBinding.xml) using the Biztalk Server Deployment Wizard
11. Assign read/write permissions to the C:\SocketSample\rcvFromFile and C:\SocketSample\sndToFile directories
12. Start the “SocketAdapterTester.OrchSocketClient” and “SocketAdapterTester.OrchSocketServer” Orchestrations, including send and receive ports etc.
13. Start the Socket Listener Client , located in “C:\SocketSample\BizTalk Server Socket Adapter Sample\SocketRecvListener\bin\Debug\SocketRecvListener.exe”
14. Start the Biztalk Host (if not already started).
15. Drop the “C:\SocketSample\SampleInstance\SampleInstance.xml” file into “C:\SocketSample\rcvFromFile”
16. Biztalk will process the file (via the socket listener) and place an output file in the “C:\SocketSample\sndToFile” directory
17. Take the time to review the OPTION 1 to familiarise yourself with what has been modified. If you have time work through Option 1 to get yourself familiar with the principles
because once you’ve done it once the method should be the same some any new adapters you create.


Conclusion


I hope this post was of use. If you have any problems with this walkthrough let me know and time permitting I’ll do my very best to assist you. Code is provided as is. No guarantees are made as it its ability to perform in a production environment.