Quantcast
Channel: BizTalk – SANDRO PEREIRA BIZTALK BLOG
Viewing all 287 articles
Browse latest View live

XI Porto.Data Community Meeting | September 30, 2015 | How to process Flat Files documents (TXT, CSV …) in BizTalk Server

$
0
0

This post is for the BizTalk Server and other Portuguese Community, will be held on September 30, 2015 between 18:45 – 21:30 the XI Porto.Data Community meeting at the Science and Technology Park of University of Porto (UPTEC) in Oporto.

For me it is a pleasure to return, for the second time this year, to this community. This time I chose a topic, which at first sight it seems very simple and basic, but it hides some techniques in which even the most experienced ones are unaware of, forget or fail.

I will be speaking about: “How to process Flat Files documents (TXT, CSV …) in BizTalk Server

(Initially I was going to call this session: "Teach me something new about Flat Files")

Abstract: Despite over the year’s new protocols, formats or patterns emerged like Web Services, WCF RESTful services, XML, JSON, among others. The use of text files (Flat Files ) as CSV (Comma Separated Values) or TXT, one of the oldest common patterns for exchanging messages, still remains today one of the most used standards in systems integration and / or communication with business partners.

While tools like Excel can help us interpret such files, this type of process is always iterative and requires few user tips so that software can determine where is need to separate the fields/columns as well the data type of each field. But for a system integration (Enterprise Application Integration) like BizTalk Server, you must reduce any ambiguity, so that these kind of operations can be performed thousands of times with confidence and without having recourse to a manual operator.

In this session we will first address: How we can easily implement a robust File Transfer integration in BizTalk Server (using Content-Based Routing in BizTalk with retries, backup channel and so on).

And second: How to process Flat Files documents (TXT, CSV …) in BizTalk Server. Addresing what types of flat files are supported? How is the process of transforming text files (also called Flat Files) into XML documents (Syntax Transformations) – where does it happen and which components are needed. How can I perform a flat file validation?

XI Evento da Comunidade Porto.Data

A comunidade Porto.Data tem como objectivo a partilha de experiências e conhecimento entre os profissionais no Porto.

Para mim é um prazer voltar, pela segunda vez este ano, a esta comunidade. Desta vez eu escolhi um tema, que à primeira vista parece muito simples e básico, mas que esconde algumas técnicas ou segredos em que até mesmo os mais experientes desconhecem, se esquecem ou falham.

Desta vez vou vos falar sobre: "Como processar documentos Flat Files (TXT, CSV, …) em BizTalk Server"

Descrição:

Apesar de ao longo dos anos surgirem novos protocolos, formatos ou padrões: Web Services, WCF, RESTful services, XML, JSON entre outros. No entanto, um dos padrões mais antigos e comuns para a troca de mensagens, e que continua ainda a ser hoje em dia um dos padrões mais usados na integração de sistemas e/ou na comunicação com parceiros de negócio, é a utilização de arquivos texto (Flat Files) como: CSV (Comma Separated Values) ou TXT.

Embora ferramentas como Excel nos ajudem a interpretar um ficheiro destes (CSV), o processo é sempre interactivo e requer algumas dicas do utilizador para que o software consiga determinar onde separar os campos/colunas, bem como o tipo de dados de cada campo. Ora para um sistema de integração (Enterprise Application Integration) como o BizTalk Server, é preciso reduzir todas as ambiguidades, por forma a estas operações poderem ser efectuadas milhares de vezes com confiança e sem que seja necessário recorrer a um operador manual.

Nesta sessão vamos abordar, primeiro, como podemos facilmente efectuar uma integração do género File Transfer robusto em BizTalk Server. E em segundo, como é que o BizTalk Server processa Flat Files (CSV, TXT, …): Que tipos de flat files são suportados? Como é o processo de transformação de arquivos de texto (também chamados de Flat Files) em documentos XML (Transformação de sintaxe)? e onde essas transformações ocorrem, bem como na validação da informação neles contida.

 

O evento irá ocorrer no próximo dia 30 de Setembro no auditório da UPTEC, pelas 18:45 no Porto. As inscrições não tem custos mas é obrigatório que reserve o seu lugar aqui uma vez que os lugares são limitados.

Confira a agenda abaixo:

18:45 – Abertura e recepção.

18:50 – Community News.

19:00 – "Columnstore Indexes Revealed – Uncut & Unedited" – Niko Neugebauer MVP – Oh22.net

20:10 – Coffee break.

20:30 – "Como processar documentos Flat Files (TXT, CSV, …) em BizTalk Server" – Sandro Pereira MVP – DevScope

21:15 – Fim do evento.

21:20 – Sorteio de prémios.

21:30 – Jantar livre.

Reserve aqui o seu lugar! Estamos a sua espera.



BizTalk Server: Teach me something new about Flat Files (or not) – Introduction

$
0
0

Following one of my last speaking engagement in the Porto.Data Community Meeting about Flat Files: How to process Flat Files documents (TXT, CSV …) in BizTalk Server where I address some of the following topics:

  • How to process Flat Files documents (TXT, CSV …) in BizTalk Server.
  • What types of flat files are supported?
  • How is the process of transforming text files (also called Flat Files) into XML documents (Syntax Transformations)
  • Where does it happen and which components are needed
  • Or how can I perform a flat file validation?
  • And so on

I decided to return writing about this topic in my blog, a topic that I already wrote in the past describing and explaining almost all of the topics mention above:

But this time transforming my previous session in a sequence of blog posts where I will address and explain how to solve some of the typical or common flat files structures and scenarios.

The simplest ones:

  • Text Files Delimited by symbols
    • For example:
Sandro;Pereira;1978;Crestuma;4415
Vânia;Braziela;1981;Vila Nova de Gaia;4400
José;Silva;1972;Crestuma;4415
Rui;Barbosa;1975;Lever;4415
    • Where we have: Name,Surname,Birthyear,Address,ZipCode
  • Positional Text Files
    • For example:
0120200300 01 PT        Sandro      Pereira         Rua Central, 133      Crestuma    Vila Nova de Gaia  4415 Crestuma
0120200300 01 PT        José        Silva           Crestuna              Crestuma    Vila Nova de Gaia  4415 Crestuma
0120200300 01 PT        Rui         Barbosa         Porto                 Porto       Porto              4400
0120200300 01 PT        Miguel      Silva                                 Porto       Porto              4415 Crestuma
    • Where we have:
GroupId|PrimaryKey|SecondaryKey|ControlFlag|PartyNo|Remark|Country|Name|Surname|Street|City|District|ZipCode

0120|20|03|0|0 |01 |PT |Sandro |Pereira |Rua Central, 133 |Crestuma |Vila Nova de Gaia |4415 Crestuma

And evolve to more challenger scenarios like:

  • Handling Record Tag Identifiers, were we will treated each Tag Identifier differently
    • For example:
PO1999-10-20
USERSandro Pereira,1978-04-04, Crestuma
USERCelso Pereira,1978-04-04, Crestuma
ITEM872-AA|Super Bock|Green
ITEM871-AA|Super Bock|Black
East Coast Facility
ERROR102|0|High|Sprocket query fails.|1999-05-31T13:20:00.000-05:00
ERROR16502|2|Low|Time threshold exceeded.|1999-05-31T13:20:00.000-05:00
8675309
    • Where we have:
      • Location
      • ERROR
        • ID|Type|Priority|Description|DateTime
      • BatchID
  • Or simple How can I remove a simple header from a Text File
    • For example
P_ABB,NUMBER,SHIP_ID,CREATE_DATE,SHIP_NO,SHIP_DATE,SHIP_DEST,PO_NO,LOT_TYPE,LOT_NO,SHIP_QTY,SHIP_PRD_NO,OBS_LOT
PA1,IN1900011,K1-N-A1,11/9/2015,BA511,15/9/2015,GTW,9871119,K,LTSGT 11A,12,PD806-D0,AGT;AKT;LOOP
PA1,IN1900012,K1-N-A1,11/9/2015,BA511,15/9/2015,GTW,9871119,K,LTSGT 11A,12,PM806-D0.0J,AGT;AKT;FLAT
    • Where the structure of the message is described in the header (first line) – This scenario for example is very common in CSV files.

Until we reach and address advance topic like:

  • Debatching Flat Files messages
  • Perform Deep Validation in flat files processes
  • Create generic Receive and Send Pipelines and how to configures this pipelines through BizTalk Administration Console
  • And so on

And hopefully teaching you something new (trick or tip) about Flat Files or at least trying to demystify some issues related with Flat Files.

Most of this things will be solved by explaining you how to create, for each scenario, flat file schema from flat file document instances using the BizTalk Flat File Schema Wizard.

Others how can we tuning some properties afterwards so that we can have the desired output.

Let’s the fun begin.


Collection of Microsoft Integration Stencils for Visio 2013 updated #2 with new stencils

$
0
0

After some requests from the community, I decided to update my Microsoft Integration Stencils for Visio 2013 stencils with an additional of 60 new shapes, making ate the moment a total of 361 shapes that will help you to visually represent Integration architectures and solutions diagrams in a simple and beautiful way.

Some of the shapes added in this release:

  • Infrastructure and Devices: Manufacturer(s), new Server shapes, Industry Devices, Windows Phone, Surface
  • Components and features: Azure Store, Applications, Deployment, Azure Deployment, On-Premises Deployment, EAI/EDI, Content Delivery Network, Partner Network, Manage Network Policy, App Controller, Redundancy, Data Synchronization and do on
  • Data Virtualization
  • Power BI: new Power BI shapes
  • Others: HTML5, Google, Apple, Twitter, Hotmail, Android, Linux, World Map, Browser, Help, Cost, IoT, Attach, new Users shapes, and so on

new-integration-stencils-visio-data-visualization-powerBi

That you can use and resize without losing quality, in particular the new shapes.

Again, I didn’t create all of this shapes, only a few of them, the rest it was one the work of gathering some resources and combine them together. There are still many points that could be improved as well as adding new stencils.

You can download Microsoft Integration Stencils for Visio 2013 from:

Collection of Microsoft Integration Stencils for Visio 2013 (2,3 MB)
Microsoft | TechNet Gallery


BizTalk Server: Teach me something new about Flat Files (or not) – Files Delimited by Symbols

$
0
0

This post is intended to consolidate some basic principles about Flat File Schema Wizard

First of all, BizTalk Flat File Schema Wizard is a template inside Visual Studio that allows you to converting Flat File into XML message, which BizTalk can understand, in a graphical a simple manner. That basically supports two types of text files: Positional text files and/or delimited by symbols. See more:

The following walkthrough shows you how to create a flat file schema from a semicolons separate flat file document that stores people information using the BizTalk Flat File Schema Wizard.

Name

Surname

Birth year

Address

Zip Code

Sandro Pereira 1978 Crestuma 4415
José Silva 1972 Crestuma 4415

File sample:

Sandro;Pereira;1978;Crestuma;4415
Vânia;Braziela;1981;Vila Nova de Gaia;4400
José;Silva;1972;Crestuma;4415
Rui;Barbosa;1975;Lever;4415

You can see that we have, in this example, four records with five fields specifying Name, Surname, Birth year, Address and Zip code of each person.

Now I will walk you through the required steps at design time:

  • using the Flat File Schema Wizard to generate the Flat File Schema;
  • and the pipeline editor to create a custom pipeline;

To enable the runtime to support the processing of the Flat File described earlier (People)

We begin then by launching Visual Studio and create or open a BizTalk project:

  • “File –> New –> Project”, on BizTalk Projects, select the option “Empty BizTalk Server Project”;
  • Insert the project name, physical location on the disk and the name of the solution.
Using Flat File Schema Wizard to generate a schema based on a file delimited by Symbols

To create the schema which will recognize the ‘people’ text file, we need to go to the BizTalk solution created in Visual Studio and perform the following steps:

  • Press the right button on top of the project in Solution Explorer, and select the option “Add –> New Item…

01-Visual-Studio-Solution-Add-a-New-Item

  • On “Installed Templates” menu in the window “Add New Item”, select the option “Schema Files”, and then select the option “Flat File Schema Wizard”, then provide the name you want to give the scheme in this example: “FF_DSYMBOL_PEOPLE.xsd”

02-Visual-Studio-Schema-Files-Items-Select-Flat-File-Schema-Wizard

By selecting this option, we will be guided automatically by the tool “BizTalk Flat File Schema Wizard” that will help us to create a Flat File Schema and define its data structure (records, elements, attributes …) based on the text file specified.

  • Click “Next” to continue.

03-BizTalk-Flat-File-Schema-Wizard-Welcome-Page

  • In the window “Flat File Schema Information” we will have to:
    • Select an instance of the text file that will serve as the model of the structure that we want to transform;
    • Although it is not necessary, it is good practice to rename the Record name “Root”.
      • In this case we will rename it to “People
    • And finally, assign a “Target namespace” to the scheme and define the encoding of the input file
    • Click “Next” to continue.

04-BizTalk-Flat-File-Schema-Wizard-Information-Page

Note: The wizard will load the text file so that we can begin to split it and map it into the desired structure. In this step we need to define how the records or rows are differentiated. The structure of the example is: Name;Surname;Birthdate;Address;Zip Code{CR}{LF}

  • Since each record “Person” that we want to create is defined in a single line, in the “Select Document Data” we can select only the data portion of the document that will set the record, i.e. the whole first line. Click “Next” to continue.

05-BizTalk-Flat-File-Schema-Wizard-Select-Document-Data-Page

Note: Alternatively, let’s call it option 2, we could select all the data of the file, however with this approach we need to treat differently the data a few steps ahead in the “Child Elements” window.

06-BizTalk-Flat-File-Schema-Wizard-Select-Document-Data-Page-option-2

  • In the window “Select Record Format” we will define whether we are dealing with a Flat File Delimited by symbols or is positional, in our case we will select the “By delimiter symbol”, because each record is delimited by a return Carriage Return/Line Feed ({CR}{LF}). Click “Next” to continue.

07-BizTalk-Flat-File-Schema-Wizard-Select-Record-Format-Page

  • In the window “Delimited Record” we will provide the record delimiter, in this case as we want to define the structure of person, i.e. each row is a person, our limiter is {CR}{LF} (Carriage Return/Line Feed). The “Child delimiter” combo box include by default the following options: {CR}, {LF}, {TAB}, {SPACE}, {0x1A}, {}, {.}, {;} and {CR}{LF}, however you can provide your own symbol.
    • Click “Next” to continue.

08-BizTalk-Flat-File-Schema-Wizard-Delimited-Record-Page

  • In the window “Child Elements” we will define what kind of element we want to assign to the registry. As we are defining the Person structure and the file contains multiple people, we have to select the “Element Type” as “Repeating record” If we do not perform this step, we will not have the ability to split the record into multiple elements / attributes individual.
    • Note: If you do not define the element as “Repeating record” (or “Record”), you will not have the ability to break down your record into individual elements or attributes.
    • Click “Next” to continue.

09-BizTalk-Flat-File-Schema-Wizard-Child-Elements-Page

Note: earlier I told that we could select all the data inside the flat file and that we would need to treat the information differently in this step – option 2. So if you select this option, it will present all the lines in the document in this window, because we want to have an “Array” of Persons, in this step we need to select the “Element Type” of the first element as “Repeating record” and the rest of the set as “Ignore” (You set this to Ignore because you have already specified Repeating Record for the Person element)

19-BizTalk-Flat-File-Schema-Wizard-Child-Elements-Page-option-2

In this point, I have defined how the element Record looks like but I have not broken down the various elements that make up the record itself. We have just map that each line of the text file corresponds to a record Person.

  • In the “Schema View”, click “Next” to continue processing the message. Click “Next” to continue.

10-BizTalk-Flat-File-Schema-Wizard-Schema-View-Page

