public void TryUpdateWithContactedEndpoint()
        {
            var endpoint   = new EndpointId("a");
            var connection = new EndpointInformation(
                new EndpointId("a"),
                new DiscoveryInformation(new Uri("http://localhost/discovery/invalid")),
                new ProtocolInformation(
                    new Version(),
                    new Uri("http://localhost/protocol/invalid")));

            var storage = new EndpointInformationStorage();

            Assert.IsTrue(storage.TryAdd(endpoint, connection));

            var newConnection = new EndpointInformation(
                endpoint,
                new DiscoveryInformation(new Uri("http://other/discovery/invalid")),
                new ProtocolInformation(
                    new Version(),
                    new Uri("http://other/protocol/invalid")));

            Assert.IsTrue(storage.TryUpdate(newConnection));

            EndpointInformation storedConnection;

            storage.TryGetConnectionFor(endpoint, out storedConnection);
            Assert.AreSame(newConnection, storedConnection);
        }
        public bool TryCompleteApproval(EndpointId endpoint)
        {
            if (endpoint != null)
            {
                EndpointInformation info = null;
                lock (m_Lock)
                {
                    if (!m_ContactedEndpoints.ContainsKey(endpoint) &&
                        m_EndpointsWaitingForApproval.ContainsKey(endpoint) &&
                        !m_ApprovedEndpoints.ContainsKey(endpoint))
                    {
                        var pair = m_EndpointsWaitingForApproval[endpoint];
                        m_EndpointsWaitingForApproval.Remove(endpoint);
                        m_ApprovedEndpoints.Add(endpoint, pair.Item1);

                        info = pair.Item1;
                    }
                }

                if (info != null)
                {
                    RaiseOnEndpointConnected(info);
                    return(true);
                }
            }

            return(false);
        }
        public void TryAddWithExistingEndpoint()
        {
            var storage = new EndpointInformationStorage();

            var endpoint   = new EndpointId("a");
            var connection = new EndpointInformation(
                new EndpointId("a"),
                new DiscoveryInformation(new Uri("http://localhost/discovery/invalid")),
                new ProtocolInformation(
                    new Version(),
                    new Uri("http://localhost/protocol/invalid")));

            Assert.IsTrue(storage.TryAdd(endpoint, connection));
            Assert.IsFalse(storage.CanCommunicateWithEndpoint(endpoint));
            Assert.IsTrue(storage.HasBeenContacted(endpoint));
            Assert.IsFalse(storage.IsWaitingForApproval(endpoint));

            var newConnection = new EndpointInformation(
                endpoint,
                new DiscoveryInformation(new Uri("http://other/discovery/invalid")),
                new ProtocolInformation(
                    new Version(),
                    new Uri("http://other/protocol/invalid")));

            Assert.IsFalse(storage.TryAdd(endpoint, newConnection));

            EndpointInformation otherConnection;
            var result = storage.TryGetConnectionFor(endpoint, out otherConnection);

            Assert.IsTrue(result);
            Assert.AreSame(connection, otherConnection);
        }
        public void TryApprove()
        {
            var endpoint   = new EndpointId("a");
            var connection = new EndpointInformation(
                new EndpointId("a"),
                new DiscoveryInformation(new Uri("http://localhost/discovery/invalid")),
                new ProtocolInformation(
                    new Version(),
                    new Uri("http://localhost/protocol/invalid")));

            var description = new ProtocolDescription(new List <CommunicationSubject>());
            var storage     = new EndpointInformationStorage();

            var wasApproved = false;

            storage.OnEndpointConnected +=
                (s, e) =>
            {
                wasApproved = true;
                Assert.AreSame(connection.Id, e.Endpoint);
            };

            Assert.IsTrue(storage.TryAdd(endpoint, connection));
            Assert.IsFalse(storage.CanCommunicateWithEndpoint(endpoint));
            Assert.IsTrue(storage.HasBeenContacted(endpoint));
            Assert.IsFalse(storage.IsWaitingForApproval(endpoint));

            Assert.IsTrue(storage.TryStartApproval(endpoint, description));
            Assert.IsTrue(storage.TryCompleteApproval(endpoint));
            Assert.IsTrue(storage.CanCommunicateWithEndpoint(endpoint));
            Assert.IsFalse(storage.HasBeenContacted(endpoint));
            Assert.IsFalse(storage.IsWaitingForApproval(endpoint));
            Assert.IsTrue(wasApproved);
        }
        public bool TryUpdate(EndpointInformation connectionInformation)
        {
            if (connectionInformation != null)
            {
                lock (m_Lock)
                {
                    if (m_ContactedEndpoints.ContainsKey(connectionInformation.Id))
                    {
                        m_ContactedEndpoints[connectionInformation.Id] = connectionInformation;
                        return(true);
                    }

                    if (m_EndpointsWaitingForApproval.ContainsKey(connectionInformation.Id))
                    {
                        var tuple = m_EndpointsWaitingForApproval[connectionInformation.Id];
                        m_EndpointsWaitingForApproval.Remove(connectionInformation.Id);
                        m_EndpointsWaitingForApproval.Add(
                            connectionInformation.Id,
                            new Tuple <EndpointInformation, ProtocolDescription>(connectionInformation, tuple.Item2));

                        return(true);
                    }
                }
            }

            return(false);
        }
        public virtual IActionResult PostCreateEndpointForClient(
            [FromRoute] Guid clientUid,
            [FromBody] EndpointInformation endpoint)
        {
            if (clientUid == Guid.Empty)
            {
                return(StatusCode((int)HttpStatusCode.BadRequest));
            }

            if (!EndpointManager.IsUrlPartAvailable(endpoint.UrlPart))
            {
                return(StatusCode((int)HttpStatusCode.BadRequest, "{\"error\":\"URL Part already in use\"}"));
            }

            if (endpoint.Uid == Guid.Empty)
            {
                endpoint.Uid = Guid.NewGuid();
            }

            // create this endpoint and register to this client
            EndpointManager.AddOrUpdate(
                endpoint.Uid,
                endpoint.ChannelType,
                endpoint.UrlPart,
                clientUid);

            return(StatusCode((int)HttpStatusCode.Created, endpoint));
        }
        /// <summary>
        /// Returns the connection information for the given endpoint.
        /// </summary>
        /// <param name="endpoint">The ID of the endpoint.</param>
        /// <param name="information">The connection information for the endpoint.</param>
        /// <returns>
        /// <see langword="true" /> if the information for the endpoint was retrieved successfully; otherwise, <see langword="false" />.
        /// </returns>
        public bool TryGetConnectionFor(EndpointId endpoint, out EndpointInformation information)
        {
            information = null;
            if (endpoint != null)
            {
                lock (m_Lock)
                {
                    if (m_ApprovedEndpoints.ContainsKey(endpoint))
                    {
                        information = m_ApprovedEndpoints[endpoint];
                        return(true);
                    }

                    if (m_EndpointsWaitingForApproval.ContainsKey(endpoint))
                    {
                        information = m_EndpointsWaitingForApproval[endpoint].Item1;
                        return(true);
                    }

                    if (m_ContactedEndpoints.ContainsKey(endpoint))
                    {
                        information = m_ContactedEndpoints[endpoint];
                        return(true);
                    }
                }
            }

            return(false);
        }
