Пример #1
0
        public void RecentlyConnectedEndpointWithoutDiscoveryPermissions()
        {
            var translator  = new Mock <ITranslateVersionedChannelInformation>();
            var translators = new[]
            {
                new Tuple <Version, ITranslateVersionedChannelInformation>(new Version(1, 0), translator.Object),
            };

            var template = new Mock <IDiscoveryChannelTemplate>();
            {
                template.Setup(t => t.GenerateBinding())
                .Verifiable();
            }

            Func <ChannelTemplate, IDiscoveryChannelTemplate> templateBuilder =
                t =>
            {
                return(template.Object);
            };
            var diagnostics = new SystemDiagnostics((l, s) => { }, null);
            var discovery   = new ManualDiscoverySource(
                translators,
                templateBuilder,
                diagnostics);

            discovery.RecentlyConnectedEndpoint(
                EndpointIdExtensions.CreateEndpointIdForCurrentProcess(),
                new Uri("net.pipe://localhost/discovery/invalid"));
            template.Verify(t => t.GenerateBinding(), Times.Never());
        }
        public void CloseChannel()
        {
            var id       = EndpointIdExtensions.CreateEndpointIdForCurrentProcess();
            var template = new Mock <IDiscoveryChannelTemplate>();

            var versionedEndpoint = new Mock <IVersionedDiscoveryEndpoint>();
            Func <Version, ChannelTemplate, Tuple <Type, IVersionedDiscoveryEndpoint> > endpointBuilder =
                (v, t) => new Tuple <Type, IVersionedDiscoveryEndpoint>(versionedEndpoint.Object.GetType(), versionedEndpoint.Object);

            var host = new Mock <IHoldServiceConnections>();
            {
                host.Setup(h => h.OpenChannel(It.IsAny <IReceiveInformationFromRemoteEndpoints>(), It.IsAny <Func <ServiceHost, ServiceEndpoint> >()))
                .Returns <IReceiveInformationFromRemoteEndpoints, Func <ServiceHost, ServiceEndpoint> >(
                    (h, e) => new Uri("http://localhost/invalid"));
                host.Setup(h => h.CloseConnection())
                .Verifiable();
            }

            Func <IHoldServiceConnections> hostBuilder = () => host.Object;
            Action <Uri> storage = u => { };

            var channel = new BootstrapChannel(
                id,
                template.Object,
                endpointBuilder,
                hostBuilder,
                storage);

            channel.OpenChannel(true);
            channel.CloseChannel();

            host.Verify(h => h.CloseConnection(), Times.Exactly(2));
        }
        public void Create()
        {
            var commandHub        = new Mock <ISendCommandsToRemoteEndpoints>();
            var id                = new DatasetId();
            var endpoint          = EndpointIdExtensions.CreateEndpointIdForCurrentProcess();
            var networkId         = NetworkIdentifier.ForLocalMachine();
            var systemDiagnostics = new SystemDiagnostics((p, s) => { }, null);

            var notifications   = new Mock <IDatasetApplicationNotifications>();
            var notificationHub = new Mock <INotifyOfRemoteEndpointEvents>();
            {
                notificationHub.Setup(n => n.HasNotificationsFor(It.IsAny <EndpointId>()))
                .Returns(true);
                notificationHub.Setup(n => n.NotificationsFor <IDatasetApplicationNotifications>(It.IsAny <EndpointId>()))
                .Callback <EndpointId>(e => Assert.AreSame(endpoint, e))
                .Returns(notifications.Object);
            }

            var info = new DatasetOnlineInformation(
                id,
                endpoint,
                networkId,
                commandHub.Object,
                notificationHub.Object,
                systemDiagnostics);

            Assert.AreSame(id, info.Id);
            Assert.AreSame(endpoint, info.Endpoint);
            Assert.AreSame(networkId, info.RunsOn);
        }
