Monday, November 21

BizTalk 2010 message submission with transport-level security to SharePoint 2010 forms library without the WSS adapter

This was a solution I designed and built on one of my projects. The idea here was that the client had a process which needed to receive foreign exchange information from an external web service, have that information presented to certain management-level users in a readable, user-friendly fomat and added to a repository, and the information then needed to be read and approved as valid before the process would continue. One of the key design issues here was that for various reasons we could not use the SharePoint Adapter

I designed a BizTalk application which generated an xml file based on the foreign exchange currency information received from the external web service. An orchestration using a correlation set sent the information using WCF into a forms library hosted within SharePoint 2010, and then sent an email via SMTP on a dynamic port to certain management users with a link to the file. A loop ws created to continuously send the email after a certain number of minutes until the form was approved in SharePoint. They could then click on the link to open the document with an InfoPath form within SharePoint and approve the document. Upon approval, the approved xml was sent to a BizTalk WCF service hosted within IIS which (after confirming the approval based on certain business rules) sent a response to resume the same waiting BizTalk orchestration.

Whilst researching into this, I also came across R Seroter's wonderful blog post here which confirmed my design and helped speed up the development

I will try not to focus too much on the design of the BizTalk application itself as that is not the aim of this post. I will instead delve into the SharePoint and InfoPath aspects of the development more, and touch the BizTalk aspects architecturally

The steps are basically as follows:
  1. Design an InfoPath 2010 form to approve the xml information
  2. Create a SharePoint 2010 forms library based on the form design to accept the initial forms and store approved forms
  3. Design a BizTalk orchestration which adds InfoPath processing instructions to an xml message in a message assignment shape (This is to make sure that once the xml messages are published, clicking on the xml documents will automatically open them in our InfoPath form).
  4. The BizTalk orchestration sends the modified message to the SharePoint Forms library (through a WCf application which was created earlier) using a WCf-Custom adapter, as well as an email message to the management users (through the SMTP adapter) telling them the document is ready to be approved, and waits for a response (in my case, there is also a listen shape with a delay which sends a reminder email message to the management after a certain amount of time has elapsed to let them know the approval is holding things up)
  5. The management users open the document using the InfoPath form and approve the document, thereby changing the status of the document to approved, and sending a confirmation to the web service
  6. The web service sends a confirmation (approval) message directly to BizTalk, resuming the orchestration