Пример #8
0
 private void OnServerDiscovered(MulticastClient sender, EndpointInformation args)
 {
     _ = CoreApplication.MainView.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
     {
         MessagesListBox.Items.Add($"Discovered {args.Name} at {args.Address}");
     });
 }
Пример #9
0
        private Dictionary <Type, ServiceHostInfo> FindAllHosts()
        {
            var hosts = new Dictionary <Type, ServiceHostInfo>();

            foreach (Type type in TypeLocator.FindTypes(_dllSearchPattern, typeof(IServiceHost)))
            {
                ServiceHostInfo info = new ServiceHostInfo();

                Type interfaceType = (Type)type.GetMethod("GetInterfaceType", BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy).Invoke(null, null);

                info.InterfaceType = interfaceType;
                info.Logger        = _logger;
                info.Host          = new ServiceHost(type);

                info.Host.Description.Behaviors.Add(new HostErrorHandlerBehavior(info));
                info.Host.Authorization.ServiceAuthorizationManager = new RoleBasedAuthorizationManager();

                ContractDescription contract = ContractDescription.GetContract(interfaceType);

                EndpointAddress endpoint = EndpointInformation.BuildEndpoint(new EndpointInformation(), ServerConnectionInformation.Instance, interfaceType);
                Binding         binding  = BindingInformation.BuildBinding(new BindingInformation(), ServerConnectionInformation.Instance);
                ServiceEndpoint service  = new ServiceEndpoint(contract, binding, endpoint);
                info.Host.AddServiceEndpoint(service);

                hosts.Add(interfaceType, info);
            }

            return(hosts);
        }
