Don't miss out Virtual Happy Hour this Friday (April 26).

Try our conversational search powered by Generative AI!

Shahram Shahinzadeh
Apr 26, 2010
  6219
(1 votes)

Custom Mirroring Transfer Provider on USB

Custom Mirroring Transfer Provider on USB

Summary:

Would you like to export the entire site on USB memory and importing to other places or why not saving it as backup?
In this blog I will go through Custom Mirroring Transfer Provider (MTP). The custom implementation of USB Provider contains two parts the first one is MirroringTransferUSBProvider class which has responsibility to export packages to USB memory stick. And the second part is MirroringUSBProvider class which imports the exported packages to an arbitrary site.

MirroringTransferUSBProvider

MirroringTransferUSBProvider class is a derived class from EPiServer.MirroringService.MirroringTransferProtocol.Common.MirroringTransferProviderBase.  As you see in this simple class we only implement the InitializeMirroring and CompleteMirroring methods. In the InitializeMirroring we save all necessary information to a file with the name MirroringInfo.mir and I choose to save at the same place that the SourcePath attribute points to. I have not override the source path but if you like you can do it by code, by default its value reads from mirroring service web config file. If you will do mirroring on same site or import to same site you should find out the site unique id for the site otherwise you can generate a new guid and assign to DestinationUniqueId.  And in the CompleteMirroring method only sends a mirroringJobcompleted state to the mirroring service. It is good to know when you send back status to mirroring service with MirroringjobCompleted state the mirroring service terminates the job and notifies the mirroring job is finished but in this case we have not imported the packages yet, the status on the mirroring schedule service shows only exported pages and number of imported pages is zero. Here is the code example.

   1: namespace MirroringSample
   2: {
   3:  public class MirroringTransferUSBProvider : MirroringTransferProviderBase
   4:  {
   5:         private MirroringInitializeData _mirroringInitializeData;
   6:         private Guid _contextId;
   7:  
   8:         // InitializeMirroring be called from mirroring serice and lets the provider to do stuff before prcoess package            
   9:         public override MirroringStatus InitializeMirroring(Guid context, MirroringInitializeData mirroringInitializeData)
  10:         {
  11:             _contextId = context;
  12:             _mirroringInitializeData = mirroringInitializeData;
  13:  
  14:             // If you like to do mirroring on same site you have to find out the site unique id otherwise you can generate new guid
  15:             _mirroringInitializeData.DestinationUniqueId = new Guid().ToString();
  16:  
  17:             // Save the mirroring settings in a file with name MirroringInfo.mir
  18:             SaveMirroringInfoFile(context, mirroringInitializeData);
  19:             MirroringStatus status = new MirroringStatus();
  20:             status.State = MirroringState.MirroringJobInitialized;
  21:             return status;
  22:         }
  23:  
  24:  
  25:         // CompleteMirroring be called when all packages is process and there is nothing more to do
  26:         public override void CompleteMirroring(Guid context)
  27:         {
  28:             MirroringStatusEventArgs e = new MirroringStatusEventArgs();
  29:             e.Context = _contextId;
  30:             e.MirroringTransferData.MirroringInitializeData = _mirroringInitializeData;
  31:             e.MirroringTransferData.Status.State =  MirroringState.MirroringJobCompleted;
  32:  
  33:             // We notify mirroring service the USB MTP is also finished, If you like you can frezz the mirrornig service 
  34:             // thread unitl you have import the packages and then notify MirroringJobCompleted.
  35:             OnMirroringStatus(e);
  36:  
  37:         }
  38:  
  39:         // ProcessFilePackage be called when a file packages is ready to be process 
  40:         // But in this case we have nothing to do with the package and we leave it.
  41:         public override void ProcessFilePackage(Guid context, string filePath)
  42:         {}
  43:  
  44:         // ProcessPackage be called when a file packages is ready to be process 
  45:         // But in this case we have nothing to do with the package and we leave it.
  46:         public override void ProcessPackage(Guid context, string filePath)
  47:         {}
  48:  
  49:         // Save mirroring settings in file. We are going to use them for importing...
  50:         public void SaveMirroringInfoFile(Guid context, MirroringInitializeData mirroringInitializeData)
  51:         {
  52:             using (FileStream fs = new FileStream(Path.Combine(SourcePath.FullName, "MirroringInfo.mir"), FileMode.OpenOrCreate, FileAccess.Write))
  53:             {
  54:                 XmlSerializer xmlSerializer = new XmlSerializer(typeof(USBMirroringInfo));
  55:                 xmlSerializer.Serialize(fs, new USBMirroringInfo() { Context = context, MirroringInitializeData = mirroringInitializeData });
  56:             }
  57:         }
  58:     }
  59: }

