%Filename% macro is not replaced with the disk filename

I’ve seen this issue showing a couple of times on the BizTalk Newsgroups so I thought it’s worth posting about this on my blog. The user expectation, which is probably correct from usability point of view, is that the %Filename% macro is replaced with the name of the original file no matter if that file was received from the disk through FILE adapter or from a document library through SharePoint adapter. This doesn’t happen like that since the WSS adapter send ports will resolve the %Filename% macro to empty string if the message was originally received from any other adapter than WSS adapter. This is by design.


The %Filename% macro is replaced with the name of the SharePoint file (and not with the name of a file on disk). If the message was received through FILE adapter (or any other adapter than WSS) then the %Filename% macro is probably replaced with empty string. Macros (like %Filename%) and context properties (like WSS.Filename) are implemented by each adapter separately, they are specific to each adapter, and there is no ‘framework’ that would provide a unified set of macros/context properties accross all adapters. This makes sense since ‘%Filename%’ might not make sense for a POP3 adapter or it could have a slightly different behavior for 3rd party adapters. Coincidently, some adapters have used the same macro name (I would guess %Filename% is a common one) and ocasionally the same context property. However, the %Filename% macro in a WSS adapter send port is totally different from a %Filename% macro in an FTP adapter send port, for instance.


To workaround this you can use an orchestration or a custom pipeline. All you need to do is get the disk file name from FILE.ReceivedFileName property and save it in the WSS.Filename property like below. Make sure that the Filename field in the send port UI dialog box is left empty so that the value supplied through the context property WSS.Filename is used to set the filename.
   sharepointOutgoingMsg(WSS.Filename) = diskIncomingMsg(FILE.ReceivedFileName);


http://msdn.microsoft.com/library/en-us/BTS06Operations/html/1ff50fb8-7ba0-47b8-9476-d57413989346.asp?frame=true
http://msdn.microsoft.com/library/en-us/BTS06Operations/html/c5ae5339-67bf-4fde-a721-5b1aa3b9caca.asp?frame=true


You don’t have to use dynamic send ports for the workaround above. In the case of WSS adapter, you can define the send port configuration through the WSS.Config*, WSS.Filename context properties of the outgoing message and then configure the WSS send port equivalent properties so that they are either empty (text boxes) or have a value of Orchestration (drop-down boxes) in order to not overwrite the configuration information specified through the context properties.

Deployment Framework for BizTalk 2006…

(Update: The original download files were missing the PDB-to-GAC functionality
I’ve discussed before.  Please download again if you have already…)

The BizTalk
Deployment Framework has been updated to work with BizTalk 2006…It is hard to
believe that this project has been going on since May of 2004!

The Deployment Framework for BizTalk 2006 still has the same goals as the
2004 version:

  • Streamline the deployment process for developers, ensuring repeatability

  • Make it easier for a team of BizTalk developers to stay in sync – not just with BizTalk
    artifacts, but with all the other infrastructure that surrounds the solution (virtual
    directories, queues, file folders, etc.)

  • Extremely close parity between server-side deployments and developer deployments –
    so you are always testing your server deployments as you go through a typical developer
    work day.

BizTalk 2006 itself introduced quite a few features to make deployment easier, and
can work fine for small (or solo) projects.  Here are a few limitations I’ve
encountered:

  • Though much improved, it is still possible to get into “dependency chaos” – where
    you spend time manually undeploying/deploying individual artifacts.

  • Binding changes have to be communicated “manually” between developers on a team, since
    the import process is done through the Admin MMC or command-line.  Just “getting
    latest” from version control isn’t sufficient.

  • Binding files for your various environments have to be maintained as separate files
    (manually), rather than “merging in” environment-specific settings

  • Artifacts such as rules, virtual directories, queues, folders, additional dependent
    assemblies, etc. can be represented as “Resources” within the Admin MMC (and in exported
    MSIs), but not in a fashion that easily moves between developers on a team.