Пример #4
0
        public void CompareWithUnequalObjects()
        {
            var proposal1 = new DatasetActivationProposal
            {
                Endpoint                   = EndpointIdExtensions.CreateEndpointIdForCurrentProcess(),
                IsAvailable                = true,
                ActivationTime             = new TimeSpan(50),
                TransferTime               = new TimeSpan(50),
                PercentageOfAvailableDisk  = 50,
                PercentageOfMaximumMemory  = 50,
                PercentageOfPhysicalMemory = 50,
            };

            var proposal2 = new DatasetActivationProposal
            {
                Endpoint                   = EndpointIdExtensions.CreateEndpointIdForCurrentProcess(),
                IsAvailable                = true,
                ActivationTime             = new TimeSpan(500),
                TransferTime               = new TimeSpan(500),
                PercentageOfAvailableDisk  = 50,
                PercentageOfMaximumMemory  = 50,
                PercentageOfPhysicalMemory = 50,
            };

            var comparer = new DatasetActivationProposalComparer();

            Assert.AreEqual(-1, comparer.Compare(proposal1, proposal2));
        }
        public void OpenChannel()
        {
            var id      = EndpointIdExtensions.CreateEndpointIdForCurrentProcess();
            var baseUri = new Uri("http://localhost/invalid");
            var versionedEndpointUri = new Uri("http://localhost/invalid/v1");
            var template             = new Mock <IDiscoveryChannelTemplate>();
            {
                template.Setup(
                    t => t.AttachDiscoveryEntryEndpoint(It.IsAny <ServiceHost>(), It.IsAny <Type>(), It.IsAny <EndpointId>(), It.IsAny <bool>()))
                .Returns(new ServiceEndpoint(new ContractDescription("a"), new NetNamedPipeBinding(), new EndpointAddress(baseUri)));
            }

            var versionedEndpointCounter = 0;
            var versionedEndpoint        = new Mock <IVersionedDiscoveryEndpoint>();
            Func <Version, ChannelTemplate, Tuple <Type, IVersionedDiscoveryEndpoint> > endpointBuilder =
                (v, t) =>
            {
                versionedEndpointCounter++;
                return(new Tuple <Type, IVersionedDiscoveryEndpoint>(versionedEndpoint.Object.GetType(), versionedEndpoint.Object));
            };

            BootstrapEndpoint baseEndpoint = null;
            var host = new Mock <IHoldServiceConnections>();
            {
                host.Setup(h => h.OpenChannel(It.IsAny <IReceiveInformationFromRemoteEndpoints>(), It.IsAny <Func <ServiceHost, ServiceEndpoint> >()))
                .Callback <IReceiveInformationFromRemoteEndpoints, Func <ServiceHost, ServiceEndpoint> >(
                    (h, e) =>
                {
                    e(null);
                    baseEndpoint = h as BootstrapEndpoint;
                })
                .Returns <IReceiveInformationFromRemoteEndpoints, Func <ServiceHost, ServiceEndpoint> >(
                    (h, e) => (h is IVersionedDiscoveryEndpoint) ? versionedEndpointUri : baseUri)
                .Verifiable();
            }

            Func <IHoldServiceConnections> hostBuilder = () => host.Object;

            Uri          entryAddress = null;
            Action <Uri> storage      = u => entryAddress = u;

            var channel = new BootstrapChannel(
                id,
                template.Object,
                endpointBuilder,
                hostBuilder,
                storage);

            channel.OpenChannel(true);

            host.Verify(
                h => h.OpenChannel(It.IsAny <IReceiveInformationFromRemoteEndpoints>(), It.IsAny <Func <ServiceHost, ServiceEndpoint> >()),
                Times.Exactly(2));
            Assert.AreEqual(1, versionedEndpointCounter);
            Assert.AreEqual(baseUri, entryAddress);
            Assert.IsNotNull(baseEndpoint);
            Assert.AreEqual(1, baseEndpoint.DiscoveryVersions().Length);
            Assert.AreEqual(versionedEndpointUri, baseEndpoint.UriForVersion(baseEndpoint.DiscoveryVersions()[0]));
        }
        public void Invoke()
        {
            var uploads = new WaitingUploads();
            var layer   = new Mock <IProtocolLayer>();
            {
                layer.Setup(l => l.Id)
                .Returns(new EndpointId("other"));
                layer.Setup(l => l.SendMessageTo(It.IsAny <EndpointId>(), It.IsAny <ICommunicationMessage>(), It.IsAny <int>()))
                .Callback <EndpointId, ICommunicationMessage, int>(
                    (e, m, r) =>
                {
                    Assert.IsInstanceOf <SuccessMessage>(m);
                })
                .Verifiable();
                layer.Setup(l => l.UploadData(
                                It.IsAny <EndpointId>(),
                                It.IsAny <string>(),
                                It.IsAny <CancellationToken>(),
                                It.IsAny <TaskScheduler>(),
                                It.IsAny <int>()))
                .Returns(Task.Factory.StartNew(
                             () => { },
                             new CancellationToken(),
                             TaskCreationOptions.None,
                             new CurrentThreadTaskScheduler()))
                .Verifiable();
            }

            var systemDiagnostics = new SystemDiagnostics((p, s) => { }, null);

            var action = new DataDownloadProcessAction(
                uploads,
                layer.Object,
                systemDiagnostics,
                new CurrentThreadTaskScheduler());

            var path  = @"c:\temp\myfile.txt";
            var token = uploads.Register(path);

            var msg = new DataDownloadRequestMessage(
                EndpointIdExtensions.CreateEndpointIdForCurrentProcess(),
                token);

            action.Invoke(msg);

            Assert.IsFalse(uploads.HasRegistration(token));
            layer.Verify(l => l.SendMessageTo(It.IsAny <EndpointId>(), It.IsAny <ICommunicationMessage>(), It.IsAny <int>()), Times.Once());
            layer.Verify(
                l => l.UploadData(
                    It.IsAny <EndpointId>(),
                    It.IsAny <string>(),
                    It.IsAny <CancellationToken>(),
                    It.IsAny <TaskScheduler>(),
                    It.IsAny <int>()),
                Times.Once());
        }