And you can configure it by adding the type in the mirroring service config file like this:

   1: <mirroringTransfer defaultProvider="MirroringTransferServer" validateUser="true">
   2:   <providers>
   3:    <add
   4:      name="USBProvider"
   5:      type="MirroringSample.MirroringTransferUSBProvider, USBMirroringTransferProvider" />
   6:   </providers>
   7: </mirroringTransfer>

MirroringUSBProvider

MirroringUSBProvider class is a derived class from MirroringProviderBase. We can use it on the importing side of mirroring. The RunTimeInitializeMirroring initializes the database and other necessary initializations and it should be called once per mirroring job. The next step is to call RuntimeProcessPackage which imports the packages. Before calling RuntimeProcessPackage you have to sort the files according to the creation time. Ordering of files for importing is very important. Here is an example.

   1: namespace MirroringSample
   2: {
   3:     public class MirroringUSBProvider : MirroringProviderBase
   4:     {
   5:         public MirroringUSBProvider(){}
   6:         public void Initialize(String path)
   7:         {
   8:             USBMirroringInfo = ReadMirroringInfoFromFile(path);
   9:         }
  10:  
  11:         public MirroringStatus Run(String pathToExportPackages, Action<MirroringStatus> progress)
  12:         {
  13:             MirroringInitializeData m = USBMirroringInfo.MirroringInitializeData;
  14:             RuntimeInitializeMirroring(USBMirroringInfo.Context, USBMirroringInfo.MirroringInitializeData.DestinationRoot, ref m);
  15:             USBMirroringInfo.MirroringInitializeData = m;
  16:             MirroringStatus ms = new MirroringStatus();
  17:             ms.State = MirroringState.MirroringJobCompleted;
  18:             DirectoryInfo dir = new DirectoryInfo(Path.Combine(pathToExportPackages, USBMirroringInfo.Context.ToString()));
  19:             if (!dir.Exists)
  20:             {
  21:                 ms.State = MirroringState.ImportingError;
  22:                 ms.StatusLog.Errors.Add("Failed to import packges: reason the {0} path does not exist");
  23:                 return ms;
  24:             }
  25:  
  26:             FileInfo[] files = GetExistingPackages(dir);
  27:             RunTimeMirroringProxyData proxyData = new RunTimeMirroringProxyData();
  28:             proxyData.ContinueOnError = USBMirroringInfo.MirroringInitializeData.ContinueOnError;
  29:             proxyData.DestinationConnectionStringName = USBMirroringInfo.MirroringInitializeData.DestinationConnectionStringName;
  30:             proxyData.DestinationPageGuid = USBMirroringInfo.MirroringInitializeData.DestinationPageGuid;
  31:             proxyData.DestinationRoot = USBMirroringInfo.MirroringInitializeData.DestinationRoot;
  32:             proxyData.DestinationUri = USBMirroringInfo.MirroringInitializeData.DestinationUri;
  33:             proxyData.TransferAction = USBMirroringInfo.MirroringInitializeData.MirroringTransferAction;
  34:             for (Int32 i = 0; i < files.Length; i++)
  35:             {
  36:                 try
  37:                 {
  38:                     proxyData.PackagePath= files[i].FullName;
  39:                     progress(RuntimeProcessPackage(USBMirroringInfo.Context, proxyData));
  40:                 }
  41:                 catch
  42:                 {
  43:                     if (USBMirroringInfo.MirroringInitializeData.ContinueOnError)
  44:                     {
  45:                         ms.State = MirroringState.ImportingError;
  46:                         // log
  47:                     }
  48:                     else
  49:                     {
  50:                         ms.State = MirroringState.ImportingError;
  51:                         throw;
  52:                     }
  53:                 }
  54:             }
  55:             return ms;
  56:         }
  57:  
  58:         public FileInfo[] GetExistingPackages(DirectoryInfo dir)
  59:         {
  60:             FileInfo[] files = dir.GetFiles();
  61:             Array.Sort(files, new FileComparer());
  62:             return files;
  63:         }
  64:  
  65:  
  66:         public USBMirroringInfo ReadMirroringInfoFromFile(string path)
  67:         {
  68:             using (FileStream fs = new FileStream(Path.Combine(path, "MirroringInfo.mir"), FileMode.Open, FileAccess.Read))
  69:             {
  70:                 XmlSerializer xmlSerializer = new XmlSerializer(typeof(USBMirroringInfo));
  71:                 return (USBMirroringInfo)xmlSerializer.Deserialize(fs);
  72:             }
  73:         }
  74:  
  75:         private class FileComparer : IComparer<FileInfo>
  76:         {
  77:             #region IComparer<FileInfo> Members
  78:             public int Compare(FileInfo x, FileInfo y)
  79:             {
  80:                 if (DateTime.Compare(x.CreationTime, y.CreationTime) == 0)
  81:                 {
  82:                     return String.Compare(x.FullName, y.FullName, StringComparison.Ordinal);
  83:                 }
  84:                 return DateTime.Compare(x.CreationTime, y.CreationTime);
  85:             }
  86:             #endregion
  87:         }
  88:  
  89:         public USBMirroringInfo USBMirroringInfo
  90:         { get; set; }
  91:     }
  92: }