So!  To get started with this version, download the Deployment
Framework (Tools) zip and run the MakeBizTalkExternalTools_VS2005.vbs script. 
This will add entries to the Visual Studio tools menu for deploying and undeploying
using the framework.  You can download the full
sample to see the framework in action (first build it, then do Tools-BizTalk
Deploy.  You’ll see something like this.)

The high-level approach is the same as the 2004 framework – you supply a small project-specific
NAnt script that indicates via properties what elements of a deployment your solution
requires.  You include BizTalkDeploymentInclude.nant to get all the core deployment functionality,
and make sure the DeployTools directory is copied to your project.  (Unzipping
the Deployment
Framework Core into your project is a good way to do this.)  See the documentation for
a more complete discussion.

The primary difference in the upgraded framework for BizTalk 2006 is that
we now create a BizTalk Application definition, and use BTSTask to
add all BizTalk artifacts as resources within that application.  Starting and
stopping the application is done at an application level rather than per port/per
orchestration.

Packaging up your solution as an MSI can be done with the WiX-based scripts that have
been in the framework for awhile, or by using the MSI export mechanism in
BizTalk 2006, if you prefer.  (The latter solution will require a few additional
steps, and doesn’t give you the parity described earlier.  But it works if you
need to go that route.)

Other Notes:

  • NAnt
    .85 RC4
    (and NAntContrib )
    is required.  Be sure to copy the new BizTalk.NAnt.Tasks.dll to NAnt’s bin directory. 
    We need to call BizTalk’s .net 2.0 assemblies, and NAnt wasn’t built against 2.0 —
    so change nant.exe.config to have only<supportedRuntime version=”v2.0.50727″
    /> in the<startup> element.

  • Log4net usage in the sample (which isn’t required of course for the framework)
    has been updated to log4net
    1.2.10 , as has my serializable
    wrapper.  You can find the new log4net.Ext.Serializable in the Tools download
    (which is useful all by itself, apart from the framework.)

  • You can actually use the BizTalkDeploymentInclude.nant file in this release with BizTalk
    2004, if you like, to aid in your migration.  There is NAnt property to indicate
    2004 vs. 2006.

  • Scan all the previous
    release notes…

Leave comments with any questions/issues/etc.  Enjoy!

Download: Full
Sample, Framework
Core, Tools
Source , Docs

Deployment Framework for BizTalk 2006…

(Update: The original download files were missing the PDB-to-GAC functionality
I’ve discussed before.  Please download again if you have already…)

The BizTalk
Deployment Framework has been updated to work with BizTalk 2006…It is hard to
believe that this project has been going on since May of 2004!

The Deployment Framework for BizTalk 2006 still has the same goals as the
2004 version:

  • Streamline the deployment process for developers, ensuring repeatability

  • Make it easier for a team of BizTalk developers to stay in sync – not just with BizTalk
    artifacts, but with all the other infrastructure that surrounds the solution (virtual
    directories, queues, file folders, etc.)

  • Extremely close parity between server-side deployments and developer deployments –
    so you are always testing your server deployments as you go through a typical developer
    work day.

BizTalk 2006 itself introduced quite a few features to make deployment easier, and
can work fine for small (or solo) projects.  Here are a few limitations I’ve
encountered:

  • Though much improved, it is still possible to get into “dependency chaos” – where
    you spend time manually undeploying/deploying individual artifacts.

  • Binding changes have to be communicated “manually” between developers on a team, since
    the import process is done through the Admin MMC or command-line.  Just “getting
    latest” from version control isn’t sufficient.

  • Binding files for your various environments have to be maintained as separate files
    (manually), rather than “merging in” environment-specific settings

  • Artifacts such as rules, virtual directories, queues, folders, additional dependent
    assemblies, etc. can be represented as “Resources” within the Admin MMC (and in exported
    MSIs), but not in a fashion that easily moves between developers on a team.

So!  To get started with this version, download the Deployment
Framework (Tools) zip and run the MakeBizTalkExternalTools_VS2005.vbs script. 
This will add entries to the Visual Studio tools menu for deploying and undeploying
using the framework.  You can download the full
sample to see the framework in action (first build it, then do Tools-BizTalk
Deploy.  You’ll see something like this.)