In this phase the wizard restarts the whole process described above, but if you noticed, the wizard no longer selects all information contained in the text file, but only what was selected to define the record Person.

  • What we will do now is split the information of record “Person” in different elements, for that, we will select only the information required leaving out the Carriage Return/Line Feed. Click “Next” to continue.

11-BizTalk-Flat-File-Schema-Wizard-Select-Document-Data-Page-line-select

  • Once again our structure is delimited by symbols (;), then we will select the option “By delimiter symbol” and then c“Next” to continue.
  • As we can analyze all the elements are separated by the semicolon (;) that is our delimiter, then in the window “Delimited Record” we must change the value of the “Child delimiter” option to “;”.

20-BizTalk-Flat-File-Schema-Wizard-Delimited-Record-Page

  • In this window “Child Elements”, we will define the different elements/attributes of the structure of the record person. This operation is very similar to any XSD, where we can define the different names and data types. Adjust the values ​​according to the table below:

Element Name

Element Type

Date Type

Name Field element String
Surname Field element String
Birthyear Field element int
Address Field element String
ZipCode Field element String

12-BizTalk-Flat-File-Schema-Wizard-Child-Elements-Page-line

Note: You should rename the parent node, each record, element or attribute in the BizTalk Flat File Schema Wizard, mainly in this step by modify the “Element Name” field to your desired name, however if you forgot to do that or if you make a mistake defining one of them, you can always rectify it in the Schema Editor. The same applies to the Data Type.

  • Click “Next” to continue.
  • Finally the wizard will show the equivalent XML structure that your text file document will have. Once you select the option “Finish”, the scheme will be available for you to use in your BizTalk solution.

21-BizTalk-Flat-File-Schema-People

After we finalize the creation of the Flat File Schema which will contain the transformation rules of the text file, we can easily test our transformation, without having to get out of our development tool (Visual Studio) and without having to deploy our solution.

If we select the Flat File Schema that we just created and access to its properties, we can see that by default all properties are preconfigured so that we can perform tests to our message transformation:

  • The input instance file is configured with the file which was used to create the schema;
  • And with the correct input and output formats
    • Validate Instance Input Type: Native
    • Generate Instance Output Type: XML

To test, you simply right-click in the schema that we just created and select the option “Validate Instance”:

This option will use the configured file to execute and validate all transformation rules defined in the Flat File Schema and present the final result or occurring errors in the “Output” window

Did you know that: Delimited fields in flat files have a limit of 50000000 characters

Creating the Pipeline that will be responsible for processing and transforming the text file

As I explained in detail in one of my previous posts: BizTalk Server: Transform text files (Flat Files) into XML–Introduction (Part 1), the Syntax Transformations occur in the Disassembling and Assembling stages within the receive and send pipelines, having this Flat File schema will not do us much good until we create the pipelines to provide the translation between Flat Files and XML

To create the Receive Pipeline that will be responsible for processing and transforming the text file, we need to go to the BizTalk solution created in Visual Studio and perform the following steps:

  • Press the right button on top of the project in Solution Explorer, and select the option “Add –> New Item…”.
  • On “Installed Templates” menu in the window “Add New Item”, select the option “Pipeline Files”, and then select the option “Receive Pipeline”, then provide the name you want to give the pipeline in this example: “FF_People_ReceivePipeline.btp

22-BizTalk-Receive-Flat-File-pipeline-People-Add-New-Item

  • By selecting the option “Add”, the pipeline editor (BizTalk Pipeline Designer) will appear and that will let you view and add components to all the steps associated with receive pipeline: Decode, Disassemble, Validate and ResolveParty.

In this case, the pipeline that we will create, will be responsible for receiving a text file through a receive location and convert it to XML. For that, we will use the “Flat File Disassembler” component which is available in the Visual Studio Toolbox window (Ctrl+W, X).

  • Drag it into the Pipeline in step “Disassemble”.

23-BizTalk-Receive-Flat-File-pipeline-People-Disassembler-stage

  • Finally, select the component “Flat file disassembler”, go to its properties and on the “Document Schema” option: select the schema created earlier, in case the “FF_DSYMBOL_PEOPLE”.

24-BizTalk-Receive-Flat-File-pipeline-People-Disassembler-stage-Document-Schema

Note: If you want to create a send pipeline in order to transform an XML document into Flat File, we would follow the same steps, the difference is that we would have to drag the component “Flat File Assembler” on stage “Assemble”.

Once you have deployed your solution, you will want to ensure that you select the custom pipeline we just created in the Receive Locations that you expect to receive these flat files.

Take away

Now the big questions here is: Do you think the schema is entirely correct? Does it handles with all files accordingly to the expected results?

Or do we need to tune some of the properties of your schema… stay tuned to the next post.

Some references:

Related posts:

You can download all the code used here from:

BizTalk Server: Dealing with Files Delimited by Symbols (71,9 KB)
Microsoft | Code Gallery


BizTalk Server: Teach me something new about Flat Files (or not) – Delimited Flat File Schema Optimizations

$
0
0

We ended last post asking: Do you think the schema is entirely correct? Does it handles with all files accordingly to the expected results? Or do we need to tune some of the properties of your schema…

When we start working with Flat File schemas for BizTalk, we may think that just using the Flat File wizard is going to be enough. Once the schema is created, we just need to create a custom pipeline and add the schema to the Document Schemas of a Flat File disassembler and it will be good… well let me tell you that most probably is not enough and the reality may be very different.

A common mistake that we sometimes do is to rely on a single sample message to generate/validate our Flat File Schemas. And we ended up getting possibly several different errors in production due to unforeseen cases that end up not being supported in our current schema version.

So it is real important to get all the information, as possible, from the different teams, for example:

  • Are there any optional elements?
  • If so, will they be delete from the message? Or will they be present without any content (blank/null)
  • Does the message will always end with a blank line? i.e., does the last line contain a Carriage Return/Line Feed (CR+LF)
  • What are the Data type of the elements?

And many, many more….

The following walkthrough shows you some of the common scenarios that you can expect and how you can tune some of the properties of our Flat File Schemas to deal with them.

Cosmetic operations

While generating the Flat File Schema with the Flat File Schema Wizard you should always provide/set:

  • The correct or proper namespace for the schema
  • Rename the parent node, each record, element or attribute
  • And set the correct data type of each element or attribute

However if you forgot to do that or if you make a mistake defining one of them, you can always easily rectify it in the Schema Editor.

I call it cosmetic operations because they don’t infer “any changes” in the translation rules generated by the wizard, they only changed the way the elements are presented in the message, if you change the name of the element or attributes. Or they will have effect in the validation of the message, if we change the data types.

You can accomplished that by:

  • Open the schema in BizTalk Editor.
  • Change the Schema Target Namespace
    • In the BizTalk Editor dialog, right-click the <Schema> node in the tree view and click Properties. The Properties dialog appears.
    • In the Properties dialog, the Target Namespace displays under the General category for the <Schema> node.
    • In the Target Namespace field, type the name of your new target namespace and click OK.
  • Change the Field Attribute or Field Element Name
    • Select the Field Attribute or Field Element node and then right-click and select the “Rename” option
    • Type the desired Field Attribute or Field Element name and press “Enter”
  • Change the Field Attribute or Field Element Data Type
    • Select the Field Attribute or Field Element node and then right-click and select the “Properties” option
    • In Properties window, set the “Data Type” property to the desired type

01-BizTalk-Flat-File-Schema-Cosmetic-Operations

Validating Flat Files Schemas through the Visual Studio with different scenarios

Let us forget the runtime for now, and focus firstly on the development phase where we can test and validate our schemas directly from Visual Studio as explained, once again, in the previous post.

Dealing with Files ending with a newline or that doesn’t ends with a newline

Initially we had the following example:

Sandro;Pereira;1978;Crestuma;4415{CR}{LF}
Vânia;Braziela;1981;Vila Nova de Gaia;4400{CR}{LF}
José;Silva;1972;Crestuma;4415{CR}{LF}
Rui;Barbosa;1975;Lever;4415{CR}{LF}

Which was the base to generate our Flat File schema: “FF_DSYMBOL_PEOPLE.xsd”.

If you paid attention, while we were generating our Flat File Schema, that in the “Select Document Data” window of the BizTalk Flat File Schema Wizard, you can notice that the last line contains a Carriage Return/Line Feed (CR+LF), which means that if you open the file for example in Notepad, you will notice that the file ends with a blank line.

01-BizTalk-Flat-File-Schema-Wizard-Select-Document-Data-Page-CR-LF

Note: You can check the file “FF_DSYMBOL_PEOPLE.txt” that is available with the source code.

So let us try with a simple change by removing the Carriage Return/Line Feed so that the files does not end with a newline:

Sandro;Pereira;1978;Crestuma;4415{CR}{LF}
Vânia;Braziela;1981;Vila Nova de Gaia;4400{CR}{LF}
José;Silva;1972;Crestuma;4415{CR}{LF}
Rui;Barbosa;1975;Lever;4415

Check the file: “FF_DSYMBOL_PEOPLE WithoutEnterLastLine.txt

If we now try this file instance against our Flat File Schema by:

  • In Solution Explorer, right-click the schema that you want to validate, and then click Properties.
  • In Properties window for the schema, for Input Instance Filename enter the name and path for the “FF_DSYMBOL_PEOPLE
    • Check more about Schema File Properties here.
  • WithoutEnterLastLine.txt” message instance, or browse to the file, select it, and then click OK.
  • Right-click the schema that you want to validate, and then click Validate Schema

You will notice that we will get the following error:

Invoking component…
<path>\DemoFile\FF_DSYMBOL_PEOPLE WithoutEnterLastLine.txt: error BEC2004: Unexpected data found while looking for:
‘\r\n’
The current definition being parsed is Person. The stream offset where the error occured is 133. The line number where the error occured is 4. The column where the error occured is 23.
<path>\FF_DSYMBOL_PEOPLE.xsd: error BEC2004: Validate Instance failed for schema FF_DSYMBOL_PEOPLE.xsd, file: <file:///path\FF_DSYMBOL_PEOPLE WithoutEnterLastLine.txt>.
Component invocation succeeded.

02-Visual-Studio-Flat-File-Instance-Validation-Failed

If, on the other hand, we had originally generated the Flat File Schema using the message instance without the Carriage Return/Line Feed at the end.

03-BizTalk-Flat-File-Schema-Wizard-Select-Document-Data-Page-option-3

And if we know try it with an instance containing a blank line at the end of the message we would receive a similar but different error:

Invoking component…
<path>\FF_DSYMBOL_PEOPLE.txt: error BEC2004: Unexpected end of stream while looking for:
‘;’
The current definition being parsed is People. The stream offset where the error occured is 139. The line number where the error occured is 5. The column where the error occured is 0.
<path>\FF_DSYMBOL_PEOPLE_Advance.xsd: error BEC2004: Validate Instance failed for schema FF_DSYMBOL_PEOPLE_Advance.xsd, file: <file:///path\FF_DSYMBOL_PEOPLE.txt>.
Component invocation succeeded.

04-Visual-Studio-Flat-File-Instance-Validation-Failed

I’ve seen situations/solutions where there were created pipeline components to address and solve these type of problems, which isn’t the best and the proper solution!

In both cases the solution for solving these problems is the same: ensure that the “Allow Message Breakup At Infix Root” property on the Schemas node is set to “true” by:

  • Double-click the schema to open the item in the Schema Editor;
  • In BizTalk Editor, right-click in the Schema node and select the Properties option
  • In Properties window for the schema, set the “Allow Message Breakup At Infix Root” property to “true”

05-Visual-Studio-Flat-File-Instance-Validation-Failed-solved

After making this change, if we try to validate the two previous messages instances, we will notice that now everything will work perfectly.

So if you notice in the properties of our Schema:

  • The “Child Order” property of the People Root Node is set as: “Postfix”
  • And the “Child Order” property of the “Person” record is set as: “Infix”

What does it means? Child Order must always have a value. The possible values are:

  • Prefix: Specifies that the delimiter appears before the data that it is delimiting.
  • Postfix: Specifies that the delimiter appears after the data that it is delimiting.
  • Infix: Specifies that the delimiter appears between different items of data, resulting in one less delimiter than when Prefix or Postfix is chosen.
  • Default Child Order: Sets the child_order attribute to “default”, specifying that the child order specified using the Default Child Order property should be used.
  • And Conditional Default: Removes the corresponding annotation in the XSD representation of the schema, if any, resulting in the following behavior:
    • If the Record node has a tag identifier, then the child order will be prefix.
    • Otherwise, the child order will be infix.

There are two scenarios related to delimited flat files for which special considerations apply when setting the Child Order property.

  • The first such scenario concerns situations in which the flat file document has a header, a body, and optionally, a trailer.
  • The second scenario is that this property must be set according to what the runtime components expect for the nodes

In our instance message, the data/delimiter sequence in the conceptual loop would merely be one or more person records. Of course, only in the case where there are more than one person records would there be a delimiter to separate them. In that case, the number of delimiters is one less than the sets of things being delimited, and the delimiters are located between the delimited items in a structure known as Infix.

  • Number delimiter = Number Records – 1

Which is not the case in all our messages instances. Our first instance have the same number of “valid records” and delimiters.

By setting “Allow Message Breakup At Infix Root” property to “true”, this tells the parser whether to allow message breakup, and will ensure that the Infix stream is processed properly by the FF Disassembler.

Dealing with Optional Elements

Using Suppress Empty Nodes property

So let’s imagine a different scenario, this time we will deal with optional elements. In our first scenario while discussing with our time we realize that the element “Birthyear” was appearing empty in several messages, and it should be considered as an optional element:

Sandro;Pereira;1978;Crestuma;4415
Vânia;Braziela;1981;Vila Nova de Gaia;4300
José;Silva;;Crestuma;4415
Rui;Barbosa;1975;Lever;4415

By default, we need to have a complete instance of the message, for us developers be able to create all the transformation rules, which means that by default, when we finish creating the Flat File Schema through Flat File Schema Wizard tool, none of the records, elements or attributes are optional.

All of these changes/optimizations/configurations, they have to be made after the Flat File Schema been created.

You can always modify an existing Flat File schema that was created by the wizard (name of the elements, data type and so on). So to accomplish that we need to:

  • Double-click the schema to open the item in the Schema Editor;
  • In BizTalk Editor, expand People root node, expand Person record and right-click in the Birthyear element and select the Properties option
  • In Properties window, set the “Min Occurs” property to “0”

If we now try to validate the previous message instance (“FF_DSYMBOL_PEOPLE WithOptional.txt”), we ended up receiving another error:

Invoking component…
Validation generated XML output <file:///<path>\FF_DSYMBOL_PEOPLE_Advance_output.xml>.
<path>\FF_DSYMBOL_PEOPLE_Advance_output.xml: error BEC2004: The ‘Birthyear’ element is invalid – The value ” is invalid according to its datatype ‘http://www.w3.org/2001/XMLSchema:int&#8217; – The string ” is not a valid Int32 value.
<path>\FF_DSYMBOL_PEOPLE_Advance.xsd: error BEC2004: Validate Instance failed for schema FF_DSYMBOL_PEOPLE_Advance.xsd, file: file:///path\FF_DSYMBOL_PEOPLE WithOptional.txt.
Component invocation succeeded.

06-Visual-Studio-Flat-File-Instance-Validation-Failed-Element-String-Not-valid

And of course the reason is obvious, an empty string is not a valid integer.

Making this element nillable doesn’t make any difference, because in both situations the parser will continue to add an empty element:

<Person xmlns="">
    <Name>José</Name>
    <Surname>Silva</Surname>
    <Birthyear></Birthyear>
    <Address>Crestuma</Address>
    <ZipCode>4415</ZipCode>
  </Person>

