Blog Home  Home |  Breeze Home RSS 2.0 Atom 1.0 CDF  
Scott's Breeze Blog - RFID, BizTalk - Friday, June 06, 2008
...and everything in between
 
 Friday, June 06, 2008

Recently I implemented a BizTalk web services interface that required the need to support SoapFault messages. I quickly fell into a common trap and received a compiler error:

error X2162: must receive before sending a fault message on an implemented port

(see Scott Colestock's post that nicely outlines his experience with the same issue)

As Scott describes, the solution involved using the succeeded() function to first test if a transaction scope had succeeded or not in order to send out my soap-fault correctly. I vaguely recalled this function but never used it in anger before. After having spent a hour or so I will never get back, I made a note-to-self to seek out and reacquaint myself with the other operators and functions available to use in expression shapes within an orchestration.

Here is the full list taken from the online documentation:

Operator

Description

Example

checked()

raise error on arithmetic overflow

checked(x = y * 1000)

unchecked()

ignore arithmetic overflow

unchecked(x = y * 1000)

new

create an instance of a class

myObject = new MyClass;

typeof

Type retrieval

myMapType = typeof(myMap)

succeeded()

test for successful completion of transactional scope or orchestration

succeeded(<transaction ID for child transaction of current scope or service>)

exists

test for the existence of a message context property

BTS.RetryCount exists Message_In

+

unary plus

+(int x)

-

unary minus

-(int x)

!

logical negation

!myBool

~

bitwise complement

x = ~y

()

cast

(bool) myInt

*

times

Weight = MyMsg.numOrders * 20

/

divided by

x / y

+

plus

x + y

-

minus

x - y

<<

shift left

x << 2

>>

shift right

x >> 2

<

less than

If (MyMsg.numOrders < 10)...

>

greater than

If (MyMsg.numOrders > 10)...

<=

less than or equal to

If (MyMsg.numOrders <= 10)...

>=

greater than or equal to

If (MyMsg.numOrders >= 10)...

==

equal to

If (MyMsg.numOrders == 10)...

!=

not equal to

If (MyMsg.numOrders != 10)...

&

and

If (myByte & 255)...

^

exclusive or

If (myByte ^ 1)...

|

or

If (myByte | 1)...

&&

conditional and

If (MyMsg.numOrders > 10) && (MyMsg.numOrders < 100)

||

conditional or

If (MyMsg.numOrders < 10) || (MyMsg.numOrders > 100)

//

commenting

//This is the comment

Since then, this little exercise has helped in a few occasions, particularly the need for the exists function when working with optional property schema fields.

I knew I should of read the manufacturers instructions smile_wink

6/6/2008 12:42:47 AM (AUS Eastern Standard Time, UTC+10:00)  #    Comments [0]   BizTalk General  |  Trackback
 Tuesday, May 27, 2008

Today I was working on a BizTalk solution to intercept, transform, and relay emails sent from a LOB system. BizTalk polled a POP3 mailbox and my orchestration replaced the original plain/text email body with some fancy, template driven HTML content and sent it out a dynamic SMTP send port. Only the email body was to be modified, the rest of the email message was to replicate the original email message, including any attachments (that may or may not be present).

To aid in testing I wrote a simple .Net email client. (I got tired of composing a new email in Outlook every time I wanted to test the solution)

Breeze Simple Email Client

The solution worked well (and perhaps I may post about the details sometime later) accept for the fact the outbound message had lost the attachment filenames.

inbound showing attachment

outbound showing attachment

Note: The attachment on the outbound message has a filename of ATT00241.DAT smile_confused

A helper class in my orchestration inspected the inbound message for attachments and added them to the new outbound message. Each message part (attachment) was assigned the MIME message part context properties of the same inbound message part. What I found was the MIME.FileName property was not being populated by the MIME decoder.

The MIME decoder in the POP3 adapter (when configured to apply MIME decoding) populates the following message part context properties when a MIME encoded message is received:

MIME/SMIME Property Schema and Properties

I checked the message source of the email I was sending (via my DIY email client) to check the MIME headers were present.

incorrect message source

Appears OK right?...

content-type: application/octet-stream; name=SampleAttachment.zip
content-transfer-encoding: base64

Wrong smile_embaressed

It turns out the MIME decoder is looking for the content-disposition header values

content-type: application/octet-stream; name=SampleAttachment.zip
content-transfer-encoding: base64
content-disposition: attachment; filename=SampleAttachment.zip

So some quick changes to the Breeze Simple Email Client ...

attach.ContentDisposition.DispositionType = System.Net.Mime.DispositionTypeNames.Attachment
attach.ContentDisposition.FileName = Path.GetFileName(attachmentFileName)

...and we were back to cooking with gas.

correct message source

and now attachments on our outbound message retain their original filename...noysh!

outbound showing correct attachment

And BTW, not all commercial email clients populate these MIME headers correctly either (or so a friend of a friend who's aunt once knew someone that was talking to a girlfriend at the supermarket said). Check out the message source of items in your inbox. You might be surprised. smile_regular

Happy spamming er...umm...BizTalking

5/27/2008 12:10:09 AM (AUS Eastern Standard Time, UTC+10:00)  #    Comments [2]   BizTalk General  |  Trackback
 Monday, October 29, 2007

BizTalk RFID ships with the Business Rules Framework (commonly called the Business Rules Engine or BRE). BRE is a rules execution engine that allows you to dynamically create, publish, deploy, and execute policies without having to stop and restart running business processes. There is actually much, much more to BRE than my one sentence overview, but that is not what this post is all about.

In BizTalk RFID land, we can call our business policies within RFID Processes using the OOTB RuleEnginePolicyExecutor component. We can use business rules to filter and enrich RFID tag event data. Having created the policy, we add and configure an instance of the RuleEnginePolicyExecutor component to our RFID process. We configure the component to specify any database and/or xml facts to pass to the executing policy.

A good friend to business rule developers working with BizTalk RFID processes is the RfidRuleEngineContext class. It contains a number of properties and methods that make working with tag read event data very easy. An instance of this class is always passed to the executing policy by the RuleEnginePolicyExecutor component.

Ok, so there is some context for the post...

The Problem:

The other day, I had a BRE policy that, amongst other things, was updating SQL tables in some rule actions. I was calling the BRE policy from a BizTalk RFID process and all was working fine, until I noticed the database changes were not being made. I checked the process log file and verified the SQL update rule actions were firing...but the database facts were not being updated. Why?

Tip: Troubleshooting BRE policy execution within a RFID process is made easy by setting the process log level to Verbose. This writes all BRE tracking info to the process log file. smile_wink

In BizTalk Orchestrations, when we update database facts in rule actions, we had to manually commit the changes on the SQL Data Connection (using an expression shape, not the call rules shape).

The Solution:

In BizTalk RFID we can use the RfidRuleEngineContext.UpdateDataConnections method to commit all changes on the SQL data connection(s) used during policy execution (the database fact we configured at design time). Keep in mind the message handling reliability setting (sometimes called the Tag Processing Mode) of your RFID process. If you have set message handling reliability to Transactional, BizTalk RFID will create a transaction scope over all event handlers in the process. That is, if any event handler fails, the transaction is aborted.

Mick's Tip: Include enlist=false; in your connection string when configuring the RuleEnginePolicyExecutor if you do not want your SQL data connection to participate in the transaction. smile_wink

The Business Rules Engine is a powerful tool in your BizTalk RFID toolbox. If you have never used it before, check out the Walkthroughs for Creating and Using Policies in RFID Processes in the online help. There is also a great sample in the SDK as well.

10/29/2007 10:10:14 PM (AUS Eastern Standard Time, UTC+10:00)  #    Comments [0]    |  Trackback
 Sunday, October 21, 2007

If you are receiving this error when validating your RFID process and don't know why, or you have never seen this error before, read on as it just might save you some pain...

RFID Processes - 101 smile_nerd

RFID Processes consist of device bindings and component bindings. The device bindings link physical RFID devices to logical devices. Component bindings define the event handlers that perform the processing. Conceptually, an RFID process looks something like this:

 

Source: Microsoft BizTalk RFID Online Help

When PhysicalDevice1 raises an event, it is sent via LogicalDevice1 to EventHandler1 for processing. EventHandler1 processes the event and passes the event data to EventHandler2. Event handlers can also terminate the event processing and not pass the event on. (but lets leave that for another post)

When we put together RFID Processes that consist of multiple event handlers, we need to ensure that each event handler in the process can accept the event(s) passed from the previous one.

Back to the Problem

BizTalk RFID will throw "The process has a component that is not reachable..." error when it determines that an event handler in the process can not receive an event.

process validation error

This can happen in two ways:

  1. The device binding is not set and the event can not reach the first event handler.
  2. An event handler can not pass an event(s) to the next event handler in the pipeline.

And it is this last case that can cause the pain.

A Common Scenario

You have a RFID process with two event handlers. The OOTB SqlServerSink event handler (EH1) and a custom event handler (EH2). BizTalk RFID throws the above error when you try to save. Why?..

In this case the first event handler, SqlServerSink, is not designed to pass on events. It's event handler method has no output parameter. (check out the method signatures PostEventToSink and PostEventsToSink in online help) Event processing will always stop at the SqlServerSink component.

The solution: Move the custom event handler (EH2) ahead of the SqlServerSink (EH1) event handler to pass validation.

An Actual Scenario (that resulted in much loss of sleep)

I had a RFID process that used the OOTB event handler RuleEnginePolicyExecutor to call BRE policies from the process. The next event handler in the pipeline was my custom component that I had used in many processes before with no issue. The output type of the RuleEnginePolicyExecutor event handler method(s) is RfidEventBase[]. The event handler method on my custom component only accepted RfidEventBase as an input parameter. That is, the RuleEnginePolicyExecutor component was passing my custom component an array of events and I only supported a single event in my event handler.

The solution: Create another event handler method that accepts RfidEventBase[] as the input parameter. I iterated through the array calling my original event handler method. Now my component supports both scenarios.

Troubleshooting

So when you receive this error, examine the message to identify the component at fault. Check the event handler method signatures of this and the previous component. What you are looking for:

  1. The previous event handler passes on the event (i.e. has an output parameter)
  2. The event handler at fault can accept the event (i.e. has an input parameter type that matches the event type sent)

As event handlers can have more than one event handler method, ensure that the event handler at fault has an event handler method with the right input type for each of the output types of the previous component. This becomes quite complex when we consider pipelines mat contain multiple logical sources as well.smile_confused

Tip: The Custom Event Handler Project Template that shipped with the SDK Samples only implements event handlers that accept TagReadEvent and TagListEvent input types. You will need to implement another event handler that accepts RfidEventBase[] as an input type to use your component with the RuleEnginePolicyExecutor component.

10/21/2007 11:42:35 PM (AUS Eastern Standard Time, UTC+10:00)  #    Comments [0]    |  Trackback
 Tuesday, October 16, 2007

For those early adopters who grabbed the DLP Design RFID Reader/Writer and launched into the wonderful world of BizTalk RFID in Beta 2, there may be a rude shock when you install the RTM...the device provider fails to install.

dlp provider fails to install

Ok, so don't panic. Here are the re-built DLP Design DSPI provider assemblies.

If you want to explore BizTalk RFID a little deeper then follow the steps below to re-build the DSPI provider from source.

If you haven't already, download the source for the DSPI provider. Mick Badran kindly linked to them in a blog post not so long ago. Unpack the compressed file and open the solution in VS 2005.

Take a look at the project references

DlpDesign references

Refresh the references to Microsoft.Rfid.SpiSdk and Microsoft.Rfid.Util assemblies found in the BizTalk RFID bin folder (C:\Program Files\Microsoft BizTalk RFID\bin for a typical install)

Build the project...Before you build, take a look at the project Build Events (Right-click DlpDesignDSPI project and select Properties). The build event uses the RfidClientConsole.exe command line tool to register and copy the DSPI assemblies to the Providers bin folder. Go explore the RfidClientConsole command line tool a bit more closely as you will cross paths with it frequently in BizTalk RFID land.

Ok...now Build the project.

In RFID Manager, the device provider should be installed and in the Registered state.

To those who are using the device simulator in BizTalk RFID, I fully recommend getting a physical RFID device, like the Dlp Design Kits we got. Actually swiping tags across the reader and seeing the HD led go nuts is a much better experience than clicking a button that's labeled "Pretend you swiped a tag"

Now you are back up and running. Enjoy!

10/16/2007 10:13:27 AM (AUS Eastern Standard Time, UTC+10:00)  #    Comments [0]    |  Trackback
 Thursday, October 11, 2007

So you have BizTalk Server 2006 R2 installed and are chomping at the bit to check out what BizTalk RFID is all about. Here is a quickstart guide to installing BizTalk RFID and some helpful pointers to get you up and running.

Prep Work

  • I'm assuming you have a typical BTS 2006 R2 developer install on a stand-alone or virtual machine. (although BizTalk RFID can be installed stand-alone!)
  • You have already downloaded the Install Guide.

Components of a BizTalk RFID Install

  • BizTalk RFID Server - Including Business Rules Engine - way cool!
  • BizTalk RFID Manager  - UI Administration Console (MMC snap-in)
  • RFIDSTORE - SQL Server Configuration and Management db
  • RFIDSINK - SQL Server Tag Events Sink db

We can choose to install each component on a single machine (as I have done on a development VM side-by-side with BTS 2006 R2) or you can slice and dice as you needs dictate. Perhaps moving the SQL DB's to remote machines, or even clustering the whole show is supported.

Types of Installs

  • Typical - Installs everything but the SDK
  • Custom - Roll your own install
    • Complete - Installs everything

      Tip: Choose the Complete install as you will definitely want the SDK.

      Pre-Requisites

      • MSMQ - Install via Add or Remove Programs > Windows Components
      • WSE 3.0 - Get it from here 

      Note: I assumed you have BTS 2006 R2 installed so pre-requisites for R2 have been met.

      Run the Installation Wizard

      Follow the install process and refer to the guide you downloaded first if you run into a hurdle. The only install issue I had was

      "Failed to execute deferred command line C:\Program Files\Microsoft BiztalkRFID\bin\ManagedCustomActions.exe "CreateADMarker".

      Ignore this as its relates to Active Directory. Only appears when installing to a workgroup machine (i.e. that is not on a domain) and is not an critical error.

      Post Install

      Tip: Change the default web site that BizTalk RFID uses

      During a typical install of BTS 2006 R2, Windows SharePoint Services is configured to use the default web site in IIS. BizTalk RFID uses IIS to host all process and device provider WCF services and, by default, also uses the default web site. WSS and BizTalk RFID do not play well together (In fact they refuse to even talk!)

      Although the solution is now documented in the Install guide, this is probably the number one gotcha and many hours and hair follicles have been lost already.

      Create a new web site in IIS

      1. In IIS, right-click the Web Sites node and select New > Web Site.
      2. Call your new site something like RFIDServices.
      3. Create a new folder under Inetpub called wwwrfid and choose it as the Path.
      4. Make sure Anonymous access is allowed.
      5. Select Read, Run scripts, Execute, and Browse access permissions.
      6. Finish the wizard.
      7. After the site is created, check the ASP.NET framework version is set to 2.0 (on the ASP.NET tab of the Properties dialog)

      Change Web Site ID

      When IIS creates a new site is generates a new web site identifier. We need to configure BizTalk RFID with the new web site ID.

      1. In IIS, select the Web Sites node.
      2. In the right-hand-side panel, note the identifier value listed.

      Nice 11 digit number...So lets change that to something easier to remember.

      1. Open a command window.
      2. Execute the following command replacing the <web site id> with your current web site id and <new web site id> with something like 3 (i.e. the next number)

        CSCRIPT %SYSTEMDRIVE%\Inetpub\AdminScripts\adsutil.vbs STOP_SERVER W3SVC/<web site id>
        CSCRIPT %SYSTEMDRIVE%\Inetpub\AdminScripts\adsutil.vbs MOVE W3SVC/<web site id> W3SVC/<new site id>
        CSCRIPT %SYSTEMDRIVE%\Inetpub\AdminScripts\adsutil.vbs START_SERVER W3SVC/<new site id>

      Configure BizTalk RFID to use new web site

      1. Launch BizTalk RFID Manager.
      2. Right-click on the server node, and select Properties.
      3. On the Advanced page, enter the new web site id.
      4. Ensure the other IIS settings are correct if you set non-default ones when you created the new web site above.
      5. Click OK.

      Now when you add a device provider or RFID process, BizTalk RFID will use your new, clean, web site to host the WCF services.

      Finished. Well done.

      Tip: The last tip tonight is also a gem. Here is the link to the BizTalk RFID Samples.

      They're all good, but particularly the Event Handler and Provider Project Templates. (a must for any self-respecting developer). Download them and go explore, play, and let me know how you get on.

      10/11/2007 12:10:53 AM (AUS Eastern Standard Time, UTC+10:00)  #    Comments [1]    |  Trackback
       Tuesday, October 02, 2007

      With the BizTalk R2 launch behind us now, it's time to grab hold of the BizTalk Server 2006 R2 Developer Edition from MSDN Subscriber Downloads. (available as of Wed 26th and not everyone was happy 'bout that)

      Don't forget to download the install guides.

      I could not wait, and installed the 120-day eval. I wanted to check out whether a few "undocumented features" I had with beta 2 magically disappear.

      To all those RFID followers, I will post shortly on getting started with BizTalk RFID and share some post install tips with you...

      10/2/2007 11:13:27 PM (AUS Eastern Standard Time, UTC+10:00)  #    Comments [0]    |  Trackback
      Copyright © 2008 Breeze Training. All rights reserved.