Introduction
This article will give you an idea of how to write a custom send pipeline component to compress a Zip file and encrypt it with a password.
Background
Usually, in most enterprise applications, we will have several enterprise partners who will receive our data. If the data which is transferred from source A to source B is huge in size and sensitive, then we will have to compress and encrypt the file. By which the data transmission time is reduced. In this article, I am giving an example to compress a single text file in to a Zip file and encrypt that zip file with a given password. You can extend this to compress multiple files. We have a MpasFileValidator
(MapsFileIntegrityDecoder
) component, which just checks the length of each record in the input file and pass it to a dissassembler. If you don't want it, don't use it.
Using the code
You can download both zip files and compile and run, but to give your own values to the custom send pipeline component properties, follow these steps:
- Step 1: Download and extract the ZipFileComponent.zip file (custom pipeline component). Open the project and select the project properties and set its assembly output directory path to Program Files\Microsoft BizTalk Server 2006\PipelineComponents\.
- Step 2: Download and extract FileZippingPOC.zip (BizTalk artifact application), and open the project and select Zipline.btp.
- Step 3: In the encode stage, select the existing custom component I already dropped and set the properties in the Properties dialog box with your own values.
The properties to set:
- File name: Your absolute file path which has to be zipped.
- Compression level: 1 to 5 (used to stream compression level); default is 5.
- Password: The password value which has to be set to the zip file.
- Step 4: Deploy BizTalk artifacts.
- Step 5: Set the bindings for the receive port (input file) and send port (output zip file).
- Step 6: Drop the file in the input folder (where your receive location is bound to the receive port), and you will see the output Zip file at the send port location.
Here are the code part blocks used to develop this pipeline component:
Setting the custom properties is as shown below:
Private _CompressionLevel As String
Public Property CompressionLevel() As String
Get
Return _CompressionLevel
End Get
Set
_CompressionLevel = value
End Set
End Property
Call your function which implements zipping and encrypting in the Execute()
method. Here I am calling my zipping and encrypting function Encode(stream)
in the Execute method.
Public Function Execute(ByVal pc As Microsoft.BizTalk.Component.Interop.IPipelineContext, _
ByVal inmsg As Microsoft.BizTalk.Message.Interop.IBaseMessage) _
As Microsoft.BizTalk.Message.Interop.IBaseMessage _
Implements Microsoft.BizTalk.Component.Interop.IComponent.Execute
Try
If Not inmsg Is Nothing Then
Dim originalStream As Stream = inmsg.BodyPart.GetOriginalDataStream()
inmsg.BodyPart.Data = Encode(originalStream)
pc.ResourceTracker.AddResource(inmsg.BodyPart.Data)
End If
Catch ex As Exception
System.Diagnostics.Debug.WriteLine(_
"Exception caught in_ABC.BizTalk.PipelineComponents." & _
"PGPEncodeComponent::Execute: " & ex.Message)
End Try
Return inmsg
End Function
Here is the Encode
function:
Private Function Encode(ByVal inStream As Stream) As Stream
Dim outStream As Stream = inStream
Dim inFile As String = Path.GetTempFileName()
Dim outFile As String = Path.ChangeExtension(inFile, "zip")
Try
Dim zipStream As ZipOutputStream = New ZipOutputStream(File.Create(outFile))
If Not String.IsNullOrEmpty(_Password) Then
zipStream.Password = _Password
End If
Dim compressionLevel As Integer = DEFAULT_COMPRESSIONLEVEL
If (Not _CompressionLevel Is Nothing) AndAlso (_CompressionLevel <> "") Then
compressionLevel = Convert.ToInt32(_CompressionLevel)
End If
If (compressionLevel < 0) OrElse (compressionLevel > 9) Then
compressionLevel = DEFAULT_COMPRESSIONLEVEL
End If
zipStream.SetLevel(compressionLevel)
Dim fileName As String
If (Not _FileName Is Nothing) AndAlso (_FileName <> "") Then
fileName = _FileName
Else
fileName = DEFAULT_FILENAME
End If
Dim entry As ZipEntry = New ZipEntry(fileName)
zipStream.PutNextEntry(entry)
Dim buffer As Byte() = New Byte(1024) {}
Dim count As Integer = inStream.Read(buffer, 0, buffer.Length)
Do While (count <> 0)
zipStream.Write(buffer, 0, count)
count = inStream.Read(buffer, 0, buffer.Length)
Loop
zipStream.Finish()
zipStream.Close()
outStream = ReadFileToMemoryStream(outFile)
Catch ex As Exception
System.Diagnostics.Debug.WriteLine(ex)
Throw ex
Finally
If File.Exists(inFile) Then
File.Delete(inFile)
End If
If File.Exists(outFile) Then
File.Delete(outFile)
End If
End Try
Return outStream
End Function
That's all!