Пример #7
0
        public void RecentlyConnectedEndpointWithCommunicationFault()
        {
            var translator  = new Mock <ITranslateVersionedChannelInformation>();
            var translators = new[]
            {
                new Tuple <Version, ITranslateVersionedChannelInformation>(new Version(1, 0), translator.Object),
            };

            var configuration = new Mock <IConfiguration>();
            {
                configuration.Setup(c => c.HasValueFor(It.IsAny <ConfigurationKey>()))
                .Returns(false);
            }

            var template = new NamedPipeDiscoveryChannelTemplate(configuration.Object);
            Func <ChannelTemplate, IDiscoveryChannelTemplate> templateBuilder = t => template;
            var diagnostics = new SystemDiagnostics((l, s) => { }, null);
            var discovery   = new ManualDiscoverySource(
                translators,
                templateBuilder,
                diagnostics);

            discovery.OnEndpointBecomingAvailable += (s, e) => Assert.Fail();
            discovery.StartDiscovery();

            var uri      = new Uri("net.pipe://localhost/pipe/discovery");
            var receiver = new MockEndpoint(
                () =>
            {
                throw new ArgumentException();
            },
                null);

            var host    = new ServiceHost(receiver, uri);
            var binding = new NetNamedPipeBinding(NetNamedPipeSecurityMode.None)
            {
                TransferMode = TransferMode.Buffered,
            };
            var address  = string.Format("{0}_{1}", "ThroughNamedPipe", Process.GetCurrentProcess().Id);
            var endpoint = host.AddServiceEndpoint(typeof(IBootstrapEndpoint), binding, address);

            host.Open();
            try
            {
                discovery.RecentlyConnectedEndpoint(
                    EndpointIdExtensions.CreateEndpointIdForCurrentProcess(),
                    endpoint.ListenUri);
            }
            finally
            {
                host.Close();
            }
        }
        public void AvailableCommands()
        {
            var id                = new DatasetId();
            var endpoint          = EndpointIdExtensions.CreateEndpointIdForCurrentProcess();
            var networkId         = NetworkIdentifier.ForLocalMachine();
            var systemDiagnostics = new SystemDiagnostics((p, s) => { }, null);

            var commandList = new Dictionary <Type, ICommandSet>
            {
                {
                    typeof(IMockCommandSetWithTaskReturn),
                    new Mock <IMockCommandSetWithTaskReturn>().Object
                },
                {
                    typeof(IMockCommandSetWithTypedTaskReturn),
                    new Mock <IMockCommandSetWithTaskReturn>().Object
                },
                {
                    typeof(IMockCommandSetForInternalUse),
                    new Mock <IMockCommandSetWithTaskReturn>().Object
                },
            };

            var commandHub = new Mock <ISendCommandsToRemoteEndpoints>();
            {
                commandHub.Setup(h => h.AvailableCommandsFor(It.IsAny <EndpointId>()))
                .Returns(commandList.Keys);
                commandHub.Setup(h => h.CommandsFor(It.IsAny <EndpointId>(), It.IsAny <Type>()))
                .Returns <EndpointId, Type>((e, t) => commandList[t]);
            }

            var notifications   = new Mock <IDatasetApplicationNotifications>();
            var notificationHub = new Mock <INotifyOfRemoteEndpointEvents>();
            {
                notificationHub.Setup(n => n.HasNotificationsFor(It.IsAny <EndpointId>()))
                .Returns(true);
                notificationHub.Setup(n => n.NotificationsFor <IDatasetApplicationNotifications>(It.IsAny <EndpointId>()))
                .Callback <EndpointId>(e => Assert.AreSame(endpoint, e))
                .Returns(notifications.Object);
            }

            var info = new DatasetOnlineInformation(
                id,
                endpoint,
                networkId,
                commandHub.Object,
                notificationHub.Object,
                systemDiagnostics);
            var commands = info.AvailableCommands();

            Assert.AreEqual(2, commands.Count());
        }
        public void Close()
        {
            var id                = new DatasetId();
            var endpoint          = EndpointIdExtensions.CreateEndpointIdForCurrentProcess();
            var networkId         = NetworkIdentifier.ForLocalMachine();
            var systemDiagnostics = new SystemDiagnostics((p, s) => { }, null);

            var datasetCommands = new Mock <IDatasetApplicationCommands>();
            {
                datasetCommands.Setup(d => d.Close())
                .Returns(
                    Task.Factory.StartNew(
                        () => { },
                        new CancellationToken(),
                        TaskCreationOptions.None,
                        new CurrentThreadTaskScheduler()))
                .Verifiable();
            }

            var commandHub = new Mock <ISendCommandsToRemoteEndpoints>();
            {
                commandHub.Setup(h => h.HasCommandFor(It.IsAny <EndpointId>(), It.IsAny <Type>()))
                .Returns(true);
                commandHub.Setup(h => h.CommandsFor <IDatasetApplicationCommands>(It.IsAny <EndpointId>()))
                .Returns(datasetCommands.Object);
            }

            var notifications   = new Mock <IDatasetApplicationNotifications>();
            var notificationHub = new Mock <INotifyOfRemoteEndpointEvents>();
            {
                notificationHub.Setup(n => n.HasNotificationsFor(It.IsAny <EndpointId>()))
                .Returns(true);
                notificationHub.Setup(n => n.NotificationsFor <IDatasetApplicationNotifications>(It.IsAny <EndpointId>()))
                .Callback <EndpointId>(e => Assert.AreSame(endpoint, e))
                .Returns(notifications.Object);
            }

            var info = new DatasetOnlineInformation(
                id,
                endpoint,
                networkId,
                commandHub.Object,
                notificationHub.Object,
                systemDiagnostics);

            info.Close();

            datasetCommands.Verify(d => d.Close(), Times.Once());
        }
        public void Command()
        {
            var id                = new DatasetId();
            var endpoint          = EndpointIdExtensions.CreateEndpointIdForCurrentProcess();
            var networkId         = NetworkIdentifier.ForLocalMachine();
            var systemDiagnostics = new SystemDiagnostics((p, s) => { }, null);

            var commandList = new SortedList <Type, ICommandSet>
            {
                {
                    typeof(IMockCommandSetWithTaskReturn),
                    new Mock <IMockCommandSetWithTaskReturn>().Object
                },
            };
            var commandHub = new Mock <ISendCommandsToRemoteEndpoints>();
            {
                commandHub.Setup(h => h.CommandsFor <IMockCommandSetWithTaskReturn>(It.IsAny <EndpointId>()))
                .Returns((IMockCommandSetWithTaskReturn)commandList.Values[0]);
            }

            var notifications   = new Mock <IDatasetApplicationNotifications>();
            var notificationHub = new Mock <INotifyOfRemoteEndpointEvents>();
            {
                notificationHub.Setup(n => n.HasNotificationsFor(It.IsAny <EndpointId>()))
                .Returns(true);
                notificationHub.Setup(n => n.NotificationsFor <IDatasetApplicationNotifications>(It.IsAny <EndpointId>()))
                .Callback <EndpointId>(e => Assert.AreSame(endpoint, e))
                .Returns(notifications.Object);
            }

            var info = new DatasetOnlineInformation(
                id,
                endpoint,
                networkId,
                commandHub.Object,
                notificationHub.Object,
                systemDiagnostics);
            var commands = info.Command <IMockCommandSetWithTaskReturn>();

            Assert.AreSame(commandList.Values[0], commands);
        }
        public void ProposeDistributionFor()
        {
            var systemDiagnostics = new SystemDiagnostics((p, s) => { }, null);
            var offlineInfo       = CreateOfflineInfo(new Mock <IPersistenceInformation>().Object);
            var result            = new DatasetActivationProposal
            {
                Endpoint                   = EndpointIdExtensions.CreateEndpointIdForCurrentProcess(),
                IsAvailable                = true,
                ActivationTime             = new TimeSpan(0, 1, 0),
                TransferTime               = new TimeSpan(0, 1, 0),
                PercentageOfAvailableDisk  = 50,
                PercentageOfMaximumMemory  = 50,
                PercentageOfPhysicalMemory = 50,
            };

            var localDistributor = new Mock <ICalculateDistributionParameters>();
            {
                localDistributor.Setup(l => l.ProposeForLocalMachine(It.IsAny <ExpectedDatasetLoad>()))
                .Returns(result);
            }

            var communicationLayer = new Mock <ICommunicationLayer>();
            {
                communicationLayer.Setup(s => s.LocalConnectionFor(It.Is <ChannelType>(c => c == ChannelType.NamedPipe)))
                .Returns(
                    new Tuple <EndpointId, Uri, Uri>(
                        EndpointIdExtensions.CreateEndpointIdForCurrentProcess(),
                        new Uri("net.pipe://localhost/pipe"),
                        new Uri("net.pipe://localhost/pipe/data")));
            }

            var loader          = new Mock <IDatasetActivator>();
            var commandHub      = new Mock <ISendCommandsToRemoteEndpoints>();
            var notificationHub = new Mock <INotifyOfRemoteEndpointEvents>();
            var uploads         = new Mock <IStoreUploads>();

            var distributor = new LocalDatasetDistributor(
                localDistributor.Object,
                loader.Object,
                commandHub.Object,
                notificationHub.Object,
                uploads.Object,
                (d, e, n) =>
            {
                return(new DatasetOnlineInformation(
                           d,
                           e,
                           n,
                           commandHub.Object,
                           notificationHub.Object,
                           systemDiagnostics));
            },
                communicationLayer.Object,
                systemDiagnostics,
                new CurrentThreadTaskScheduler());

            var request = new DatasetActivationRequest
            {
                DatasetToActivate      = offlineInfo,
                ExpectedLoadPerMachine = new ExpectedDatasetLoad(),
                PreferredLocations     = DistributionLocations.All,
            };
            var plans = distributor.ProposeDistributionFor(request, new CancellationToken());

            Assert.AreEqual(1, plans.Count());

            var plan = plans.First();

            Assert.IsTrue(ReferenceEquals(offlineInfo, plan.DistributionFor));
            Assert.AreEqual(new NetworkIdentifier(result.Endpoint.OriginatesOnMachine()), plan.MachineToDistributeTo);
            Assert.IsTrue(ReferenceEquals(result, plan.Proposal));
        }
        public void ImplementPlan()
        {
            var systemDiagnostics = new SystemDiagnostics((p, s) => { }, null);

            var filePath = @"c:\temp\myfile.txt";
            var storage  = new Mock <IPersistenceInformation>();
            {
                storage.Setup(s => s.AsFile())
                .Returns(new FileInfo(filePath));
            }

            var offlineInfo      = CreateOfflineInfo(storage.Object);
            var plan             = CreateNewDistributionPlan(new DatasetActivationProposal(), offlineInfo, systemDiagnostics);
            var localDistributor = new Mock <ICalculateDistributionParameters>();

            var datasetEndpoint = new EndpointId("OtherMachine:5678");
            var loader          = new Mock <IDatasetActivator>();
            {
                loader.Setup(l => l.ActivateDataset(It.IsAny <EndpointId>(), It.IsAny <ChannelType>(), It.IsAny <Uri>()))
                .Returns(datasetEndpoint);
            }

            var commands = new Mock <IDatasetApplicationCommands>();
            {
                commands.Setup(c => c.Load(It.IsAny <EndpointId>(), It.IsAny <UploadToken>()))
                .Returns(
                    Task.Factory.StartNew(
                        () => { },
                        new CancellationToken(),
                        TaskCreationOptions.None,
                        new CurrentThreadTaskScheduler()));
            }

            var commandHub = new Mock <ISendCommandsToRemoteEndpoints>();
            {
                commandHub.Setup(h => h.HasCommandsFor(It.IsAny <EndpointId>()))
                .Returns(true);
                commandHub.Setup(h => h.HasCommandFor(It.IsAny <EndpointId>(), It.IsAny <Type>()))
                .Returns(true);
                commandHub.Setup(h => h.CommandsFor <IDatasetApplicationCommands>(It.IsAny <EndpointId>()))
                .Callback <EndpointId>(e => Assert.AreSame(datasetEndpoint, e))
                .Returns(commands.Object);
            }

            var notifications   = new Mock <IDatasetApplicationNotifications>();
            var notificationHub = new Mock <INotifyOfRemoteEndpointEvents>();
            {
                notificationHub.Setup(n => n.HasNotificationsFor(It.IsAny <EndpointId>()))
                .Returns(true);
                notificationHub.Setup(n => n.NotificationsFor <IDatasetApplicationNotifications>(It.IsAny <EndpointId>()))
                .Callback <EndpointId>(e => Assert.AreSame(datasetEndpoint, e))
                .Returns(notifications.Object);
            }

            var communicationLayer = new Mock <ICommunicationLayer>();
            {
                communicationLayer.Setup(s => s.LocalConnectionFor(It.Is <ChannelType>(c => c == ChannelType.NamedPipe)))
                .Returns(
                    new Tuple <EndpointId, Uri, Uri>(
                        EndpointIdExtensions.CreateEndpointIdForCurrentProcess(),
                        new Uri("net.pipe://localhost/pipe"),
                        new Uri("net.pipe://localhost/pipe/data")));
            }

            var uploads = new Mock <IStoreUploads>();

            var distributor = new LocalDatasetDistributor(
                localDistributor.Object,
                loader.Object,
                commandHub.Object,
                notificationHub.Object,
                uploads.Object,
                (d, e, n) =>
            {
                return(new DatasetOnlineInformation(
                           d,
                           e,
                           n,
                           commandHub.Object,
                           notificationHub.Object,
                           systemDiagnostics));
            },
                communicationLayer.Object,
                systemDiagnostics,
                new CurrentThreadTaskScheduler());

            Action <int, string, bool> progress = (p, m, e) => { };
            var result = distributor.ImplementPlan(plan, new CancellationToken(), progress);

            result.Wait();

            Assert.AreSame(datasetEndpoint, result.Result.Endpoint);
            Assert.AreSame(plan.DistributionFor.Id, result.Result.Id);
            Assert.AreSame(plan.MachineToDistributeTo, result.Result.RunsOn);
        }
