예제 #1
0
        internal void Exercise(DirtyDeviceActivityData activityData, NetworkCredential userCredential, PluginEnvironment environment)
        {
            _activityData   = activityData;
            _userCredential = userCredential;

            string localMachineName    = NetUtil.GetFQDN();
            string fileShareServerName = $"{activityData.DigitalSend.OutputFolder.ServerHostName}.{environment.UserDnsDomain}";
            var    externalFacingProtocolSpecificPath = activityData.DigitalSend.OutputFolder.MonitorLocation;
            var    correspondingSharePath             = $@"\\{fileShareServerName}\{externalFacingProtocolSpecificPath.Replace("/", @"\")}";

            EndpointPath fileSharePath = new EndpointPath(
                DestinationType.NetworkFolder,
                fileShareServerName,
                null,
                externalFacingProtocolSpecificPath,
                correspondingSharePath);

            EndpointPath ftpPath = new EndpointPath(
                DestinationType.Ftp,
                localMachineName,
                null,
                externalFacingProtocolSpecificPath,
                correspondingSharePath);

            EndpointPath httpPath = new EndpointPath(
                DestinationType.Http,
                localMachineName,
                EndpointManager.HttpPort,
                externalFacingProtocolSpecificPath,
                correspondingSharePath);

            var pathManager = new PathManager(fileSharePath, ftpPath, httpPath);

            _endpointManager = new EndpointManager(pathManager, environment);
            _endpointManager.UpdateStatus += (s, e) => _owner.OnUpdateStatus(s, e.StatusMessage);

            // eschew "all inspectable pages are in use" exception
            foreach (var protocol in new[] { DestinationType.Ftp, DestinationType.Http, DestinationType.NetworkFolder })
            {
                for (var attempt = 1; attempt <= MaxRetryCount; attempt++)
                {
                    _owner.OnUpdateStatus(this, $"");
                    _preparationManager.InitializeDevice(true);
                    try
                    {
                        ExecuteScanToDestination(protocol);
                        // If we got this far successfully, we are done.  We do not need to retry.
                        break;
                    }
                    catch (Exception x)
                    {
                        _owner.OnUpdateStatus(this, $"  Digital send failed.  (Device: {_deviceDat.Address}; Protocol: {protocol}; Error: {x.Message})");
                        if (attempt >= MaxRetryCount)
                        {
                            throw;
                        }
                        _owner.OnUpdateStatus(this, $"  Will attempt {MaxRetryCount - attempt} more times.");
                    }
                }
            }
            _owner.OnUpdateStatus(this, string.Empty);
            _preparationManager.InitializeDevice(true);
        }
예제 #2
0
 public PathManager(EndpointPath fileSharePath, EndpointPath ftpPath, EndpointPath httpPath)
 {
     FileSharePath = fileSharePath;
     FtpPath       = ftpPath;
     HttpPath      = httpPath;
 }