To solve that situation there are a few additional flat file node properties that we can use. You can see the full list here:

And in our case we are looking for the “Suppress Empty Nodes” property (or suppress_empty_nodes). By setting this property to “True” it will remove all the empty nodes from the XML stream.

  • This can be used to eliminate fields that are empty after being parsed, but the XSD type doesn’t allow empty values.

To accomplish that we need to:

  • In BizTalk Editor, right-click in the Schema node and select the Properties option
  • In Properties window for the schema, set the Suppress Empty Nodes property to “true”

07-Visual-Studio-Flat-File-Schema-Suppress-Empty-Nodes

After making this change, if we try to validate the previous message instance, we will notice that now everything will work perfectly.

Note: When using Delimited files, the optional element in the beginning or in the middle of the each line (record node) need always to be present in the text with empty values (;;) otherwise the parsing rules will fail or will perform an incorrect translation of the message.

If the “Birthyear” is set as string and we receive this type of messages

Sandro;Pereira;1978;Crestuma;4415
Vânia;Braziela;1981;Vila Nova de Gaia;4300
José;Silva;Crestuma;4415
Rui;Barbosa;1975;Lever;4415

The message will be translated incorrectly and there is nothing you can do about it, the end result would look like this:

  <Person xmlns="">
    <Name>José</Name>
    <Surname>Silva</Surname>
    <Birthyear>Crestuma</Birthyear>
    <Address>
      4415
      Rui
    </Address>
    <ZipCode>Barbosa;1975;Lever;4415</ZipCode>
  </Person>
Dealing with Optional Elements (last element with the data type string)

Continue in the same scenario/message type, after a further series of tests, we noticed another unforeseen situation. Once again several messages were being executed incorrected because some of the element were not being parsed the element “ZipCode” – note that this element is a string

Sandro;Pereira;1978;Crestuma;4415
Vânia;Braziela;1981;Vila Nova de Gaia;4300
José;Silva;1972;Crestuma
Rui;Barbosa;1975;Lever;4415

Note: Contrary to what happens with elements at the beginning and end of the message, if the last element is an optional element, then it is not required to appear in the text (see line 3 – it has one element less)

We don’t receive any error message in BizTalk Server runtime but we notice that we messages are being integrated with incorrect data. After further analysis, let’s take the sample above, we notice that the message are being translated incorrectly and the last node is being added to the “ZipCode” element and not in a different Person node as supposed

  <Person xmlns="">
    <Name>José</Name>
    <Surname>Silva</Surname>
    <Birthyear>1972</Birthyear>
    <Address>
      Crestuma
      Rui
    </Address>
    <ZipCode>Barbosa;1975;Lever;4415</ZipCode>
  </Person>

To solve this problem we once again need set the element, in this case “ZipCode” as optional:

  • Double-click the schema to open the item in the Schema Editor;
  • In BizTalk Editor, expand People root node, expand Person record and right-click in the ZipCode element and select the Properties option
  • In Properties window, set the “Min Occurs” property to “0”
<People xmlns="http://DelimitedBySymbols.FF_DSYMBOL_PEOPLE_Advance">
  <Person xmlns="">
    <Name>Sandro</Name>
    <Surname>Pereira</Surname>
    <Birthyear>1978</Birthyear>
    <Address>Crestuma</Address>
    <ZipCode>4415</ZipCode>
  </Person>
  <Person xmlns="">
    <Name>Vânia</Name>
    <Surname>Braziela</Surname>
    <Birthyear>1981</Birthyear>
    <Address>Vila Nova de Gaia</Address>
    <ZipCode>4300</ZipCode>
  </Person>
  <Person xmlns="">
    <Name>José</Name>
    <Surname>Silva</Surname>
    <Birthyear>1972</Birthyear>
    <Address>Crestuma</Address>
  </Person>
  <Person xmlns="">
    <Name>Rui</Name>
    <Surname>Barbosa</Surname>
    <Birthyear>1975</Birthyear>
    <Address>Lever</Address>
    <ZipCode>4415</ZipCode>
  </Person>
</People>

There is a Flat File Schema property call “allow_early_termination” (Early Terminate Optional Fields) that is a Boolean property. The use of this property is this situation is incorrect and does produce any changes in outcome. We will address and explain this property at another time.

Some references:

Related posts:

You can download all the code used here from:

BizTalk Server: Dealing with Files Delimited by Symbols (96 KB)
Microsoft | Code Gallery


BizTalk Server: Teach me something new about Flat Files (or not) – Positional Files

$
0
0

In the second post of this series we follow a simple walkthrough explaining the basic principles to create a flat file schema from a file delimited by symbols. Now it’s time to do the same thing, but this time translating an inbound positional flat-file.

A positional flat file it’s normally a file that has fields that have a fixed maximum length and records that have a common end-of-record terminator, for example:

Sandro      Pereira         {CR}{LF}
José        Silva           {CR}{LF}

Where the first fixed 12 characters describe the Name field and the following 16 characters describe the Surname field. White space padding the end of each field and the Carriage Return/Line Feed characters is the common end-of-record terminator.

The following walkthrough shows you how to create a flat file schema from a positional flat-file document that stores employee information using the BizTalk Flat File Schema Wizard.

Field Description Length
GroupId 4
PrimaryKey 2
SecondaryKey 2
ControlFlag 1
PartyNo 1
Remark 3
Country 10
Name 12
Surname 16
Street 22
City 12
District 19
ZipCode

File sample:

0120200300 01 PT        Sandro      Pereira         Rua Central, 133      Crestuma    Vila Nova de Gaia  4415 Crestuma
0120200300 01 PT        José        Silva           Crestuna              Crestuma    Vila Nova de Gaia  4415 Crestuma
0120200300 01 PT        Rui         Barbosa         Porto                 Porto       Porto              4400 Crestuma
0120200300 01 PT        Miguel      Silva                                 Porto       Porto              4415 Crestuma

Once again I will walk you through the required steps at design time:

  • using the Flat File Schema Wizard to generate the Flat File Schema;
  • and the pipeline editor to create a custom pipeline;

To enable the runtime to support the processing of the Flat File described earlier (Employees)

We begin then by launching Visual Studio and create or open a BizTalk project:

  • “File –> New –> Project”, on BizTalk Projects, select the option “Empty BizTalk Server Project”;
  • Insert the project name, physical location on the disk and the name of the solution.
Using Flat File Schema Wizard to generate a schema based on a positional flat-file

To create the schema which will recognize the ‘Employees’ text file, we need to go to the BizTalk solution created in Visual Studio and perform the following steps:

  • Press the right button on top of the project in Solution Explorer, and select the option “Add –> New Item…
  • On “Installed Templates” menu in the window “Add New Item”, select the option “Schema Files”, and then select the option “Flat File Schema Wizard”, then provide the name you want to give the scheme in this example: “FF_Positional_Employees.xsd”

Once again, has we explain previous, by selecting this option, we will be guided automatically by the tool “BizTalk Flat File Schema Wizard” that will help us to create a Flat File Schema and define its data structure (records, elements, attributes …) based on the text file specified.

  • Select “Next” to continue.

01-BizTalk-Flat-File-Schema-Wizard-Welcome-Page-positional

  • In the window “Flat File Schema Information” we will have to:
    • Select an instance of the text file that will serve as the model of the structure that we want to transform;
    • Although it is not necessary, it is good practice to rename the Record name “Root”.
      • In this case we will rename it to “Employees”
    • And finally, assign a “Target namespace” to the scheme and define the encoding of the input file

02-BizTalk-Flat-File-Schema-Wizard-information-positional

Note: The wizard will load the text file so that we can begin to split it and map it into the desired structure. In this step we need to define how the records or rows are differentiated.

  • Since each record “Employee” that we want to create is defined in a single line, in the “Select Document Data” we can select only the data portion of the document that will set the record, i.e. the whole first line.

04-BizTalk-Flat-File-Schema-Wizard-Document-Data-positional

Note: Alternatively, let’s call it option 2, we could select all the data of the file, however with this approach we need to treat differently the data a few steps ahead in the “Child Elements” window.

05-BizTalk-Flat-File-Schema-Wizard-Document-Data-positional

Note: if you notice that some characters are not being parsed correctly as the picture bellow shows, then you probably need to go back to the “Flat File Schema Information” windows and set a different code page, for example “Western-European (1252)” instead of “UTF-8 (65001)”.

03-BizTalk-Flat-File-Schema-Wizard-Document-Data-positional

  • In the window “Select Record Format”, even though we are dealing with a positional flat-file, at this point we are trying to define the structure of each “Employee” record witch is delimited by a return Carriage Return/Line Feed ({CR}{LF}). So in this case we will have to select the “By delimiter symbol” option.

06-BizTalk-Flat-File-Schema-Wizard-Record-Format-positional

  • In the window “Delimited Record” we will provide the record delimiter, once again, we want to define the structure of Employee, i.e. each row is an Employee node, our limiter is this sample will be the {CR}{LF} (Carriage Return/Line Feed).

07-BizTalk-Flat-File-Schema-Wizard-Delimited-Record-positional

  • In the window “Child Elements” we will define what kind of element we want to assign to the registry. As we are defining the Employee structure and the file contains multiple employees, we have to select the “Element Type” as “Repeating record” If we do not perform this step, we will not have the ability to split the record into multiple elements / attributes individual.
    • Note: If you do not define the element as “Repeating record” (or “Record”), you will not have the ability to break down your record into individual elements or attributes.

08-BizTalk-Flat-File-Schema-Wizard-Child-Elements-positional

Note: earlier I told that we could select all the data inside the flat file and that we would need to treat the information differently in this step – option 2. So if you select this option, it will present all the lines in the document in this window, because we want to have an “Array” of Employees, in this step we need to select the “Element Type” of the first element as “Repeating record” and the rest of the set as “Ignore” (You set this to Ignore because you have already specified Repeating Record for the Employee node)

09-BizTalk-Flat-File-Schema-Wizard-Child-Elements-positional

In this point, we have defined the translation rules for the repeating record “Employee” but we have not broken down the various elements that compose the record itself. We have just map that each line of the text file corresponds to a record Employee.

  • In the “Schema View” select “Next” to continue processing the message

10-BizTalk-Flat-File-Schema-Wizard-Employee-Record-positional

At this point everything is exactly the same as we did in the Delimited by Symbols example. From here forward is that the changes will emerge.

  • In this phase the wizard restarts the whole process described above, but if you noticed, the wizard no longer selects all information contained in the text file, but only what was selected to define the record Employee. What we will do now is split the information of record “Employee” in different elements, for that, we will select only the information required leaving out the Carriage Return/Line Feed. On the “Select Document Data” screen click “Next”.

11-BizTalk-Flat-File-Schema-Wizard-Document-Data-positional

  • On the “Select Record Format” screen, because now the content of the “Employee” record needs to be parsed according to predefined length (positional), we need to select the option “By relative positions” and then click “Next”

12-BizTalk-Flat-File-Schema-Wizard-Record-Format-positional

  • The wizard provides a visual tool for showing and calculating the distance between the fields. On the “Positional Record” page, Use the left mouse button (or the right) to click a position marker in the position selection box to set the new position marker line. The position marker is represented as a solid line in will represent the rule in which a specific name field begins.
    • Position Marker selection box: Click an area on the page to represent the beginning position of the element. Click again to remove the position marker.
    • By default, a position marker line exists at the beginning of the record at position zero.
    • Click the following position markers to represent the rest of the data fields:
Field name Position Marker
GroupId 0
PrimaryKey 4
SecondaryKey 6
ControlFlag 8
PartyNo 9
Remark 11
Country 14
Name 24
Surname 36
Street 52
City 74
District 86
ZipCode 105

13-BizTalk-Flat-File-Schema-Wizard-Positional-Record-positional

  • In the “Child Elements” page, we will define the different elements/attributes of the structure of the record person. This operation is very similar to any XSD, where we can define the different names and data types. Adjust the values to:
    • Have the same name of the table above in the “Element Name”
    • Leave the default “Element Type” and “Date Type” – Field element and String

14-BizTalk-Flat-File-Schema-Wizard-Child-Elements-positional

Note: Once again, you should rename the parent node, each record, element or attribute in the BizTalk Flat File Schema Wizard, mainly in this step by modify the “Element Name” field to your desired name, however if you forgot to do that or if you make a mistake defining one of them, you can always rectify it in the Schema Editor. The same applies to the Data Type.

  • Select “Next” to continue.
  • Finally the wizard will show the equivalent XML structure that your text file document will have. Once you select the option “Finish”, the scheme will be available for you to use in your BizTalk solution.

15-BizTalk-Flat-File-Schema-Wizard-Complete-positional

After we finalize the creation of the Flat File Schema which will contain the translation/transformation rules of the text file, we can easily test our parsing rules, without having to get out of our development tool (Visual Studio) and without having to deploy our solution.

If we select the Flat File Schema that we just created and access to its properties, we can see that by default all properties are preconfigured so that we can perform tests to our message transformation:

  • The input instance file is configured with the file which was used to create the schema;
  • And with the correct input and output formats
    • Validate Instance Input Type: Native
    • Generate Instance Output Type: XML

To test, you simply right-click in the schema that we just created and select the option “Validate Instance”. This option will use the configured file to execute and validate all transformation rules defined in the Flat File Schema and present the final result or occurring errors in the “Output” window

16-BizTalk-Flat-File-Schema-Wizard-Testing-positional

Did you know that Fields in positional records have a limit of 50000000 characters?

Creating the Pipeline that will be responsible for processing and transforming the text file

Once again we need to create at least one custom pipeline (receive pipeline) to process this flat-file document and translate it into is equivalent in XML.

To create the Receive Pipeline that will be responsible for processing and transforming the text file, we need to go to the BizTalk solution created in Visual Studio and perform the following steps:

  • Press the right button on top of the project in Solution Explorer, and select the option “Add –> New Item…”.
  • On “Installed Templates” menu in the window “Add New Item”, select the option “Pipeline Files”, and then select the option “Receive Pipeline”, then provide the name you want to give the pipeline in this example: “FF_Employee_ReceivePipeline.btp”
  • By selecting the option “Add”, the pipeline editor (BizTalk Pipeline Designer) will appear and that will let you view and add components to all the steps associated with receive pipeline: Decode, Disassemble, Validate and ResolveParty.

In this case, the pipeline that we will create, will be responsible for receiving a text file through a receive location and convert it to XML. For that, we will use the “Flat File Disassembler” component which is available in the Visual Studio Toolbox window (Ctrl+W, X).

  • Drag it into the Pipeline in step “Disassemble”.

17-BizTalk-Flat-File-Pipeline-positional

  • Finally, select the component “Flat file disassembler”, go to its properties and on the “Document Schema” option: select the schema created earlier, in case the “PositionalTextFiles.FF_Positional_Employees”.

18-BizTalk-Flat-File-Pipeline-positional

Note: If you want to create a send pipeline in order to transform an XML document into Flat File, we would follow the same steps, the difference is that we would have to drag the component “Flat File Assembler” on stage “Assemble”.

Once you have deployed your solution, you will want to ensure that you select the custom pipeline we just created in the Receive Locations that you expect to receive these flat files.

Now here it comes the same questions: Do you think the schema is entirely correct? Does it handles with all files accordingly to the expected results?

Or do we need to tune some of the properties of your schema… stay tuned to the next post.

Related posts:

You can download all the code used here from:

BizTalk Server: Dealing with Positional Flat Files (14 KB)
Microsoft | Code Gallery


The coolest tracking app for your Microsoft Band

$
0
0

I know that is not the coolest app that you will find, nor was that the goal, but probably will be the first BizTalk Blog available for your band Smile