Пример #13
0
        /// <summary>
        /// Takes the set of distribution plans and loads the given datasets onto the specified machines.
        /// </summary>
        /// <param name="planToImplement">The distribution plan that should be implemented.</param>
        /// <param name="token">The token used to indicate cancellation of the task.</param>
        /// <param name="progressReporter">The action that handles the reporting of progress.</param>
        /// <returns>
        /// A set of objects which allow act as proxies for the loaded datasets.
        /// </returns>
        public Task <DatasetOnlineInformation> ImplementPlan(
            DistributionPlan planToImplement,
            CancellationToken token,
            Action <int, string, bool> progressReporter)
        {
            Func <DatasetOnlineInformation> result =
                () =>
            {
                IDatasetActivationCommands activationCommands;
                lock (m_Lock)
                {
                    if (!m_ActivatorCommands.ContainsKey(planToImplement.Proposal.Endpoint))
                    {
                        throw new EndpointNotContactableException(planToImplement.Proposal.Endpoint);
                    }

                    activationCommands = m_ActivatorCommands[planToImplement.Proposal.Endpoint];
                }

                // We shouldn't have to load the TCP channel at this point because that channel would have
                // been loaded when the loaders broadcast their message indicating that they exist.
                var info         = m_CommunicationLayer.LocalConnectionFor(ChannelType.TcpIP);
                var endpointTask = activationCommands.Activate(info.Item1, ChannelType.TcpIP, info.Item2, planToImplement.DistributionFor.Id);
                endpointTask.Wait();

                var endpoint   = endpointTask.Result;
                var resetEvent = new AutoResetEvent(false);
                var commandAvailabilityNotifier =
                    Observable.FromEventPattern <CommandSetAvailabilityEventArgs>(
                        h => m_CommandHub.OnEndpointSignedIn += h,
                        h => m_CommandHub.OnEndpointSignedIn -= h)
                    .Where(args => args.EventArgs.Endpoint.Equals(endpoint))
                    .Take(1)
                    .Subscribe(
                        args =>
                {
                    resetEvent.Set();
                });

                using (commandAvailabilityNotifier)
                {
                    if (!m_CommandHub.HasCommandsFor(endpoint) || !m_NotificationHub.HasNotificationsFor(endpoint))
                    {
                        resetEvent.WaitOne();
                    }
                }

                EventHandler <ProgressEventArgs> progressHandler =
                    (s, e) => progressReporter(e.Progress, e.Description, e.HasErrors);
                var notifications = m_NotificationHub.NotificationsFor <IDatasetApplicationNotifications>(endpoint);
                notifications.OnProgress += progressHandler;
                try
                {
                    // Store the file
                    var file        = planToImplement.DistributionFor.StoredAt.AsFile();
                    var uploadToken = m_Uploads.Register(file.FullName);

                    // The commands have been registered, so now load the dataset
                    Debug.Assert(
                        m_CommandHub.HasCommandFor(endpoint, typeof(IDatasetApplicationCommands)), "No application commands registered.");
                    var applicationCommands = m_CommandHub.CommandsFor <IDatasetApplicationCommands>(endpoint);
                    var task = applicationCommands.Load(
                        EndpointIdExtensions.CreateEndpointIdForCurrentProcess(),
                        uploadToken);
                    task.Wait();

                    return(m_DatasetInformationBuilder(
                               planToImplement.DistributionFor.Id,
                               endpoint,
                               planToImplement.MachineToDistributeTo));
                }
                finally
                {
                    notifications.OnProgress -= progressHandler;
                }
            };

            return(Task <DatasetOnlineInformation> .Factory.StartNew(
                       result,
                       token,
                       TaskCreationOptions.LongRunning,
                       m_Scheduler));
        }