Пример #10
0
        /// <summary>
        /// Initiates the handshake process between the current endpoint and the specified endpoint.
        /// </summary>
        /// <param name="information">The connection information for the endpoint.</param>
        private void InitiateHandshakeWith(EndpointInformation information)
        {
            var template       = information.ProtocolInformation.MessageAddress.ToChannelTemplate();
            var connectionInfo = m_Layer.LocalConnectionFor(information.ProtocolInformation.Version, template);

            if (connectionInfo != null)
            {
                lock (m_Lock)
                {
                    Debug.Assert(m_EndpointApprovalState.ContainsKey(information.Id), "The endpoint tick list is not stored.");
                    var tickList = m_EndpointApprovalState[information.Id];

                    if (!tickList.HaveSendConnect && !m_PotentialEndpoints.CanCommunicateWithEndpoint(information.Id))
                    {
                        tickList.HaveSendConnect = true;

                        var message = new EndpointConnectMessage(
                            m_Layer.Id,
                            new DiscoveryInformation(m_DiscoveryChannel.EntryChannel(template)),
                            new ProtocolInformation(
                                information.ProtocolInformation.Version,
                                connectionInfo.Item2,
                                connectionInfo.Item3),
                            m_Descriptions.ToStorage());
                        var task = m_Layer.SendMessageToUnregisteredEndpointAndWaitForResponse(
                            information,
                            message,
                            CommunicationConstants.DefaultMaximuNumberOfRetriesForMessageSending,
                            m_SendTimeout);
                        task.ContinueWith(HandleResponseToConnectMessage, TaskContinuationOptions.ExecuteSynchronously);
                    }
                }
            }
        }
Пример #11
0
        /// <summary>
        /// Sends the given message to the specified endpoint and returns a task that
        /// will eventually contain the return message.
        /// </summary>
        /// <param name="connection">The connection information for the endpoint to which the message has to be send.</param>
        /// <param name="message">The message that has to be send.</param>
        /// <param name="maximumNumberOfRetries">
        /// The maximum number of times the endpoint will try to send the message if delivery fails.
        /// </param>
        /// <param name="timeout">The maximum amount of time the response operation is allowed to take.</param>
        /// <returns>A task object that will eventually contain the response message.</returns>
        public Task <ICommunicationMessage> SendMessageToUnregisteredEndpointAndWaitForResponse(
            EndpointInformation connection,
            ICommunicationMessage message,
            int maximumNumberOfRetries,
            TimeSpan timeout)
        {
            {
                Lokad.Enforce.Argument(() => connection);
                Lokad.Enforce.Argument(() => message);
            }

            using (m_Diagnostics.Profiler.Measure(CommunicationConstants.TimingGroup, "ProtocolLayer: sending message and waiting for response"))
            {
                var pair   = ChannelPairFor(connection);
                var result = pair.Item2.ForwardResponse(connection.Id, message.Id, timeout);

                m_Diagnostics.Log(
                    LevelToLog.Trace,
                    CommunicationConstants.DefaultLogTextPrefix,
                    string.Format(
                        CultureInfo.InvariantCulture,
                        "Sending msg of type {0} to endpoint ({1}) while waiting for the response.",
                        message.GetType(),
                        connection));

                pair.Item1.Send(connection.ProtocolInformation, message, maximumNumberOfRetries);

                RaiseOnConfirmChannelIntegrity(connection.Id);
                return(result);
            }
        }