Microsoft Band helps you live healthier and achieve more by tracking your heart rate, exercise, calorie burn, and sleep quality, and helps you be productive with email, text, and calendar alerts… and now also your favorite blog (or not Smile)

SandroaspBizTalkBlog-Web-Tile-Microsoft-band-v2

I had (and still have) the original Microsoft Band but on my last trip to the United States, in which I was attend in another MVP Summit in Redmond, I decided to buy the new Microsoft Band 2 and while I was searching about new features and capabilities I found out that Microsoft had announced, more or less this last July, some new features and functionality for both the Microsoft Band and Microsoft Health, especially the Web Tiles. And with that, the capability for this device to receive glanceable information from nearly any source.

So, just for fun I decide play around with this features and create the “SandroaspBizTalkBlog Web Tile” that will allow you to “track” my blog from your new or old Microsoft Band.

SandroaspBizTalkBlog-Web-Tile-Microsoft-band-app

This way, when a new blog post will be published you will receive a notification on your wrist!

You can download the “SandroaspBizTalkBlog Web Tile” here:

SandroaspBizTalkBlog Web Tile for Microsoft Band (5 KB)
Microsoft | TechNet Gallery

 

To install it you just need to open the “mytile.webtile” from your mobile device that has the Microsoft Health application installed. The app will do the rest.


How to fix or configure the Deployment Properties of a BizTalk Project with PowerShell

$
0
0

It is nothing new that before you can deploy a solution from Visual Studio into a BizTalk application, you must first set project properties, especially the Server and the Configuration Database. Otherwise two things may happen:

  • Deployment will fail when you try do to deploy it through Microsoft Visual Studio or will you are redeploying a previously deployed BizTalk project.
  • The assemblies and all their artifacts will be deployed to and unwanted BizTalk Application (normally BizTalk Application 1)

If a solution in Visual Studio contains multiple projects, you must separately configure properties for each project.

To configure project properties you normally need to:

  • In Visual Studio Solution Explorer right-click a project for which you want to configure properties, and then click Properties.
  • Click the Deployment tab in Project Designer.
  • Configure the following project properties
    • Application Name: Name of the BizTalk application to which to deploy the assemblies in this project. If the application already exists, the assemblies will be added to it when you deploy the project. If the application does not exist, the application will be created. If this field is blank, the assemblies will be deployed to the default BizTalk application in the current group. Names that include spaces must be enclosed by double quotation marks (“).
    • Configuration Database: Name of the BizTalk Management database for the group, BizTalkMgmtDb by default.
    • Server: Name of the SQL Server instance that hosts the BizTalk Management database on the local computer. In a single-computer installation, this is usually the name of the local computer.
    • Redeploy: Setting this to True (the default) enables you to redeploy the BizTalk assemblies without changing the version number.
    • Install to Global Assembly Cache: Setting this to True (the default) installs the assemblies to the Global Assembly Cache (GAC) on the local computer when you install the application. Set this to False only if you plan to use other tools for this installation, such as gacutil.
    • Restart Host Instances: Setting this to True automatically restarts all host instances running on the local computer when the assembly is redeployed. If set to False (the default), you must manually restart the host instances when you redeploy an assembly.
    • Enable Unit Testing: Specifies whether to enable unit testing for the project.
  • And then click OK.
  • Repeat steps 1, 2, and 3 for each project in the solution.

Deployment-Properties-BizTalk-Project-Visual-Studio

This seems a slight and easy task but now imagine that you have almost 200 projects inside a unique Visual Studio Solution! It will be an insane operation and the most likely to happen is you to fall asleep in front of the pc.

With this PowerShell you will be able to parameterize all projects inside a Visual Studio Solution running a single line of code and avoid spending numerous hours doing this task manually.

    $allPropertyGroup = $xml.Project.PropertyGroup
    foreach($node in $allPropertyGroup)
    {
        if($node.Server -ne $null)
        {
            $node.Server= "<BizTalkServer>";
            $node.ConfigurationDatabase= "BizTalkMgmtDb";
            $node.ApplicationName= "<BTSApplicationName>";
            $node.Redeploy= "False";
            $node.Register= "True";
            $node.RestartHostInstances= "False";
        }
    }

You can download the PowerShell Script used here from:

BizTalk Server: Fixing BizTalk Project Deployment Properties with PowerShell (1 KB)
Microsoft | TechNet Gallery



How to fix or configure the Signing Properties of a BizTalk Project with PowerShell

$
0
0

In the previous post it was provide a PowerShell script to fix or configure the Deployment Properties of a BizTalk project. However, and this is also nothing new, before deploying a BizTalk project we must first strongly sigh the assemblies involved in the project to give them an unique identification for allowing them to be installed into the GAC.

GAC (Global Assembly Cache) is a machine code cache that stores assemblies that can be shared by multiple applications on the computer. This assemblies needs to be strongly signed so that they can have a unique identification in the GAC.

A strong-named assembly provides several security benefits:

  • A strong name guarantees the uniqueness of the assembly by assigning a digital signature and a unique key pair.
  • A strong name protects the lineage of the assembly by ensuring that no one else can generate a subsequent version of the assembly.
  • A strong name provides a strong integrity check to guarantee that the contents of the assembly have not changed since the last build.

In the process of deploying a BizTalk solution, Visual Studio first builds the assemblies. The deployment process requires that each assembly is strongly signed. You can strongly sign your assemblies by associating the project with a strong name assembly key file. If you haven’t already done so, before deploying a solution from Visual Studio, use the following procedure to generate a strong name assembly key file and assign it to each project in the solution.

To configure a strong name assembly key file

  • In Visual Studio Solution Explorer, right-click the project and then click Properties.
  • Click the Signing tab and choose “Browse…” or “New…” in the Choose a strong name key file drop down box.
  • Create a new key or browse to the key file and click it. Click Open, and then close the project properties.
  • Repeat steps 3 through 6 for each project in the solution that you want to deploy using this strong name assembly key file.

Signing-Properties-BizTalk-Project-Visual-Studio

Once again, if a solution in Visual Studio contains multiple projects, you must separately configure properties for each project.

This seems a slight and easy task but now imagine that you have almost 200 projects inside a unique Visual Studio Solution! It will be an insane operation and the most likely to happen is you to fall asleep in front of the pc… once again.

With this PowerShell you will be able to parameterize all projects inside a Visual Studio Solution running a single line of code and avoid spending numerous hours doing this task manually.

    foreach($node in $allPropertyGroup)
    {
        if($node.AssemblyOriginatorKeyFile -ne $null)
        {
            $node.AssemblyOriginatorKeyFile= "<keyname>.snk";
        }
    }

    if($xml.Project.ItemGroup.None -eq $null)
    {
        $childItemGroup = $xml.CreateElement("ItemGroup",$xdNS)
        $childNone = $xml.CreateElement("None",$xdNS)
        $childNone.SetAttribute("Include", "<keyname>.snk")
        $childItemGroup.AppendChild($childNone)
        $xml.Project.InsertBefore($childItemGroup, $xml.Project.Import[0])
    }

You can download the PowerShell Script used here from:

BizTalk Server: Fixing BizTalk Project Signing Properties with PowerShell (2 KB)
Microsoft | TechNet Gallery


Microsoft Message Queuing Testing Tool

$
0
0

In the last couple of days I been working (migrating a BizTalk Solution from BizTalk Server 2004 to BizTalk Server 2013 R2) in a solution that works deeply with Microsoft Message Queuing (MSMQ). It receives messages from private queue with the use of the MSMQ Adapter and send messages to other Queues (among other channels) that are consumed by other applications/servers.

And one of the things that I intended to do was partial tests, in a very simple way, to validate if all my receive ports were well configured in order to consume the expected messages.

Microsoft Message Queuing Testing Tool” is a simple tool that you can use to test sending files to Microsoft Queue.

Microsoft Message Queuing or MSMQ is a message queue implementation developed by Microsoft and deployed in its Windows Server operating systems and enables applications running at different times to communicate across heterogeneous networks and systems that may be temporarily offline. It provides guaranteed message delivery, efficient routing, security, and priority-based messaging.

With this tool you can easily send messages to a queue in order to evaluate whether other applications are reading correctly the messages.

Microsoft-Message-Queuing-Testing-Tool

This tool allows you to set:

  • The queue where you want to send the files/messages
  • A Label associated to the file/message
  • The Queue transaction type
  • Import an existing file or manually add a message

Microsoft-Message-Queuing-Testing-Tool-result

And it will provide:

  • success of delivery information (with transaction id)
  • or error detail information

I like simple tool that allow me to test my integration scenarios/projects, so I decided today to take some of my time to create this very simple and basic tools, but at least for me, that will be very useful.

Hope you enjoy also.

You can download this tool here:

Microsoft Message Queuing Testing Tool (79,9 KB)
Microsoft | Code Gallery


Microsoft Message Queuing Testing Tool updated

$
0
0

I just released yesterday, but I’ve decided to do a small update to this tool bringing new functionalities in order to solve some limitations, especially Character Encoding problem.

Portuguese language have many letters with accents and while importing/reading the files in the previous version, all accented letters are printed as a question mark. It was obvious that I had a problem with Encoding.

Again, “Microsoft Message Queuing Testing Tool” is a simple tool that you can use to test sending files to Microsoft Queue in order to evaluate whether other applications are reading correctly the messages.

I’m using it to send messages to a queue that is being consumed by BizTalk Server

RELEASE NOTES

Version 2.0 brings:

  • Improvements in the “Message Label” auto fill
  • Improvements in the “Import Message File” functionality with better control of the encoder associated with the file
    • Add the ability to choose the code page identifier

Microsoft-Message-Queuing-Testing-Tool-v2

Hope you enjoy it.

You can download this tool here:

Microsoft Message Queuing Testing Tool (79,9 KB)
Microsoft | Code Gallery


Thanks! Awarded as Microsoft Azure MVP 2016

$
0
0
Microsoft Integration MVP 2013

Microsoft Azure MVP 2016

Thanks Microsoft for another wonderful start of New Year. Once again I’m delighted to share that I was renewed, for the 6th straight year, as MVP (Microsoft Most Valuable Professional), this time after the changes that have occurred in the Microsoft MVP Program, as a Microsoft Azure MVP.

I never thought to become who I am today, it never crossed my mind… I started playing with computers when I was 5 or 6-year-old with my Timex Sinclair 2068 and the felling I had that day is still on my blood… I grow playing games and compete with my old brother, my two young cousins and some of my friends, looking back, I knew somehow that my future would be related with this area (IT, computers). Then I was lucky to find the ideal people at the right time who believed in me and that encouraged me to become what I am today, for that a huge and special thanks to Rui Barbosa and José António Silva… and I am a lucky person because I am paid to do what I love the most!

But it was only a few years ago that I decide to start to share my knowledge, largely through my blog, which began as a kind of personal notebook, it was all about having fun and a way to escape the stress of everyday life…nothing has change! But without realizing it, sharing my knowledge allowed me to grow as a person, to see the World and to meet amazing people and the most amazing friends!

My “wife” says that the computer in an extension of my personality, she met me that way, she loves me the way I am and for that reason she encourage me to become even better, thanks Fernanda for all your support!

Once again a big thanks to the MVP Team in especially to my MVP Lead Cristina Herrero and Alessandro Teglia, to all members of BizTalk and Azure Product Teams, Microsoft Portugal, all community members and special to my readers.

To my family, to the BizTalkCrew (Nino Crudele, Tord Glad Nordahl, Saravana Kumar and Steef-Jan Wiggers) and to all my coworkers at DevScope: THANKS for all the support during this last years!

It’s a big honor to be in the program and I’m looking forward to another great year. And remember Enjoy life, follow your dreams and most importantly have fun!

WP_20160101_21_59_48_ProWP_20151206_16_08_37_Pro

(In the right: my family celebrating; in the left: me and Fernanda)

In my native language (Portuguese):

Obrigado Microsoft para outro maravilhoso início de Ano Novo. Estou muito feliz por poder partilhar com todos vocês que fui nomeado Microsoft Most Valuable Professional (MVP) 2016|

Esta é a sexta vez que recebo este prémio e como é normal nestas ocasiões, gostaria de agradecer a todos os leitores do meu blog, amigos, a todos os membros da comunidade. Também gostaria de agradecer a minha MVP Lead Cristina Herrero, ao Alessandro Teglia, a todas as pessoas da Microsoft em especial à equipa de produto do BizTalk e Azure, Microsoft Portugal, a todos os meus colegas Microsoft Integration MVP’s e a todos os MVP’s Portugueses.

Eu também gostaria de fazer um agradecimento muito especial a minha há minha família e a minha linda namorada Fernanda por todo o seu suporte neste ultimo ano, ao membros do BizTalkCrew (Nino Crudele, Tord Glad Nordahl, Saravana Kumar e Steef-Jan Wiggers) e, finalmente, a todos os meus colegas de trabalho na DevScope, dos quais eu gostaria de destacar este ano o Rui Quintino e o João Sousa que se tornaram este ano MVP’s pela primeira vez! Parabéns!

É uma grande honra estar no programa e espero continuar a contribuir para a comunidade BizTalk, e integração no geral, e a merecer o reconhecimento.


BizTalk Mapper tips and tricks: How to reuse Scripting Functoids with Inline C# inside the same map

$
0
0

In the last days I’ve been migrating old maps from BizTalk Server 2004 to the last versions of BizTalk Server: 2013 and 2013 R2 and I have seen several “styles/approaches” to address mappings, some of them great, some of them not so much and other completely crazy.

Today I will address a topic that I, unfortunately, have seen constantly: Reusing Scripting Functoids with Inline C# inside the same map. This is also something that I address in my book: “BizTalk Mapping Patterns & Best Practices

Inline scripts are convenient for custom code that you are unlikely to use elsewhere in your application or other maps. In addition to being convenient for one-time scripts, inline scripts are also useful for declaring global variables for use among a number of scripts and to use several times inside the same map.

In general, some of the main reasons to use Scripting Functoid are:

  • Perform functions otherwise not available with built-in Functoids
  • It also allows you to perform complex logic transformations that are impossible to make with built-in Functoids.
  • To simplify the map, making it sometimes more easy to read, instead of using a complex Functoid chain
  • Or simply to optimize the transformation rules

However, you need to have some precautions when using, or reusing the same, Custom Inline C# scripts inside the Scripting Functoid:

  • Function Names Limitation
  • Compiler limitations
  • Reusability
Function Names Limitation

For each function/method inside the Scripting Functoid you need to give different Method statements (name of the method + method parameters). If you have the same Method statement with different behaviors inside, for example:

  • In the first Scripting Functoid:
public string FormatDate(string inputDate, string inputFormat, string outputFormat)
{
    System.DateTime date;
    if (System.DateTime.TryParseExact(inputDate, inputFormat,
        System.Globalization.CultureInfo.InvariantCulture,
        System.Globalization.DateTimeStyles.AssumeLocal, out date))
    {
        return date.ToString(outputFormat);
    }
    return "";
}
  • And in the second Scripting Functoid:
public string FormatDate(string inputDate, string inputFormat, string outputFormat)
{
    if (String.IsNullOrEmpty(inputDate))
        return System.DateTime.Now.ToString(outputFormat);
    return inputDate;
}

Different-Scripting-Functoid-With-The-Same-Name-Not-Ok

Because both methods have the name and the same number of parameters, the mapper will interpret has the same, regardless if the code inside the functions are the same of not. In this case the first mapping rules to be reached is the first scripting functoid, which means that the second code inside the second functoid will be ignored and instead will be executed the exact same code that the first one, which is not what intended to do.

You can validate this map behavior if you validate the map and see the XSL produced:

<msxsl:script language="C#" implements-prefix="userCSharp"><![CDATA[
public string FormatDate(string inputDate, string inputFormat, string outputFormat)
{
 System.DateTime date;
 if (System.DateTime.TryParseExact(inputDate, inputFormat, System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.AssumeLocal, out date))
 {
    return date.ToString(outputFormat);
 }
 return "";
}
]]></msxsl:script>

To fixed this we need to give a different name to the second method, for example:

public string ValidateAndFormatDate(string inputDate, string inputFormat, string outputFormat)
{
    if (String.IsNullOrEmpty(inputDate))
        return System.DateTime.Now.ToString(outputFormat);
    return inputDate;
}

Nevertheless, you can give the same method name, if the method has a different number of inputs, for example this case is a valid example:

  • In the first Scripting Functoid:
public string FormatDate(string inputDate, string inputFormat, string outputFormat)
{
    System.DateTime date;
    if (System.DateTime.TryParseExact(inputDate, inputFormat,
        System.Globalization.CultureInfo.InvariantCulture,
        System.Globalization.DateTimeStyles.AssumeLocal, out date))
    {
        return date.ToString(outputFormat);
    }
    return "";
}
  • And in the second Scripting Functoid:
public string FormatDate()
{
    return System.DateTime.Now.ToString();
}

Different-Scripting-Functoid-With-The-Same-Name-Ok

Once again if you validate the map to see the XSL produced, you can see that in this case both functions are being generated:

 <msxsl:script language="C#" implements-prefix="userCSharp"><![CDATA[
public string FormatDate(string inputDate, string inputFormat, string outputFormat)
{
 System.DateTime date;
 if (System.DateTime.TryParseExact(inputDate, inputFormat, System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.AssumeLocal, out date))
 {
   return date.ToString(outputFormat);
 }
 return "";
}
public string FormatDate()
{
 return System.DateTime.Now.ToString();
}
]]></msxsl:script> 
Compiler limitations

When you create a script, for example a C# function, remember to give it a correct name because all scripts with the same name are treated as one by the compiler regardless of whether the code is equal or not.