Пример #14
0
        public void RecentlyConnectedEndpoint()
        {
            var uri          = new Uri("net.pipe://localhost/pipe/discovery/");
            var versionedUri = new Uri(uri, new Uri("/1.0", UriKind.Relative));
            var protocolInfo = new ProtocolInformation(
                new Version(2, 0),
                new Uri("http://localhost/protocol/message/invalid"),
                new Uri("http://localhost/protocol/data/invalid"));
            var translator = new Mock <ITranslateVersionedChannelInformation>();
            {
                translator.Setup(t => t.FromUri(It.IsAny <Uri>()))
                .Callback <Uri>(u => Assert.AreEqual(versionedUri, u))
                .Returns(protocolInfo);
            }

            var translators = new[]
            {
                new Tuple <Version, ITranslateVersionedChannelInformation>(new Version(1, 0), translator.Object),
            };

            var configuration = new Mock <IConfiguration>();
            {
                configuration.Setup(c => c.HasValueFor(It.IsAny <ConfigurationKey>()))
                .Returns(false);
            }

            var template = new NamedPipeDiscoveryChannelTemplate(configuration.Object);
            Func <ChannelTemplate, IDiscoveryChannelTemplate> templateBuilder = t => template;
            var diagnostics = new SystemDiagnostics((l, s) => { }, null);
            var discovery   = new ManualDiscoverySource(
                translators,
                templateBuilder,
                diagnostics);

            var eventWasRaised = false;

            discovery.OnEndpointBecomingAvailable += (s, e) =>
            {
                eventWasRaised = true;
            };
            discovery.StartDiscovery();

            var channels = new[]
            {
                new Tuple <Version, Uri>(new Version(1, 0), versionedUri),
            };
            var receiver = new BootstrapEndpoint(channels);

            var host    = new ServiceHost(receiver, uri);
            var binding = new NetNamedPipeBinding(NetNamedPipeSecurityMode.None)
            {
                TransferMode = TransferMode.Buffered,
            };
            var address  = string.Format("{0}_{1}", "ThroughNamedPipe", Process.GetCurrentProcess().Id);
            var endpoint = host.AddServiceEndpoint(typeof(IBootstrapEndpoint), binding, address);

            host.Open();
            try
            {
                discovery.RecentlyConnectedEndpoint(
                    EndpointIdExtensions.CreateEndpointIdForCurrentProcess(),
                    endpoint.ListenUri);
            }
            finally
            {
                host.Close();
            }

            Assert.IsTrue(eventWasRaised);
        }
        public void ProposeDistributionFor()
        {
            var systemDiagnostics = new SystemDiagnostics((p, s) => { }, null);

            var offlineInfo = CreateOfflineInfo(new Mock <IPersistenceInformation>().Object);
            var result      = new DatasetActivationProposal
            {
                Endpoint                   = EndpointIdExtensions.CreateEndpointIdForCurrentProcess(),
                IsAvailable                = true,
                ActivationTime             = new TimeSpan(0, 1, 0),
                TransferTime               = new TimeSpan(0, 1, 0),
                PercentageOfAvailableDisk  = 50,
                PercentageOfMaximumMemory  = 50,
                PercentageOfPhysicalMemory = 50,
            };

            var loaderCommands = new Mock <IDatasetActivationCommands>();
            {
                loaderCommands.Setup(l => l.ProposeFor(It.IsAny <ExpectedDatasetLoad>()))
                .Returns(
                    Task.Factory.StartNew(
                        () => result,
                        new CancellationToken(),
                        TaskCreationOptions.None,
                        new CurrentThreadTaskScheduler()))
                .Verifiable();
            }

            var commandHub = new Mock <ISendCommandsToRemoteEndpoints>();
            {
                commandHub.Setup(h => h.CommandsFor <IDatasetActivationCommands>(It.IsAny <EndpointId>()))
                .Returns(loaderCommands.Object);
            }

            var notificationHub = new Mock <INotifyOfRemoteEndpointEvents>();

            var offlimitsMachines = new SortedList <string, object>
            {
                { "someKeyStuff", "otherMachine" }
            };
            var config = new Mock <IConfiguration>();
            {
                config.Setup(c => c.HasValueFor(It.IsAny <ConfigurationKey>()))
                .Returns(true);
                config.Setup(c => c.Value <IDictionary <string, object> >(It.IsAny <ConfigurationKey>()))
                .Returns(offlimitsMachines);
            }

            var communicationLayer = new Mock <ICommunicationLayer>();
            {
                communicationLayer.Setup(s => s.LocalConnectionFor(It.Is <ChannelType>(c => c == ChannelType.TcpIP)))
                .Returns(
                    new Tuple <EndpointId, Uri, Uri>(
                        EndpointIdExtensions.CreateEndpointIdForCurrentProcess(),
                        new Uri("net.tcp://localhost/tcp"),
                        new Uri("net.tcp://localhost/tcp/data")));
            }

            var distributor = new RemoteDatasetDistributor(
                config.Object,
                commandHub.Object,
                notificationHub.Object,
                new Mock <IStoreUploads>().Object,
                (d, e, n) => new DatasetOnlineInformation(
                    d,
                    e,
                    n,
                    commandHub.Object,
                    notificationHub.Object,
                    systemDiagnostics),
                communicationLayer.Object,
                systemDiagnostics,
                new CurrentThreadTaskScheduler());

            // Add the remote endpoints
            var forbiddenMachineId = new EndpointId("otherMachine:8080");

            commandHub.Raise(
                h => h.OnEndpointSignedIn += null,
                new CommandSetAvailabilityEventArgs(
                    forbiddenMachineId,
                    new[] { typeof(IDatasetActivationCommands) }));

            var legalMachineId = new EndpointId("myMachine:8080");

            commandHub.Raise(
                h => h.OnEndpointSignedIn += null,
                new CommandSetAvailabilityEventArgs(
                    legalMachineId,
                    new[] { typeof(IDatasetActivationCommands) }));

            var request = new DatasetActivationRequest
            {
                DatasetToActivate      = offlineInfo,
                ExpectedLoadPerMachine = new ExpectedDatasetLoad(),
                PreferredLocations     = DistributionLocations.All,
            };
            var plans     = distributor.ProposeDistributionFor(request, new CancellationToken());
            var listPlans = plans.ToList();

            Assert.AreEqual(1, listPlans.Count());

            var plan = listPlans[0];

            Assert.IsTrue(ReferenceEquals(offlineInfo, plan.DistributionFor));
            Assert.AreEqual(new NetworkIdentifier(result.Endpoint.OriginatesOnMachine()), plan.MachineToDistributeTo);
            Assert.IsTrue(ReferenceEquals(result, plan.Proposal));

            loaderCommands.Verify(l => l.ProposeFor(It.IsAny <ExpectedDatasetLoad>()), Times.Once());
        }
        public void ImplementPlan()
        {
            var systemDiagnostics = new SystemDiagnostics((p, s) => { }, null);

            var loaderEndpoint = new EndpointId("myMachine:8080");
            var proposal       = new DatasetActivationProposal
            {
                Endpoint                   = loaderEndpoint,
                IsAvailable                = true,
                ActivationTime             = new TimeSpan(0, 1, 0),
                TransferTime               = new TimeSpan(0, 1, 0),
                PercentageOfAvailableDisk  = 50,
                PercentageOfMaximumMemory  = 50,
                PercentageOfPhysicalMemory = 50,
            };

            var filePath = @"c:\temp\myfile.txt";
            var storage  = new Mock <IPersistenceInformation>();
            {
                storage.Setup(s => s.AsFile())
                .Returns(new FileInfo(filePath));
            }

            var plan            = CreateNewDistributionPlan(proposal, CreateOfflineInfo(storage.Object), systemDiagnostics);
            var datasetEndpoint = new EndpointId("OtherMachine:5678");
            var loaderCommands  = new Mock <IDatasetActivationCommands>();
            {
                loaderCommands.Setup(l => l.Activate(It.IsAny <EndpointId>(), It.IsAny <ChannelType>(), It.IsAny <Uri>(), It.IsAny <DatasetId>()))
                .Returns(
                    Task.Factory.StartNew(
                        () => datasetEndpoint,
                        new CancellationToken(),
                        TaskCreationOptions.None,
                        new CurrentThreadTaskScheduler()));
            }

            var applicationCommands = new Mock <IDatasetApplicationCommands>();
            {
                applicationCommands.Setup(c => c.Load(It.IsAny <EndpointId>(), It.IsAny <UploadToken>()))
                .Returns(
                    Task.Factory.StartNew(
                        () => { },
                        new CancellationToken(),
                        TaskCreationOptions.None,
                        new CurrentThreadTaskScheduler()));
            }

            var commandHub = new Mock <ISendCommandsToRemoteEndpoints>();
            {
                commandHub.Setup(h => h.HasCommandsFor(It.IsAny <EndpointId>()))
                .Returns(true);
                commandHub.Setup(h => h.CommandsFor <IDatasetActivationCommands>(It.IsAny <EndpointId>()))
                .Returns(loaderCommands.Object);
                commandHub.Setup(h => h.CommandsFor <IDatasetApplicationCommands>(It.IsAny <EndpointId>()))
                .Callback <EndpointId>(e => Assert.AreSame(datasetEndpoint, e))
                .Returns(applicationCommands.Object);
            }

            var notifications   = new Mock <IDatasetApplicationNotifications>();
            var notificationHub = new Mock <INotifyOfRemoteEndpointEvents>();
            {
                notificationHub.Setup(n => n.HasNotificationsFor(It.IsAny <EndpointId>()))
                .Returns(true);
                notificationHub.Setup(n => n.NotificationsFor <IDatasetApplicationNotifications>(It.IsAny <EndpointId>()))
                .Callback <EndpointId>(e => Assert.AreSame(datasetEndpoint, e))
                .Returns(notifications.Object);
            }

            var config = new Mock <IConfiguration>();
            {
                config.Setup(c => c.HasValueFor(It.IsAny <ConfigurationKey>()))
                .Returns(false);
            }

            var communicationLayer = new Mock <ICommunicationLayer>();
            {
                communicationLayer.Setup(s => s.LocalConnectionFor(It.Is <ChannelType>(c => c == ChannelType.TcpIP)))
                .Returns(
                    new Tuple <EndpointId, Uri, Uri>(
                        EndpointIdExtensions.CreateEndpointIdForCurrentProcess(),
                        new Uri("net.tcp://localhost/tcp"),
                        new Uri("net.tcp://localhost/tcp/data")));
            }

            var distributor = new RemoteDatasetDistributor(
                config.Object,
                commandHub.Object,
                notificationHub.Object,
                new Mock <IStoreUploads>().Object,
                (d, e, n) => new DatasetOnlineInformation(
                    d,
                    e,
                    n,
                    commandHub.Object,
                    notificationHub.Object,
                    systemDiagnostics),
                communicationLayer.Object,
                systemDiagnostics,
                new CurrentThreadTaskScheduler());

            // Add the remote endpoints
            commandHub.Raise(
                h => h.OnEndpointSignedIn += null,
                new CommandSetAvailabilityEventArgs(
                    loaderEndpoint,
                    new[] { typeof(IDatasetActivationCommands) }));

            Action <int, string, bool> progress = (p, m, e) => { };
            var result = distributor.ImplementPlan(plan, new CancellationToken(), progress);

            result.Wait();

            Assert.AreSame(datasetEndpoint, result.Result.Endpoint);
            Assert.AreSame(plan.DistributionFor.Id, result.Result.Id);
            Assert.AreSame(plan.MachineToDistributeTo, result.Result.RunsOn);
        }