The high-level approach is the same as the 2004 framework – you supply a small project-specific
NAnt script that indicates via properties what elements of a deployment your solution
requires.  You include BizTalkDeploymentInclude.nant to get all the core deployment functionality,
and make sure the DeployTools directory is copied to your project.  (Unzipping
the Deployment
Framework Core into your project is a good way to do this.)  See the documentation for
a more complete discussion.

The primary difference in the upgraded framework for BizTalk 2006 is that
we now create a BizTalk Application definition, and use BTSTask to
add all BizTalk artifacts as resources within that application.  Starting and
stopping the application is done at an application level rather than per port/per
orchestration.

Packaging up your solution as an MSI can be done with the WiX-based scripts that have
been in the framework for awhile, or by using the MSI export mechanism in
BizTalk 2006, if you prefer.  (The latter solution will require a few additional
steps, and doesn’t give you the parity described earlier.  But it works if you
need to go that route.)

Other Notes:

  • NAnt
    .85 RC4
    (and NAntContrib )
    is required.  Be sure to copy the new BizTalk.NAnt.Tasks.dll to NAnt’s bin directory. 
    We need to call BizTalk’s .net 2.0 assemblies, and NAnt wasn’t built against 2.0 —
    so change nant.exe.config to have only<supportedRuntime version=”v2.0.50727″
    /> in the<startup> element.

  • Log4net usage in the sample (which isn’t required of course for the framework)
    has been updated to log4net
    1.2.10 , as has my serializable
    wrapper.  You can find the new log4net.Ext.Serializable in the Tools download
    (which is useful all by itself, apart from the framework.)

  • You can actually use the BizTalkDeploymentInclude.nant file in this release with BizTalk
    2004, if you like, to aid in your migration.  There is NAnt property to indicate
    2004 vs. 2006.

  • Scan all the previous
    release notes…

Leave comments with any questions/issues/etc.  Enjoy!

Download: Full
Sample, Framework
Core, Tools
Source , Docs

%Filename% macro is not replaced with the disk filename

I’ve seen this issue showing a couple of times on the BizTalk Newsgroups so I thought it’s worth posting about this on my blog. The user expectation, which is probably correct from usability point of view, is that the %Filename% macro is replaced with the name of the original file no matter if that file was received from the disk through FILE adapter or from a document library through SharePoint adapter. This doesn’t happen like that since the WSS adapter send ports will resolve the %Filename% macro to empty string if the message was originally received from any other adapter than WSS adapter. This is by design.


The %Filename% macro is replaced with the name of the SharePoint file (and not with the name of a file on disk). If the message was received through FILE adapter (or any other adapter than WSS) then the %Filename% macro is probably replaced with empty string. Macros (like %Filename%) and context properties (like WSS.Filename) are implemented by each adapter separately, they are specific to each adapter, and there is no ‘framework’ that would provide a unified set of macros/context properties accross all adapters. This makes sense since ‘%Filename%’ might not make sense for a POP3 adapter or it could have a slightly different behavior for 3rd party adapters. Coincidently, some adapters have used the same macro name (I would guess %Filename% is a common one) and ocasionally the same context property. However, the %Filename% macro in a WSS adapter send port is totally different from a %Filename% macro in an FTP adapter send port, for instance.


To workaround this you can use an orchestration or a custom pipeline. All you need to do is get the disk file name from FILE.ReceivedFileName property and save it in the WSS.Filename property like below. Make sure that the Filename field in the send port UI dialog box is left empty so that the value supplied through the context property WSS.Filename is used to set the filename.
   sharepointOutgoingMsg(WSS.Filename) = diskIncomingMsg(FILE.ReceivedFileName);


http://msdn.microsoft.com/library/en-us/BTS06Operations/html/1ff50fb8-7ba0-47b8-9476-d57413989346.asp?frame=true
http://msdn.microsoft.com/library/en-us/BTS06Operations/html/c5ae5339-67bf-4fde-a721-5b1aa3b9caca.asp?frame=true


