/// <summary>
        /// Fetches the files from Remote Storage for the restore script.
        /// </summary>
        /// <param name="database">The database.</param>
        /// <param name="sortOrder">The sort order.</param>
        /// <returns></returns>
        public StringBuilder FetchFilesForRestoreScript(string database, ItemSortOrder sortOrder)
        {
            var remoteItems = m_remoteItemClass == ItemClass.Blob
                                ? m_azureHelper.GetBlobItems()
                                : m_fileHelper.GetFileItems();

            Console.WriteLine("Number of items found in Remote Storage: {0}", remoteItems.Count);
            Console.WriteLine();

            Console.WriteLine("Starting file review ...");

            var filesToFetch = ParseLatestBackup(remoteItems, database);

            var rfh = new RemoteFetchHelper(m_remoteItemClass);

            // Actually fetch the files
            var files = rfh.FetchItemsFromRemoteStorage(filesToFetch, sortOrder);

            // Generate the script and return it
            return(BuildRestoreScript(files));
        }
示例#2
0
        public SyncHelper(ItemClass itemClass, bool debug)
        {
            m_remoteItemClass = itemClass;
            m_common          = new Common();

            m_isDebug = debug;

            if (m_remoteItemClass == ItemClass.Blob)
            {
                m_azureStorageHelper = m_azureStorageHelper ?? new AzureStorageHelper();
            }
            else
            {
                m_fileStorageHelper = m_fileStorageHelper ?? new FileStorageHelper();
                m_remoteStorage     = new DirectoryInfo(ConfigHelper.GetConfigurationValue("RemoteStorage"));
                m_remoteUsername    = ConfigHelper.GetFileStorageUsername();
                m_remotePassword    = ConfigHelper.GetFileStoragePassword();
            }

            m_isRunningOnWindows = Path.DirectorySeparatorChar.Equals('\\') ? true : false;

            // Get the application settings
            m_localDirectory = new DirectoryInfo(ConfigHelper.GetConfigurationValue("LocalPath"));
            m_remoteStorage  = new DirectoryInfo(ConfigHelper.GetConfigurationValue("RemoteStorage"));

            m_copyFilesToRemoteStorage             = ConfigHelper.GetConfigurationBoolean("CopyFilesToRemoteStorage");
            m_deleteExplicitFilesFromRemoteStorage = ConfigHelper.GetConfigurationBoolean("DeleteExplicitFilesFromRemoteStorage");
            m_fetchExplicitFilesFromRemoteStorage  = ConfigHelper.GetConfigurationBoolean("FetchExplicitFilesFromRemoteStorage");
            m_deleteMissingFilesFromRemoteStorage  = ConfigHelper.GetConfigurationBoolean("DeleteMissingFilesFromRemoteStorage");
            m_deleteMissingFilesFromLocalStorage   = ConfigHelper.GetConfigurationBoolean("DeleteMissingFilesFromLocalStorage");
            m_fetchFilesFromRemoteStorage          = ConfigHelper.GetConfigurationBoolean("FetchFilesFromRemoteStorage");
            m_explicitFilesToDeleteMatchingString  = ConfigHelper.GetConfigurationValue("ExplicitFilesToDeleteMatchingString");
            m_explicitFilesToFetchMatchingString   = ConfigHelper.GetConfigurationValue("ExplicitFilesToFetchMatchingString");
            m_itemSortOrder = ConfigHelper.GetConfigurationValue("ItemSortOrder")
                              .Equals("Size", StringComparison.InvariantCultureIgnoreCase)
                                ? ItemSortOrder.Size
                                : ItemSortOrder.Name;
            var compressAndEncrypt = ConfigHelper.GetConfigurationBoolean("CompressAndEncrypt");
            var encryptOnly        = ConfigHelper.GetConfigurationBoolean("EncryptOnly");


            if (string.IsNullOrEmpty(m_explicitFilesToDeleteMatchingString))
            {
                // Don't delete any explicit files from Remote Path
                m_deleteExplicitFilesFromRemoteStorage = false;
                m_explicitFilesToDeleteMatchingString  = string.Empty;
            }

            if (string.IsNullOrEmpty(m_explicitFilesToFetchMatchingString))
            {
                // Don't delete any explicit files from Remote Path
                m_fetchExplicitFilesFromRemoteStorage = false;
                m_explicitFilesToFetchMatchingString  = string.Empty;
            }

            // Override the debug value
            m_isDebug = !ConfigHelper.GetConfigurationValue("DebugOverride")
                        .Equals("True", StringComparison.InvariantCultureIgnoreCase);

            // Encrypt and Compress settings -- only one can be true, default to EncryptOnly if set
            if (compressAndEncrypt && encryptOnly)
            {
                compressAndEncrypt = false;
            }

            // Will only synchronise files that have the EncryptedFileExtension file type
            // And this is only set if either of the encryption settings is set
            m_syncEncryptedFilesOnly = compressAndEncrypt || encryptOnly;
            m_encryptedFileExtension = ConfigHelper.GetConfigurationValue("EncryptedFileExtension") ?? ".absz";
        }
        /// <summary>
        /// Generates the restore script.
        /// </summary>
        /// <param name="database">The database.</param>
        /// <param name="dumpFileList">Dump list of all files on RemoteStorage</param>
        /// <param name="sortOrder">The sort order</param>
        /// <returns></returns>
        public StringBuilder GenerateRestoreScript(string database, bool dumpFileList, ItemSortOrder sortOrder)
        {
            if (!dumpFileList)
            {
                return(FetchFilesForRestoreScript(database, sortOrder));
            }

            var remoteItems = m_remoteItemClass == ItemClass.Blob
                                ? m_azureHelper.GetBlobItems()
                                : m_fileHelper.GetFileItems();

            Console.WriteLine("Number of items found in Remote Storage: {0}", remoteItems.Count);
            Console.WriteLine();

            Console.WriteLine("Dumping list of Blob Items to disk ...");

            var fileList = new StringBuilder();

            foreach (var item in remoteItems)
            {
                fileList.AppendLine(item.Name);
            }
            return(fileList);
        }
        /// <summary>
        /// Fetches the files from Remote Storage.
        /// </summary>
        /// <param name="filesToFetch">The files to fetch.</param>
        /// <param name="sortOrder">The item sort order.</param>
        /// <returns></returns>
        public Dictionary <FileInfo, string> FetchItemsFromRemoteStorage(IEnumerable <RemoteItem> filesToFetch,
                                                                         ItemSortOrder sortOrder)
        {
            var fileList = filesToFetch.ToList();

            if (m_remoteItemClass == ItemClass.Blob)
            {
                var       blobClient  = m_azureHelper.StorageAccount.CreateCloudBlobClient();
                var       container   = blobClient.GetContainerReference(m_azureHelper.ContainerName);
                const int segmentSize = 1 * 1024 * 1024; // 1 MB chunk
                                                         // int segmentSize = 64 * 1024; // 64 KB chunk

                // Build list of files for restore script
                var files = fileList.ToDictionary(file => new FileInfo($@"{m_localDirectory}\{file.Name.Replace(@"/", @"\")}"),
                                                  file => file.BackupType.ToFriendlyString());

                // Sort by smallest file first
                var sortedFilesToFetch = sortOrder == ItemSortOrder.Size
                    ? fileList.OrderBy(x => x.Size)
                    : fileList.OrderBy(x => x.Name);

                Console.WriteLine("Fetching files {0} with block size [{1}] ...",
                                  sortOrder == ItemSortOrder.Size ? "from smallest to largest" : "in alphabetical order",
                                  segmentSize.ToString("N0", CultureInfo.InvariantCulture));

                foreach (var file in sortedFilesToFetch)
                {
                    Console.Write("Fetching [{0}]: ", file.Name);

                    // Retrieve reference to a blob named "myblob".
                    var blockBlob = container.GetBlockBlobReference(file.Name);

                    var localFilePath = $@"{m_localDirectory}\{file.Name.Replace(@"/", @"\")}";

                    var fi = new FileInfo(localFilePath);

                    // Skip the file if it exists
                    if (fi.Exists && fi.Length == file.Size)
                    {
                        Common.SetFileCreationDate(file, fi);
                        Console.WriteLine("Done.");
                        continue;
                    }

                    if (fi.DirectoryName != null)
                    {
                        var di = new DirectoryInfo(fi.DirectoryName);
                        if (!di.Exists)
                        {
                            di.Create();
                        }
                    }

                    using (var fileStream = new FileStream(fi.FullName, FileMode.OpenOrCreate))
                    {
                        ParallelDownloadBlob(fileStream, blockBlob);
                    }

                    Common.SetFileCreationDate(file, fi);
                    Console.WriteLine("Done.");
                }

                return(files);
            }
            else
            {
                // Build list of files for restore script
                var files = fileList.ToDictionary(file => new FileInfo($@"{file.PathOrUrl.Replace(m_remoteStorage, m_localDirectory)}\{file.Name}"),
                                                  file => file.BackupType.ToFriendlyString());

                // Sort by smallest file first
                var sortedFilesToFetch = sortOrder == ItemSortOrder.Size
                    ? fileList.OrderBy(x => x.Size)
                    : fileList.OrderBy(x => x.Name);

                Console.WriteLine("Fetching files {0} ...",
                                  sortOrder == ItemSortOrder.Size ? "from smallest to largest" : "in alphabetical order");

                foreach (var file in sortedFilesToFetch)
                {
                    Console.Write("Fetching [{0}]: ", file.Name);

                    var remoteFilePath = $@"{file.PathOrUrl}\{file.Name}";
                    var localFilePath  = remoteFilePath.Replace(m_remoteStorage, m_localDirectory);

                    var localFile  = new FileInfo(localFilePath);
                    var remoteFile = new FileInfo(remoteFilePath);

                    // Skip the file if it exists
                    if (localFile.Exists && localFile.Length == file.Size)
                    {
                        Common.SetFileCreationDate(file, localFile);
                        Console.WriteLine("Done.");
                        continue;
                    }

                    if (localFile.DirectoryName != null)
                    {
                        var di = new DirectoryInfo(localFile.DirectoryName);
                        if (!di.Exists)
                        {
                            di.Create();
                        }
                    }

                    try
                    {
                        File.Copy(remoteFile.FullName, localFilePath);
                        Common.SetFileCreationDate(file, localFile);
                        Console.WriteLine("Done.");
                    }
                    catch (Exception)
                    {
                        Console.WriteLine("Failed copying file from {0} to {1}.", remoteFile.FullName, localFilePath);
                    }
                }

                return(files);
            }
        }