Пример #17
0
        private static void RunApplication(string[] args, ApplicationContext context)
        {
            string hostIdText            = null;
            string channelUriText        = null;
            var    communicationSubjects = new List <CommunicationSubject>();

            var options = new OptionSet
            {
                {
                    Resources.CommandLine_Param_Host_Key,
                    Resources.CommandLine_Param_Host_Description,
                    v => hostIdText = v
                },
                {
                    Resources.CommandLine_Param_ChannelUri_Key,
                    Resources.CommandLine_Param_ChannelUri_Description,
                    v => channelUriText = v
                },
                {
                    Resources.CommandLine_Options_CommunicationSubject_Key,
                    Resources.CommandLine_Options_CommunicationSubject_Description,
                    v => communicationSubjects.Add(new CommunicationSubject(v))
                },
            };

            try
            {
                options.Parse(args);
            }
            catch (OptionException)
            {
                return;
            }

            context.ThreadExit += (s, e) => s_Container.Dispose();

            var allowChannelDiscovery = (hostIdText == null) || (channelUriText == null);

            s_Container = DependencyInjection.CreateContainer(context, communicationSubjects, allowChannelDiscovery);
            s_Container.Resolve <IFormTheApplicationCenter>();

            if (!allowChannelDiscovery)
            {
                var hostId      = EndpointIdExtensions.Deserialize(hostIdText);
                var diagnostics = s_Container.Resolve <SystemDiagnostics>();
                diagnostics.Log(
                    LevelToLog.Debug,
                    string.Format(
                        CultureInfo.InvariantCulture,
                        Resources.Log_Messages_ConnectingToHost_WithConnectionParameters,
                        hostId,
                        channelUriText));

                var resolver = s_Container.Resolve <ManualEndpointConnection>();
                resolver(hostId, channelUriText);
            }

            var window = s_Container.Resolve <IInteractiveWindow>();

            ElementHost.EnableModelessKeyboardInterop(window as Window);
            window.Show();
        }