Пример #12
0
        /// <summary>
        /// Sends the given message to the specified endpoint.
        /// </summary>
        /// <param name="connection">The connection information for the endpoint to which the message has to be send.</param>
        /// <param name="message">The message that has to be send.</param>
        /// <param name="maximumNumberOfRetries">The maximum number of times the endpoint will try to send the message if delivery fails.</param>
        /// <exception cref="FailedToSendMessageException">
        ///     Thrown when the channel fails to deliver the message to the remote endpoint.
        /// </exception>
        public void SendMessageToUnregisteredEndpoint(EndpointInformation connection, ICommunicationMessage message, int maximumNumberOfRetries)
        {
            {
                Lokad.Enforce.Argument(() => connection);
                Lokad.Enforce.Argument(() => message);
            }

            using (m_Diagnostics.Profiler.Measure(
                       CommunicationConstants.TimingGroup,
                       "ProtocolLayer: sending message without waiting for response"))
            {
                var channel = ChannelFor(connection);
                m_Diagnostics.Log(
                    LevelToLog.Trace,
                    CommunicationConstants.DefaultLogTextPrefix,
                    string.Format(
                        CultureInfo.InvariantCulture,
                        "Sending msg of type {0} to endpoint ({1}) without waiting for the response.",
                        message.GetType(),
                        connection.Id));

                channel.Send(connection.ProtocolInformation, message, maximumNumberOfRetries);
                RaiseOnConfirmChannelIntegrity(connection.Id);
            }
        }
        public void TryRemoveWithApprovedEndpoint()
        {
            var storage = new EndpointInformationStorage();

            var endpoint   = new EndpointId("a");
            var connection = new EndpointInformation(
                new EndpointId("a"),
                new DiscoveryInformation(new Uri("http://localhost/discovery/invalid")),
                new ProtocolInformation(
                    new Version(),
                    new Uri("http://localhost/protocol/invalid")));

            Assert.IsTrue(storage.TryAdd(endpoint, connection));
            Assert.IsFalse(storage.CanCommunicateWithEndpoint(endpoint));
            Assert.IsTrue(storage.HasBeenContacted(endpoint));
            Assert.IsFalse(storage.IsWaitingForApproval(endpoint));

            var description = new ProtocolDescription(new List <CommunicationSubject>());

            Assert.IsTrue(storage.TryStartApproval(endpoint, description));
            Assert.IsTrue(storage.TryCompleteApproval(endpoint));
            Assert.IsTrue(storage.CanCommunicateWithEndpoint(endpoint));
            Assert.IsFalse(storage.IsWaitingForApproval(endpoint));

            Assert.IsTrue(storage.TryRemoveEndpoint(endpoint));
            Assert.IsFalse(storage.CanCommunicateWithEndpoint(endpoint));
            Assert.IsFalse(storage.IsWaitingForApproval(endpoint));
            Assert.IsFalse(storage.HasBeenContacted(endpoint));
        }
        public void TryUpdateWithApprovalUnderWay()
        {
            var endpoint   = new EndpointId("a");
            var connection = new EndpointInformation(
                new EndpointId("a"),
                new DiscoveryInformation(new Uri("http://localhost/discovery/invalid")),
                new ProtocolInformation(
                    new Version(),
                    new Uri("http://localhost/protocol/invalid")));

            var description = new ProtocolDescription(new List <CommunicationSubject>());
            var storage     = new EndpointInformationStorage();

            Assert.IsTrue(storage.TryAdd(endpoint, connection));
            Assert.IsTrue(storage.TryStartApproval(endpoint, description));

            var newConnection = new EndpointInformation(
                endpoint,
                new DiscoveryInformation(new Uri("http://other/discovery/invalid")),
                new ProtocolInformation(
                    new Version(),
                    new Uri("http://other/protocol/invalid")));

            Assert.IsTrue(storage.TryUpdate(newConnection));

            EndpointInformation storedConnection;

            storage.TryGetConnectionFor(endpoint, out storedConnection);
            Assert.AreSame(newConnection, storedConnection);
        }
Пример #15
0
        /// <summary>
        /// Initializes a new instance of the <see cref="EndpointDiscoveredEventArgs"/> class.
        /// </summary>
        /// <param name="endpointInformation">The connection information for the new endpoint.</param>
        /// <exception cref="ArgumentNullException">
        ///     Thrown if <paramref name="endpointInformation"/> is <see langword="null" />.
        /// </exception>
        public EndpointDiscoveredEventArgs(EndpointInformation endpointInformation)
        {
            {
                Lokad.Enforce.Argument(() => endpointInformation);
            }

            ConnectionInformation = endpointInformation;
        }