예제 #3
0
        internal void ExecuteScanToDestination(DestinationType destinationType)
        {
            const int MaxPageCountThresholdForProcessingNotificationError = 2;
            int       expectedNumberOfGeneratedFiles = 1;
            int       step        = 0;
            string    uiContextId = "<Missing uiContextId>";

            _owner.OnUpdateStatus(this, $"Step {++step}: Setup {destinationType} scan ticket.");
            ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls;

            var tree        = DiscoveryTreeTranslator.GetOXPdDiscoveryTree(_deviceDat.Address);
            var scanFactory = new ScanProxyFactory();
            var scanProxy   = scanFactory.CreateProxy(tree, _deviceDat.Address, _deviceDat.AdminPassword);
            var uiFactory   = new UIConfigurationProxyFactory();
            var uiProxy     = uiFactory.CreateProxy(tree, _deviceDat.Address, _deviceDat.AdminPassword);
            var testFactory = new TestProxyFactory();
            var testProxy   = testFactory.CreateProxy(tree, _deviceDat.Address, _deviceDat.AdminPassword);

            ScanTicket jobTicket = new ScanTicket();

            jobTicket.transmissionMode         = TransmissionMode.Job;
            jobTicket.basicOptions             = scanProxy.GetDefaultBasicOptions(jobTicket.transmissionMode);
            jobTicket.basicOptions.mediaSource = MediaSource.Flatbed;
            jobTicket.destination = new OXPd.Common.WebResourceWithTimeoutAndRetry();
            jobTicket.destination.connectionTimeout = 60;
            jobTicket.destination.responseTimeout   = 300;
            jobTicket.destination.retryInterval     = 1;
            jobTicket.destination.binding           = OXPd.Common.Binding.Plain;

            switch (destinationType)
            {
            case DestinationType.Ftp:
                jobTicket.destination.uri = _endpointManager.FtpServer.EndpointAddress;
                jobTicket.destination.networkCredentials = new OXPd.Common.NetworkCredentials()
                {
                    userName = _userCredential.UserName, password = _userCredential.Password
                };
                break;

            case DestinationType.Http:
                jobTicket.destination.uri = _endpointManager.HttpScanReceiver.EndpointAddress;
                jobTicket.destination.networkCredentials = new OXPd.Common.NetworkCredentials()
                {
                    userName = "******", password = "******"
                };
                break;

            case DestinationType.NetworkFolder:
                jobTicket.destination.uri = _endpointManager.NetworkFolder.EndpointAddress;
                jobTicket.destination.networkCredentials = new OXPd.Common.NetworkCredentials()
                {
                    domain = _userCredential.Domain, userName = _userCredential.UserName, password = _userCredential.Password
                };
                break;
            }

            jobTicket.fileOptions      = scanProxy.GetDefaultFileOptions(jobTicket.basicOptions.fileType, jobTicket.basicOptions.colorMode);
            jobTicket.metadata         = null;
            jobTicket.scanFileNameBase = DateTimeStampForNaming + "_" + EndpointPath.GetProtocolAsString(destinationType);
            _owner.OnUpdateStatus(this, $"Target Folder as URI (PathManager): {_endpointManager.PathManager.GetEndpointPath(destinationType).GetPathAsUrl()}");
            _owner.OnUpdateStatus(this, $"Target Folder as URI (JobTicket): {jobTicket.destination.uri}");
            _owner.OnUpdateStatus(this, $"Target Folder as Path: {_endpointManager.PathManager.GetEndpointPath(destinationType).CorrespondingFileSystemPath}");
            _owner.OnUpdateStatus(this, $"Target File as Path: {_endpointManager.PathManager.GetEndpointPath(destinationType).CorrespondingFileSystemPath + @"\" + jobTicket.scanFileNameBase + "*.*"}");
            string qualifiedUserName = (jobTicket.destination.networkCredentials.domain == null) ? jobTicket.destination.networkCredentials.userName : $"{jobTicket.destination.networkCredentials.domain}\\{jobTicket.destination.networkCredentials.userName}";

            _owner.OnUpdateStatus(this, $"Credentials: Username = { qualifiedUserName}; Password = { jobTicket.destination.networkCredentials.password}");

            try
            {
                var    targetFolder         = new DirectoryInfo(_endpointManager.PathManager.GetEndpointPath(destinationType).CorrespondingFileSystemPath);
                int    preexistingFileCount = 0;
                string increaseCountMessage = $"This job is expected to create {expectedNumberOfGeneratedFiles} more file(s).";
                if (targetFolder.Exists)
                {
                    _owner.OnUpdateStatus(this, $"Step {++step}: Get pre-existing file count on destination folder.");
                    preexistingFileCount = CurrentFileCount(targetFolder);
                    _owner.OnUpdateStatus(this, $"Found {preexistingFileCount} files. {increaseCountMessage}");
                }
                else
                {
                    _owner.OnUpdateStatus(this, $"Step {++step}: Found {preexistingFileCount} files because destination folder does not exist. {increaseCountMessage}");
                    targetFolder.Create();
                }

                _owner.OnUpdateStatus(this, $"Step {++step}: Reserve UI context.");
                uiContextId = uiProxy.ReserveUIContext(_endpointManager.HttpServerSim.EndpointAddress);
                _owner.OnUpdateStatus(this, $"Step {++step}: Wait for OXPd browser state to be {BrowserState.Idle}.");
                Wait.ForTrue(() => testProxy.GetBrowserState() == BrowserState.Idle, new TimeSpan(0, 0, 30), new TimeSpan(0, 0, 1));
                _owner.OnUpdateStatus(this, $"Step {++step}: Start scan job.");
                string scanJobId = scanProxy.StartScanJob(uiContextId, null, jobTicket);

                _owner.OnUpdateStatus(this, $"Step {++step}: Wait for scan progress window.");
                const string NotificationText = "Processing";
                if (!JediOmniDeviceHelper.WaitForValue(_deviceDat, ".hp-popup-content:visible", "innerHTML", OmniPropertyType.Property, NotificationText, StringMatch.Contains, StringComparison.InvariantCulture, new TimeSpan(0, 0, 5), new TimeSpan(0, 0, 5)))
                {
                    string message = $"Step {step} '{NotificationText}' notification was not detected.";
                    if (expectedNumberOfGeneratedFiles <= MaxPageCountThresholdForProcessingNotificationError)
                    {
                        message += $"  This is probably okay since this is a small scan job.";
                    }
                    else
                    {
                        message = $"Non-fatal error.  {message}  Enough pages are being scanned that this should not happen.";
                    }
                    _owner.OnUpdateStatus(this, message);
                }

                _owner.OnUpdateStatus(this, $"Step {++step}: Verify {nameof(ResultCode)} returned by device scan service.  (Expecting: {ResultCode.Succeeded}).");
                Wait.ForTrue(() => scanProxy.GetScanJobStatus(scanJobId).resultCode == ResultCode.Succeeded, new TimeSpan(0, 0, 30), new TimeSpan(0, 0, 1));

                switch (destinationType)
                {
                case DestinationType.Http:
                    try
                    {
                        _owner.OnUpdateStatus(this, $"Step {++step}: Verify webserver received {expectedNumberOfGeneratedFiles} requests(s).");
                        _endpointManager.HttpScanReceiver.WaitForRequests(expectedNumberOfGeneratedFiles, new TimeSpan(0, 0, 5 * 60));
                        _owner.OnUpdateStatus(this, $"Step {++step}: Verify webserver requests resulted in {expectedNumberOfGeneratedFiles} uploaded file(s).");
                        var webServerFiles = _endpointManager.HttpScanReceiver.SaveUploadedFiles(targetFolder).ToList();

                        if (webServerFiles.Count() != expectedNumberOfGeneratedFiles)
                        {
                            string paramMessage = $"Expected: {expectedNumberOfGeneratedFiles}; Actual: {webServerFiles.Count}";
                            throw new ActualVsExpectedException($"Web server reports incorrect uploaded file count. {paramMessage}");
                        }

                        _endpointManager.HttpScanReceiver.RequestsReceived.Clear();
                    }
                    catch (ThreadAbortException tax)
                    {
                        _owner.OnUpdateStatus(this, $"{tax.GetType().Name} in Step {step}{Environment.NewLine}{tax.ToString()}.");
                        _owner.OnUpdateStatus(this, $"Will attempt to continue.");
                    }
                    break;
                }

                _owner.OnUpdateStatus(this, $"Step {++step}: Verify that {expectedNumberOfGeneratedFiles} file(s) arrived on server.");
                VerifyFileCount(targetFolder, preexistingFileCount, expectedNumberOfGeneratedFiles, new TimeSpan(0, 5, 0));
            }
            catch (Exception x)
            {
                _owner.OnUpdateStatus(this, $"{x.GetType().Name} in Step {step}{Environment.NewLine}{x.ToString()}");
                throw;
            }
            finally
            {
                try
                {
                    _owner.OnUpdateStatus(this, $"Step {++step}: Release UI Context ID.");
                    uiProxy.ReleaseUIContext(uiContextId);
                }
                catch (Exception idX)
                {
                    _owner.OnUpdateStatus(this, $"Could not release uiContextId: {idX.Message}.");
                }

                _owner.OnUpdateStatus(this, $"Step {++step}: Wait for home screen.");
                JediOmniDeviceHelper.WaitForHome(_deviceDat, new TimeSpan(0, 0, 30));
            }
        }