Пример #18
0
        /// <summary>
        /// Takes the set of distribution plans and loads the given datasets onto the specified machines.
        /// </summary>
        /// <param name="planToImplement">The distribution plan that should be implemented.</param>
        /// <param name="token">The token used to indicate cancellation of the task.</param>
        /// <param name="progressReporter">The action that handles the reporting of progress.</param>
        /// <returns>
        /// A set of objects which allow act as proxies for the loaded datasets.
        /// </returns>
        public Task <DatasetOnlineInformation> ImplementPlan(
            DistributionPlan planToImplement,
            CancellationToken token,
            Action <int, string, bool> progressReporter)
        {
            Func <DatasetOnlineInformation> result =
                () =>
            {
                m_Diagnostics.Log(LevelToLog.Info, BaseConstants.LogPrefix, "Activating dataset");

                var        info = m_CommunicationLayer.LocalConnectionFor(ChannelType.NamedPipe);
                EndpointId endpoint;
                try
                {
                    endpoint = m_Loader.ActivateDataset(info.Item1, ChannelType.NamedPipe, info.Item2);
                }
                catch (Exception e)
                {
                    m_Diagnostics.Log(
                        LevelToLog.Error,
                        BaseConstants.LogPrefix,
                        string.Format(
                            CultureInfo.InvariantCulture,
                            "Failed to activate the dataset. Error was: {0}",
                            e));
                    throw;
                }

                var resetEvent = new AutoResetEvent(false);
                var commandAvailabilityNotifier =
                    Observable.FromEventPattern <CommandSetAvailabilityEventArgs>(
                        h => m_CommandHub.OnEndpointSignedIn += h,
                        h => m_CommandHub.OnEndpointSignedIn -= h)
                    .Where(args => args.EventArgs.Endpoint.Equals(endpoint))
                    .Take(1);

                var notificationAvailabilityNotifier =
                    Observable.FromEventPattern <NotificationSetAvailabilityEventArgs>(
                        h => m_NotificationHub.OnEndpointSignedIn += h,
                        h => m_NotificationHub.OnEndpointSignedIn -= h)
                    .Where(args => args.EventArgs.Endpoint.Equals(endpoint))
                    .Take(1);

                var availability = commandAvailabilityNotifier.Zip(
                    notificationAvailabilityNotifier,
                    (a, b) => { return(true); })
                                   .Subscribe(
                    args =>
                {
                    resetEvent.Set();
                });

                using (availability)
                {
                    if (!m_CommandHub.HasCommandsFor(endpoint) || !m_NotificationHub.HasNotificationsFor(endpoint))
                    {
                        m_Diagnostics.Log(LevelToLog.Trace, BaseConstants.LogPrefix, "Waiting for dataset to connect.");

                        resetEvent.WaitOne();
                    }
                }

                m_Diagnostics.Log(LevelToLog.Trace, "Received commands and notifications from dataset.");

                IDatasetApplicationNotifications notifications;
                try
                {
                    notifications = m_NotificationHub.NotificationsFor <IDatasetApplicationNotifications>(endpoint);
                }
                catch (Exception e)
                {
                    m_Diagnostics.Log(
                        LevelToLog.Error,
                        BaseConstants.LogPrefix,
                        string.Format(
                            CultureInfo.InvariantCulture,
                            "Failed to get the notifications. Error was: {0}",
                            e));
                    throw;
                }

                EventHandler <ProgressEventArgs> progressHandler =
                    (s, e) => progressReporter(e.Progress, e.Description, e.HasErrors);
                notifications.OnProgress += progressHandler;
                try
                {
                    // Store the file
                    var file        = planToImplement.DistributionFor.StoredAt.AsFile();
                    var uploadToken = m_Uploads.Register(file.FullName);

                    // The commands have been registered, so now load the dataset
                    Debug.Assert(
                        m_CommandHub.HasCommandFor(endpoint, typeof(IDatasetApplicationCommands)), "No application commands registered.");
                    var commands = m_CommandHub.CommandsFor <IDatasetApplicationCommands>(endpoint);
                    var task     = commands.Load(
                        EndpointIdExtensions.CreateEndpointIdForCurrentProcess(),
                        uploadToken);
                    task.Wait();

                    // Now the dataset loading is complete
                    return(m_DatasetInformationBuilder(
                               planToImplement.DistributionFor.Id,
                               endpoint,
                               planToImplement.MachineToDistributeTo));
                }
                finally
                {
                    notifications.OnProgress -= progressHandler;
                }
            };

            return(Task <DatasetOnlineInformation> .Factory.StartNew(
                       result,
                       token,
                       TaskCreationOptions.LongRunning,
                       m_Scheduler));
        }