You also have to take in consideration that BizTalk Mapper engine will save the inline scripts in the Extensible Stylesheet Language Transformations (XSLT) Stylesheet defining the map in the within the msxsl:script element. The following namespaces are supported by default: System, System.Collection, System.Text, System.Text.RegularExpressions, System.Xml, System.Xml.Xsl, System.Xml.Xpath, Microsoft.VisualBasic. You can add support for additional namespaces outside the listed using the namespace attribute of the child element, <msxsl:using>, of the <msxsl:script> element, but this will force us to use an External Custom XSLT file to accomplish the transformation. See more here: XSLT Stylesheet Scripting Using <msxsl:script> (http://msdn.microsoft.com/en-us/library/533texsx%28v=vs.110%29.aspx)

Reusability

Now let go to the main topic of this post Reusability of Scripting Functoids with Inline C# inside the same map.

What I normally see is people doing two things:

  • Copy and paste the entire method to all the Scripting Functoids – I’m calling that: Reusing in a Bad Way
    • In this case both scripting functoids have the exact same code
public string FormatDate(string inputDate, string inputFormat, string outputFormat)
{
    System.DateTime date;
    if (System.DateTime.TryParseExact(inputDate, inputFormat,
        System.Globalization.CultureInfo.InvariantCulture,
        System.Globalization.DateTimeStyles.AssumeLocal, out date))
    {
        return date.ToString(outputFormat);
    }
    return "";
}

Reuse-Scripting-Functoid-Bad-Way

This is a very simple case, now imagine a map with several grid pages and several functoids. The problem is this approach, as we explained earlier, is that if we for some reason change the code of one the scripting functoids, that is not the first to be translated by the mapper engine, the changes will not take effect!!!

  • Copy and paste the entire method to all the Scripting Functoids and give it a different name! – I’m calling that: Reusing in a Crazy Way
    • In this case the first scripting functoids have:
public string FormatDate(string inputDate, string inputFormat, string outputFormat)
{
    System.DateTime date;
    if (System.DateTime.TryParseExact(inputDate, inputFormat,
        System.Globalization.CultureInfo.InvariantCulture,
        System.Globalization.DateTimeStyles.AssumeLocal, out date))
    {
        return date.ToString(outputFormat);
    }
    return "";
}
  • And the second one have:
public string FormatDate2(string inputDate, string inputFormat, string outputFormat)
{
    System.DateTime date;
    if (System.DateTime.TryParseExact(inputDate, inputFormat,
        System.Globalization.CultureInfo.InvariantCulture,
        System.Globalization.DateTimeStyles.AssumeLocal, out date))
    {
        return date.ToString(outputFormat);
    }
    return "";
}

The one difference is that the first one is call FormatDate and the second FormatDate2. I’m not joking, I saw this approach being used nearly 8 times (Func1, Func2, Func3, Func4, … Func8) in a map! Of course this solve the problem of the first approach but now you have another! The artifact size deployed will be larger, not critical, but if you can avoid is better. This will happen because in this case all method will be embed in the XSL file that will be deployed to your environment.

  <msxsl:script language="C#" implements-prefix="userCSharp"><![CDATA[
public string FormatDate(string inputDate, string inputFormat, string outputFormat)
{
 System.DateTime date;
 if (System.DateTime.TryParseExact(inputDate, inputFormat, System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.AssumeLocal, out date))
 {
    return date.ToString(outputFormat);
 }
 return "";
}
public string FormatDate2(string inputDate, string inputFormat, string outputFormat)
{
 System.DateTime date;
 if (System.DateTime.TryParseExact(inputDate, inputFormat, System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.AssumeLocal, out date))
 {
    return date.ToString(outputFormat);
 }
 return "";
}
]]></msxsl:script>

Another problem, even worse, of this approach is that, if you need to make some changes in the method… you need to do the same changes in every single functoid! If you want them to work in a coherent and transparent way.

So what is the best way to reuse Scripting Functoids with inline C#?

Easy! You need to remember that when you have two or more Custom Inline C# scripts with the same Method statement (name of the method + method parameters), the compile will only take in consideration the first one linked in the map, even if the others have a different code inside they are ignored by the compiler.

Reuse-Scripting-Functoid-Good-Way

When we use Custom Inline C# scripts the best way to implement reusability is to specify the body function in only one Scripting Functoid and the remaining ones specify only the function declaration, in this sample in the first Scripting Functoid will have the following code:

public string FormatDate(string inputDate, string inputFormat, string outputFormat)
{
    System.DateTime date;
    if (System.DateTime.TryParseExact(inputDate, inputFormat,
        System.Globalization.CultureInfo.InvariantCulture,
        System.Globalization.DateTimeStyles.AssumeLocal, out date))
    {
        return date.ToString(outputFormat);
    }
    return "";
}

And the second one only the following declaration:

public string FormatDate(string inputDate, string inputFormat, string outputFormat)

Easy, isn’t it?
Hope you enjoy it.

You can download this tool here:

BizTalk Mapper Tips and Tricks: How To Reuse Scripting Functoids with Inline C# (18,6 KB)
Microsoft | Code Gallery


Installing BizTalk Server 2013 R2 in a Basic Multi-Computer Environment (User Guide)

$
0
0

Finally, something that many community members have been requesting me to publish is here! I already made this manual several months ago, however, for several reasons (speaking engagements, publishing other content and so on) I have been delaying its publication. But I have offered this same guide to all my customers.

There are many things to consider when planning this type of installation, often the network infrastructure already exists and BizTalk Server must coexist with other network applications.

Installing BizTalk Server 2013 R2 in a Basic Multi-Computer Environment (User Guide) is a 145 pages detailed installation document that explains how to install, configure and optimize Microsoft BizTalk Server 2013 R2 on a basic multi-computer running Windows Server 2012 R2. This information will help you to plan the installation and configuration of BizTalk Server 2013 R2, applications and components on which it depends.

Contents                                      
  1. BizTalk Server Installation scenario.
  2. The need for a Domain Controller – Windows Groups and Service Accounts.
    1. Create Domain Groups and Users.
    2. Planning the use of a new Organizational Unit.
    3. Windows Groups Used In BizTalk Server.
    4. IIS_WPG and IIS_IUSRS Group.
    5. User and Service Accounts Used In BizTalk Server.
    6. Summary of users and Groups Affiliation.
    7. SQL Server Service Accounts.
    8. References.
  3. Preparing Computers for Installation – Important considerations before set up the servers.
    1. Change the Machine name.
    2. Join the Local Administrators Group.
    3. The user running the BizTalk Server configuration must belong…
    4. Install Critical Windows Updates.
    5. Disable IPv6 (optional).
    6. Turn off Internet Explorer Enhanced Security Configuration (optional).
    7. Disable User Account Control (optional).
    8. Turn Windows Firewall off (optional).
    9. Configure Microsoft Distributed Transaction Coordinator (MS DTC).
    10. COM+ Network Access considerations.
  4. Preparing and Install SQL Server 2014 machine.
    1. Important considerations before set up the servers.
    2. Install SQL Server 2014.
    3. Configure SQL Server Database Mail feature.
    4. Install Service Pack 1 for Microsoft SQL Server 2014.
    5. Configure SQL Server for Remote Connections.
    6. Configured SQL Server protocols – Disable the Shared Memory Protocol, Enable TCP/IP and Named Pipes.
    7. Configure SQL Server Database Engine to listen on a specific TCP Port (optional).
    8. Configure SQL Analysis Server to listen on a specific TCP Port (optional).
    9. Configuring Microsoft Distributed Transaction Coordinator (DTC) to work through a firewall or network address translation firewalls (optional).
    10. List of ports between BizTalk Server and SQL Server (optional).
    11. Configure Firewall on SQL Server machine (optional).
      1. Inbound Rules.
      2. Outbound Rules.
  5. Preparing and install prerequisites on BizTalk Server 2013 R2 machine.
    1. Important considerations before set up the servers.
    2. Enable Internet Information Services.
    3. Running the BAM Portal in a 64-bit Environment.
    4. Install Windows Identity Foundation (WIF) (optional).
    5. Install Microsoft Office Excel 2013 (optional).
    6. Install Visual Studio 2013 (optional).
    7. Remove Microsoft SQL Server Express.
    8. SQL Server Considerations.
    9. Install SQL Server 2014 Client Tools.
    10. Create SQL Alias to communicate with remote SQL Server using Non-Standard Port (optional).
    11. List of ports between SQL Server and BizTalk Server (optional).
    12. Configure Firewall on BizTalk Server machine.
      1. Inbound Rules.
      2. Outbound Rules.
  6. Testing environment connectivity’s.
    1. TCPView.
    2. DTCPing.
    3. DTCTester.
    4. SQL Server 2014 Client Tools.
  7. Install and configure BizTalk Server 2013 R2 machine.
    1. Install BizTalk Server 2013 R2.
      1. Verify Your Installation.
    2. Configure BizTalk Server.
      1. Pin BizTalk Server Administration to taskbar.
    3. Validate Mail account used by BizTalk to send BAM Alerts.
    4. Install BizTalk Adapter Pack.
      1. Microsoft BizTalk Adapter Pack and Microsoft BizTalk Adapter Pack (x64).
      2. Steps to install BizTalk Adapter Pack.
      3. Add adapters to BizTalk Administration Console.
    5. Install Critical Windows Updates and BizTalk Server Cumulative Update Package.
    6. Configure BizTalk Server SQL Jobs.
      1. How to configure Backup BizTalk Server (BizTalkMgmtDb).
      2. How to configure DTA Purge and Archive (BizTalkDTADb).
      3. MessageBox_Message_Cleanup_BizTalkMsgBoxDb.
  8. Optimize the BizTalk Server 2013 R2 environment
    1. Deleting BizTalk backup files.
      1. Implementing a custom sp_DeleteBackupHistory.
      2. Implementing a Maintenance Plan to clean BizTalk Database backup’s files.
    2. Pre-allocate space and define auto-growth settings for BizTalk Server databases. 112
    3. Configure BizTalk Server Windows Services.
    4. Install and configure BizTalk Health Monitor.
      1. How to register BizTalk Health Monitor Snap-In.
      2. How to integrate BHM Snap-In into BizTalk Admin Console
    5. Install SSO Configuration Application MMC Snap-In
    6. Configure BizTalk Jobs History (Microsoft SQL Server Agent job history log).
      1. To resize the job history log based on raw size.
    7. Force Full Backup BizTalk Server (BizTalkMgmtDb) job.
    8. Managing and cleaning BizTalk Server MarkLog database tables.
    9. Configure host and Host instances.
      1. What’s is Host, Host Instances and Adapter Handlers?.
      2. Best practices to Configuring Hosts and Host Instances.
      3. How can I automate this task?.
    10. Power Mode.
    11. Consider setting the ‘text in row’ table option to boost BizTalk Server Performance.
      1. How to exploit the Text in Row table option in BizTalk Server.
    12. General network TCP settings that can impact BizTalk Server
      1. How to Disable the Scalable Networking Pack (SNP) features
      2. How to Disable Privilege Attribute Certificate (PAC)
      3. How to Check and if necessary increase the ephemeral ports and reduce the TCP re-use timeout setting

download-whitepaper

If you are interest to see other version check the following posts:


XLANG Uncaught exception: A failure occurred while evaluating the distinguished field [MY_FIELD_NAME] against the message part data.

$
0
0

Well let’s go back to the topic: you are doing crazy things with your maps!

I was thinking that I had already seen it all, I was thinking that I had already seen it all, but the reality is that I continue to be blown away. While testing a project migration I end up catching this error:

Xlang/s engine event log entry: Uncaught exception (see the ‘inner exception’ below) has suspended an instance of service ‘[MY_ORCHESTRATION_NAME] (1582c665-816d-07db-3dee-1c6a750944a0)’.
The service instance will remain suspended until administratively resumed or terminated.
If resumed the instance will continue from its last persisted state and may re-throw the same unexpected exception.
InstanceId: 4e0d3e55-b481-442d-a2a4-9f4ee6e13fb7
Shape name: Create Client Msg
ShapeId: 0e4a8cba-c6a0-4a0f-ad94-574b2e8ab7ad
Exception thrown from: segment 1, progress 54

Inner exception: A failure occurred while evaluating the distinguished field [MY_FIELD_NAME] against the message part data. The message part data does not contain at least one of the nodes specified by the XPath expression (listed below) that corresponds to the distinguished field. The cause for this error may be that the message part data has not been initialized or that the message part data does not conform to the message part schema. Ensure that the message part data is initialized correctly. XPath expression: /*[local-name()=’ROOT_NAME’ and namespace-uri()=’NAMESPACE’]/*[local-name()=’MY_FIELD_NAME’ and namespace-uri()=”]

Exception type: XPathUpdateException
Source: Microsoft.XLANGs.Engine
Target Site: Void SetDistinguishedField(System.String, System.Object)
The following is a stack trace that identifies the location where the exception occurred
at Microsoft.XLANGs.Core.XSDPart.SetDistinguishedField(String dottedPath, Object val)
at Siva.CRM.EAI.SIVOrchestration.Client.SIV_Client_ClientAccountSubscriber_UpdDel.segment1(StopConditions stopOn)
at Microsoft.XLANGs.Core.SegmentScheduler.RunASegment(Segment s, StopConditions stopCond, Exception& exp)

I got curious to see that this problem, as the error specify clearly, was related to a distinguished field element and it was happening inside a Construct Message that was using a map.

CAUSE

The error details points for the cause of the problem and it is for sure something related to the XPath expression: /*[local-name()=’ROOT_NAME’ and namespace-uri()=’NAMESPACE’]/*[local-name()=’MY_FIELD_NAME’ and namespace-uri()=”], however, the cause may not be exactly the same.

In my case when I opened the map, I easily realize that the field that was promoted as distinguished field was being mapped twice, i.e., two source elements where being mapped to the same destination element what was causing this element to appear twice in the final message even though the destination element is defined as Max Occurs 1 and Min Occurs 0.

wrong-transformation-rule-causing-error-evaluating-distinguished-field

Of course you may know that distinguished fields are essentially XPath aliases, which simply point to the appropriate XML data field. They don’t have a size limitation but they only can appear once. You cannot promote a repeating element.

And you also should know that the map doesn’t validate the input or the output messages in runtime!

And the curious thing was that this particular distinguished field it was not being used inside the orchestration!

SOLUTION

The solution it easy for this case.

First:

  • Don’t promote elements that you are not really using or need to do some logic inside your orchestrations… If you don’t need them, don’t promote them. Distinguished fields cost less than Property Fields but they still have a cost for performance!

Second:

  • Fix the ma rule associated with this element. In my case I decide to remove the “nipc” rule and leave only the “accountId” direct link to the “EntityGuid”


BizTalk Mapper tips and tricks: How to properly implement conditions using Functoids chains

$
0
0

It’s always good to analyze code performed by others, please do not consider this a criticism, it is not my intention. Doing that you will, compare technics, learn new things, noted and we become aware of how some transformation rules are made inside the maps… and sometimes, most often when things are done in the wrong way, or not quite correct, we gain inspiration or idea to talk about it. And this is one of them, that in fact, I have seen often happening: Applying conditions (if-then-else) using sometimes complex Functoid chain.

So far nothing new, this is a trivial operation that we normally, or often, do. The thing is that often we do it wrong or not quite well.

I have already addressed the processing model of BizTalk maps on my BizTalk Mapping Patterns and Best Practices book but it is always useful to refer again. BizTalk maps follows the model below:

  • The BizTalk mapping engine traverses the destination schema from beginning to end;
  • The mapping rules are constructed and executed as links are encountered in the destination schema;
  • The information is extracted from the source when a link is encountered in the destination schema.

But you need to be extremely aware, and this is important, that when BizTalk mapper engine reach to a condition rules to construct, all the operation that are present downstream of the condition needs to be translated (executed) before the condition rule itself.

Let’s look to the following example:

Complex-Functoid-Chain-Condition-wrong

Where the basic rule that we want to implement is:

  • If the operation is equal to “insert”
    • Then we need to set, in the Cross Referencing tables, and return an identifier (Set Common ID Functoid), based on some content from the source schema and in some values present or not in the Cross Referencing tables (Get Common ID Functoid), and mapped to the “CommonId” element in the destination schema
  • If the operation is different of “insert”
    • Then we need to retrieve an identifier from the Cross Referencing tables (Get Common ID Functoid), again based on some content from the source schema, and mapped the result to the “CommonId” element in the destination schema

So, to be simple and clear, what the BizTalk mapper engine is doing in the picture above is:

  • It found 2 rules to translate, because we have two links connected with the “CommonId” element
  • In the first rule it will: If the operation is equal to “insert”
    • Get one element from the “keys” record in the source schema and put it into a variable
    • Try’s to retrieve two identifiers’, based on some content from the source schema or static data.
    • From the identifiers’ retrieve earlier, it applies some transformation rule (not important for this demo)
    • Set and return an identifier, based on the content of:
      • one element from the “keys”
      • and the transformation rule, associated to the identifiers’ retrieve earlier
    • And finally, will check if the operation is equal to “insert”
      • Then map the value of the identifier created in the previous step to the element “CommonId”
  • In the second rule it will: If the operation is different of “insert”
    • Try’s to retrieve two identifiers’, based on some content from the source schema or static data.
    • From the identifiers’ retrieve earlier, it applies some transformation rule (not important for this demo)
    • And finally, will check if the operation is different to “insert”
      • Then map the value of the identifier created in the previous step to the element “CommonId”

Are you already seeing the problem with this sample?

Let’s analyze the generated XSLT code and try to see if it makes more sense and detect the problem in a clear way:

<xsl:variable name="var:v14" select="userCSharp:LogicalNe(&quot;insert&quot; , string(@operation))" />
<xsl:variable name="var:v23" select="userCSharp:LogicalEq(&quot;insert&quot; , $var:v22)" />
<xsl:variable name="var:v18" select="ScriptNS1:GetCommonID(&quot;INPUT1&quot; , &quot;INPUT2&quot; , string($var:v17))" />
<xsl:variable name="var:v19" select="ScriptNS1:GetCommonID(&quot;INPUT1&quot; , &quot;INPUT3&quot; , string(keys/myelement/text()))" />
<xsl:variable name="var:v15" select="ScriptNS0:GetValue()" />
<xsl:variable name="var:v20" select="ScriptNS2:GetValue(string($var:v15) , string($var:v18) , string($var:v19))" />

<xsl:if test="string($var:v14)='true'">
     <xsl:variable name="var:v21" select="string($var:v20)" />
     <btsCommonId>
            <xsl:value-of select="$var:v21" />
     </btsCommonId>
</xsl:if>

<xsl:variable name="var:v25" select="ScriptNS1:SetCommonID(&quot;FamilyMemberVehicle&quot; , &quot;CRM&quot; , $var:v24 , string($var:v20))" />

<xsl:if test="string($var:v23)='true'">
     <xsl:variable name="var:v26" select="string($var:v25)" />
     <btsCommonId>
            <xsl:value-of select="$var:v26" />
     </btsCommonId>
</xsl:if>

And now, do you see the problem with this sample?

The problem is that independent of the type of operation, if is an insert or other operation, it will always set an identifier in the Cross Referencing tables! (which by the way in my scenario, will induce problems – violate key). And this happens because the condition was defined at the end of the rule (in the right corner)

Complex-Functoid-Chain-Condition-problem

How you should read the rules

Important Note: basically, there are some exceptions, you always need to read the rules:

  • from top to bottom in the order that they happier in the destination schema
  • and from the left to the right (from the source schema to the destination schema) for a specific link connected to an element, field or record in the destination schema;

So, in this case the solution here is very simple, we need to move the condition to a position further downstream, which will allow to be executed sooner, especially the condition is equal to “insert”, because the second part (get two identifiers’ from the Cross Referencing tables) is common for both rules (then and else).

In this case we need to place the condition before we execute the set and return an identifier from the Cross Referencing tables operation, as the picture bellow shows:

Complex-Functoid-Chain-Condition-right

If we check the XSLT code once again, now we will notice that:

  • We are doing all the common operations before the condition rule to e executed
  • And for each particular scenario we will map the result (not equal to “insert”) or apply more operations and map the result (equal to “insert”)
<xsl:variable name="var:v14" select="userCSharp:LogicalNe(&quot;insert&quot; , string(@operation))" />
<xsl:variable name="var:v18" select="ScriptNS1:GetCommonID(&quot;INPUT1&quot; , &quot;INPUT2&quot; , string($var:v17))" />
<xsl:variable name="var:v19" select="ScriptNS1:GetCommonID(&quot;INPUT1&quot; , &quot;INPUT3&quot; , string(keys/myelement/text()))" />
<xsl:variable name="var:v15" select="ScriptNS0:GetValue()" />
<xsl:variable name="var:v20" select="ScriptNS2:GetValue(string($var:v15) , string($var:v18) , string($var:v19))" />
<xsl:variable name="var:v23" select="userCSharp:LogicalEq(&quot;insert&quot; , $var:v22)" />

<xsl:if test="string($var:v14)='true'">
     <xsl:variable name="var:v21" select="string($var:v20)" />
     <btsCommonId>
            <xsl:value-of select="$var:v21" />
     </btsCommonId>
</xsl:if>

<xsl:if test="string($var:v23)='true'">
     <xsl:variable name="var:v24" select="string($var:v20)" />
     <xsl:variable name="var:v25" select="string(keys/siva_viaturaagregadoid/text())" />
     <xsl:variable name="var:v26" select="ScriptNS1:SetCommonID(&quot;FamilyMemberVehicle&quot; , &quot;CRM&quot; , $var:v25 , string($var:v24))" />
     <btsCommonId>
            <xsl:value-of select="$var:v26" />
     </btsCommonId>
</xsl:if>

Like this scenario there are several, more or less complex, more or less critical. Some of them we don’t “even notice” because everything works well but if we check careful, sometimes will make several unnecessary operations that can induce, or may induce, performance problems in our transformations.

Good practices

As a reference and good practice, when you are implement conditions using Functoids chains, you should make the conditions as early as possible, i.e., put the conditions (if-then-else) as possible as you can in the left side of the Functoid chain.

This will allow you:

  • To group and execute certain task only on the context of the condition (inside the <xsl:if> statement)
  • And better performance because we are reducing the “noise” produced in the XSLT generated code by the compiler.

Easy, isn’t it?
Hope you enjoy it.


Why is so hard to make a simple If-Then-Else Functoid? … well, not anymore!

$
0
0

Sometimes I ask myself: Why is so hard to make a simple If-Then-Else Functoid, or even so painful to do an If-Then-Else operation, using BizTalk mapper?

I don’t mean to say that it is complicated, quite the opposite, is quite easy to make If…Then…Else statements using the Mapper. You can use If…Then…Else statements, to be completely correct, you can use something related to an If…Then…Else statements, to execute blocks of statements depending on the Boolean value of a condition by, normally, using:

  • One Logical Functoid (Logical Existence, Logical String, Logical Numeric, Equal, Greater Than, Less Than and so on) to determine:
    • whether the Record, Field Element, or Field Attribute node that is linked to it exists or have a valid value in a particular input instance message
    • or if a condition match.
  • One Logical NOT Functoid to negate the Logical Functoid
  • And two Value Mapping Functoids to returns the value that we want to linked based on the result of the condition

BizTalk-out-of-the-box-if-then-else-condition

In this sample, if the “Operation” element is equal to “Create”

  • Then: you will map the value of the element “ValueA” from the source schema to the element “Result” in the destination schema
  • Else (otherwise): you will map the value of the element “ValueB” from the source schema to the element “Result” in the destination schema

So, this functoid chain will provide a secondary path of execution when an “if” clause evaluates to false, the Else path. I said earlier: “something related to an If…Then…Else statement” because, programming speaking, If…Then…Else  statements are implemented by:

//C#
if(condition)
{
    //something if true
}
else
{
    //something if false
}

Or

<!-- XSLT -->
<xsl:choose>
  <xsl:when test="expression">
    ... something if true ...
  </xsl:when>
  <xsl:otherwise>
    ... something if false ...
  </xsl:otherwise>
</xsl:choose>

But in fact what this functoid chain does is two If statements

<!-- something if true -->
<xsl:if test="string($var:v1)='true'">
  <xsl:variable name="var:v2" select="ValueA/text()" />
  <Result>
    <xsl:value-of select="$var:v2" />
  </Result>
</xsl:if>
<!-- something if false (var:v3 contains the negation of var:v1) -->
<xsl:if test="string($var:v3)='true'">
  <xsl:variable name="var:v4" select="ValueB/text()" />
  <Result>
    <xsl:value-of select="$var:v4" />
  </Result>
</xsl:if>

This approach is good for small messages, but even with small messages, the Mapper will add many unnecessary code and operations. Because of that I decided to create a If-Then-Else Functoid to use in these situations and improve a little more the performance of the map, of course, undoubtedly, that the best option and with most performance to make conditions is using custom XSLT code (but this is another story).

The annoying things in using this out-of-the-box functois are:

  • We get these  annoying warnings (but they are useful in many scenarios) when we validate the maps:
    • warning btm1004: The destination node “Result” has multiple inputs. For a destination node to have multiple inputs, one of its ancestors should be connected to a looping functoid.
  • And for a simple if-then-else operation we need to use a minimum of 4 functoids. If we have several conditions inside the map, it will be easily filled with functoids and in result, will become a little confused and sometimes difficult to manager.
  • And, obvious, we will have several unnecessary operations.
So, why is so hard to make an If-Then-Else Functoid?

What I want to archive is create a custom functoid that accepts 3 inputs:

  • A Boolean – the result of a previous Logical Functoid (Logical Existence, Logical String, Logical Numeric, Equal, Greater Than, Less Than and so on)
  • And two inputs

Were the custom Functoid will return a value from one of two input parameters based on a condition.

  • If the condition (first input) is True, then the value of the second input parameter is returned;
  • Otherwise the Third input is returned.

Translating to C# code, will be something like this:

public string IfThenElseOperation(string condition, string trueValue, string falseValue)
{
    if (System.Convert.ToBoolean(condition))
        return trueValue;
    return falseValue;
}

Note: I will not address this topic here, this is content deserved a completely different post and dedicated to the topic, but the best option that you have is create a custom functoid belonging to the String functoid category (if you like it, put a comment in the post and I will address this topic in another time/post).

However, if you do that, you will find that, out-of-the-box, it is impossible to create a custom functoid based on a Logical Functoid and the reason why this is true is that, all Logical Functoids available out-of-the-box with BizTalk only accept the following outputs connection types:

  • ConnectionType.Element
  • ConnectionType.FunctoidAssert
  • ConnectionType.FunctoidNilValue
  • ConnectionType.FunctoidKeyMatch
  • ConnectionType.FunctoidTableLooping
  • ConnectionType.FunctoidValueMapping
  • ConnectionType.FunctoidScripter
  • ConnectionType.FunctoidLogical;

ConnectionType Enumeration: Specifies the types of connections that can be used as inputs or outputs for a functoid. This enumeration has a FlagsAttribute attribute that allows a bitwise combination of its member values.

ConnectionType.FunctoidString is not allowed in all the existing Logical Functoids. And that is the reason why you will find impossible to create a custom functoid based on a Logical functoid (don’t know the reason why Microsoft decide to implement this limitation)

How did I solve (or I overcame) this limitation?

To solve (work around) this limitation, so that I could create and use a custom if-then-else functoid, at the same time be fully compatible with existing functoids and don’t produce any more additional code, I was force to create my own personal custom Logical Functoids:

  • Advance Logical AND Functoid
  • Advance Equal Functoid
  • Advance Greater Than Functoid
  • Advance Greater Than or Equal To Functoid
  • Advance Less Than Functoid
  • Advance Less Than or Equal To Functoid
  • Advance Not Equal Functoid
  • Advance Logical NOT Functoid
  • Advance Logical OR Functoid

Toolbox-with-custom-logical-functoids

That have the same behavior as the out-of-the-box Logical Functoids:

  • Logical AND Functoid
  • Equal Functoid
  • Greater Than Functoid
  • Greater Than or Equal To Functoid
  • Less Than Functoid
  • Less Than or Equal To Functoid
  • Not Equal Functoid
  • Logical NOT Functoid
  • Logical OR Functoid

with the advantage that also accept the String output connection type.

base.OutputConnectionType = ConnectionType.FunctoidString | ConnectionType.Element | ConnectionType.FunctoidAssert | ConnectionType.FunctoidNilValue | ConnectionType.FunctoidKeyMatch | ConnectionType.FunctoidTableLooping | ConnectionType.FunctoidValueMapping | ConnectionType.FunctoidScripter | ConnectionType.FunctoidLogical;

By doing that, I can create my if-then-else custom functoid:

namespace BizTalk.CustomAdvanced.Functoids
{
    [Serializable]
    public class IfThenElse : BaseFunctoid
    {
        public IfThenElse()
            : base()
        {
            //ID for this functoid
            this.ID = 10900;

            // resource assembly must be ProjectName.ResourceName if building with VS.Net
            SetupResourceAssembly("BizTalk.Logical.Functoids.LogicalResources", Assembly.GetExecutingAssembly());

            //Setup the Name, ToolTip, Help Description, and the Bitmap for this functoid
            SetName("IDS_IFELSEFUNCTOID_NAME");
            SetTooltip("IDS_IFELSEFUNCTOID_TOOLTIP");
            SetDescription("IDS_IFELSEFUNCTOID_DESCRIPTION");
            SetBitmap("IDS_IFELSEFUNCTOID_BITMAP");

            //category for this functoid. This functoid goes under the String Functoid Tab in the
            this.Category = FunctoidCategory.String;

            // Set the limits for the number of input parameters. This example: 1 parameter
            this.SetMinParams(3);
            this.SetMaxParams(3);

            // Add one line of code as set out below for each input param. For multiple input params, each line would be identical.
            this.AddInputConnectionType(ConnectionType.AllExceptRecord); //first input
            this.AddInputConnectionType(ConnectionType.AllExceptRecord); //Second input
            this.AddInputConnectionType(ConnectionType.AllExceptRecord); //Third input

            // The functoid output can go to any node type.
            this.OutputConnectionType = ConnectionType.AllExceptRecord;

            SetScriptBuffer(ScriptType.CSharp, this.GetCSharpBuffer());
            HasSideEffects = false;
        }

        private string GetCSharpBuffer()
        {
            StringBuilder builder = new StringBuilder();
            builder.Append("public string IfThenElseOperation(string condition, string trueValue, string falseValue)\n");
            builder.Append("{\n");
            builder.Append("\tif (System.Convert.ToBoolean(condition))\n");
            builder.Append("\t\treturn trueValue;\n");
            builder.Append("\treturn falseValue;\n");
            builder.Append("}\n");
            return builder.ToString();
        }
    }
}

And have the ability to connect my logical functoids to a custom String functoid. Of course you need to use it wisely!

BizTalk-custom-if-then-else-condition

The beauty of this approach is that:

  • We reduce the functoids chain. By using less functoids we simplify the map visually, and this is very useful when you have a lot of conditions, even if they are simple conditions.
  • We will improve the map performance a little more, compared to the use of out-of-the-box functoids
    • Using Custom If-Then-Else Functoid:
<xsl:variable name="var:v1" select="userCSharp:LogicalEq(string(Operation/text()) , &quot;Create&quot;)" />
<xsl:variable name="var:v2" select="userCSharp:IfThenElseOperation(string($var:v1) , string(ValueA/text()) , string(ValueB/text()))" />

    <ns0:Output>
      <Result>
        <xsl:value-of select="$var:v2" />
      </Result>
    </ns0:Output>

public bool LogicalEq(string val1, string val2)
{
	bool ret = false;
	double d1 = 0;
	double d2 = 0;
	if (IsNumeric(val1, ref d1) && IsNumeric(val2, ref d2))
	{
		ret = d1 == d2;
	}
	else
	{
		ret = String.Compare(val1, val2, StringComparison.Ordinal) == 0;
	}
	return ret;
}

public string IfThenElseOperation(string condition, string trueValue, string falseValue)
{
	if (System.Convert.ToBoolean(condition))
		return trueValue;
	return falseValue;
}

public bool IsNumeric(string val)
{
	if (val == null)
	{
		return false;
	}
	double d = 0;
	return Double.TryParse(val, System.Globalization.NumberStyles.AllowThousands | System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out d);
}

public bool IsNumeric(string val, ref double d)
{
	if (val == null)
	{
		return false;
	}
	return Double.TryParse(val, System.Globalization.NumberStyles.AllowThousands | System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out d);
}
    • Using Out-of-the-box Functoids:
<xsl:variable name="var:v1" select="userCSharp:LogicalEq(string(Operation/text()) , &quot;Create&quot;)" />
<xsl:variable name="var:v3" select="userCSharp:LogicalNot(string($var:v1))" />

    <ns0:Output>
      <xsl:if test="string($var:v1)='true'">
        <xsl:variable name="var:v2" select="ValueA/text()" />
        <Result>
          <xsl:value-of select="$var:v2" />
        </Result>
      </xsl:if>
      <xsl:if test="string($var:v3)='true'">
        <xsl:variable name="var:v4" select="ValueB/text()" />
        <Result>
          <xsl:value-of select="$var:v4" />
        </Result>
      </xsl:if>
    </ns0:Output>

public bool LogicalEq(string val1, string val2)
{
	bool ret = false;
	double d1 = 0;
	double d2 = 0;
	if (IsNumeric(val1, ref d1) && IsNumeric(val2, ref d2))
	{
		ret = d1 == d2;
	}
	else
	{
		ret = String.Compare(val1, val2, StringComparison.Ordinal) == 0;
	}
	return ret;
}

public bool LogicalNot(string val)
{
	return !ValToBool(val);
}

public bool IsNumeric(string val)
{
	if (val == null)
	{
		return false;
	}
	double d = 0;
	return Double.TryParse(val, System.Globalization.NumberStyles.AllowThousands | System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out d);
}

public bool IsNumeric(string val, ref double d)
{
	if (val == null)
	{
		return false;
	}
	return Double.TryParse(val, System.Globalization.NumberStyles.AllowThousands | System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out d);
}

public bool ValToBool(string val)
{
	if (val != null)
	{
		if (string.Compare(val, bool.TrueString, StringComparison.OrdinalIgnoreCase) == 0)
		{
			return true;
		}
		if (string.Compare(val, bool.FalseString, StringComparison.OrdinalIgnoreCase) == 0)
		{
			return false;
		}
		val = val.Trim();
		if (string.Compare(val, bool.TrueString, StringComparison.OrdinalIgnoreCase) == 0)
		{
			return true;
		}
		if (string.Compare(val, bool.FalseString, StringComparison.OrdinalIgnoreCase) == 0)
		{
			return false;
		}
		double d = 0;
		if (IsNumeric(val, ref d))
		{
			return (d > 0);
		}
	}
	return false;
}
  • You don’t need to deploy any of these custom functoids (advance logical functoids or/and if-the-else functoid) to your production environment, you only need to have then in your development environment to be used inside Visual Studio because all of them are custom inline functoids, i.e., they will add the necessary code inside the XSLT file:
  • And finally, you can use all the custom advance Logical Functoids allow side with the out-of-the-box Logical Functoids without any impact and without producing additional code, because they will produce the exact same code of out-of-the-box Logical Functoids!

BizTalk-custom-and-out-of-the-box-if-then-else-condition-side-by-side

Generated code:

<!-- Custom Functoid -->
<xsl:variable name="var:v1" select="userCSharp:LogicalEq(string(Operation/text()) , &quot;Create&quot;)" />
<xsl:variable name="var:v2" select="userCSharp:IfThenElseOperation(string($var:v1) , string(ValueA/text()) , string(ValueB/text()))" />

<!-- out-of-the-box Functoids -->
<xsl:variable name="var:v3" select="string(Operation/text())" />
<xsl:variable name="var:v4" select="userCSharp:LogicalEq($var:v3 , &quot;Create&quot;)" />
<xsl:variable name="var:v6" select="userCSharp:LogicalNot(string($var:v4))" />

    <ns0:Output>
<!-- Custom Functoid -->
      <Result>
        <xsl:value-of select="$var:v2" />
      </Result>
<!-- out-of-the-box Functoids -->
      <xsl:if test="string($var:v4)='true'">
        <xsl:variable name="var:v5" select="ValueA/text()" />
        <Total>
          <xsl:value-of select="$var:v5" />
        </Total>
      </xsl:if>
      <xsl:if test="string($var:v6)='true'">
        <xsl:variable name="var:v7" select="ValueB/text()" />
        <Total>
          <xsl:value-of select="$var:v7" />
        </Total>
      </xsl:if>
    </ns0:Output>
  </xsl:template>

<!-- Both out-of-the-box Functoids and custom functoids will produce this LogicalEq code! -->
public bool LogicalEq(string val1, string val2)
{
	bool ret = false;
	double d1 = 0;
	double d2 = 0;
	if (IsNumeric(val1, ref d1) && IsNumeric(val2, ref d2))
	{
		ret = d1 == d2;
	}
	else
	{
		ret = String.Compare(val1, val2, StringComparison.Ordinal) == 0;
	}
	return ret;
}

public string IfThenElseOperation(string condition, string trueValue, string falseValue)
{
	if (System.Convert.ToBoolean(condition))
		return trueValue;
	return falseValue;
}

public bool LogicalNot(string val)
{
	return !ValToBool(val);
}

public bool IsNumeric(string val)
{
	if (val == null)
	{
		return false;
	}
	double d = 0;
	return Double.TryParse(val, System.Globalization.NumberStyles.AllowThousands | System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out d);
}

public bool IsNumeric(string val, ref double d)
{
	if (val == null)
	{
		return false;
	}
	return Double.TryParse(val, System.Globalization.NumberStyles.AllowThousands | System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out d);
}

public bool ValToBool(string val)
{
	if (val != null)
	{
		if (string.Compare(val, bool.TrueString, StringComparison.OrdinalIgnoreCase) == 0)
		{
			return true;
		}
		if (string.Compare(val, bool.FalseString, StringComparison.OrdinalIgnoreCase) == 0)
		{
			return false;
		}
		val = val.Trim();
		if (string.Compare(val, bool.TrueString, StringComparison.OrdinalIgnoreCase) == 0)
		{
			return true;
		}
		if (string.Compare(val, bool.FalseString, StringComparison.OrdinalIgnoreCase) == 0)
		{
			return false;
		}
		double d = 0;
		if (IsNumeric(val, ref d))
		{
			return (d > 0);
		}
	}
	return false;
}

May not be the perfect solution, I agree on that but I found a very interesting and useful approach for many scenarios. I hope you enjoy it, because I have been used it a lot lately :)

BizTalk-custom-and-out-of-the-box-if-then-else-condition-side-by-side-2

The functoids will be available in the next version of BizTalk Mapper Extensions UtilityPack, until then you have all the source code and samples here:

BizTalk Mapper: How to create a custom If-Then-Else Functoid (18,6 KB)
Microsoft | Code Gallery


BizTalk DevOps: Monitor your BizTalk environment using PowerShell –Monitoring Suspended Service Instances with Auto-Healing capabilities

$
0
0

Welcome back to this serial of articles about Monitor your BizTalk environment using PowerShell that already have several previous editions:

One of the principal needs for BizTalk Administrators is the ability to monitor the health of BizTalk environments and react promptly to possible problems, you can accomplish this by using certain tools such as: BizTalk Administration Console; BizTalk360; SCOM and many more… However, unfortunately many times, some of these tools are not available for us but we still need to accomplish this task.

Today we will talk about a topic that was previously covered by Jeroen: “How to monitor Suspended instance in BizTalk Server using PowerShell”, but this time, I will also add Auto Healing functionalities to the script.

There are bunch of things that can go wrong and the longer they have in an error/failure situation, more impact could have in your business! So, we don’t just want to be notified of failures (that will always lead to a manual human intervention) but instead, when possible, be also able to try to automatically fix it, bringing them to the desired state (running, resumed, enable – depending on the artifact)

So how can PowerShell help us?

With this script you can be able to monitoring your BizTalk environment for suspended service instance, and automatically resume then according to certain conditions, using PowerShell.

Only if the script finds any suspended messages a mail notification will be sent.

This script allows you to set:

  • Set your email notification settings
#Set mail variables
[STRING]$PSEmailServer = "mySMTPServer" #SMTP Server.
[STRING]$SubjectPrefix = "Suspended Messages - "
[STRING]$From = "biztalksupport@mail.pt"
[array]$EmailTo = ("sandro.pereira@devscope.net")
  • The Service Instances desired states to monitor
#Get suspended messages
[ARRAY]$suspendedMessages = get-wmiobject MSBTS_ServiceInstance -namespace 'root\MicrosoftBizTalkServer' -filter '(ServiceStatus = 4 or ServiceStatus = 16 or ServiceStatus = 32 or ServiceStatus = 64)'
  • The amount of hours that a suspended message can be resumed automatically. Only if the (Current Date – Automatic Resume hours) is less than Instance start time, the instance will be automatically resumed.
#This variable sets the amount of hours a suspended message can be resumed automatically
[INT]$AutomaticResume = 8

Main monitoring script:

foreach ($msgSuspended in $suspendedMessages)
{
    $msg = $bo.GetServiceInstance($msgSuspended.InstanceID)

    #Add mail content
    $mailBodySM += "<th>Message Instance ID: <b><font color='blue'>" + $msgSuspended.InstanceID + "</font></b></th>"
    $mailBodySM += "<table style='boder:0px 0px 0px 0px;'>"
    $mailBodySM += "<TR style='background-color:white;'><TD>Application</TD>"
    $mailBodySM += "<TD>" + $msg.Application + "</TD></TR>"

    $mailBodySM += "<TR style='background-color:rgb(245,245,245);';><TD>Service Name</TD>"
    $mailBodySM += "<TD><b><font color='red'>" + $msgSuspended.ServiceName + "</font></b></TD></TR>"

    $mailBodySM += "<TR style='background-color:white;'><TD>Class</TD>"
    $mailBodySM += "<TD>" + $msg.Class + "</TD></TR>"

    $mailBodySM += "<TR style='background-color:rgb(245,245,245);';><TD>Assembly Name</TD>"
    $mailBodySM += "<TD>" + $msgSuspended.AssemblyName + ", Version=" + $msgSuspended.AssemblyVersion + ", Culture=" + $msgSuspended.AssemblyCulture +", PublicKeyToken=" + $msgSuspended.AssemblyPublicKeyToken + "</TD></TR>"

    $spActivationTime= [datetime]::ParseExact($msgSuspended.ActivationTime.Substring(0,14),'yyyyMMddHHmmss',[Globalization.CultureInfo]::InvariantCulture )
    $mailBodySM += "<TR style='background-color:white;'><TD>Activation Time</TD>"
    $mailBodySM += "<TD>" + $spActivationTime.ToString("dd-MM-yyyy HH:mm:ss") + "</TD></TR>"

    $myDate= [datetime]::ParseExact($msgSuspended.SuspendTime.Substring(0,14),'yyyyMMddHHmmss',[Globalization.CultureInfo]::InvariantCulture )
    $mailBodySM += "<TR style='background-color:rgb(245,245,245);';><TD>Suspend Time</TD>"
    $mailBodySM += "<TD>" + $myDate.ToString("dd-MM-yyyy HH:mm:ss") + "</TD></TR>"

    #ServiceStatus = 1 - Ready To Run
    #ServiceStatus = 2 - Active
    #ServiceStatus = 4 - Suspended (Resumable)
    #ServiceStatus = 8 - Dehydrated
    #ServiceStatus = 16 - Completed With Discarded Messages' in BizTalk Server 2004
    #ServiceStatus = 32 - Suspended (Not Resumable)
    #ServiceStatus = 64 - In Breakpoint

    if ($msgSuspended.ServiceStatus -eq 4)
    {
        $statusMsg = "Suspended (Resumable)"
    }
    if ($msgSuspended.ServiceStatus -eq 16)
    {
        $statusMsg = "Completed With Discarded Messages"
    }
    if ($msgSuspended.ServiceStatus -eq 32)
    {
        $statusMsg = "Suspended (Not Resumable)"
    }
    if ($msgSuspended.ServiceStatus -eq 64)
    {
        $statusMsg = "In Breakpoint"
    }

    $mailBodySM += "<TR style='background-color:white;'><TD>Service Name</TD>"
    $mailBodySM += "<TD><b><font color='red'>" + $statusMsg + "</font></b></TD></TR>"

    $mailBodySM += "<TR style='background-color:rgb(245,245,245);';><TD>HostName</TD>"
    $mailBodySM += "<TD>" + $msgSuspended.HostName + " (" + $msgSuspended.PSComputerName + ")</TD></TR>"

    $mailBodySM += "<TR style='background-color:white;'><TD>Error Code</TD>"
    $mailBodySM += "<TD>" + $msgSuspended.ErrorId + "</TD></TR>"

    $mailBodySM += "<TR style='background-color:rgb(245,245,245);';><TD>Error Description</TD>"
    $mailBodySM += "<TD>" + $msgSuspended.ErrorDescription + "</TD></TR>"

    $mailBodySM += "<TR style='background-color:white;'><TD>Error Category</TD>"
    $mailBodySM += "<TD>" + $msgSuspended.ErrorCategory + "</TD></TR>"

    $mailBodySM += "<TR style='background-color:rgb(245,245,245);';><TD>In Breakpoint</TD>"
    $mailBodySM += "<TD>" + $msg.InBreakpoint + "</TD></TR>"

    $mailBodySM += "<TR style='background-color:white;'><TD>Pending Operation</TD>"
    $mailBodySM += "<TD>" + $msg.PendingOperation + "</TD></TR>"


    If (($spActivationTime -ge $currentdateSI.AddHours(-$AutomaticResume)) -and ($msg.Class -like "Orchestration") -and ($msgSuspended.ServiceStatus -eq 4))
    {
        $msgSuspended.InvokeMethod("Resume",$null)

        $mailBodySM += "<TR style='background-color:rgb(245,245,245);';><TD><font color='green'>Note</font></TD>"
        $mailBodySM += "<TD><font color='green'>The suspended message was resumed automatically by this script! Please access the environment to check if the processes are running or completed.</font></TD></TR>"
    }

    $mailBodySM += "</table>"
    $mailBodySM += "<BR><BR>"
}

Again, only if the script finds any suspended messages a mail notification will be sent.

Report sample:

BizTalk-Suspended-Instances-Report

Note: This type of script must be viewed as a complement to the tools mentioned above or used in the absence of them.

THIS POWERSHELL IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND.

The script can be found and download on Microsoft TechNet Gallery:
Monitoring BizTalk Suspended Service Instances with Auto-Healing with PowerShell (8.0 KB)
Microsoft TechNet Gallery


BizTalk DevOps: Monitor your BizTalk environment using PowerShell –Monitoring Ports (Stopped/disabled/unelisted) with Auto-Healing capabilities

$
0
0

In the sequence of my last post, welcome back, once again, to this serial of articles about Monitor your BizTalk environment using PowerShell.

Today we will talk about a topic that was also previously covered by Jeroen, ” Monitor your BizTalk environment using PowerShell – Port monitoring”, but this time, I will also add Auto Healing functionalities to the script.

Note: This type of script must be viewed as a complement to the tools mentioned above or used in the absence of them.

One of the principal needs for BizTalk Administrators is the ability to monitor the health of BizTalk environments and react promptly to possible problems, you can accomplish this by using certain tools such as: BizTalk Administration Console; BizTalk360; SCOM and many more… However, unfortunately many times, some of these tools are not available for us but we still need to accomplish this task.

There are bunch of things that can go wrong and the longer they have in an error/failure situation, more impact could have in your business! So, we don’t just want to be notified of failures (that will always lead to a manual human intervention) but instead, when possible, be also able to try to automatically fix it, bringing them to the desired state (running, resumed, enable – depending on the artifact)

So how can PowerShell help us?

With this script you can be able to monitoring your BizTalk environment for disabled receive locations and stopped or unenlisted send ports, and automatically resume then according to certain conditions, using PowerShell.

A mail notification will be sent only if this scripts finds any receive location or send port in a non-conform situation.

This sample will demonstrate how can you easily create a script with a set of conditions to be able to monitor and to automatically fix the receive locations and send ports to the desired state:

  • “Enable” for receive locations
  • “Started” for send ports

This script allows you to set:

  • Set your email notification settings
#Set mail variables
[STRING]$PSEmailServer = "mySMTPServer" #SMTP Server.
[STRING]$SubjectPrefix = "Port status - "
[STRING]$From = "biztalksupport@mail.pt"
[array]$EmailTo = ("sandro.pereira@devscope.net")

The following Windows PowerShell script is a fragment that will help us demonstrate this capabilities:

#Get Counters: Check if there are any disable receive locations and stopped/unelisted send ports
if ($sendports.count -ne (get-wmiobject MSBTS_SendPort -namespace 'root\MicrosoftBizTalkServer' -filter '(Status = 3)').count)
{
    [BOOL]$script:Continuescript = $True
    [INT]$countSendPorts = $sendports.count - $(get-wmiobject MSBTS_SendPort -namespace 'root\MicrosoftBizTalkServer' -filter {Status = 3}).count
}
if ($ReceiveLocations.count -ne (get-wmiobject MSBTS_ReceiveLocation -namespace 'root\MicrosoftBizTalkServer' -filter '(IsDisabled = False)').count)
{
    [BOOL]$script:Continuescript = $True
    [INT]$countReceivePorts = $ReceiveLocations.count - $(get-wmiobject MSBTS_ReceiveLocation -namespace 'root\MicrosoftBizTalkServer' -filter '(IsDisabled = False)').count
}

if($countSendPorts -gt 0)
{
    $mailTextReportPT += "" + $countSendPorts + " send ports stopped; "
    $mailBodyPT += "<h3>Send ports Stopped</h3>"

    #Add mail content for stopped send ports
    Foreach ($SendPort in $SendPorts)
    {
        #only add stopped send ports to the mail
        if ($SendPort.status -eq 2 -OR $SendPort.status -eq 1)
        {
            $StoppedSendPort = $True
            #Set status to a user friendly name
            if ($SendPort.status -eq 2)
            {
                $SendPortStatus = "Stopped"
            }
            elseif ($SendPort.status -eq 1)
            {
                $SendPortStatus = "Unelisted"
            }

            #Add mail content
            $mailBodyPT += "<th><b><font color='red'>" + $SendPort.name + "</font></b></th>"
            $mailBodyPT += "<table style='boder:0px 0px 0px 0px;'>"

            $mailBodyPT += "<TR style='background-color:white;'><TD>Status</TD>"
            $mailBodyPT += "<TD><b><font color='red'>" + $SendPortStatus + "</font><b></TD></TR>"

            $mailBodyPT += "<TR style='background-color:rgb(245,245,245);';><TD>URI</TD>"
            $mailBodyPT += "<TD>" + $SendPort.PTAddress + "</TD></TR>"

            $mailBodyPT += "<TR style='background-color:white;'><TD>Transport type</TD>"
            $mailBodyPT += "<TD>" + $SendPort.PTTransportType + "</TD></TR>"

            if ($SendPort.status -eq 2)
            {
                #Auto-Healing feature
                $SendPort.InvokeMethod("Start",$null)

                $mailBodyPT += "<TR style='background-color:rgb(245,245,245);';><TD><font color='green'>Note</font></TD>"
                $mailBodyPT += "<TD><font color='green'>The Stopped port was automatically Started by this script! Please access the environment to check if ports are running correctly.</font></TD></TR>"
            }

            $mailBodyPT += "</table>"
            $mailBodyPT += "<BR><BR>"
        }
    }
}

if($countReceivePorts -gt 0)
{
    $mailTextReportPT += "" + $countReceivePorts + " receive locations disabled; "
    $mailBodyPT += "<h3>Receive locations Disabled</h3>"

    #Add mail content for stopped receive locations
    Foreach ($ReceiveLocation in $ReceiveLocations)
    {
        #only add stopped receive locations to the mail
        if ($ReceiveLocation.IsDisabled -eq "True")
        {
            $StoppedReceiveLocation = $True

            #Set status to a user friendly name
            $ReceiveLocationStatus = "Disabled"

            #Add mail content
            $mailBodyPT += "<th><b><font color='red'>" + $ReceiveLocation.name + "</font></b></th>"
            $mailBodyPT += "<table style='boder:0px 0px 0px 0px;'>"
            $mailBodyPT += "<TR style='background-color:white;'><TD>Status</TD>"
            $mailBodyPT += "<TD><b><font color='red'>" + $ReceiveLocationStatus + "</font></b></TD></TR>"

            $mailBodyPT += "<TR style='background-color:rgb(245,245,245);';><TD>URI</TD>"
            $mailBodyPT += "<TD>" + $ReceiveLocation.InboundTransportURL + "</TD></TR>"

            $mailBodyPT += "<TR style='background-color:white;'><TD>Transport type</TD>"
            $mailBodyPT += "<TD>" + $ReceiveLocation.AdapterName + "</TD></TR>"

            #Auto-Healing feature
            $ReceiveLocation.InvokeMethod("Enable",$null)

            $mailBodyPT += "<TR style='background-color:rgb(245,245,245);';><TD><font color='green'>Note</font></TD>"
            $mailBodyPT += "<TD><font color='green'>The Disabled port was automatically Enable by this script! Please access the environment to check if ports are running correctly.</font></TD></TR>"

            $mailBodyPT += "</table>"
            $mailBodyPT += "<BR><BR>"
        }
    }
}

Note: The script should be adjusted to your needs. Maybe having a variable or a list of receive location and Send ports that should be excluded for the monitoring or have a different expected status.

Here is example expected report output from running the Windows PowerShell script sample, if any of the ports are in an unwanted state.

BizTalk-Ports-Status-Report

Again, this type of script must be viewed as a complement to the tools mentioned above or used in the absence of them.

THIS POWERSHELL IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND.

The script can be found and download on Microsoft TechNet Gallery:
Monitoring BizTalk Server Ports with Auto-Healing capabilities with PowerShell (14.0 KB)
Microsoft TechNet Gallery


BizTalk DevOps Monitor your BizTalk environment using PowerShell – Monitoring Host Instances with Auto-Healing capabilities

$
0
0

In the sequence of my last two posts, welcome back, once again (probably the last one for now), to this serial of articles about Monitor your BizTalk environment using PowerShell.

Today we will talk about a topic that a new topic, “How to monitor Host Instance in BizTalk Server using PowerShell”, and once again, we will add Auto Healing functionalities to the script.

One of the principal needs for BizTalk Administrators is the ability to monitor the health of BizTalk environments and react promptly to possible problems, you can accomplish this by using certain tools such as: BizTalk Administration Console; BizTalk360; SCOM and many more… However, unfortunately many times, some of these tools are not available for us but we still need to accomplish this task.

There are bunch of things that can go wrong and the longer they have in an error/failure situation, more impact could have in your business! So, we don’t just want to be notified of failures (that will always lead to a manual human intervention) but instead, when possible, be also able to try to automatically fix it, bringing them to the desired state (running, resumed, enable – depending on the artifact)

Note: This type of script must be viewed as a complement to the tools mentioned above or used in the absence of them.

So how can PowerShell help us?

With this script you can be able to monitoring your BizTalk environment for Host Instance that aren’t Started (Stopped, Start pending, Stop pending, Continue pending, Pause pending, Paused or Unknown), and automatically bring them to desired state (Started) according to certain conditions, using PowerShell.

Only if the script finds any suspended messages a mail notification will be sent.

This script allows you to set:

  • Set your email notification settings
#Set mail variables
[STRING]$PSEmailServer = "mySMTPServer" #SMTP Server.
[STRING]$SubjectPrefix = "Host instances not running - "
[STRING]$From = "biztalksupport@mail.pt"
[array]$EmailTo = ("sandro.pereira@devscope.net")

The following Windows PowerShell script is a fragment that will help us demonstrate this capabilities:

# Get Host instances not running
[ARRAY]$hostInstances = get-wmiobject MSBTS_HostInstance  -namespace 'root\MicrosoftBizTalkServer' -filter '(HostType = 1 and ServiceState != 4)'

foreach ($hostInstance in $hostInstances)
{
    #Add mail content
    $mailBodyHI += "<th><b><font color='blue'>" + $hostInstance.Name + "</font></b></th>"
    $mailBodyHI += "<table style='boder:0px 0px 0px 0px;'>"
    $mailBodyHI += "<TR style='background-color:white;'><TD>Host Name</TD>"
    $mailBodyHI += "<TD><b><font color='red'>" + $hostInstance.HostName + "</font></b></TD>
</TR>"

    $mailBodyHI += "<TR style='background-color:rgb(245,245,245);';><TD>Host Type</TD>"
    $mailBodyHI += "<TD>In-process</TD></TR>"

    $mailBodyHI += "<TR style='background-color:white;'><TD>Running Server</TD>"
    $mailBodyHI += "<TD><b><font color='red'>" + $hostInstance.RunningServer + "</font></b></TD></TR>"

    # Stopped: 1
    # Start pending: 2
    # Stop pending: 3
    # Running: 4
    # Continue pending: 5
    # Pause pending: 6
    # Paused: 7
    # Unknown: 8

    if ($hostInstance.ServiceState -eq 1)
    {
        $statusHI = "Stopped"
    }
    if ($hostInstance.ServiceState -eq 2)
    {
        $statusHI = "Start pending"
    }
    if ($hostInstance.ServiceState -eq 3)
    {
        $statusHI = "Stop pending"
    }
    if ($hostInstance.ServiceState -eq 5)
    {
        $statusHI = "Continue pending"
    }
    if ($hostInstance.ServiceState -eq 6)
    {
        $statusHI = "Pause pending"
    }
    if ($hostInstance.ServiceState -eq 7)
    {
        $statusHI = "Paused"
    }
    if ($hostInstance.ServiceState -eq 8)
    {
        $statusHI = "Unknown"
    }

    $mailBodyHI += "<TR style='background-color:rgb(245,245,245);';><TD>Service State</TD>"
    $mailBodyHI += "<TD><b><font color='red'>" + $statusHI + "</font></b></TD></TR>"

    #0: UnClusteredInstance
    #1: ClusteredInstance
    #2: ClusteredVirtualInstance
    if ($hostInstance.ClusterInstanceType -eq 0)
    {
        $statusHI = "UnClustered Instance"
    }
    if ($hostInstance.ClusterInstanceType -eq 1)
    {
        $statusHI = "Clustered Instance"
    }
    if ($hostInstance.ClusterInstanceType -eq 2)
    {
        $statusHI = "Clustered Virtual Instance"
    }

    $mailBodyHI += "<TR style='background-color:white;'><TD>Cluster Instance Type</TD>"
    $mailBodyHI += "<TD>" + $statusHI + "</TD></TR>"

    $mailBodyHI += "<TR style='background-color:rgb(245,245,245);';><TD>Is Disabled</TD>"
    $mailBodyHI += "<TD>" + $hostInstance.IsDisabled + "</TD></TR>"

    $mailBodyHI += "<TR style='background-color:white;'><TD>NT Group Name</TD>"
    $mailBodyHI += "<TD>" + $hostInstance.NTGroupName + "</TD></TR>"

    $mailBodyHI += "<TR style='background-color:rgb(245,245,245);';><TD>Logon</TD>"
    $mailBodyHI += "<TD>" + $hostInstance.Logon + "</TD></TR>"

    #Auto-Healing feature
    if($hostInstance.IsDisabled = "False")
    {
        $hostInstance.InvokeMethod("Start",$null)

        $mailBodyHI += "<TR style='background-color:white;'><TD><font color='green'>Note</font></TD>"
        $mailBodyHI += "<TD><font color='green'>The Host Instance was started automatically by this script! Please access the environment to validate if all host instances are running.</font></TD></TR>"
    }

    $mailBodyHI += "</table>"
    $mailBodyHI += "<BR><BR>"
}

Here is example expected report output from running the Windows PowerShell script sample, if any of the Host instance are in an unwanted state.

BizTalk-Host-Instances-Report

Note: This type of script must be viewed as a complement to the tools mentioned above or used in the absence of them. The script should also be adjusted to your needs.

THIS POWERSHELL IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND.

The script can be found and download on Microsoft TechNet Gallery:
Monitoring BizTalk Host Instances with Auto-Healing with PowerShell (14.0 KB)
Microsoft TechNet Gallery


Viewing all 287 articles
Browse latest View live