Пример #16
0
 private static bool IsComplete(EndpointInformation storedInformation)
 {
     return((storedInformation != null) &&
            (storedInformation.DiscoveryInformation.Address != null) &&
            (storedInformation.ProtocolInformation.Version != null) &&
            (storedInformation.ProtocolInformation.MessageAddress != null) &&
            (storedInformation.ProtocolInformation.DataAddress != null));
 }
        /// <summary>
        /// Removes the endpoint from the storage.
        /// </summary>
        /// <param name="endpoint">The ID of the endpoint.</param>
        /// <returns>
        /// <see langword="true" /> if the endpoint was removed successfully; otherwise, <see langword="false" />.
        /// </returns>
        public bool TryRemoveEndpoint(EndpointId endpoint)
        {
            if (endpoint == null)
            {
                return(false);
            }

            bool hasEndpoint;

            lock (m_Lock)
            {
                hasEndpoint = m_ApprovedEndpoints.ContainsKey(endpoint) ||
                              m_EndpointsWaitingForApproval.ContainsKey(endpoint) ||
                              m_ContactedEndpoints.ContainsKey(endpoint);
            }

            if (!hasEndpoint)
            {
                return(false);
            }

            RaiseOnEndpointDisconnecting(endpoint);

            EndpointInformation info = null;

            lock (m_Lock)
            {
                if (m_ApprovedEndpoints.ContainsKey(endpoint))
                {
                    info = m_ApprovedEndpoints[endpoint];
                    m_ApprovedEndpoints.Remove(endpoint);
                }

                if (m_EndpointsWaitingForApproval.ContainsKey(endpoint))
                {
                    // Always notify because we can send messages to an endpoint
                    // while we're establishing if an endpoint is worth connecting to
                    info = m_EndpointsWaitingForApproval[endpoint].Item1;
                    m_EndpointsWaitingForApproval.Remove(endpoint);
                }

                if (m_ContactedEndpoints.ContainsKey(endpoint))
                {
                    // Always notify because we can send messages to an endpoint
                    // while we're establishing if an endpoint is worth connecting to
                    info = m_ContactedEndpoints[endpoint];
                    m_ContactedEndpoints.Remove(endpoint);
                }
            }

            if (info != null)
            {
                RaiseOnEndpointDisconnected(info);
                return(true);
            }

            return(false);
        }
        private void RaiseOnEndpointDisconnected(EndpointInformation info)
        {
            var local = OnEndpointDisconnected;

            if (local != null)
            {
                local(this, new EndpointEventArgs(info.Id));
            }
        }
Пример #19
0
        internal void UpdateEndpointEntryOnAccessStart(EndpointInformation entry)
        {
            var now = DateTime.UtcNow;

            lock (entry.lockObj)
            {
                entry.LastUpdatedTimestamp = now;
            }
        }
Пример #20
0
        private void RaiseOnEndpointBecomingAvailable(EndpointInformation info)
        {
            var local = OnEndpointBecomingAvailable;

            if (local != null)
            {
                local(this, new EndpointDiscoveredEventArgs(info));
            }
        }