Пример #19
0
 /// <summary>
 /// Initializes a new instance of the <see cref="DistributionCalculator"/> class.
 /// </summary>
 public DistributionCalculator()
 {
     m_LocalEndpoint = EndpointIdExtensions.CreateEndpointIdForCurrentProcess();
 }
Пример #20
0
        private static int RunApplication(string[] arguments, ApplicationContext context)
        {
            string hostIdText      = null;
            string channelTypeText = null;
            string channelUriText  = null;

            // Parse the command line options
            var options = new OptionSet
            {
                {
                    "h=|host=",
                    "The {ENDPOINTID} of the host application that requested the start of this application.",
                    v => hostIdText = v
                },
                {
                    "t=|channeltype=",
                    "The {TYPE} of the channel over which the connection should be made.",
                    v => channelTypeText = v
                },
                {
                    "u=|channeluri=",
                    "The {URI} of the connection that can be used to connect to the host application.",
                    v => channelUriText = v
                },
            };

            options.Parse(arguments);
            if (string.IsNullOrWhiteSpace(hostIdText) ||
                string.IsNullOrWhiteSpace(channelTypeText) ||
                string.IsNullOrWhiteSpace(channelUriText))
            {
                throw new InvalidCommandLineArgumentsException();
            }

            // Load the communication system and get it going
            // All startables are automatically started once the container gets
            // build.
            // The container will stay in scope as long as the app runs, because
            // we won't exit the app until we exit this method, which happens
            // when we exit the main message loop.
            var container = DependencyInjection.Load(context);

            var hostId      = EndpointIdExtensions.Deserialize(hostIdText);
            var channelType = (ChannelType)Enum.Parse(typeof(ChannelType), channelTypeText);

            // Notify the host app that we're alive, after which the
            // rest of the app should pick up the loading of the dataset etc.
            // Note that this call to the container also registers all global commands and initializes the
            // communication channels etc.
            var resolver = container.Resolve <ManualEndpointConnection>();

            resolver(hostId, channelType, channelUriText);

            // Connect to the assembly resolve event so that we can intercept assembly loads for plugins etc.
            var assemblyResolver = container.Resolve <PluginLoadingAssemblyResolver>(
                new TypedParameter(
                    typeof(EndpointId),
                    EndpointIdExtensions.Deserialize(hostIdText)));

            AppDomain.CurrentDomain.AssemblyResolve += assemblyResolver.LocatePluginAssembly;

            // Start with the message processing loop and then we
            // wait for it to either get terminated or until we kill ourselves.
            Application.Run(context);
            return(NormalApplicationExitCode);
        }