You can use the MirroringUSBProvider class to import the packages to the target site. Like this code example.

   1: MirroringUSBProvider usbProvider = new MirroringUSBProvider();
   2: usbProvider.Initialize(folderBrowserDialog.SelectedPath);


If you like you can change the settings on the mirroring settings like this: 

   1:  
   2: usbProvider.USBMirroringInfo.MirroringInitializeData.ContinueOnError = true;
   3: usbProvider.USBMirroringInfo.MirroringInitializeData.DestinationRoot.ID = 26

 

And remember your app.config should conatins at least a connectionstrings.
After changing the mirroring settings you call process to importing packages.

 

   1: usbProvider.Process(folderBrowserDialog.SelectedPath, ProgressUpdate);
Apr 26, 2010

Comments

Please login to comment.
Latest blogs
Solving the mystery of high memory usage

Sometimes, my work is easy, the problem could be resolved with one look (when I’m lucky enough to look at where it needs to be looked, just like th...

Quan Mai | Apr 22, 2024 | Syndicated blog

Search & Navigation reporting improvements

From version 16.1.0 there are some updates on the statistics pages: Add pagination to search phrase list Allows choosing a custom date range to get...

Phong | Apr 22, 2024

Optimizely and the never-ending story of the missing globe!

I've worked with Optimizely CMS for 14 years, and there are two things I'm obsessed with: Link validation and the globe that keeps disappearing on...

Tomas Hensrud Gulla | Apr 18, 2024 | Syndicated blog

Visitor Groups Usage Report For Optimizely CMS 12

This add-on offers detailed information on how visitor groups are used and how effective they are within Optimizely CMS. Editors can monitor and...

Adnan Zameer | Apr 18, 2024 | Syndicated blog

Azure AI Language – Abstractive Summarisation in Optimizely CMS

In this article, I show how the abstraction summarisation feature provided by the Azure AI Language platform, can be used within Optimizely CMS to...

Anil Patel | Apr 18, 2024 | Syndicated blog

Fix your Search & Navigation (Find) indexing job, please

Once upon a time, a colleague asked me to look into a customer database with weird spikes in database log usage. (You might start to wonder why I a...

Quan Mai | Apr 17, 2024 | Syndicated blog