Procesando diferentes tipos de archivos en el mismo receive location

Cuando se usa el adaptador FILE (u otros adaptadores) en BizTalk Server no es posible procesar diferentes tipos de archivos texto (flat-file) nombrados de igual forma en la misma ruta.  Esta restriccion se da porque no se pueden configurar varios receive locations con el adaptador FILE que lean de la misma ruta los archivos, ya que al procesarlos el adaptador bloquea los archivos prohibiendo que otros procesos (incluidos otros receive locations) accedan al contenido del archivo.

Actualmente en BizTalk Server 2006 se puede resolver este inconveniente, basta con enviar todos los mensajes a una misma orquestacion (orchestration) y usando el metodo XLANGPipelineManager.ExecuteReceivePipeline evaluar el mensaje con diferentes tipos de documentos previamente configurados en Custom Pipelines.

Pero esta solucion no es posible en BizTalk Server 2004 ya que el metodo XLANGPipelineManager.ExecuteReceivePipeline no existe.  Sin embargo, si es posible desarrollar un Custom Pipeline Component que valide un mismo archivo de texto recibido contra una coleccion de esquemas de archivos de texto (flat-file schemas) y generar un mensaje valido para redireccionarlo a la plataforma de integracion.

El nuevo componente debe implementar los metodos IProbeMessage.Probe, IDisassemblerComponent.Disassemble, y IDisassemblerComponent.GetNext que corresponden a las interfaces IProbeMessage y IDisassemblerComponents (necesarias para el desarrollo del componente) sobreescribiendo de esta forma la ejecucion del Custom Pipeline Component.  Para mas informacion acerca de como desarrollar un Custom Pipeline Component visitar aqui, a continuacion se hara una breve descripcion del codigo utilizado.  A continuacion se daran mas detalles del desarrolla de este componente.

Design Time Properties

Esta region implementa la propiedad publica por medio de la cual el usuario selecciona los tipos de documentos (flat-file schemas) a validar en tiempo de diseno.  Los documentos se almacenan en la variable schemaList.

Pueden encontrar mas informacion de esta implementa aqui.

#region Design Time Properties
private SchemaList schemaList = new SchemaList();
public SchemaList DocumentSchemaList
{
get { return this.schemaList; }
set { this.schemaList = value; }
}
#endregion Design Time Properties

IProbeMessage and Private Members

El metodo IProbeMessage.Probe implementa la logica que recorre cada uno de los tipos de documentos previamente configurados en la variable schemaList.  Por cada tipo de documento se invoca el metodo FFDisassembler quien valida el tipo de documento contra el contenido del archivo, y en caso de ser exitosa la validacion se almacenaran los mensajes de BizTalk resultantes en una nueva coleccion llamada baseMessages.

El codigo a continuacion presenta las varialbes privadas utilizadas y los metodos Probe y FFDisassembler.

#region IProbeMessage and Private Members
public bool Probe ( IPipelineContext pContext, IBaseMessage pInMsg )
{
bool isValid = false;

// probe the disassembler for-each messageType
foreach(Schema schema in schemaList)
{
try
{
FFDisassembler(pContext, pInMsg, schema);
goto EndProbe;
}
catch(Exception e)
{
System.Diagnostics.Trace.WriteLine(e.ToString());
// create a NACK message
}
}
// eval the isValid variable
if (!isValid)
throw new ApplicationException("The message doesn't have a valid flat-file format");

  EndProbe:
return true;
}

private object disassembler = null;
private ArrayList baseMessages = new ArrayList();
private int idxBaseMessages = 0;
private string XmlNormNamespaceURI = "https://schemas.microsoft.com/BizTalk/2003/xmlnorm-properties"
private string DocumentSpecNamePropertyName = "DocumentSpecName"
private void FFDisassembler(IPipelineContext pContext, IBaseMessage pInMsg, Schema schema)
{
disassembler = new FFDasmComp();

  string messageType = string.Format("{0}#{1}", schema.TargetNamespace, schema.RootName);
IFFDocumentSpec docDefinition = (IFFDocumentSpec) pContext.GetDocumentSpecByType(messageType);
string docSpecStrongName = docDefinition.DocSpecStrongName;
pInMsg.Context.Write(DocumentSpecNamePropertyName, XmlNormNamespaceURI, docSpecStrongName);
pInMsg.BodyPart.GetOriginalDataStream().Seek(0, SeekOrigin.Begin);

  ((FFDasmComp) disassembler).DocumentSpecName = new SchemaWithNone(docSpecStrongName);
((FFDasmComp) disassembler).Disassemble(pContext, pInMsg);

  IBaseMessage baseMessage = null;
while ((baseMessage = ((FFDasmComp)disassembler).GetNext(pContext)) != null)
baseMessages.Add(baseMessage);
}
#endregion IProbeMessage and Private Members

IDisassemblerComponent

El metodo Disassemble no debe implementar ninguna logica, esto se debe a que previamente ya se habia hecho el desensamble del mensaje.

A continuacion, en el metodo GetNext se implementa la logica necesaria para retornar uno a uno los mensajes de la coleccion baseMessages y enviarlo automaticamente a la MessageBox para que continue su proceso.

#region IDisassemblerComponent
public IBaseMessage GetNext ( IPipelineContext pContext )
{
if (idxBaseMessages < baseMessages.Count)
return baseMessages[idxBaseMessages++] as IBaseMessage;
return null;
}

public void Disassemble ( IPipelineContext pContext, IBaseMessage pInMsg ) { }
#endregion IDisassemblerComponent

Este nuevo Custom Pipeline Component, puede ser utilizado en Custom Pipelines para las versiones BizTalk Server 2004 y 2006.  Si desea el codigo fuente puede enviar un email aqui.

 

Autor: Carlos Medina
Este mensaje se proporciona "como está" sin garantías de ninguna clase, y no otorga ningun derecho