PART 1 - Designing the InfoPath form.
(For this paticular implementation, make sure you have access to a SharePoint server, although with a little extra research, you can also implement similar but not exactly the same solutions without SP server (I used SharePoint 2010)

There are various ways to start off this part: for example you could start the form design from the schema based on the BizTalk message, or work backwards by basing the form design on the WCF service the form will be submitting to. I am not a SarePoint guru, but I found the second approach more foolproof, since you are sure the end result will submit successfully

  1. Open InfoPath Designer (Start, All Programs, Microsoft Office, Microsoft InfoPath Designer)
  2. Select 'New', and under 'Advanced Form Templates' choose the 'Web Service' option to create a form based on the web (WCF) service you wish to submit to
  3. Click on 'Design Form' in the right-most panel
  4. Make sure 'Submit data' is ticked on the next screen to indicate that your form will be submitting data to a service and click 'Next'
  5. Enter the URL of the service WSDL (the service you wish to submit data to). If the WSDL address is correct, the wizard will expose the operations available in the service
  6. Select the operation you wish to submit data to and click 'Next'
  7. Enter a name for the data connection (e.g Submit To Approvals Service) and click 'Finish' (the form design view opens).
  8. It is now important to remember that there are two services involved here. One is the WCF service we submit the form data to, which informs BizTalk that the form has been approved, and the other is the actual WCf service that BizTalk will call, which submits the forms to SharePoint in the first place. You should now see the schema structure expected by the WCF service we wish to submit data to in the right-side pane. Later you must ensure that your BizTalk application also uses this exact schema structure to create the xml message we want to send to SharePoint
  9. Design the form interface by dragging the fields from the schema in the right-side panel. For more indepth information on this, you can try Kent Weare's post, which despite being based on an older version of SharePoint and InfoPath, is still very helpful. Also note that you can use the nifty repeating table to create the unbounded nodes from your schema quite easily. 
  10. In the Controls section of the form menu, select and add any controls you wish to use on your form 
  11. After all the form controls are in place, add a button to the form.
  12. Right-click on the button and select 'Button Properties'
  13. Select Submit as the button Action and type in a Label (e.g Approve). You can also do this using rules instead of the submit option
  14. Click on 'Submit Options'
  15. Click on the 'Advanced' button and fill in the page similarly to the diagram below (replace the data connection name with the name of your data connection that you created when making the form earlier, and fill in a label value to suit your preference).
  16. Save the form as an xsn (form template). Note where the form template is saved to (you can use the save as dialog)
  17. Click on 'File' on the menu bar and click on 'Publish'. Click on the 'SharePoint Server' button to indicate that you wish to publish the form to a SharePoint Server resource
  18. Enter the address of the SharePoint site to which you wish to publish your forms. To understand this process better, you can read here or here or for some other ideas and information, you can read here
  19. Select 'Form Library' and click Next. Some users of the form library might not have InfoPath installed. To enable such users to view and submit the forms in a browser, tick 'Enable this form to be submitted by a web browser'. If you don't have this option, go to Notes at the bottom of this post
  20. Select the 'Create a new form library' option and click Next
  21. Type in a descriptive name like 'ApproveRates' (make a note of this name for future reference), add a description (optional) and click Next
  22. Add the xml/schema columns you wish to promote (make visible) in your forms library and click Next
  23. Review the information, make a note of the Location and the Form Library name and click 'Publish'
  24. Tick 'Open this form library' and click on the Close button
  25. You should now see a preview of the new form library
  26. My scenario was a SharePoint server which was part of a federated domain with the user profile service enabled. I now needed to set permissions for the BizTalk host instance to be able to add forms to the library, to avoid an error when trying to send the xml data through the SharePoint web services via BizTalk. I basically had to grant site permissions to the BizTalk user running the application pool under which the forms submission WCF service (the second service) would run. I granted permissions through the User Profile service (SharePoint Administration, 'Application Management', 'Manage Service Applications', 'User Profile Service Application'). I will not delve into this as I am not a SharePoint guru as I mentioned earlier. In a similar situation, I would assume you have a SharePoint administrator on hand to set the correct permissions
  27. If your setup is simpler, you can also simply set permissions for the BizTalk user on the SharePoint site. To do this, browse to the actual site that will host your form library, click on Site Actions, Site Permissions, Grant permissions and add the BizTalk user with (at least) read and contribute permissions
  28. To get the processing instructions, open the published form library by browsing to it (should be in the format http://your sharepoint server/your sharepoint site/your form library name)
  29. Click on the 'Documents' tab, and click on 'Add Document' button as shown below
  30. This will open up your form. Click on File and Save As to save the form. Ignore any validaiton warnings and click 'Yes' to save. Save the form as an InfoPath form (basically an xml file with InfoPath processing instructions, so that it automatically opens with InfoPath if InfoPath is installed on the user's computer) to a location you can remember
  31. You have now finished the InfoPath forms design process
Notes
  • If you want users of the form library to be able to submit the forms using Internet Explorer and you didn't have the tick box enabled at step 20 above, open a browser and browse to the sharepoint site in which you wish to host the form library (e.g. http:siteserver/site). You must be logged into SharePoint with an account that has enough priviledges to modify the site settings
  • Click on Site Actions
  • Click on Site Settings
  • Under the Site Collection Administration heading, click on Site Collection Features
  • Activate the SharePoint Server enterprise Site Collection Features
  • Close the site
  • Go back to step 19 above

Go on to Part 2 - The form submittal WCF service

Friday, November 18

Convert xml file to string inside BizTalk map using inline XSLT

I have a love for BizTalk maps because of their speed and the obvious load benefits when compared against orchestrations. I am therefore always pushing myself to find solutions that will avoid the use of orchestrations as much as possible when building applications. Inline XSLT is proven as one of the fastest methods for map conversions

One such endeavour led me to this solution. This solution allows you to convert a whole xml message into a string and feed it into one string node which can then be used in another map which (for whatever reason) may require a string message version of your original xml message. This could be done in an expression shape and message assignment shape in an orchestration, but as I said above, if you can avoid the load, why not?

  1. Create a schema with a root node and a child field element node of string Data Type
  2. Create a map which references your schema(s)
  3. Add the xml schema to be converted as the source schema of your map
  4. Add the new schema as the destination schema
  5. Add a scripting functoid to the map
  6. Connect the Root node of the source schema and the string data type (not the root) node of the source schema
  7. Configure the scripting functoid (right-click, configure functoid script, Script functoid configuraiton) and choose Inline XSLT Call Ttemplate
  8. Add the following script to the functoid: <xsl:template name="xml-to-string-called-template">
       <xsl:param name="param1" />
              <xsl:element name="ns0:NameofNodetoHoldString">
                    <xsl:text disable-output-escaping="yes">&lt;![CDATA[</xsl:text>
                    <xsl:call-template name="identity" />
                    <xsl:text disable-output-escaping="yes">]]&gt;</xsl:text>
               </xsl:element>
    </xsl:template>
    <xsl:template name="identity" match="@*|node()">
       <xsl:copy>
    <xsl:apply-templates select="@*|node()" />
       </xsl:copy>
     </xsl:template>
  9. Test the map, and your whole source xml would have been nicely converted into a string and added  into the string node within the CDATA! section (which tells the processing receiver that everything within those should be treated as strings)



Thursday, November 3

WCF / Web Service Serialization Error:Unable to generate a temporary class (result=1)

This was a funny one to fix:

Sometimes, when you consume a web service from within a wcf service or some other form of calling client application, trying to use the WSDL from the seb service gives the error described above.

This is due to serialization errors in the proxy code generation process. This is especially prevalent in cases where you are working with unbounded nodes from the xml files generated by the web service in BizTalk

According to Microsoft, "the Web Services Description Language tool (Wsdl.exe) generates proxy code for XML Web services. The generated types that are used in the proxy class are based on the contents of the WSDL document that describes the XML Web service. However, the generated types might not be what you want nor what you expect.

Wsdl.exe determines the best generated type to use for the objects that are specified in the service description. In some cases, the tool uses a least-common-denominator approach for casting objects to a type. For example, an ArrayList parameter in a WebMethod is described in WSDL as a XML Schema (XSD) sequence. When Wsdl.exe finds this array description in the service description, Wsdl.exe then generates a proxy class that uses an Object Array. You may prefer to work with an ArrayList, which was the original type that was used in the WebMethod. If you do not want to use the generated types, you can change the generated types to more desirable types. To get the appropriate object type, you can open the file that contains the generated proxy class, manually change the generated method parameter, and then return types to the appropriate object types"


Basically, what this means is if you add a service reference to a client applicaiton using the web service URI for example, you will generate some files from the wsdl of the web service.

If you browse to your application folder (the client application) on your computer, you should see a service references folder containing the folder for the particular service reference relating to the web service causing the error. In this folder, look for the reference.cs file and replace all the '[][]' with '[]'.

Save the file and close it. Next time you call the web service, you should not get the error above.

Sunday, October 30

Unable to load DLL 'BAUtil.dll': Invalid access to memory location error when using a 32-bit host with a domain group in BizTalk Server

Following on from this post, when you change the Host Instance to a 32-bit host, you may get the error described above. Something like -  "Unable to load DLL 'BAUtil.dll': Invalid access to memory location. (Exception from HRESULT: 0x800703E6)"
This issue occurs if the domain user account that is configured as the BizTalk host instance cannot read the following registry key: HKEY_LOCAL_MACHINE\Software\Microsoft\BizTalkAdapters\Config.

Basically, cthe biztalk applicaiton users group user that you used to configure the host instance is typically not a member of any group on the local computer (the BizTalk Server Machine), and therefore is restricted on the BizTalk Server Machine.

Depending on security considerations, one quick fix is to add the BizTalk Applicaiton Users group to local Administrators on the local machine. This is not the recommended approach, but could at least allow a quick fix in emergency situaitons and / or troubleshooting situations

The Microsoft recommended approach as seen in this post is to modify the registry by granting Read permissions on the registry key HKEY_LOCAL_MACHINE\Software\Microsoft\BizTalkAdapters\Config.

  1. Click Start, click Run, type Regedit, and then click OK.
  2. Locate the following registry key:
    HKEY_LOCAL_MACHINE\Software\Microsoft\BizTalkAdapters\Config
  3. Right-click the registry key that you located in step 2, and then click Permissions.
  4. On the Security tab, click Add.
  5. Type the domain group or the domain user account that is configured as the BizTalk host instance, and then click OK.
  6. On the Security tab, click the domain group or the domain user account that you added in step 5, click to select the Read check box, and then click OK.
  7. Exit Registry Editor.

Friday, October 28

Microsoft.BizTalk.Adapters.CoreTransmitter.dll Not Found error when using the BizTalk Enterprise Adapter for PeopleSoft

There are numerous white papers on the BizTalk Enterprise Adapter for PeopleSoft. It is a wonderful tool, but unfortunately, none of these white papers thoroughly covers the challenges you may face in getting it up and running.


This post continues from this post in explaining some challenges you might face whilst using this Adapter, with the solutions I discovered.


Also read this post for the next error you are likely to encounter


When using the adapter Enterprise Adapter for PeopleSoft with BizTalk Server 2010 on a 64 bit server like Windows 2008 server, you will most likely get an error of the type:


The Messaging Engine failed to create the transport adapter "PeopleSoft".
OutboundAssemblyPath: "NULL"
OutboundTypeName: "Microsoft.BizTalk.Adapters.PeopleSoftTransmitter, Microsoft.BizTalk.Adapters.CoreTransmitter, Version=1.0.5025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
Exception Details: "Could not load file or assembly 'Microsoft.BizTalk.Adapters.CoreTransmitter, Version=1.0.5025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The system cannot find the file specified."



For me, a search through the Internet produced little or no results.This error is actually caused because the dll it is seeking is a 32-bit dll and it is in the 32-bit GAC in C:\Windows\Assembly.


In order to use this dll, you therefore need to configure your PeopleSoft port to use a 32-bit Host. In my case, Sendhost was our default host, running in 64-bit mode. All our hosts were specifically allocated as we had a whole host of applications. I created a new host (in this case the BizTalkServerApplication host, as we had no need for it before now). I set the host to run in 32-bit mode and created a new host instance running on the domain app users group
  1. Open BizTalk Server Administration Console
  2. Open the BizTalk Group
  3. Open Platform Setings and Right-click on Hosts, select New, Host
  4. Type a name for the host (BizTalkServerApplicaiton in my case, but most times, this host would already be in use, so you can create a new host with a descriptive name of your choosing)
  5. Select In-Process for the Host Type, and tick the 32-Bit Only box for the mode under Options
  6. In the Windows Group box, type in your BizTalk Application Users Group (If you're in a large organization, then this would most likely be a domain group like it was in my case - read the next post for a fix to the error that is generated for domain groups). Click Apply and OK
  7. Right-click on the new Host you have just created, select New, Host Instance
  8. For the Server, select the correct server instance and click on the Configure button
  9. For the Logon and password , enter the credentials for a BizTalk instance user in the BizTalk Application Users Group (I'm afraid the correct setup of the BTS Application Users Group is out of the scope of this post). Click OK, Apply and OK
  10. Start the new Host Instance (Right-click and click Start)
Go back to your PeopleSoft port (the one you created by following the configuraiton instructions in my previous post).


Right-click on the port, click on Properties and change the Send Handler to the new host


This should fix the error described above.


Next post: Error message 'Unable to load DLL 'BAUtil.dll': Invalid access to memory location' error when using a 32-bit host with a domain group in BizTalk Server

Thursday, October 27

Force an exception with a Throw Exception shape and send the notification using the ESB Portal from an Orchestration Send Port

Sometimes you might wish to force your application to throw an exception if the processing logic goes down a certain decide branch, just to inform the tester or support administrator that the message is being terminated according to plan. the example below forces an exception and sends customized information to the ESB portal

Looking at the post, some might wonder why the scope and exception block? Well, ESB has a known bug - if you try to use the message assignment expression used below outside an exception handler, you will create an endless loop on your host instance. This bug is better described here

1.       In your orchestration, add a reference to Microsoft.Practices.ESB.ExceptionHandling and Microsoft.Practices.ESB.ExceptionHandling.Schemas.Faults (Open your project, Richt-Click on References à Add Reference à .Net)
2.       Create a Scope of transaction type None. Create a variable of .Net type System.ApplicationException (found in mscorlib) called excApplication
3.       Add an Expression Shape called ‘CreateException’ in this scope
4.       Add a Throw Exception Shape called ‘ThrowException’. In the Throw Exception Shape properties, enter the exception object you created above as the exception object type (i.e. excApplication)
5.       Create an orchestration Message called ‘msgESBFault’ of type Microsoft.Practices.ESB.ExceptionHandling.Schemas.Faults.FaultMessage
6.       Right-click on the scope and add a new Exception Handler called ‘ThrowExceptionHandler’
7.       In the Exception properties, enter exApplicationobj as the exception object name
8.       In the Exception properties, Select  System.ApplicationException as your exception object type (found in .Net Exception à mscorlib à system à ApplicationException)
9.       Add a Construct Message Shape called ‘ConstructESBFaultmsg’ with Message Assignment Shape  called ‘AssignESBFaultmsg’ and Send Shape called ‘SndESBFaultmsg’
11.    Add ‘Microsoft.Practices.ESB.ExceptionHandling.Schemas.Faults.FaultMessage’ as the Message Type of the direct send port’s Operation
12.    In the Message Assignment shape, generate the ESB fault message and the ESB message such as:
// create new fault message msgESBFault=Microsoft.Practices.ESB.ExceptionHandling.ExceptionMgmt.CreateFaultMessage();
// set fault message properties
msgESBFault.FaultCode="0202";
msgESBFault.FaultDescription="Exception notification from branch <branch descriptor> of orchestration <orchestration name>" + System.Environment.NewLine + "InnerXML is: " + exApplicationobj.InnerException.ToString();
msgESBFault.FailureCategory="Exception notification from branch <branch descriptor> of orchestration <orchestration name>";
msgESBFault.FaultSeverity=Microsoft.Practices.ESB.ExceptionHandling.FaultSeverity.Information;
//Add the fault message to the original message
Microsoft.Practices.ESB.ExceptionHandling.ExceptionMgmt.AddMessage(msgESBFault, <Originalmsg>);
13.    Connect the send shape ‘SndESBFaultmsg’ to the direct send port

Create a Delivery Failure Exception Catching Process from an Orchestration Send Port using the ESB Portal

Note that, as explained in posts including this post by Kevin B Smith in 2004, the performance cost of using delivery notifications can be up to 50% depending on design. Therefore, for Request-Response ports, you can use the SOAP error handling capabilities instead of using delivery notification
  1. In your orchestration, add a reference to Microsoft.Practices.ESB.ExceptionHandling and Microsoft.Practices.ESB.ExceptionHandling.Schemas.Faults (Open your project, Richt-Click on References à Add Reference à .Net)
  2. Create a Scope of Transaction Type ‘None’. You can also set the scope synchronization to true depending on your requirements. (This will suspend processing of the orchestration until the acknowledgement (Ack/Nack) has been received for the transmitted message)
  3. Add your operations for which you wish to catch the exception in this scope (make sure any messages to be used in the exception catching block are created outside this scope, though they can also be created within the scope if they must be, but some extra steps will be needed to initializie the message properly)
  4. On the Send port from which you wish to capture the delivery failure exception, in the properties, change the ‘Delivery Notification’ Type to ‘Transmitted
  5. Create orchestration Message called ‘msgESBFault’ of type Microsoft.Practices.ESB.ExceptionHandling.Schemas.Faults.FaultMessage
  6. Right-click on the scope and add a new Exception Handler
  7. In the Exception properties, Enter ‘DeliveryExceptionobjmsg’ as the Exception Object Name (or a name of your choosing)
  8. In the Exception properties, Select .Net Exception type Microsoft.XLANGs.BaseTypes.DeliveryFailureException as the Exception Object Type
  9. Add an Expression Shape called ‘WriteTraceLog’, a Construct Message Shape called ‘ConstructESBFaultmsg’ and a Send Shape called ‘SndESBFaultmsg’.
  10. Within the construct message shape, add a Message Assignment shape called ‘AssignESBFaultmsg’.
  11. Add a direct-bound Send Port ‘ESBFaultPort’ of Type ESBFaultPortType (See step 11 in earlier post Create a Soap Exception Catching Process from an Orchestration Request-Response Port using the ESB Portal)
  12. Add ‘Microsoft.Practices.ESB.ExceptionHandling.Schemas.Faults.FaultMessage’ as the Message Type of the direct-bound send port’s Operation
  13. In the Message Assignment shape, generate the ESB fault message and add your original message (from the actual scope) such as:
    // create new fault message msgESBFault=Microsoft.Practices.ESB.ExceptionHandling.ExceptionMgmt.CreateFaultMessage();
    // set fault message properties
    msgESBFault.FaultCode="0202";
    msgESBFault.FaultDescription="Delivery notification from port <portname> " + System.Environment.NewLine + "InnerXML is: " + DeliveryExceptionobjmsg.InnerException.ToString();
    msgESBFault.FailureCategory="Delivery notification from port <portname>";
    msgESBFault.FaultSeverity=Microsoft.Practices.ESB.ExceptionHandling.FaultSeverity.Severe;
    //Add the fault message to the original message
    Microsoft.Practices.ESB.ExceptionHandling.ExceptionMgmt.AddMessage(msgESBFault, msgFromOutsideScope);
  14. Connect the send shape ‘SndESBFaultmsg’ to the direct send port
  15. In the Expression shape called ‘WriteTraceLog’, add the event log entry and debug helper messages such as:  System.Diagnostics.Trace.WriteLine("Delivery notification from port <portname>");

WCF errors: simple jargon-free problem and solution approach

There are lots of big terms in internet posts about WCF but it is actually a very simple concept once you can achieve an understanding of it's fundamental ideology. Getting to the core of the methodology can be very daunting for beginners. I just thought I'd make a growing journal of errors I encountered in my first WCF implementations (which I have just discovered nicely noted in one of my old work journals. Hope these will help asomeone out there at some point....

P: You get the error The message could not be processed because the action 'http://schemas.xmlsoap.org/ws/2005/02/trust/RST/SCT' is invalid or unrecognized” when trying to implement wshttpbinding configuraiton with establishsecuritycontext set to false

S: Most likely caused because your ser4vice reference did not update the establishSecurityContext attribute of the Message element in the binding configuration. This is a VS bug
In your client configuraiton (app.config) manually add the establishSecurityContext="true" attribute to the message node of the security element for the relevant binding. e'g
<message clientCredentialType="Windows" negotiateServiceCredential="true"establishSecurityContext="true" algorithmSuite="Default" />

P: when using the svcutil tool to generate metadata from a wsdl, you get an error of the type "the t option requires that a value be specified"
S: You have most likely added a space between the /t and :metadata in the svcutil.exe command syntax. Remove the space so the command is of the form 'svcutil.exe /t:metadata http:/getme/data.wsdl (where http/getme/data.wsdl is the url of the service wsdl). See this link for more information  on the tool


P: After making changes to a BizTalk IIS-hosted WCF service, when trying to use the service from a client you get constant timeouts. On checking events, you find the BizTalk error "The Messaging Engine received an error from transport adapter "WCF-CustomIsolated" when notifying the adapter with the BatchComplete event. Reason "Attempted to access an unloaded AppDomain."."
S: Reset IIS


P: When publishing your BizTalk application as a wcf service, you get an error of the sort "The Messaging Engine failed to register an adapter.... 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 "
S: You need to create a new applicaiton pool for the service. An isolated host instance can run only one adapter. If you configure the receive handlers of HTTP and SOAP adapters with the same isolated host, you must create two application pools, one application pool for each adapter


P: 'An existing connection was forcibly closed by the remote host' error when using a wcf service - more often than not occurs with large files…”
S: The first port of call for this is to amend your web.config file in the wcf service and increase the maxBufferPoolSize and maxReceivedMessageSize in your binding configuration. (If connecting from BizTalk, you should also increase these values in your port binding configuration from the default .Net value of 65, 356 bytes. This is not the probem in this case anyway, as this would have given you a different error). Setting the attribute transferMode="Streamed" in this section also helps to minimize memory impact

In my case, I was using a WCf service as a wrapper for extra protection to modify and send an xml file to an old-fashioned xmlhttpRequest web page hosted in PeopleSoft. the configuration above (which I had already done when building the wcf service anyway) did not solve the problem. If changing those settings does not work, add a httpruntime config setting in the System.Web section of your web.config file as shown below, using values that work more with your expected message size etc:

<httpRuntime executionTimeout="90" maxRequestLength="200000000" useFullyQualifiedRedirectUrl="false" minFreeThreads="8" minLocalRequestFreeThreads="4" appRequestQueueLimit="100"/>
  </system.web>


P: Trying to load a WCF web service and getting error similar to “the runtime is built with a newer runtime…”
S: Browse to Application Pool in IIS (double click) and change the runtime to the same runtime as the one specified in your web service web.config file’s target framework declaration
(e.g. targetFramework="4.0") – This solution may lead to the next error

P: When trying to browse your web service svc file in a IIS hosting environment, you get the error HTTP Error 500.21 - Internal Server Error
Handler "svc-Integrated" has a bad module "ManagedPipelineHandler" in its module list
S: IIS is not properly registered with visual studio – Open visual studio command prompt (run as administrator if using Vista) and type aspnet_regiis.exe –i

P: trying to browse your web service svc file in a IIS hosting environment, you get the error ‘The protocol 'net.pipe' is not supported’
S: IIS 5 and 6 only support http-based bindings. Remove any bindings that do not use one of the http-based protocols to remove this error

P: wcftestclient command runs your client successfully, but once in IIS environment, you get the error ‘Failed to add a service. Service metadata may not be accessible. Make sure your service is running and exposing metadata.’
S: You need to add a metadata exchange (mex) endpoint to your service config file:
Something like:
<services> 
   
<service name="NewService.Service1" behaviorConfiguration="metadataBehavior"> 
     
<endpoint  
         
address="http://localhost/MyService.svc"  
         
binding="customBinding" bindingConfiguration="jsonpBinding"  
         
behaviorConfiguration="MyService.MyService" 
         
contract="MyService.IMyService"/> 
     
<endpoint  
         
address="mex"  
         
binding="mexHttpBinding"  
         
contract="IMetadataExchange"/> 
   
</service> 
</services> 

P: you want to create a wcf service but you don't want the default tempuri.org namespace on your generated schemas
S: You need to add a namespace attribute to your ServiceContract declaration:
Something like:
[ServiceContract( Namespace = "http://www.mynamespace.com/myfunctions.anythingelse" )]

Create a Soap Exception Catching Process from an Orchestration Request-Response Port using the ESB Portal

  1. In your orchestration, add a reference to Microsoft.Practices.ESB.ExceptionHandling and Microsoft.Practices.ESB.ExceptionHandling.Schemas.Faults (Open your project, Richt-Click on References > Add Reference > .Net and double-click on Microsoft.Practices.ESB.ExceptionHandling and use the same process for Microsoft.Practices.ESB.ExceptionHandling.Schemas.Faults )
  2. In your orchestration, create a Scope of Transaction Type ‘None’
  3. Add your operations for which you wish to catch the exception in this scope (make sure any messages to be used in the exception catching block are created outside this scope, although the message can also be created within the scope if necessary, in which case extra steps will need to be taken to initialize the message)
  4. On the Request-Response port from which you wish to capture the soap exception, Right-click on the port Operation and create a new orchestration Message called ‘Soapfaultmsg’ of Type ‘BTS.soap_envelope_1__1.Fault’. (you can find this type in Referenced Schemas à Microsoft.BizTalk.globalPropertySchemas)
  5. Create an orchestration Message called ‘msgESBFault’ of Type Microsoft.Practices.ESB.ExceptionHandling.Schemas.Faults.FaultMessage (Schemas >Select from referenced assemblies)
  6. Create orchestration Message called ‘msgSoapFault’ of type System.Xml.XmlDocument
  7. Right-click on the scope and add a new Exception Handler called ‘CatchSoapException’
  8. In the Exception properties, Enter ‘SoapExceptionobjmsg’ as the Exception Object Name (or any other descriptive name you choose)
  9. In the Exception properties, Select ‘<Your Request-Response Port>.<Your Request-Response Port Operation>. Soapfaultmsg’ as the Exception Object Type
  10. In the Exception Handler, add an Expression Shape called ‘WriteTraceEventLog’, Construct Message Shape called ‘ConstructESBFaultmsg’ and a Send Shape called ‘SndESBFaultmsg’. In the construct message shape, add a Message Assignment Shape called ‘AssignESBFaultmsg’
  11. Add a direct Send Port ‘ESBFaultPort’ of Type ‘ESBFaultPortType’ (See steps below)
    • Add a Send Port Shape to the left or right Port Surface in the orchestration designer
    • On the ‘Welcome To The Port Configuratio’n page that opens up in the Port Configuration Wizard, click Next
    • In the Port Properties, enter ‘ESBFaultPort’ as the port name. Click Next
    • On the ‘Select A Port Type’ page, select ‘Create a new Port Type’, in the ‘Port Type Name’ field, enter ‘ESBFaultPortType’, Select ‘One-Way’ as the port Communication Pattern and leave the ‘Access Restrictions’ on the default (Internal). Click Next
    • On the ‘Port Binding’ page, In the ’Port direction of Communication’ drop-down, select ‘I’ll always be sending messages on this port’. In the ‘Port Binding’ drop-down, select ‘Direct’ as the binding method. Leave the default values. Click Next
    • On the ‘Completing the Port Wizard’ page, click Finish
  12. Add ‘Microsoft.Practices.ESB.ExceptionHandling.Schemas.Faults.FaultMessage’ as the message type of the direct send port’s Operation (see step 5 above)
  13. In the Message Assignment shape, generate the ESB fault message and add your original message (from the actual scope – see full sample for more information) such as:
    msgSoapFault = SoapExceptionobjmsg;
    // create new fault message msgESBFault=Microsoft.Practices.ESB.ExceptionHandling.ExceptionMgmt.CreateFaultMessage();
    // set fault message properties
    msgESBFault.FaultCode="0001";
    msgESBFault.FaultDescription="SOAP Exception whilst requesting Information from blah-blah system:" + System.Environment.NewLine + "InnerXML is: " + msgSoapFault.InnerXml.ToString();
    msgESBFault.FailureCategory="SOAP Exception whilst requesting Information from wcf service";
    msgESBFault.FaultSeverity=Microsoft.Practices.ESB.ExceptionHandling.FaultSeverity.Severe;
    //Add the fault message to the original message Microsoft.Practices.ESB.ExceptionHandling.ExceptionMgmt.AddMessage(msgESBFault, msgFromOutsideScope);
  14. Connect the send shape ‘SndESBFaultmsg’ to the direct send port ESBFaultPort
  15. In the Expression shape called ‘WriteTraceEventLog’, add the event log entry and debug helper messages such as:  System.Diagnostics.Trace.WriteLine("SOAP Exception whilst requesting Information from <The SOAP Port Service> system"); System.Diagnostics.EventLog.WriteEntry("<Your Application Name>", "SOAP Exception whilst requesting Information from <The SOAP Port Service> system");
Note: To use the event log, you must ensure your BizTalk instance user has sufficient permissions to write to the host system's event log, otherwise, omit the 'System.Diagnostics.EventLog.WriteEntry' line

Monday, October 24

Adding the PeopleSoft Adapter for Enterprise Applications to BizTalk Server 2010 + Adapter Configuration Information

There are numerous white papwrs on the BizTalk Enterprise Adapter for PeopleSoft. It is a wonderful tool, but unfortunately, none of these white papers thoroughly covers the challenges you may face in getting it up and running. I will try to explain some challenges you might face whilst using this Adapter in the next few posts, with the solutions I discovered.

Please follow up by also reading this post and this post for solutions to challenges you will most likely face if you are using a similar to environment to mine (i.e. BizTalk Server 2010 and Windows Server 2008 R2)

Once you have finished the process below, you can use the adapter by following the steps at this link: http://msdn.microsoft.com/en-us/library/aa995588.aspx. (I will try to find the time to create another post on the steps at some point)

At design time, the BizTalk Server 2010 PeopleSoft LOB adapter evaluates the PeopleSoft Component Interfaces on the PeopleSoft server and exposes a listing of these APIs which can then be consumed within BizTalk Server 2010. This adapter is a send adapter, and is used for initiating calls to PeopleSoft from BizTalk Server. However, note that while the PeopleSoft LOB adapter does not handle retrieving data from PeopleSoft directly, the send handler from BizTalk Server can be used to initiate a request for information using the Get or Find methods of the Component Interfaces exposed by the adapter, provided that the appropriate requesting parameters (keys, guids etc.) are made available
  1. Install the Enterprise Applications Adapters
    1. Double-click ‘Setup.exe’ from your enterprise applications adapters installation pack
    2. Select ‘Install Microsoft BizTalk Adapters’
    3. Click on ‘Step 4: Install Microsoft BizTalk Adapters for Enterprise Applications’
    4. Use the default settings to install the adapters

  2. Register the PeopleSoft Enterprise adapter with the BizTalk Server 2010 Instance
    1. Click Start, point to Programs, point to Microsoft BizTalk Server 2010 and then click BizTalk Server Administration
    2. Expand BizTalk Server Administration, expand BizTalk Group, expand Platform Settings, and then expand Adapters
    3. Right-click Adapters, point to New, and then click Adapter
    4. Enter a Name for the adapter. e.g, PeopleSoft
    5. From the Adapter list, select the adapter, and then click OK
    6. The prompt reads “This configuration changes requires host instance restart. Please restart the associated host instances for the changes to take effect." Click OK to finish the configuration.
    7. From the BizTalk Server 2006/2009 Administration console, navigate to BizTalk Server 2010 Administration -> BizTalk Group -> Platform Settings-> Host Instance
    8. Right-click BizTalkServerApplication, and then click Restart. BizTalkServerApplication is the typical default in-process host instance. If you assigned the adapter to a different host instance, you must restart that host instance instead.

  3. Install the Sun Java JDK
    1. Although BizTalk Server 2010 is built on the Microsoft .NET Framework, the connection of the PeopleSoft LOB adapter into the PeopleSoft application uses Java, and communicates with BizTalk Server using the PeopleSoft JOLT transaction protocol. This is especially evident when configuring the port because it is necessary to reference several JAR file locations in addition to the PeopleSoft connection information
        
      For this reason, the Java Development Kit (JDK) also needs to be installed
      • Download the latest JDK rom Sun microsystems (current version is JDK 7, but I only got a successful connection with jdk 6 in my case at first. I later realised this was because I needed the 32 bit version of the JDK 7 even though I am running on a 64-bit OS - Windows 2008 R2. I installed the 32-bit version of the JDK 7 and got it to work)
      • Double-click the downloaded JDK file (jdk-6-windows-i586.exe and thewn jdk-7-windows-i586.exe in my case) executable. You must have administrative permissions in order to install the JDK on Microsoft Windows)
      • Install the components you need – note the location of the installation (typically something like C:\Program Files (x86)\Java\jdk1.7.0)
      • Set the PATH environment Variable.(You can run the JDK without setting the PATH environment variable, or you can optionally set it so that you can conveniently run the JDK executable files (javac.exe, java.exe, javadoc.exe, and so forth) from any directory without having to type the full path of the command. If you do not set the PATH variable, - I didn't - you need to specify the full path to the executable file every time you run it, in the port configurations)
        1. To set the PATH environment variable, Click Start, then Control Panel, then System
        2. Click Advanced System Settings, then Environment Variables
        3. Under ‘System Variables’, scroll to PATH and Add the location of the bin folder of the JDK installation at the end of the PATH variable. The PATH environment variable is a series of directories separated by semicolons (;) and is not case-sensitive

          The following is a typical value for the PATH variable: C:\WINDOWS\system32;C:\WINDOWS;C:\Program Files\Java\jdk1.7.0_01
  4. Configure the adapter

    1. The PeopleSoft adapter requires that the send and receive pipelines use the default XML pipelines of XML Transmit and XML Receive respectively
    2. The adapter uses transport properties (see Tables 1 and 2) to connect to PeopleSoft. One important characteristic to note about these transport settings is that the values are case sensitive. Take care when specifying the properties
                                                    

      Figure 1 – Adapter Properties

    Transport Property

    Description / Example
    Application Server PathThe name of the computer and port on which the PeopleSoft application server is running and listening. The syntax of the URL path to the PeopleSoft 8 application is //<machine_name>:<port>

    The <port> value is the JOLT protocol Listener port, not the App Server port. The default JOLT port is 9000.
    JAVA_HOMEThe location where the JDK was installed.

    For example: C:\Program Files (x86)\Java\jdk1.7.0. (Not required if you set up the environment PATH variable as described in step 3d above
    PasswordThe user’s password used to access the PeopleSoft system. The characters do not appear but are represented by asterisks (*).

    This is required only if you are not using Enterprise Single Sign-On (SSO).
    PeopleSoft 8x JAR FilesThe location of the psjao.jar file on the PeopleSoft server.. (I copied the psao.jar file from the PeopleSoft server onto the BizTalk server in my case, so I ecreated a folder for it and entered it as C:\PSJarLoc\psjoa.jar)

    For example: C:\PeopleSoft\psjoa.jar or \\<PeopleSoft Server>\web\psjoa\psjoa.jar

    The psjoa.jar file is unique to each version and installation of PeopleSoft. This file is typically located at <PeopleSoft_Home>\web\PSJOA\psjoa.jar.
    User NameThe user’s login name used to access the PeopleSoft system.

    This is required only if you are not using SSO

    Table 1 – Required Transport Properties

    Transport Property
    Description / Example
    Database date format
    The default format is YYYY-MM-DD - When a date is used as a key value, it may have a different format which needs to tally with the format on the PeopleSoft database.

    Max Concurrent Calls

    Default is 5 - This value specifies the maximum number of concurrent calls that can be made on this send port. If the number of calls exceeds this value, the additional requests will become dehydrated until processing threads become available.

    –1 indicates an unlimited number of calls

    Maximum number of sessions
    Default is 40 - This determines the maximum number of sessions that can be connected to the server at one time

    - Sessions relate to the way in which a client connects to the server. For example, if the login credentials are the same, they use the same session. Concurrent calls relate to the number of simultaneous connections that can be made to a server at a time. You may need to limit the number of sessions based on the number of client licenses, whereas the number of concurrent calls impacts performance and is determined by back-end processing capabilities

    Event Log Level

    Error - This is the level of events that are to be recorded as they are encountered. The default value is Error. Possible values are Info (includes warnings and errors), Warning (includes errors), and Error.

    Refresh Agent

    Yes - When Yes is selected, the runtimeagent.exeand the browsingagent.exe processes will be restarted automatically as required. They are processes that the BizTalk Server runtime and Visual Studio.Net respectively invoke on the LOB adapters for metadata generation

    Affiliate application
    This value is created by Enterprise Single Sign-On tools and is used to represent an external application. The user credentials are stored in the SSO Credential database

    Use SSO – This value determines whether SSO is to be used or not

    Table 2 – Additional Transport Properties




Appendix: References and more reading:
http://msdn.microsoft.com/en-us/library/bb820917(v=bts.10).aspx
http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=16310
http://download.oracle.com/javase/7/docs/webnotes/install/windows/jdk-installation-windows.html
http://go.microsoft.com/fwlink/?LinkId=96136
http://hosteddocs.ittoolbox.com/KK022704.pdf
http://download.microsoft.com/download/1/6/9/16968441-c6c8-4bd0-9410-5f4014bc61f0/peoplesoft.doc