|
using System;
using System.IO;
using System.Net;
using System.Xml;
using System.Text;
using System.Security;
using System.Threading;
using System.Collections;
using System.Diagnostics;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using Microsoft.BizTalk.Component.Interop;
using Microsoft.BizTalk.Message.Interop;
using Microsoft.BizTalk.TransportProxy.Interop;
using Microsoft.Samples.BizTalk.Adapter.Common;
namespace FaxAdapter
{
internal class FaxReceiverEndpoint : ReceiverEndpoint
{
// constants
private const string MESSAGE_BODY = "body";
private const string DOT_NET_FILE_PROP_REMOTEFILENAME = "FileName";
// properties
private FaxAdapterReceiveProperties properties;
// handle to the EPM
private IBTTransportProxy transportProxy;
// used to create new messages / message parts etc.
private IBaseMessageFactory messageFactory;
// used in the creation of messages
private string transportType;
// used in the creation of messages
private string propertyNamespace;
// used to track inflight work
private ControlledTermination controlledTermination;
// error count for comparison with the error threshold
int errorCount;
private System.Threading.Timer timer = null;
// support for Update
IPropertyBag updatedConfig;
IPropertyBag updatedBizTalkConfig;
IPropertyBag updatedHandlerPropertyBag;
public FaxReceiverEndpoint()
{
}
public override void Open(string uri, IPropertyBag config, IPropertyBag bizTalkConfig, IPropertyBag handlerPropertyBag, IBTTransportProxy transportProxy, string transportType, string propertyNamespace, ControlledTermination control)
{
Trace.WriteLine("[FaxReceiverEndpoint] Open called");
this.errorCount = 0;
this.properties = new FaxAdapterReceiveProperties();
// Location properties - possibly override some Handler properties
XmlDocument locationConfigDom = ConfigProperties.ExtractConfigDom(config);
this.properties.ReadLocationConfiguration(locationConfigDom);
// this is our handle back to the EPM
this.transportProxy = transportProxy;
// used to create new messages / message parts etc.
this.messageFactory = this.transportProxy.GetMessageFactory();
// used in the creation of messages
this.transportType = transportType;
// used in the creation of messages
this.propertyNamespace = propertyNamespace;
// used to track inflight work for shutting down properly
this.controlledTermination = control;
Start();
}
private void Start()
{
this.timer = new Timer(new TimerCallback(ControlledEndpointTask));
this.timer.Change(0, this.properties.PollingInterval * 1000);
}
private void Stop()
{
this.timer.Dispose();
}
public void ControlledEndpointTask(object val)
{
if (this.controlledTermination.Enter())
{
try
{
lock (this)
{
this.EndPointTask();
}
GC.Collect();
}
finally
{
this.controlledTermination.Leave();
}
}
}
private void EndPointTask()
{
try
{
PickupFilesAndSubmit();
errorCount = 0;
}
catch (Exception e)
{
transportProxy.SetErrorInfo(e);
errorCount++;
}
CheckErrorThreshold();
}
private bool CheckErrorThreshold()
{
if ((0 != this.properties.ErrorThreshold) && (errorCount > this.properties.ErrorThreshold))
{
this.transportProxy.ReceiverShuttingdown(this.properties.Uri, new ErrorThresholdExceeded());
Stop();
return false;
}
return true;
}
private void PickupFilesAndSubmit()
{
Trace.WriteLine("[FaxReceiverEndpoint] PickupFilesAndSubmit called");
List<BatchMessage> files = new List<BatchMessage>();
FaxManager faxManager = new FaxManager(this.properties.FaxMachineName,this.properties.FaxArchiveFolder);
ArrayList faxFiles = faxManager.GetFilesContent(1);
for (int i = 0; i < faxFiles.Count; i++)
{
IBaseMessagePart part = this.messageFactory.CreateMessagePart();
part.Data = ((Stream)((FaxFile)faxFiles[i]).FileStream);
IBaseMessage msg = this.messageFactory.CreateMessage();
msg.AddPart(MESSAGE_BODY, part, true);
SystemMessageContext context = new SystemMessageContext(msg.Context);
context.InboundTransportLocation = this.properties.Uri;
context.InboundTransportType = this.transportType;
//msg.Context.Write(DOT_NET_FILE_PROP_REMOTEFILENAME,this.propertyNamespace,
files.Add( new BatchMessage( msg , faxFiles , BatchOperationType.Submit));
}
if (this.controlledTermination.TerminateCalled)
return;
// end of file list - one final batch to do
if (files.Count > 0)
SubmitFiles(files);
}
/// <summary>
/// Given a List of Messages submit them to BizTalk for processing
/// </summary>
private void SubmitFiles(List<BatchMessage> files)
{
if (files == null || files.Count == 0) throw new ArgumentException("SubmitFiles was called with an empty list of Files");
Trace.WriteLine(string.Format("[DotNetFileReceiverEndpoint] SubmitFiles called. Submitting a batch of {0} files.", files.Count));
//This class is used to track the files associated with this ReceiveBatch
BatchInfo batchInfo = new BatchInfo(files);
using (ReceiveBatch batch = new ReceiveBatch(this.transportProxy, this.controlledTermination, batchInfo.OnBatchComplete, this.properties.MaximumNumberOfFiles))
{
foreach (BatchMessage file in files)
{
// submit file to batch
batch.SubmitMessage(file.Message, file.UserData);
}
batch.Done(null);
}
}
public override void Update(IPropertyBag config, IPropertyBag bizTalkConfig, IPropertyBag handlerPropertyBag)
{
throw new Exception("The method or operation is not implemented.");
}
public override void Dispose()
{
base.Dispose();
}
private class BatchInfo
{
BatchMessage[] messages;
internal BatchInfo(List<BatchMessage> messageList)
{
this.messages = new BatchMessage[messageList.Count];
messageList.CopyTo(messages);
}
/// <summary>
/// Called when the BizTalk Batch has been submitted. If all the messages were submitted (good or suspended)
/// we delete the files from the folder
/// </summary>
/// <param name="overallStatus"></param>
internal void OnBatchComplete(bool overallStatus)
{
Trace.WriteLine(string.Format("[DotNetFileReceiverEndpoint] OnBatchComplete called. overallStatus == {0}.", overallStatus));
if (overallStatus == true) //Batch completed
{
//Delete the files
foreach (BatchMessage batchMessage in messages)
{
//Close the stream so we can delete this file
batchMessage.Message.BodyPart.Data.Close();
FaxManager.DeleteMessage((FaxFile)batchMessage.UserData);
}
}
}
}
}
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
Anil is from Hyderabad, Andhra Pradesh. He is Currently Working with
VisualSoft Technologies Ltd., As a Software Engineer.
Anil has more than 4 yrs of experience in the IT industry working on Microsoft Technologies. He is involved in various project activities like System Architecture, Design, and Development. Technical experience most specifically ASP.NET , Javascript, Biztalk 2004/2006, Webservices, C# and .NET framework. He has have worked on various language and platforms. He is Microsoft Certified professional.
The author has won several programming awards within the organizations worked and is well-recognized.
--