Пример #21
0
        // Assumes entry is locked.
        internal void RefreshFailedEndpointEntry(EndpointInformation entry, DateTime refreshTimestamp)
        {
            Contract.Assert(entry.LastFailureTimestamp != default(DateTime));

            if (refreshTimestamp.Subtract(entry.LastFailureTimestamp) > _failedEndpointExpiryInterval)
            {
                entry.State = EndpointState.Available;
            }
        }
        public void SendMessageToWithOpenChannel()
        {
            var remoteEndpoint = new EndpointId("b");
            var endpointInfo   = new EndpointInformation(
                remoteEndpoint,
                new DiscoveryInformation(new Uri("net.pipe://localhost/discovery")),
                new ProtocolInformation(
                    ProtocolVersions.V1,
                    new Uri("net.pipe://localhost/messages"),
                    new Uri("net.pipe://localhost/data")));
            var endpoints = new Mock <IStoreInformationAboutEndpoints>();
            {
                endpoints.Setup(e => e.CanCommunicateWithEndpoint(It.IsAny <EndpointId>()))
                .Returns(true);
                endpoints.Setup(e => e.TryGetConnectionFor(It.IsAny <EndpointId>(), out endpointInfo))
                .Returns(true);
            }

            var msg     = new SuccessMessage(new EndpointId("B"), new MessageId());
            var channel = new Mock <IProtocolChannel>();
            {
                channel.Setup(c => c.OpenChannel())
                .Verifiable();
                channel.Setup(c => c.LocalConnectionPointForVersion(It.IsAny <Version>()))
                .Returns(endpointInfo.ProtocolInformation);
                channel.Setup(c => c.Send(It.IsAny <ProtocolInformation>(), It.IsAny <ICommunicationMessage>(), It.IsAny <int>()))
                .Callback <ProtocolInformation, ICommunicationMessage, int>(
                    (e, m, r) =>
                {
                    Assert.AreSame(endpointInfo.ProtocolInformation, e);
                    Assert.AreSame(msg, m);
                })
                .Verifiable();
            }

            var pipe = new Mock <IDirectIncomingMessages>();
            Func <ChannelTemplate, EndpointId, Tuple <IProtocolChannel, IDirectIncomingMessages> > channelBuilder =
                (template, id) => new Tuple <IProtocolChannel, IDirectIncomingMessages>(channel.Object, pipe.Object);
            var diagnostics = new SystemDiagnostics((log, s) => { }, null);
            var layer       = new ProtocolLayer(
                endpoints.Object,
                channelBuilder,
                new[]
            {
                ChannelTemplate.NamedPipe,
            },
                diagnostics);

            layer.SignIn();

            layer.SendMessageTo(remoteEndpoint, msg, 1);
            channel.Verify(c => c.OpenChannel(), Times.Once());
            channel.Verify(c => c.Send(It.IsAny <ProtocolInformation>(), It.IsAny <ICommunicationMessage>(), It.IsAny <int>()), Times.Once());
        }
Пример #23
0
        private static bool CanReachEndpointWithGivenConnection(EndpointInformation info)
        {
            var endpointChannelTemplate = info.ProtocolInformation.MessageAddress.ToChannelTemplate();

            if (info.Id.IsOnLocalMachine())
            {
                return(endpointChannelTemplate == ChannelTemplate.NamedPipe);
            }

            return(endpointChannelTemplate == ChannelTemplate.TcpIP);
        }
        /// <summary>
        /// Attempts to get endpoint by URL part an EndpointInformation from the given string.
        /// </summary>
        /// <param name="urlPart"> The URL part.</param>
        /// <param name="endpoint">[out] The endpoint.</param>
        /// <returns>True if it succeeds, false if it fails.</returns>
        public static bool TryGetEndpointByUrlPart(string urlPart, out EndpointInformation endpoint)
        {
            if (!_instance._urlPartEndpointDict.ContainsKey(urlPart))
            {
                endpoint = null;
                return(false);
            }

            endpoint = _instance._urlPartEndpointDict[urlPart];
            return(true);
        }
        /// <summary>
        /// Attempts to get endpoint by UID an EndpointInformation from the given GUID.
        /// </summary>
        /// <param name="endpointUid">The endpoint UID.</param>
        /// <param name="endpoint">   [out] The endpoint.</param>
        /// <returns>True if it succeeds, false if it fails.</returns>
        public static bool TryGetEndpointByUid(Guid endpointUid, out EndpointInformation endpoint)
        {
            if (!_instance._uidEndpointDict.ContainsKey(endpointUid))
            {
                endpoint = null;
                return(false);
            }

            endpoint = _instance._uidEndpointDict[endpointUid];
            return(true);
        }
        /// <summary>Disables the given endpoint UID.</summary>
        /// <param name="endpointGuid">The endpoint UID.</param>
        /// <param name="endpoint">   [out] The endpoint.</param>
        /// <returns>True if it succeeds, false if it fails.</returns>
        public static bool TryDisable(Guid endpointGuid, out EndpointInformation endpoint)
        {
            if (_instance._uidEndpointDict.ContainsKey(endpointGuid))
            {
                _instance._uidEndpointDict[endpointGuid].Enabled = false;
                endpoint = _instance._uidEndpointDict[endpointGuid];
                return(true);
            }

            endpoint = null;
            return(false);
        }