You don’t have to use dynamic send ports for the workaround above. In the case of WSS adapter, you can define the send port configuration through the WSS.Config*, WSS.Filename context properties of the outgoing message and then configure the WSS send port equivalent properties so that they are either empty (text boxes) or have a value of Orchestration (drop-down boxes) in order to not overwrite the configuration information specified through the context properties.

Microsoft SOA? I can’t find that on the price list!?!

Astute browsers of the blog have noticed that we’ve changed the name of the October conference. It is now known as the Microsoft SOA and Business Process Conference. Why’d we do that? Well that’s an interesting story. It seems some people think that Microsoft doesn’t do SOA. Well not people per se; some press, analysts and BDM’s (marketing speak for business decision maker, or your bosses, bosses, boss) only believe in talk. Walking the walk isn’t true until you yell your message at the top of your voice.


 


As the loyal BizTalker’s reading the blog know the Microsoft technology stack is service oriented from top to bottom. From Windows Vista (.NET Fx 3.0) through 2007 Office System (XML file formats) to SharePoint (Web Service enabled) down to BizTalk, SQL Server and Windows Server itself, Service Orientation is baked in. It’s in the platform, silly.


 


Microsoft’s SOA story isn’t secret sauce locked up in the heads of suited consultants or hiding inside the box of ’out of this world’ costly software packages. It’s out in the open. It’s there in Visual Studio for developers to unleash. It’s in Operations Manager for IT to harness and it’s in Internet Explorer and ASP .NET/Atlas for the world to mash up. Architectural guidance is plainly in view on MSDN (well if you can get the query right in the search engine it is :^). Microsoft partners build SOA solutions every single day.


 


Yelling “SOA” at the top of our voices seems redundant, so we won’t do that. But if explicitly discussing real capabilities that any of us can use is your idea of ’talking the talk’ then the Microsoft SOA and Business Process Conference is the show for you. We on the BizTalk team will make sure to invite some press and analysts and you can bring your BDM. Let’s nip this nasty FUD in the bud.


 


The conference track abstracts will go up on the site next week as will a call for sessions to interested presenters. Shortly after that we’ll post the session abstracts themselves.


 


Remember the early bird registration discount is available through July 21st. You can register for the show at http://impactevents.com/biztalkconference/


 


Regards,


mike


 

Workflow Developer Starter Kit for WSS v3 + More

Fresh new goodies on the Microsoft Download site:


Share this post: Email it! | bookmark it! | digg it! | reddit!

Great New BizTalk Documentation

Wow, our User Experience team continues to amaze! They have just released an update to the BizTalk Server 2006 documentation that contains tons of new content. I’d list it all here, but there’s just too much so check out the attached doc for the full run down. Also, if you don’t already, you should monitor Luke’s blog to stay on top of the new samples, tutorials, and doc refreshes they keep pumping out.


-Kris

BizTalk Server 2006 Developer Center and TechCenter – July Adapter Release


As mentioned previously we recently launched the BizTalk Server 2006 Developer Center. This project constituted a complete rebuild of the previous BizTalk Server 2004 Developer Center. For May and June we featured orchestrations. This included new code samples, an FAQ paper on orchestrations, and in-depth content surfaced from the core documentation. With the re-design of the site it’s easier than ever to learn to develop, deploy, administer, and use BizTalk Server 2006. For July we will be focusing on Adapters


In addition to the Developer Center, we also launched the BizTalk Server 2006 TechCenter. The TechCenter provides easy access to BizTalk Server 2006 technical documentation, downloads, and community, as well as to IT Pro favorites such as the Events & Errors Message Center. Each navigation page within the technical library includes quick access to search BizTalk Server newsgroups and knowledge-base articles as seen, for example, on the Getting Started page. Among many things, the site contains:  



  • Virtual labs
  • The end-to-end tutorial as downloadable Word docs
  • New content on Clustering BizTalk Server
  • Links to the Installation Instructions
  • Links to the Production Documentation published on MSDN

A workflow sample

A workflow sample

I built a sample (you can download it here)
based upon a question asked in the WF forums last night (you can see the post here).

I wanted to post it here so I could point out some of the interesting features it
has in it.

