Continuing from part
1
, we'll now see how to handle schemas and execute receive and send
pipelines with the pipeline testing library.

Configuring Known Document Specifications

If you want to use an assembler or disassembler on your pipeline, you'll need
to make sure that it can resolve the necessary schemas based on the fully
qualified schema type, or the root element name (namespace#root). To accomplish
this, you'll need to make sure that the pipeline is aware of "known" document
specifications before you execute them, so that the mock pipeline context can
return the correct value when IPipelineContext.GetDocumentSpecByName() or
IPipelineContext.GetDocumentSpecByType() is invoked by the
assembler/disassembler component.

The library supports this through the AddDocSpec() method on the
ReceivePipelineWrapper and SendPipelineWrapper classes. AddDocSpec() takes as an
argument a Type handle referencing the strongly-typed, SchemaBase-derived class
generated by the BizTalk project system when you compile an schema into a
BizTalk Assembly. Here's an example:

ReceivePipelineWrapper
pipeline =

   PipelineFactory.CreateEmptyReceivePipeline();

pipeline.AddDocSpec(typeof(Schema2_WPP));

AddDocSpec() will automatically handle multi-root schemas and make all roots
in the schema known to the pipeline context, so you don't have to worry about
that. You can also add as many document specifications as needed, as long as
there are no conflicts among them (i.e. don't add two schemas with the
conflicting namespace#root names).

Executing Pipelines

Now that we can configure the necessary components and schemas into our
pipelines, we are ready to execute them. For both receive and send pipelines,
you execute them using the Execute() method. However, it is defined with a
different signature in both the ReceivePipelineWrapper and SendPipelineWrapper
classes: Receive pipelines take a single IBaseMessage argument and return
multiple messages in a MessageCollection object. Send pipelines, on the other
hand, take multiple messages in a MessageCollection object as input and
return a single IBaseMessage object as ouput.

Here's a complete example of configuring and executing a receive
pipeline:

ReceivePipelineWrapper
pipeline =

   PipelineFactory.CreateReceivePipeline(typeof(ReceivePipeline1));

 

//
Create the input message to pass through the pipeline

Stream
stream = DocLoader.LoadStream("SampleDocument.xml");

IBaseMessage
inputMessage = MessageHelper.CreateFromStream(stream);

 

//
Add the necessary schemas to the pipeline, so that

//
disassembling works

pipeline.AddDocSpec(typeof(Schema1_NPP));

pipeline.AddDocSpec(typeof(Schema2_WPP));

 

//
Execute the pipeline, and check the output

MessageCollection
outputMessages = pipeline.Execute(inputMessage);

 

Here's a complete example of executing a send pipeline, with multiple
inputs:

SendPipelineWrapper
pipeline =

   PipelineFactory.CreateSendPipeline(typeof(Env_SendPipeline));

 

//
Create the input message to pass through the pipeline

string
body =

   @" xmlns:o='http://SampleSchemas.SimpleBody'>

      this is a
body"
;

MessageCollection
inputMessages = new MessageCollection();

inputMessages.Add(MessageHelper.CreateFromString(body));

inputMessages.Add(MessageHelper.CreateFromString(body));

inputMessages.Add(MessageHelper.CreateFromString(body));

 

//
Add the necessary schemas to the pipeline, so that

//
assembling works

pipeline.AddDocSpec(typeof(SimpleBody));

pipeline.AddDocSpec(typeof(SimpleEnv));

 

//
Execute the pipeline, and check the output

//
we get a single message batched with all the

//
messages grouped into the envelope's body

IBaseMessage
outputMessage = pipeline.Execute(inputMessages);

 

 


Tomas Restrepo

Software developer located in Colombia. Sr. PFE at Microsoft.