Пример #27
0
        /// <summary>
        /// Continues the handshake process between the current endpoint and the specified endpoint.
        /// </summary>
        /// <param name="connection">The connection information for endpoint that started the handshake.</param>
        /// <param name="information">The handshake information for the endpoint.</param>
        /// <param name="messageId">The ID of the message that carried the handshake information.</param>
        public void ContinueHandshakeWith(
            EndpointInformation connection,
            ProtocolDescription information,
            MessageId messageId)
        {
            bool shouldSendConnect;

            lock (m_Lock)
            {
                // Potentially a new endpoint so store it
                StorePotentialEndpoint(connection);
                if (!m_EndpointApprovalState.ContainsKey(connection.Id))
                {
                    return;
                }

                var tickList = m_EndpointApprovalState[connection.Id];
                tickList.HaveReceivedConnect = true;

                if (!AllowConnection(connection.ProtocolInformation.Version, information))
                {
                    var failMsg = new FailureMessage(m_Layer.Id, messageId);
                    m_Layer.SendMessageToUnregisteredEndpoint(
                        connection,
                        failMsg,
                        CommunicationConstants.DefaultMaximuNumberOfRetriesForMessageSending);

                    RemoveEndpoint(connection.Id);
                    return;
                }

                var successMessage = new SuccessMessage(m_Layer.Id, messageId);
                m_Layer.SendMessageToUnregisteredEndpoint(
                    connection,
                    successMessage,
                    CommunicationConstants.DefaultMaximuNumberOfRetriesForMessageSending);
                tickList.HaveSendConnectResponse = true;

                m_PotentialEndpoints.TryStartApproval(connection.Id, information);
                if (tickList.IsComplete())
                {
                    ApproveConnection(connection.Id);
                }

                shouldSendConnect = !tickList.HaveSendConnect;
            }

            if (shouldSendConnect)
            {
                InitiateHandshakeWith(connection);
            }
        }
        public void OnEndpointDisconnectedAfterSigningIn()
        {
            var endpoint     = new EndpointId("a");
            var endpointInfo = new EndpointInformation(
                endpoint,
                new DiscoveryInformation(new Uri("net.pipe://localhost/discovery")),
                new ProtocolInformation(
                    ProtocolVersions.V1,
                    new Uri("net.pipe://localhost/messages"),
                    new Uri("net.pipe://localhost/data")));
            var endpoints = new Mock <IStoreInformationAboutEndpoints>();
            {
                endpoints.Setup(e => e.CanCommunicateWithEndpoint(It.IsAny <EndpointId>()))
                .Returns(true);
                endpoints.Setup(e => e.TryGetConnectionFor(It.IsAny <EndpointId>(), out endpointInfo))
                .Returns(true);
            }

            var channel = new Mock <IProtocolChannel>();
            {
                channel.Setup(c => c.LocalConnectionPointForVersion(It.IsAny <Version>()))
                .Returns(endpointInfo.ProtocolInformation);
                channel.Setup(c => c.EndpointDisconnected(It.IsAny <ProtocolInformation>()))
                .Callback <ProtocolInformation>(e => Assert.AreEqual(endpointInfo.ProtocolInformation, e))
                .Verifiable();
            }

            var pipe = new Mock <IDirectIncomingMessages>();
            {
                pipe.Setup(p => p.OnEndpointSignedOff(It.IsAny <EndpointId>()))
                .Callback <EndpointId>(e => Assert.AreEqual(endpoint, e))
                .Verifiable();
            }

            Func <ChannelTemplate, EndpointId, Tuple <IProtocolChannel, IDirectIncomingMessages> > channelBuilder =
                (template, id) => new Tuple <IProtocolChannel, IDirectIncomingMessages>(channel.Object, pipe.Object);
            var diagnostics = new SystemDiagnostics((log, s) => { }, null);
            var layer       = new ProtocolLayer(
                endpoints.Object,
                channelBuilder,
                new[]
            {
                ChannelTemplate.NamedPipe,
            },
                diagnostics);

            layer.SignIn();
            endpoints.Raise(d => d.OnEndpointDisconnecting += null, new EndpointEventArgs(endpoint));

            channel.Verify(c => c.EndpointDisconnected(It.IsAny <ProtocolInformation>()), Times.Once());
            pipe.Verify(p => p.OnEndpointSignedOff(It.IsAny <EndpointId>()), Times.Once());
        }
        public void TryAddWithNullEndpoint()
        {
            var storage = new EndpointInformationStorage();

            var connection = new EndpointInformation(
                new EndpointId("a"),
                new DiscoveryInformation(new Uri("http://localhost/discovery/invalid")),
                new ProtocolInformation(
                    new Version(),
                    new Uri("http://localhost/protocol/invalid")));

            Assert.IsFalse(storage.TryAdd(null, connection));
        }
        /// <summary>
        /// Getting endpoint information from IIS.
        /// </summary>
        public static IEnumerable <EndpointInformation> GetRunningEndpointsInformation(this ServerManager @this, ILogger logger)
        {
            var sites = @this.Sites;

            var hostIp      = string.Empty;
            var machineName = Dns.GetHostName();
            var host        = Dns.GetHostEntry(machineName);

            foreach (var ip in host.AddressList)
            {
                if (ip.AddressFamily == AddressFamily.InterNetwork)
                {
                    hostIp = ip.ToString();
                }
            }

            foreach (var site in sites)
            {
                if (!IsValidSiteForNotification(site))
                {
                    logger.Warning("Site is not valid for notification(e.g. not configured notification propagation on configuration of site) {@site}", site);
                    continue;
                }

                foreach (var siteBinding in site.Bindings)
                {
                    if (siteBinding.Schema.Name != BindingSchemaName)
                    {
                        logger.Warning("Binding scheme is not valid, must be {@schemaName}, but {@siteSchema}", BindingSchemaName, siteBinding.Schema.Name);
                        continue;
                    }

                    var endpointInfo = new EndpointInformation
                    {
                        HostName        = string.IsNullOrWhiteSpace(siteBinding.Host) ? machineName : siteBinding.Host,
                        Address         = siteBinding.EndPoint.Address.GetAddressBytes().All(x => x == 0) ? hostIp : siteBinding.EndPoint.Address.ToString(),
                        Port            = siteBinding.EndPoint.Port,
                        ApplicationName = site.Name,
                        MachineName     = machineName
                    };

                    logger.Information("Retrieved from IIS endpoint information {@endpoint}", endpointInfo);

                    yield return(endpointInfo);
                }
            }
        }
 internal void UpdateEndpointEntryOnAccessStart(EndpointInformation entry)
 {
     var now = DateTime.UtcNow;
     lock (entry.lockObj)
     {
         entry.LastUpdatedTimestamp = now;
     }
 }
 internal void UpdateEndpointEntryOnAccessCompletion(EndpointInformation entry, EndpointAccessResult accessResult)
 {
     var now = DateTime.UtcNow;
     lock (entry.lockObj)
     {
         if (accessResult == EndpointAccessResult.Failure)
         {
             entry.State = EndpointState.Failed;
             entry.LastFailureTimestamp = now;
         }
         else if (entry.State == EndpointState.Failed)
         {
             RefreshFailedEndpointEntry(entry, now);
         }
         entry.LastUpdatedTimestamp = now;
     }
 }
        // Assumes entry is locked.
        internal void RefreshFailedEndpointEntry(EndpointInformation entry, DateTime refreshTimestamp)
        {
            Contract.Assert(entry.LastFailureTimestamp != default(DateTime));

            if (refreshTimestamp.Subtract(entry.LastFailureTimestamp) > _failedEndpointExpiryInterval)
            {
                entry.State = EndpointState.Available;
            }
        }
        internal void PopulateEndpoints(List<Uri> endpoints)
        {
            _endpoints = new Dictionary<Uri, EndpointInformation>();

            foreach (Uri e in endpoints)
            {
                var info = new EndpointInformation()
                {
                    lockObj = new object(),
                    Name = e.OriginalString,
                    State = EndpointState.Available,
                    LastUpdatedTimestamp = DateTime.UtcNow,
                    LastFailureTimestamp = default(DateTime)
                };
                _endpoints.Add(e, info);
            }
        }