First – there is a CallWorkflowActivity – which creates and executes another workflow
in a synchronous manner.  The WF built-in InvokeWorkflowActivity invokes another
workflow – but does it asynchronously.    It turns out to do is synchronously
you have to build a custom activity – mostly because synchronously you have to make
some assumptions about the workflow you are calling.   In my example – the
assumption I am making is that the “called” workflow will have parameters to pass
in, and parameters that are return – but there is no other communication between the
host and the workflow.

Now – since my CallWorkflowActivity can’t talk to the WorkflowRuntime directly – in
order to make it work I implemented a service to add to the WorkflowRuntime. 
Why can’t the activity talk to the WorkflowRuntime?  Well that could create some
interesting problems – like what if an Activity could ask the WorkflowRuntime to persist
the WorkflowInstance the Activity is being executed inside of?  The Activity
would be executing waiting for persistence, the WorkflowRuntime would be waiting to
persist until the Activity completed – classic deadlock.

 

InvokeWorkflow uses a service that is installed by default – IStartWorkflow – which
works create in the async case – but doesn’t work in the sync case.  So I just
created a custom service.  One aspect of WF that I try to emphasize to people
when I do my WF trainings is that even though there are well-known services inside
of the WorkflowRuntime – you can add any number of services which won’t be known to
the WorkflowRuntime – but can be used by your Activities.  In fact this is necessary
in some cases (like this one) where the code you want to execute would be “illegal”
inside of Activity.Execute (things like spawning threads or anything that would go
against the model of WF in terms of what Activities should do).  Now in this
case I made the Service derive from WorkflowRuntimeService because my service needs
the WorkflowRuntime to do its job, and that is the easiest way to get a reference
to the WorkflowRuntime.   But it isn’t a requirement that a service added
via WorkflowRuntime.AddService derive from WorkflowRuntimeService. 

So here is how my service executes a workflow:

public class CallWorkflowService
: WorkflowRuntimeService
{

public void StartWorkflow(Type
workflowType,Dictionary<string,object>
inparms,Guid caller,IComparable qn)
{
WorkflowRuntime wr = this.Runtime;
WorkflowInstance wi = wr.CreateWorkflow(workflowType,inparms);
wi.Start();
ManualWorkflowSchedulerService ss = wr.GetService<ManualWorkflowSchedulerService>();
if (ss
!= null)
ss.RunWorkflow(wi.InstanceId);
EventHandler<WorkflowCompletedEventArgs> d = null;
d = delegate(object o,
WorkflowCompletedEventArgs e)
{
if (e.WorkflowInstance.InstanceId
==wi.InstanceId)
{
wr.WorkflowCompleted -= d;
WorkflowInstance c = wr.GetWorkflow(caller);
c.EnqueueItem(qn, e.OutputParameters, null, null);
}
};
EventHandler<WorkflowTerminatedEventArgs> te = null;
te = delegate(object o,
WorkflowTerminatedEventArgs e)
{
if (e.WorkflowInstance.InstanceId
== wi.InstanceId)
{
wr.WorkflowTerminated -= te;
WorkflowInstance c = wr.GetWorkflow(caller);
c.EnqueueItem(qn, new Exception(“Called
Workflow Terminated”
, e.Exception), null, null);
}
};
wr.WorkflowCompleted += d;
wr.WorkflowTerminated += te;

}

}

 

Notice the use of anonymous delegates really helps in this case.  No need to
keep state about workflow instances around in the service – the anonymous delegates
get registered and unregistered for each Workflow execution. 

To get the data back to the Activity – the WorkflowQueue name that the Activity created
– so the Activity can return ActivityExecutionStatus.Executing from Execute – and
it waits for an item to come back on the Queue.

If the Workflow terminates – the service sends an exception into the WorkflowQueue
– which causes that exception to promolgate to the workflow itself.

Another interesting part of this sample is the use of the WorkflowParameterBindingCollection
– similar to the way that the InvokeWorkflow,CallExternalMethod and other built-in
activities do.  Make note of the DependencyProperty declaration and the call
to base.SetReadOnlyProperty in the constructor – both are necessary to get Collections
to serialize correctly into your .designer file.