예제 #1
0
 public static async Task <ConvertFileSystemToGraphResult> ConvertFileSystemToGraphAsyncTask(string root, int asyncFileReadBlockSize, bool enableHash, IConvertFileSystemToGraphProgress?convertFileSystemToGraphProgress, Persistence <IInsertResultsAbstract>?convertFileSystemToGraphPersistence, PickAndSave <IInsertResultsAbstract>?convertFileSystemToGraphPickAndSave, CancellationToken cancellationToken)
 {
예제 #2
0
        async Task DoLoopAsync(string inputLine)
        {
            // check CancellationToken to see if this task is canceled
            CheckAndHandleCancellationToken(1);

            logger.LogDebug(uiLocalizer["{0} {1} inputLineString = {2}", "Console01BackgroundService", "DoLoopAsync", inputLine]);

            // Echo to stdOut the line that came in on stdIn
            mesg.Append(uiLocalizer["You selected: {0}", inputLine]);
            #region Write the mesg to stdout
            using (Task task = await WriteMessageSafelyAsync().ConfigureAwait(false)) {
                if (!task.IsCompletedSuccessfully)
                {
                    if (task.IsCanceled)
                    {
                        // Ignore if user cancelled the operation during output to stdout (internal cancellation)
                        // re-throw if the cancellation request came from outside the stdInLineMonitorAction
                        /// ToDo: evaluate the linked, inner, and external tokens
                        throw new OperationCanceledException();
                    }
                    else if (task.IsFaulted)
                    {
                        //ToDo: Go through the inner exception
                        //foreach (var e in t.Exception) {
                        //  https://docs.microsoft.com/en-us/dotnet/standard/io/handling-io-errors
                        // ToDo figure out what to do if the output stream is closed
                        throw new Exception("ToDo: WriteMessageSafelyAsync returned an AggregateException");
                        //}
                    }
                }
                mesg.Clear();
            }
            #endregion
            #region tempout
            switch (inputLine)
            {
            case "1":
                // ToDo: Get these from the appConfiguration
                var rootString             = appConfiguration.GetValue <string>(appStringConstants.RootStringConfigRootKey, appStringConstants.RootStringDefault);
                var asyncFileReadBlockSize = appConfiguration.GetValue <int>(appStringConstants.AsyncFileReadBlockSizeConfigRootKey, int.Parse(appStringConstants.AsyncFileReadBlockSizeDefault)); // ToDo: should validate in case the appStringConstants assembly is messed up?
                var enableHash             = appConfiguration.GetValue <bool>(appStringConstants.EnableHashBoolConfigRootKey, bool.Parse(appStringConstants.EnableHashBoolConfigRootKeyDefault));  // ToDo: should validate in case the appStringConstants assembly is messed up?
                var enableProgress         = appConfiguration.GetValue <bool>(appStringConstants.EnableProgressBoolConfigRootKey, bool.Parse(appStringConstants.EnableProgressBoolDefault));       // ToDo: should validate in case the appStringConstants assembly is messed up?
                var enablePersistence      = appConfiguration.GetValue <bool>(appStringConstants.EnablePersistenceBoolConfigRootKey, bool.Parse(appStringConstants.EnablePersistenceBoolDefault)); // ToDo: should validate in case the appStringConstants assembly is messed up?
                var enablePickAndSave      = appConfiguration.GetValue <bool>(appStringConstants.EnablePickAndSaveBoolConfigRootKey, bool.Parse(appStringConstants.EnablePickAndSaveBoolDefault)); // ToDo: should validate in case the appStringConstants assembly is messed up?
                var temporaryDirectoryBase = appConfiguration.GetValue <string>(appStringConstants.TemporaryDirectoryBaseConfigRootKey, appStringConstants.TemporaryDirectoryBaseDefault);
                var WithPersistenceNodeFileRelativePath = appConfiguration.GetValue <string>(appStringConstants.WithPersistenceNodeFileRelativePathConfigRootKey, appStringConstants.WithPersistenceNodeFileRelativePathDefault);
                var WithPersistenceEdgeFileRelativePath = appConfiguration.GetValue <string>(appStringConstants.WithPersistenceEdgeFileRelativePathConfigRootKey, appStringConstants.WithPersistenceEdgeFileRelativePathDefault);
                var filePathsPersistence = new string[2] {
                    temporaryDirectoryBase + WithPersistenceNodeFileRelativePath, temporaryDirectoryBase + WithPersistenceEdgeFileRelativePath
                };
                var WithPickAndSaveNodeFileRelativePath = appConfiguration.GetValue <string>(appStringConstants.WithPickAndSaveNodeFileRelativePathConfigRootKey, appStringConstants.WithPickAndSaveNodeFileRelativePathDefault);
                var filePathsPickAndSave = new string[1] {
                    temporaryDirectoryBase + WithPickAndSaveNodeFileRelativePath
                };
                mesg.Append(uiLocalizer["Running PartitionInfoEx Extension Function ConvertFileSystemToObjectGraph, on rootString {0} with an asyncFileReadBlockSize of {1} with hashing enabled: {2} ; progress enabled: {3} ; persistence enabled: {5} ; pickAndSave enabled: {4}", rootString, asyncFileReadBlockSize, enableHash, enableProgress, enablePersistence, enablePickAndSave]);
                if (enablePersistence)
                {
                    mesg.Append(Environment.NewLine);
                    mesg.Append(uiLocalizer["  persistence filePaths: {0}", string.Join(",", filePathsPersistence)]);
                }
                if (enablePickAndSave)
                {
                    mesg.Append(Environment.NewLine);
                    mesg.Append(uiLocalizer["  pickAndSave filePaths {0}", string.Join(",", filePathsPickAndSave)]);
                }
                if (enableProgress)
                {
                    mesg.Append(Environment.NewLine);
                    mesg.Append(uiLocalizer["  progressReporting TBD{0}", "ProgressReportingDataStructureDetails"]);
                }

                #region Write the mesg to stdout
                using (Task task = await WriteMessageSafelyAsync().ConfigureAwait(false)) {
                    if (!task.IsCompletedSuccessfully)
                    {
                        if (task.IsCanceled)
                        {
                            // Ignore if user cancelled the operation during output to stdout (internal cancellation)
                            // re-throw if the cancellation request came from outside the stdInLineMonitorAction
                            /// ToDo: evaluate the linked, inner, and external tokens
                            throw new OperationCanceledException();
                        }
                        else if (task.IsFaulted)
                        {
                            //ToDo: Go through the inner exception
                            //foreach (var e in t.Exception) {
                            //  https://docs.microsoft.com/en-us/dotnet/standard/io/handling-io-errors
                            // ToDo figure out what to do if the output stream is closed
                            throw new Exception("ToDo: WriteMessageSafelyAsync returned an AggregateException");
                            //}
                        }
                    }
                    mesg.Clear();
                }
                #endregion
                #region ProgressReporting setup
                ConvertFileSystemToGraphProgress?convertFileSystemToGraphProgress;
                if (enableProgress)
                {
                    convertFileSystemToGraphProgress = new ConvertFileSystemToGraphProgress();
                }
                else
                {
                    convertFileSystemToGraphProgress = null;
                }
                #endregion
                #region PersistenceViaFiles setup
                // Ensure the Node and Edge files are empty and can be written to

                // Call the SetupViaFileFuncBuilder here, execute the Func that comes back, with filePaths as the argument
                // ToDo: create a function that will create subdirectories if needed to fulfill path, and use that function when creating the temp files
                //ToDo: add exception handling if the setup function fails
                ISetupViaFileResults setupResultsPersistence;
                try {
                    setupResultsPersistence = PersistenceStaticExtensions.SetupViaFileFuncBuilder()(new SetupViaFileData(filePathsPersistence));
                }
                catch (System.IO.IOException ex) {
                    // prepare message for UI interface
                    // ToDo: custom exception,  and include its message here
                    mesg.Append(uiLocalizer["IOException trying to setup PersistenceViaFiles"]);

                    #region Write the mesg to stdout
                    using (Task task = await WriteMessageSafelyAsync().ConfigureAwait(false)) {
                        if (!task.IsCompletedSuccessfully)
                        {
                            if (task.IsCanceled)
                            {
                                // Ignore if user cancelled the operation during output to stdout (internal cancellation)
                                // re-throw if the cancellation request came from outside the stdInLineMonitorAction
                                /// ToDo: evaluate the linked, inner, and external tokens
                                throw new OperationCanceledException();
                            }
                            else if (task.IsFaulted)
                            {
                                //ToDo: Go through the inner exception
                                //foreach (var e in t.Exception) {
                                //  https://docs.microsoft.com/en-us/dotnet/standard/io/handling-io-errors
                                // ToDo figure out what to do if the output stream is closed
                                throw new Exception("ToDo: WriteMessageSafelyAsync returned an AggregateException");
                                //}
                            }
                        }
                        mesg.Clear();
                    }
                    #endregion
                    // Throw exception, Cancel the entire service (internal CTS), or swallow and Continue (possibly offering hints as to resolution), client's choice
                    throw ex;
                    // internalCancellationTokenSource.Signal ????
                    // or just continue and let the user make another selection or go fix the problem
                    //break;
                }
                // Create an insertFunc that references the local variable setupResults, closing over it
                var insertFunc = new Func <IEnumerable <IEnumerable <object> >, IInsertViaFileResults>((insertData) => {
                    int numberOfDatas         = insertData.ToArray().Length;
                    int numberOfStreamWriters = setupResultsPersistence.StreamWriters.Length;
                    for (var i = 0; i < numberOfDatas; i++)
                    {
                        foreach (string str in insertData.ToArray()[i])
                        {
                            //ToDo: add async versions await setupResults.StreamWriters[i].WriteLineAsync(str);
                            //ToDo: exception handling
                            setupResultsPersistence.StreamWriters[i].WriteLine(str);
                        }
                    }
                    return(new InsertViaFileResults(true));
                });
                Persistence <IInsertResultsAbstract> persistence = new Persistence <IInsertResultsAbstract>(insertFunc);
                #endregion
                #region PickAndSaveViaFiles setup
                // Ensure the Archived files are empty and can be written to
                // Call the SetupViaFileFuncBuilder here, execute the Func that comes back, with filePathsPickAndSave as the argument
                // ToDo: create a function that will create subdirectories if needed to fulfill path, and use that function when creating the temp files
                ISetupViaFileResults setupResultsPickAndSave;
                try {
                    setupResultsPickAndSave = PersistenceStaticExtensions.SetupViaFileFuncBuilder()(new SetupViaFileData(filePathsPickAndSave));
                }
                catch (System.IO.IOException ex) {
                    // prepare message for UI interface
                    // ToDo: custom exception,  and include its message here
                    mesg.Append(uiLocalizer["IOException trying to setup PickAndSaveViaFiles"]);
                    #region Write the mesg to stdout
                    using (Task task = await WriteMessageSafelyAsync().ConfigureAwait(false)) {
                        if (!task.IsCompletedSuccessfully)
                        {
                            if (task.IsCanceled)
                            {
                                // Ignore if user cancelled the operation during output to stdout (internal cancellation)
                                // re-throw if the cancellation request came from outside the stdInLineMonitorAction
                                /// ToDo: evaluate the linked, inner, and external tokens
                                throw new OperationCanceledException();
                            }
                            else if (task.IsFaulted)
                            {
                                //ToDo: Go through the inner exception
                                //foreach (var e in t.Exception) {
                                //  https://docs.microsoft.com/en-us/dotnet/standard/io/handling-io-errors
                                // ToDo figure out what to do if the output stream is closed
                                throw new Exception("ToDo: WriteMessageSafelyAsync returned an AggregateException");
                                //}
                            }
                        }
                        mesg.Clear();
                    }
                    #endregion
                    // Throw exception, Cancel the entire service (internal CTS), or swallow and Continue (possibly offering hints as to resolution), client's choice
                    throw ex;
                    // internalCancellationTokenSource.Signal ????
                    // or just continue and let the user make another selection or go fix the problem
                    //break;
                }
                // Create a pickFunc (AKA Predicate)
                var pickFuncPickAndSave = new Func <object, bool>((objToTest) => {
                    return(FileIOExtensions.IsArchiveFile(objToTest.ToString()) || FileIOExtensions.IsMailFile(objToTest.ToString()));
                });
                // Create an insert Func
                var insertFuncPickAndSave = new Func <IEnumerable <IEnumerable <object> >, IInsertViaFileResults>((insertData) => {
                    int numberOfStreamWriters = setupResultsPickAndSave.StreamWriters.Length;
                    for (var i = 0; i < numberOfStreamWriters; i++)
                    {
                        foreach (string str in insertData.ToArray()[i])
                        {
                            //ToDo: add async versions await setupResults.StreamWriters[i].WriteLineAsync(str);
                            //ToDo: exception handling
                            // ToDo: Make formatting a parameter
                            try {
                                setupResultsPickAndSave.StreamWriters[i].WriteLine(str);
                            }
                            catch (System.IO.IOException ex) {
                                throw;
                            }
                        }
                    }
                    return(new InsertViaFileResults(true));
                });
                PickAndSave <IInsertResultsAbstract> pickAndSave = new PickAndSave <IInsertResultsAbstract>(pickFuncPickAndSave, insertFuncPickAndSave);
                #endregion

                ConvertFileSystemToGraphResult convertFileSystemToGraphResult;
                #region Method timing setup
                Stopwatch stopWatch = new Stopwatch(); // ToDo: utilize a much more powerfull and ubiquitous timing and profiling tool than a stopwatch
                stopWatch.Start();
                #endregion
                try {
                    Func <Task <ConvertFileSystemToGraphResult> > run = () => ComputerInventoryHardwareStaticExtensions.ConvertFileSystemToGraphAsyncTask(rootString, asyncFileReadBlockSize, enableHash, convertFileSystemToGraphProgress, persistence, pickAndSave, linkedCancellationToken);
                    convertFileSystemToGraphResult = await run.Invoke().ConfigureAwait(false);

                    stopWatch.Stop(); // ToDo: utilize a much more powerfull and ubiquitous timing and profiling tool than a stopwatch
                                      // ToDo: put the results someplace
                }
                catch (Exception) {   // ToDo: define explicit exceptions to catch and report upon
                                      // ToDo: catch FileIO.FileNotFound, sometimes the file disappears
                    throw;
                }
                finally {
                    // Dispose of the objects that need disposing
                    setupResultsPickAndSave.Dispose();
                    setupResultsPersistence.Dispose();
                }
                #region Build the results
                BuildConvertFileSystemToGraphResults(mesg, convertFileSystemToGraphResult, stopWatch);
                #endregion

                break;
            //    case "2":
            //      #region define the Func<string,Task> to be executed when the ConsoleSourceHostedService.ConsoleReadLineAsyncAsObservable produces a sequence element
            //      // This Action closes over the current local variables' values
            //      Func<string, Task> SimpleEchoToConsoleOutFunc = new Func<string, Task>(async (inputLineString) => {
            //        #region Write the mesg to stdout
            //        using (Task task = await WriteMessageSafelyAsync(inputLineString, consoleSinkHostedService, linkedCancellationToken).ConfigureAwait(false)) {
            //          if (!task.IsCompletedSuccessfully) {
            //            if (task.IsCanceled) {
            //              // Ignore if user cancelled the operation during output to stdout (internal cancellation)
            //              // re-throw if the cancellation request came from outside the stdInLineMonitorAction
            //              /// ToDo: evaluate the linked, inner, and external tokens
            //              throw new OperationCanceledException();
            //            }
            //            else if (task.IsFaulted) {
            //              //ToDo: Go through the inner exception
            //              //foreach (var e in t.Exception) {
            //              //  https://docs.microsoft.com/en-us/dotnet/standard/io/handling-io-errors
            //              // ToDo figure out what to do if the output stream is closed
            //              throw new Exception("ToDo: WriteMessageSafelyAsync returned an AggregateException");
            //              //}
            //            }
            //          }
            //        }
            //        #endregion

            //      });
            //      #endregion
            //      break;
            //    case "10":
            //      #region setup a local block for handling this choice
            //      try {
            //        var enableHash = configurationRoot.GetValue<bool>(ConsoleMonitorStringConstants.EnableHashBoolConfigRootKey, bool.Parse(ConsoleMonitorStringConstants.EnableHashBoolConfigRootKeyDefault));  // ToDo: should validate in case the ConsoleMonitorStringConstants assembly is messed up?
            //        var enableProgress = configurationRoot.GetValue<bool>(ConsoleMonitorStringConstants.EnableProgressBoolConfigRootKey, bool.Parse(ConsoleMonitorStringConstants.EnableProgressBoolDefault));// ToDo: should validate in case the ConsoleMonitorStringConstants assembly is messed up?
            //        var enablePersistence = configurationRoot.GetValue<bool>(ConsoleMonitorStringConstants.EnablePersistenceBoolConfigRootKey, bool.Parse(ConsoleMonitorStringConstants.EnablePersistenceBoolDefault));// ToDo: should validate in case the ConsoleMonitorStringConstants assembly is messed up?
            //        var enablePickAndSave = configurationRoot.GetValue<bool>(ConsoleMonitorStringConstants.EnablePickAndSaveBoolConfigRootKey, bool.Parse(ConsoleMonitorStringConstants.EnablePickAndSaveBoolDefault));// ToDo: should validate in case the ConsoleMonitorStringConstants assembly is messed up?
            //        var dBConnectionString = configurationRoot.GetValue<string>(ConsoleMonitorStringConstants.DBConnectionStringConfigRootKey, ConsoleMonitorStringConstants.DBConnectionStringDefault);// ToDo: should validate in case the ConsoleMonitorStringConstants assembly is messed up?
            //                                                                                                                                                                                            // ToDo: This should be a string representation of a known enumeration of ORMLite DB providers that this service can support
            //        var dBProvider = configurationRoot.GetValue<string>(ConsoleMonitorStringConstants.DBConnectionStringConfigRootKey, ConsoleMonitorStringConstants.DBConnectionStringDefault);// ToDo: should validate in case the ConsoleMonitorStringConstants assembly is messed up?
            //        dBProvider = SqlServerOrmLiteDialectProvider.Instance;
            //        #region ProgressReporting setup
            //        ConvertFileSystemToGraphProgress? convertFileSystemToGraphProgress;
            //        if (enableProgress) {
            //          convertFileSystemToGraphProgress = new ConvertFileSystemToGraphProgress();
            //        }
            //        else {
            //          convertFileSystemToGraphProgress = null;
            //        }
            //        #endregion
            //        #region PersistenceViaIORMSetup
            //        // Call the SetupViaIORMFuncBuilder here, execute the Func that comes back, with dBConnectionString as the argument
            //        // Ensure the NNode and Edge Tables for this PartitionInfo are empty and can be written to
            //        // ToDo: create a function that will create Node and Edge tables if they don't yet exist, and use that function when creating the temp fiiles
            //        // ToDo: add exception handling if the setup function fails
            //        var setupResultsPersistence = PersistenceStaticExtensions.SetupViaORMFuncBuilder()(new SetupViaORMData(dBConnectionString, dBProvider, linkedCancellationToken));

            //        // Create an insertFunc that references the local variable setupResults, closing over it
            //        var insertFunc = new Func<IEnumerable<IEnumerable<object>>, IInsertViaORMResults>((insertData) => {
            //          int numberOfDatas = insertData.ToArray().Length;
            //          int numberOfStreamWriters = setupResultsPersistence.StreamWriters.Length;
            //          for (var i = 0; i < numberOfDatas; i++) {
            //            foreach (string str in insertData.ToArray()[i]) {
            //              //ToDo: add async versions await setupResults.StreamWriters[i].WriteLineAsync(str);
            //              //ToDo: exception handling
            //              setupResultsPersistence.Tables[i].SQLCmd(str);
            //            }
            //          }
            //          return new InsertViaORMResults(true);
            //        });
            //        Persistence<IInsertResultsAbstract> persistence = new Persistence<IInsertResultsAbstract>(insertFunc);
            //        #endregion
            //        #region PickAndSaveViaIORM setup
            //        // Ensure the Node and Edge files are empty and can be written to

            //        // Call the SetupViaIORMFuncBuilder here, execute the Func that comes back, with filePaths as the argument
            //        // ToDo: create a function that will create subdirectories if needed to fulfill path, and use that function when creating the temp files
            //        var setupResultsPickAndSave = PersistenceStaticExtensions.SetupViaORMFuncBuilder()(new SetupViaORMData(dBConnectionString, dBProvider, linkedCancellationToken));
            //        // Create a pickFunc
            //        var pickFuncPickAndSave = new Func<object, bool>((objToTest) => {
            //          return FileIOExtensions.IsArchiveFile(objToTest.ToString()) || FileIOExtensions.IsMailFile(objToTest.ToString());
            //        });
            //        // Create an insert Func
            //        var insertFuncPickAndSave = new Func<IEnumerable<IEnumerable<object>>, IInsertViaORMResults>((insertData) => {
            //          //int numberOfStreamWriters = setupResultsPickAndSave.StreamWriters.Length;
            //          //for (var i = 0; i < numberOfStreamWriters; i++) {
            //          //  foreach (string str in insertData.ToArray()[i]) {
            //          //    //ToDo: add async versions await setupResults.StreamWriters[i].WriteLineAsync(str);
            //          //    //ToDo: exception handling
            //          //    // ToDo: Make formatting a parameter
            //          //    setupResultsPickAndSave.StreamWriters[i].WriteLine(str);
            //          //  }
            //          //}
            //          return new InsertViaORMResults(true);
            //        });
            //        PickAndSave<IInsertResultsAbstract> pickAndSave = new PickAndSave<IInsertResultsAbstract>(pickFuncPickAndSave, insertFuncPickAndSave);
            //        #endregion
            //      }
            //      // To Catch specific exceptions that might occur
            //      catch {
            //      }
            //      // ToDo: dispose
            //      finally { }
            //      #endregion
            //      break;
            case "99":
                #region Quit the program
                //internalcancellationtoken.
                #endregion
                break;

            default:
                mesg.Clear();
                mesg.Append(uiLocalizer["InvalidInputDoesNotMatchAvailableChoices {0}", inputLine]);
                break;
            }

            #region Write the mesg to stdout
            using (Task task = await WriteMessageSafelyAsync().ConfigureAwait(false)) {
                if (!task.IsCompletedSuccessfully)
                {
                    if (task.IsCanceled)
                    {
                        // Ignore if user cancelled the operation during output to stdout (internal cancellation)
                        // re-throw if the cancellation request came from outside the stdInLineMonitorAction
                        /// ToDo: evaluate the linked, inner, and external tokens
                        throw new OperationCanceledException();
                    }
                    else if (task.IsFaulted)
                    {
                        //ToDo: Go through the inner exception
                        //foreach (var e in t.Exception) {
                        //  https://docs.microsoft.com/en-us/dotnet/standard/io/handling-io-errors
                        // ToDo figure out what to do if the output stream is closed
                        throw new Exception("ToDo: WriteMessageSafelyAsync returned an AggregateException");
                        //}
                    }
                }
            }
            #endregion

            #endregion
            #region Buildmenu
            await BuildMenu();

            #endregion
            #region Write the mesg to stdout
            using (Task task = await WriteMessageSafelyAsync().ConfigureAwait(false)) {
                if (!task.IsCompletedSuccessfully)
                {
                    if (task.IsCanceled)
                    {
                        // Ignore if user cancelled the operation during output to stdout (internal cancellation)
                        // re-throw if the cancellation request came from outside the stdInLineMonitorAction
                        /// ToDo: evaluate the linked, inner, and external tokens
                        throw new OperationCanceledException();
                    }
                    else if (task.IsFaulted)
                    {
                        //ToDo: Go through the inner exception
                        //foreach (var e in t.Exception) {
                        //  https://docs.microsoft.com/en-us/dotnet/standard/io/handling-io-errors
                        // ToDo figure out what to do if the output stream is closed
                        throw new Exception("ToDo: WriteMessageSafelyAsync returned an AggregateException");
                        //}
                    }
                }
                mesg.Clear();
            }
            #endregion
        }