public void SignOutWithoutBeingSignedIn()
        {
            var endpoints = new Mock <IStoreInformationAboutEndpoints>();

            var protocolInfo = new ProtocolInformation(
                new Version(1, 0),
                new Uri("net.pipe://localhost/protocol/message/invalid"),
                new Uri("net.pipe://localhost/protocol/data/invalid"));
            var channel = new Mock <IProtocolChannel>();
            {
                channel.Setup(c => c.OpenChannel())
                .Verifiable();
                channel.Setup(c => c.LocalConnectionPointForVersion(It.IsAny <Version>()))
                .Returns(protocolInfo);
                channel.Setup(c => c.CloseChannel())
                .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.SignOut();
            Assert.IsFalse(layer.IsSignedIn);
            channel.Verify(c => c.CloseChannel(), Times.Never());
        }
示例#2
0
        public void CloseChannelTo()
        {
            var endpointId   = new EndpointId("id");
            var endpointInfo = new ProtocolInformation(
                ProtocolVersions.V1,
                new Uri("http://localhost/messages"),
                new Uri("http://localhost/data"));
            var msg               = new EndpointDisconnectMessage(endpointId);
            var messageProxy      = new Mock <IMessageSendingEndpoint>();
            var messageDisposable = messageProxy.As <IDisposable>();

            var dataProxy      = new Mock <IDataTransferingEndpoint>();
            var dataDisposable = dataProxy.As <IDisposable>();

            var localEndpoint = new EndpointId("local");
            Func <ProtocolInformation, IMessageSendingEndpoint>  messageBuilder = id => messageProxy.Object;
            Func <ProtocolInformation, IDataTransferingEndpoint> dataBuilder    = id => dataProxy.Object;
            var sender = new SendingEndpoint(localEndpoint, messageBuilder, dataBuilder);

            sender.Send(endpointInfo, msg, 1);
            Assert.AreEqual(1, sender.KnownEndpoints().Count());

            sender.CloseChannelTo(endpointInfo);
            Assert.AreEqual(0, sender.KnownEndpoints().Count());
        }
示例#3
0
        public void SendMessageToUnknownReceiver()
        {
            var endpointId   = new EndpointId("id");
            var endpointInfo = new ProtocolInformation(
                ProtocolVersions.V1,
                new Uri("http://localhost/messages"),
                new Uri("http://localhost/data"));

            var msg          = new EndpointDisconnectMessage(endpointId);
            var messageProxy = new Mock <IMessageSendingEndpoint>();
            {
                messageProxy.Setup(p => p.Send(It.IsAny <ICommunicationMessage>(), It.IsAny <int>()))
                .Callback <ICommunicationMessage, int>((input, retries) => Assert.AreSame(msg, input));
            }

            var dataProxy = new Mock <IDataTransferingEndpoint>();
            {
                dataProxy.Setup(p => p.Send(It.IsAny <DataTransferMessage>(), It.IsAny <int>()))
                .Verifiable();
            }

            var localEndpoint = new EndpointId("local");
            Func <ProtocolInformation, IMessageSendingEndpoint>  builder     = id => messageProxy.Object;
            Func <ProtocolInformation, IDataTransferingEndpoint> dataBuilder = id => dataProxy.Object;
            var sender = new SendingEndpoint(localEndpoint, builder, dataBuilder);

            sender.Send(endpointInfo, msg, 1);
            Assert.AreEqual(1, sender.KnownEndpoints().Count());
            dataProxy.Verify(p => p.Send(It.IsAny <DataTransferMessage>(), It.IsAny <int>()), Times.Never());
        }
示例#4
0
        internal bool GetFixedSize(ref int size)
        {
            if (size < 0)
            {
                return(false);
            }

            if (_data.Length == 0)
            {
                return(true);
            }

            // Sensible?
            size = ProtocolInformation.Padded(size, Alignment);

            if (_data.Length == 1)
            {
                int valueSize = GetSize(this[0]);

                if (valueSize == -1)
                {
                    return(false);
                }

                size += valueSize;
                return(true);
            }

            if (IsStructlike)
            {
                foreach (Signature sig in GetParts())
                {
                    if (!sig.GetFixedSize(ref size))
                    {
                        return(false);
                    }
                }
                return(true);
            }

            if (IsArray || IsDict)
            {
                return(false);
            }

            if (IsStruct)
            {
                foreach (Signature sig in GetFieldSignatures())
                {
                    if (!sig.GetFixedSize(ref size))
                    {
                        return(false);
                    }
                }
                return(true);
            }

            // Any other cases?
            throw new Exception();
        }
        /// <summary>
        /// Transfers the data to the receiving endpoint.
        /// </summary>
        /// <param name="receivingEndpoint">The connection information for the endpoint that will receive the data stream.</param>
        /// <param name="filePath">The file path to the file that should be transferred.</param>
        /// <param name="token">The cancellation token that is used to cancel the task if necessary.</param>
        /// <param name="scheduler">The scheduler that is used to run the return task with.</param>
        /// <param name="maximumNumberOfRetries">The maximum number of times the endpoint will try to send the message if delivery fails.</param>
        /// <returns>
        /// An task that indicates when the transfer is complete.
        /// </returns>
        /// <exception cref="ArgumentNullException">
        ///     Thrown if <paramref name="receivingEndpoint"/> is <see langword="null" />.
        /// </exception>
        /// <exception cref="ArgumentNullException">
        ///     Thrown if <paramref name="filePath"/> is <see langword="null" />.
        /// </exception>
        /// <exception cref="ArgumentException">
        ///     Thrown if <paramref name="filePath"/> is <see langword="null" />.
        /// </exception>
        /// <exception cref="FailedToSendMessageException">
        ///     Thrown when the channel fails to deliver the message to the remote endpoint.
        /// </exception>
        public Task TransferData(
            ProtocolInformation receivingEndpoint,
            string filePath,
            CancellationToken token,
            TaskScheduler scheduler    = null,
            int maximumNumberOfRetries = CommunicationConstants.DefaultMaximuNumberOfRetriesForMessageSending)
        {
            {
                Lokad.Enforce.Argument(() => receivingEndpoint);
                Lokad.Enforce.Argument(() => filePath);
                Lokad.Enforce.Argument(() => filePath, Lokad.Rules.StringIs.NotEmpty);
            }

            var sender = SenderForEndpoint(receivingEndpoint);

            return(Task.Factory.StartNew(
                       () =>
            {
                // Don't catch any exception because the task will store them if we don't catch them.
                using (var file = new FileStream(filePath, FileMode.Open, FileAccess.Read))
                {
                    sender.Send(receivingEndpoint, file, maximumNumberOfRetries);
                }
            },
                       token,
                       TaskCreationOptions.LongRunning,
                       scheduler ?? TaskScheduler.Default));
        }
示例#6
0
        public void ToVersioned()
        {
            var input  = new ProtocolInformation(new Version(1, 2, 3, 4), new Uri("http://localhost/protocol/invalid"));
            var output = ChannelInformationToTransportConverter.ToVersioned(input);

            Assert.AreSame(input.Version, output.ProtocolVersion);
            Assert.AreSame(input.MessageAddress, output.Address);
        }
示例#7
0
 /// <summary>
 /// Initializes a new instance of the <see cref="EndpointConnectMessage"/> class.
 /// </summary>
 /// <param name="origin">The ID of the endpoint that send the message.</param>
 /// <param name="discoveryInformation">The object containing the information about the discovery channel for the remote endpoint.</param>
 /// <param name="protocolInformation">The object containing the information about the protocol channels for the remote endpoint.</param>
 /// <param name="information">
 ///     The information describing the version of the communication protocol
 ///     used by the sender, the desired communication API's for the sender and
 ///     the available communication API's provided by the sender.
 /// </param>
 /// <exception cref="ArgumentNullException">
 ///     Thrown if <paramref name="origin"/> is <see langword="null" />.
 /// </exception>
 /// <exception cref="ArgumentNullException">
 ///     Thrown if <paramref name="discoveryInformation"/> is <see langword="null" />.
 /// </exception>
 /// <exception cref="ArgumentNullException">
 ///     Thrown if <paramref name="protocolInformation"/> is <see langword="null" />.
 /// </exception>
 /// <exception cref="ArgumentNullException">
 ///     Thrown if <paramref name="information"/> is <see langword="null" />.
 /// </exception>
 public EndpointConnectMessage(
     EndpointId origin,
     DiscoveryInformation discoveryInformation,
     ProtocolInformation protocolInformation,
     ProtocolDescription information)
     : this(origin, new MessageId(), discoveryInformation, protocolInformation, information)
 {
 }
示例#8
0
        public void Create()
        {
            var version = new Version(1, 2, 3, 4);
            var message = new Uri("http://localhost/message/invalid");
            var data    = new Uri("http://localhost/data/invalid");
            var info    = new ProtocolInformation(version, message, data);

            Assert.AreSame(version, info.Version);
            Assert.AreSame(message, info.MessageAddress);
            Assert.AreSame(data, info.DataAddress);
        }
 /// <summary>
 /// Indicates that the remote endpoint has disconnected.
 /// </summary>
 /// <param name="endpoint">The ID number of the endpoint that has disconnected.</param>
 public void EndpointDisconnected(ProtocolInformation endpoint)
 {
     lock (m_Lock)
     {
         var version = endpoint.Version;
         if (m_SendingEndpoints.ContainsKey(version))
         {
             var sender = m_SendingEndpoints[version];
             sender.CloseChannelTo(endpoint);
         }
     }
 }
示例#10
0
        /// <summary>
        /// Translates the current version of the <see cref="EndpointInformation"/> to the <see cref="VersionedChannelInformation"/>.
        /// </summary>
        /// <param name="info">The channel information describing the available protocol channel.</param>
        /// <returns>A object describing the versioned channel information.</returns>
        /// <exception cref="ArgumentNullException">
        ///     Thrown if <paramref name="info"/> is <see langword="null" />.
        /// </exception>
        public static VersionedChannelInformation ToVersioned(ProtocolInformation info)
        {
            {
                Lokad.Enforce.Argument(() => info);
            }

            return(new VersionedChannelInformation
            {
                ProtocolVersion = info.Version,
                Address = info.MessageAddress
            });
        }
示例#11
0
        /// <summary>
        /// Sends the given message.
        /// </summary>
        /// <param name="endpoint">The endpoint to which the message should be send.</param>
        /// <param name="message">The message 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="ArgumentNullException">
        ///     Thrown if <paramref name="endpoint"/> is <see langword="null" />.
        /// </exception>
        /// <exception cref="ArgumentNullException">
        ///     Thrown if <paramref name="message"/> is <see langword="null" />.
        /// </exception>
        /// <exception cref="ArgumentOutOfRangeException">
        ///     Thrown if <paramref name="maximumNumberOfRetries"/> is smaller than 1.
        /// </exception>
        public void Send(ProtocolInformation endpoint, ICommunicationMessage message, int maximumNumberOfRetries)
        {
            {
                Lokad.Enforce.Argument(() => endpoint);
                Lokad.Enforce.Argument(() => message);
                Lokad.Enforce.With <ArgumentOutOfRangeException>(
                    maximumNumberOfRetries > 0,
                    Resources.Exceptions_Messages_NumberOfRetriesShouldBeLargerThanZero);
            }

            var channel = MessageChannelFor(endpoint);

            channel.Send(message, maximumNumberOfRetries);
        }
        private ISendingEndpoint SenderForEndpoint(ProtocolInformation info)
        {
            var protocolVersion = info.Version;

            lock (m_Lock)
            {
                if (!m_SendingEndpoints.ContainsKey(protocolVersion))
                {
                    var newSender = m_SenderBuilder(m_Id, BuildMessageSendingProxy, BuildDataTransferProxy);
                    m_SendingEndpoints.Add(protocolVersion, newSender);
                }

                return(m_SendingEndpoints[protocolVersion]);
            }
        }
        /// <summary>
        /// Sends the given message to the receiving endpoint.
        /// </summary>
        /// <param name="endpoint">The connection information for the endpoint to which the message should be send.</param>
        /// <param name="message">The message that should 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="ArgumentNullException">
        ///     Thrown if <paramref name="endpoint"/> is <see langword="null" />.
        /// </exception>
        /// <exception cref="ArgumentNullException">
        ///     Thrown if <paramref name="message"/> is <see langword="null" />.
        /// </exception>
        /// <exception cref="FailedToSendMessageException">
        ///     Thrown when the channel fails to deliver the message to the remote endpoint.
        /// </exception>
        public void Send(ProtocolInformation endpoint, ICommunicationMessage message, int maximumNumberOfRetries)
        {
            {
                Lokad.Enforce.Argument(() => endpoint);
                Lokad.Enforce.Argument(() => message);
            }

            var sender = SenderForEndpoint(endpoint);

            if (sender == null)
            {
                throw new EndpointNotContactableException();
            }

            sender.Send(endpoint, message, maximumNumberOfRetries);
        }
示例#14
0
        public void SendDataToKnownReceiver()
        {
            var text   = "Hello world.";
            var data   = new MemoryStream();
            var writer = new StreamWriter(data);

            writer.Write(text);
            data.Position = 0;

            var localEndpoint = new EndpointId("local");
            var endpointInfo  = new ProtocolInformation(
                ProtocolVersions.V1,
                new Uri("http://localhost/messages"),
                new Uri("http://localhost/data"));
            var messageProxy = new Mock <IMessageSendingEndpoint>();
            {
                messageProxy.Setup(p => p.Send(It.IsAny <ICommunicationMessage>(), It.IsAny <int>()))
                .Verifiable();
            }

            var dataProxy = new Mock <IDataTransferingEndpoint>();
            {
                dataProxy.Setup(p => p.Send(It.IsAny <DataTransferMessage>(), It.IsAny <int>()))
                .Callback <DataTransferMessage, int>(
                    (msg, retries) =>
                {
                    Assert.AreSame(localEndpoint, msg.SendingEndpoint);
                    Assert.AreSame(data, msg.Data);
                })
                .Verifiable();
            }

            Func <ProtocolInformation, IMessageSendingEndpoint>  builder     = id => messageProxy.Object;
            Func <ProtocolInformation, IDataTransferingEndpoint> dataBuilder = id => dataProxy.Object;
            var sender = new SendingEndpoint(localEndpoint, builder, dataBuilder);

            sender.Send(endpointInfo, data, 1);
            Assert.AreEqual(1, sender.KnownEndpoints().Count());
            messageProxy.Verify(p => p.Send(It.IsAny <ICommunicationMessage>(), It.IsAny <int>()), Times.Never());
            dataProxy.Verify(p => p.Send(It.IsAny <DataTransferMessage>(), It.IsAny <int>()), Times.Exactly(1));

            sender.Send(endpointInfo, data, 1);
            Assert.AreEqual(1, sender.KnownEndpoints().Count());
            messageProxy.Verify(p => p.Send(It.IsAny <ICommunicationMessage>(), It.IsAny <int>()), Times.Never());
            dataProxy.Verify(p => p.Send(It.IsAny <DataTransferMessage>(), It.IsAny <int>()), Times.Exactly(2));
        }
示例#15
0
        /// <summary>
        /// Initializes a new instance of the <see cref="EndpointConnectMessage"/> class.
        /// </summary>
        /// <param name="origin">The ID of the endpoint that send the message.</param>
        /// <param name="id">The ID of the current message.</param>
        /// <param name="discoveryInformation">The object containing the information about the discovery channel for the remote endpoint.</param>
        /// <param name="protocolInformation">The object containing the information about the protocol channels for the remote endpoint.</param>
        /// <param name="information">
        ///     The information describing the version of the communication protocol
        ///     used by the sender, the desired communication API's for the sender and
        ///     the available communication API's provided by the sender.
        /// </param>
        /// <exception cref="ArgumentNullException">
        ///     Thrown if <paramref name="origin"/> is <see langword="null" />.
        /// </exception>
        /// <exception cref="ArgumentNullException">
        ///     Thrown if <paramref name="id"/> is <see langword="null" />.
        /// </exception>
        /// <exception cref="ArgumentNullException">
        ///     Thrown if <paramref name="discoveryInformation"/> is <see langword="null" />.
        /// </exception>
        /// <exception cref="ArgumentNullException">
        ///     Thrown if <paramref name="protocolInformation"/> is <see langword="null" />.
        /// </exception>
        /// <exception cref="ArgumentNullException">
        ///     Thrown if <paramref name="information"/> is <see langword="null" />.
        /// </exception>
        public EndpointConnectMessage(
            EndpointId origin,
            MessageId id,
            DiscoveryInformation discoveryInformation,
            ProtocolInformation protocolInformation,
            ProtocolDescription information)
            : base(origin, id)
        {
            {
                Lokad.Enforce.Argument(() => discoveryInformation);
                Lokad.Enforce.Argument(() => protocolInformation);
                Lokad.Enforce.Argument(() => information);
            }

            DiscoveryInformation = discoveryInformation;
            ProtocolInformation  = protocolInformation;
            Information          = information;
        }
        public void Invoke()
        {
            EndpointInformation processedChannel     = null;
            ProtocolDescription processedDescription = null;
            MessageId           processedMessageId   = null;
            var sink = new Mock <IHandleProtocolHandshakes>();
            {
                sink.Setup(s => s.ContinueHandshakeWith(
                               It.IsAny <EndpointInformation>(),
                               It.IsAny <ProtocolDescription>(),
                               It.IsAny <MessageId>()))
                .Callback <EndpointInformation, ProtocolDescription, MessageId>((e, t, u) =>
                {
                    processedChannel     = e;
                    processedDescription = t;
                    processedMessageId   = u;
                });
            }

            var channelTypes = new[]
            {
                ChannelTemplate.TcpIP
            };
            var systemDiagnostics = new SystemDiagnostics((p, s) => { }, null);

            var action = new EndpointConnectProcessAction(sink.Object, channelTypes, systemDiagnostics);

            var id        = new EndpointId("id");
            var discovery = new DiscoveryInformation(new Uri("http://localhost/discovery/invalid"));
            var protocol  = new ProtocolInformation(
                new Version(1, 0),
                new Uri("http://localhost/protocol/message/invalid"),
                new Uri("http://localhost/protocol/data/invalid"));
            var description = new ProtocolDescription(new List <CommunicationSubject>());
            var msg         = new EndpointConnectMessage(id, discovery, protocol, description);

            action.Invoke(msg);

            Assert.AreEqual(msg.Id, processedMessageId);
            Assert.AreEqual(id, processedChannel.Id);
            Assert.AreSame(discovery, processedChannel.DiscoveryInformation);
            Assert.AreSame(protocol, processedChannel.ProtocolInformation);
            Assert.AreSame(description, processedDescription);
        }
示例#17
0
        /// <summary>
        /// Transfers the stream to the given endpoint.
        /// </summary>
        /// <param name="endpoint">The endpoint to which the data should be send.</param>
        /// <param name="data">The data to be send.</param>
        /// <param name="maximumNumberOfRetries">The maximum number of times the endpoint will try to transfer the data if delivery fails.</param>
        /// <exception cref="ArgumentNullException">
        ///     Thrown if <paramref name="endpoint"/> is <see langword="null" />.
        /// </exception>
        /// <exception cref="ArgumentNullException">
        ///     Thrown if <paramref name="data"/> is <see langword="null" />.
        /// </exception>
        /// <exception cref="ArgumentOutOfRangeException">
        ///     Thrown if <paramref name="maximumNumberOfRetries"/> is smaller than 1.
        /// </exception>
        public void Send(ProtocolInformation endpoint, Stream data, int maximumNumberOfRetries)
        {
            {
                Lokad.Enforce.Argument(() => endpoint);
                Lokad.Enforce.Argument(() => data);
                Lokad.Enforce.With <ArgumentOutOfRangeException>(
                    maximumNumberOfRetries > 0,
                    Resources.Exceptions_Messages_NumberOfRetriesShouldBeLargerThanZero);
            }

            var channel = DataChannelFor(endpoint);
            var msg     = new DataTransferMessage
            {
                SendingEndpoint = m_LocalEndpoint,
                Data            = data,
            };

            channel.Send(msg, maximumNumberOfRetries);
        }
        /// <summary>
        /// Opens the channel and provides information on how to connect to the given channel.
        /// </summary>
        public void OpenChannel()
        {
            lock (m_Lock)
            {
                foreach (var version in ProtocolVersions.SupportedVersions())
                {
                    if (m_MessagePipesByVersion.ContainsKey(version) || m_DataPipesByVersion.ContainsKey(version))
                    {
                        CloseChannel(version);
                    }

                    var dataUri    = CreateAndStoreDataChannelForProtocolVersion(version);
                    var messageUri = CreateAndStoreMessageChannelForProtocolVersion(version);

                    var localConnection = new ProtocolInformation(version, messageUri, dataUri);
                    m_LocalConnectionPoints.Add(localConnection);
                }
            }
        }
示例#19
0
        private IDataTransferingEndpoint DataChannelFor(ProtocolInformation endpoint)
        {
            lock (m_Lock)
            {
                if (!m_EndpointMap.ContainsKey(endpoint))
                {
                    m_EndpointMap.Add(endpoint, new Tuple <IMessageSendingEndpoint, IDataTransferingEndpoint>(null, null));
                }

                if (m_EndpointMap[endpoint].Item2 == null)
                {
                    var dataChannel = m_DataSenderBuilder(endpoint);

                    var tuple = m_EndpointMap[endpoint];
                    m_EndpointMap[endpoint] = new Tuple <IMessageSendingEndpoint, IDataTransferingEndpoint>(tuple.Item1, dataChannel);
                }

                return(m_EndpointMap[endpoint].Item2);
            }
        }
        public void Create()
        {
            var sender    = new EndpointId("sendingEndpoint");
            var discovery = new DiscoveryInformation(new Uri("http://localhost/discovery/invalid"));
            var protocol  = new ProtocolInformation(
                new Version(1, 0),
                new Uri("http://localhost/protocol/message/invalid"),
                new Uri("http://localhost/protocol/data/invalid"));
            var description = new ProtocolDescription(new List <CommunicationSubject>());
            var msg         = new EndpointConnectMessage(
                sender,
                discovery,
                protocol,
                description);

            Assert.IsNotNull(msg.Id);
            Assert.AreSame(sender, msg.Sender);
            Assert.AreSame(discovery, msg.DiscoveryInformation);
            Assert.AreSame(protocol, msg.ProtocolInformation);
            Assert.AreSame(description, msg.Information);
        }
示例#21
0
        /// <summary>
        /// Closes the channel that connects to the given endpoint.
        /// </summary>
        /// <param name="endpoint">The ID number of the endpoint to which the connection should be closed.</param>
        public void CloseChannelTo(ProtocolInformation endpoint)
        {
            lock (m_Lock)
            {
                if (!m_EndpointMap.ContainsKey(endpoint))
                {
                    return;
                }

                var tuple = m_EndpointMap[endpoint];
                m_EndpointMap.Remove(endpoint);

                if (tuple.Item1 != null)
                {
                    tuple.Item1.Dispose();
                }

                if (tuple.Item2 != null)
                {
                    tuple.Item2.Dispose();
                }
            }
        }
示例#22
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);
        }
示例#23
0
        public async Task <Message> ReceiveMessageAsync()
        {
            try
            {
                int bytesRead = await ReadCountAsync(_headerReadBuffer, 0, 16, _fileDescriptors).ConfigureAwait(false);

                if (bytesRead == 0)
                {
                    return(null);
                }
                if (bytesRead != 16)
                {
                    throw new ProtocolException("Header read length mismatch: " + bytesRead + " of expected " + "16");
                }

                EndianFlag    endianness = (EndianFlag)_headerReadBuffer[0];
                MessageReader reader     = new MessageReader(endianness, new ArraySegment <byte>(_headerReadBuffer));

                //discard endian byte, message type and flags, which we don't care about here
                reader.Seek(3);

                byte version = reader.ReadByte();
                if (version != ProtocolInformation.Version)
                {
                    throw new NotSupportedException("Protocol version '" + version.ToString() + "' is not supported");
                }

                uint bodyLength = reader.ReadUInt32();

                //discard _methodSerial
                reader.ReadUInt32();

                uint headerLength = reader.ReadUInt32();

                int bodyLen = (int)bodyLength;
                int toRead  = (int)headerLength;

                //we fixup to include the padding following the header
                toRead = ProtocolInformation.Padded(toRead, 8);

                long msgLength = toRead + bodyLen;
                if (msgLength > ProtocolInformation.MaxMessageLength)
                {
                    throw new ProtocolException("Message length " + msgLength + " exceeds maximum allowed " + ProtocolInformation.MaxMessageLength + " bytes");
                }

                byte[] header = new byte[16 + toRead];
                Array.Copy(_headerReadBuffer, header, 16);
                bytesRead = await ReadCountAsync(header, 16, toRead, _fileDescriptors).ConfigureAwait(false);

                if (bytesRead != toRead)
                {
                    throw new ProtocolException("Message header length mismatch: " + bytesRead + " of expected " + toRead);
                }

                var messageHeader = Header.FromBytes(new ArraySegment <byte>(header));

                byte[] body = null;
                //read the body
                if (bodyLen != 0)
                {
                    body = new byte[bodyLen];

                    bytesRead = await ReadCountAsync(body, 0, bodyLen, _fileDescriptors).ConfigureAwait(false);

                    if (bytesRead != bodyLen)
                    {
                        throw new ProtocolException("Message body length mismatch: " + bytesRead + " of expected " + bodyLen);
                    }
                }

                if (_fileDescriptors.Count < messageHeader.NumberOfFds)
                {
                    throw new ProtocolException("File descriptor length mismatch: " + _fileDescriptors.Count + " of expected " + messageHeader.NumberOfFds);
                }

                Message msg = new Message(
                    messageHeader,
                    body,
                    messageHeader.NumberOfFds == 0 ? null :
                    _fileDescriptors.Count == messageHeader.NumberOfFds ? _fileDescriptors.ToArray() :
                    _fileDescriptors.Take((int)messageHeader.NumberOfFds).ToArray()
                    );

                _fileDescriptors.RemoveRange(0, (int)messageHeader.NumberOfFds);

                return(msg);
            }
            catch
            {
                foreach (var fd in _fileDescriptors)
                {
                    CloseSafeHandle.close(fd.Handle);
                }
                throw;
            }
        }
示例#24
0
        public void TransferData()
        {
            var path = TempFile();

            var text = "Some random text";

            using (var writer = new StreamWriter(path, false))
            {
                writer.Write(text);
            }

            var id           = new EndpointId("a");
            var endpointInfo = new ProtocolInformation(
                ProtocolVersions.V1,
                new Uri("http://localhost/messages"),
                new Uri("http://localhost/data"));
            var template = new Mock <IProtocolChannelTemplate>();

            var messageUri = new Uri("http://localhost/messages/invalid");
            var dataUri    = new Uri("http://localhost/data/invalid");
            var host       = new Mock <IHoldServiceConnections>();
            {
                host.Setup(
                    h =>
                    h.OpenChannel(
                        It.IsAny <IReceiveInformationFromRemoteEndpoints>(),
                        It.IsAny <Func <ServiceHost, ServiceEndpoint> >()))
                .Returns <IReceiveInformationFromRemoteEndpoints, Func <ServiceHost, ServiceEndpoint> >(
                    (r, f) => r is IMessagePipe ? messageUri : dataUri)
                .Verifiable();
                host.Setup(h => h.CloseConnection())
                .Verifiable();
            }

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

            var messagePipe = new Mock <IMessagePipe>();
            Func <Version, Tuple <Type, IMessagePipe> > messageReceiverBuilder =
                version => new Tuple <Type, IMessagePipe>(typeof(IMessagePipe), messagePipe.Object);

            var dataPipe = new Mock <IDataPipe>();
            Func <Version, Tuple <Type, IDataPipe> > dataReceiverBuilder =
                version => new Tuple <Type, IDataPipe>(typeof(IDataPipe), dataPipe.Object);

            var sendingEndpoint = new Mock <ISendingEndpoint>();
            {
                sendingEndpoint.Setup(e => e.KnownEndpoints())
                .Returns(new[] { endpointInfo });
                sendingEndpoint.Setup(e => e.CloseChannelTo(It.IsAny <ProtocolInformation>()))
                .Verifiable();
                sendingEndpoint.Setup(e => e.Send(It.IsAny <ProtocolInformation>(), It.IsAny <Stream>(), It.IsAny <int>()))
                .Callback <ProtocolInformation, Stream, int>(
                    (e, m, r) =>
                {
                    string fileText;
                    using (var reader = new StreamReader(m))
                    {
                        fileText = reader.ReadToEnd();
                    }

                    Assert.AreEqual(text, fileText);
                })
                .Verifiable();
            }

            BuildSendingEndpoint senderBuilder = (endpoint, builder, endpointBuilder) => sendingEndpoint.Object;

            var messageEndpoint = new Mock <IMessageSendingEndpoint>();
            Func <Version, Uri, IMessageSendingEndpoint> versionedMessageSenderBuilder = (version, uri) => messageEndpoint.Object;

            var dataEndpoint = new Mock <IDataTransferingEndpoint>();
            Func <Version, Uri, IDataTransferingEndpoint> versionedDataSenderBuilder = (version, uri) => dataEndpoint.Object;

            var channel = new ProtocolChannel(
                id,
                template.Object,
                hostBuilder,
                messageReceiverBuilder,
                dataReceiverBuilder,
                senderBuilder,
                versionedMessageSenderBuilder,
                versionedDataSenderBuilder);

            channel.OpenChannel();
            var protocols = channel.LocalConnectionPoints().ToList();

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

            var task = channel.TransferData(endpointInfo, path, new CancellationToken(), new CurrentThreadTaskScheduler(), 1);

            task.Wait();
            sendingEndpoint.Verify(e => e.Send(It.IsAny <ProtocolInformation>(), It.IsAny <Stream>(), It.IsAny <int>()), Times.Once());
        }
示例#25
0
        public void Send()
        {
            var id           = new EndpointId("a");
            var endpointInfo = new ProtocolInformation(
                ProtocolVersions.V1,
                new Uri("http://localhost/messages"),
                new Uri("http://localhost/data"));
            var template = new Mock <IProtocolChannelTemplate>();

            var messageUri = new Uri("http://localhost/messages/invalid");
            var dataUri    = new Uri("http://localhost/data/invalid");
            var host       = new Mock <IHoldServiceConnections>();
            {
                host.Setup(
                    h =>
                    h.OpenChannel(
                        It.IsAny <IReceiveInformationFromRemoteEndpoints>(),
                        It.IsAny <Func <ServiceHost, ServiceEndpoint> >()))
                .Returns <IReceiveInformationFromRemoteEndpoints, Func <ServiceHost, ServiceEndpoint> >(
                    (r, f) => r is IMessagePipe ? messageUri : dataUri)
                .Verifiable();
                host.Setup(h => h.CloseConnection())
                .Verifiable();
            }

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

            var messagePipe = new Mock <IMessagePipe>();
            Func <Version, Tuple <Type, IMessagePipe> > messageReceiverBuilder =
                version => new Tuple <Type, IMessagePipe>(typeof(IMessagePipe), messagePipe.Object);

            var dataPipe = new Mock <IDataPipe>();
            Func <Version, Tuple <Type, IDataPipe> > dataReceiverBuilder =
                version => new Tuple <Type, IDataPipe>(typeof(IDataPipe), dataPipe.Object);

            var msg             = new SuccessMessage(id, new MessageId());
            var sendingEndpoint = new Mock <ISendingEndpoint>();
            {
                sendingEndpoint.Setup(e => e.KnownEndpoints())
                .Returns(new[] { endpointInfo });
                sendingEndpoint.Setup(e => e.CloseChannelTo(It.IsAny <ProtocolInformation>()))
                .Verifiable();
                sendingEndpoint.Setup(e => e.Send(It.IsAny <ProtocolInformation>(), It.IsAny <ICommunicationMessage>(), It.IsAny <int>()))
                .Callback <ProtocolInformation, ICommunicationMessage, int>((e, m, r) => Assert.AreSame(msg, m))
                .Verifiable();
            }

            BuildSendingEndpoint senderBuilder = (endpoint, builder, endpointBuilder) => sendingEndpoint.Object;

            var messageEndpoint = new Mock <IMessageSendingEndpoint>();
            Func <Version, Uri, IMessageSendingEndpoint> versionedMessageSenderBuilder = (version, uri) => messageEndpoint.Object;

            var dataEndpoint = new Mock <IDataTransferingEndpoint>();
            Func <Version, Uri, IDataTransferingEndpoint> versionedDataSenderBuilder = (version, uri) => dataEndpoint.Object;

            var channel = new ProtocolChannel(
                id,
                template.Object,
                hostBuilder,
                messageReceiverBuilder,
                dataReceiverBuilder,
                senderBuilder,
                versionedMessageSenderBuilder,
                versionedDataSenderBuilder);

            channel.OpenChannel();
            var protocols = channel.LocalConnectionPoints().ToList();

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

            channel.Send(endpointInfo, msg, 1);
            sendingEndpoint.Verify(e => e.Send(It.IsAny <ProtocolInformation>(), It.IsAny <ICommunicationMessage>(), It.IsAny <int>()), Times.Once());
        }
示例#26
0
        Message ReadMessageReal()
        {
            byte[]      header  = null;
            byte[]      body    = null;
            UnixFDArray fdArray = Connection.UnixFDSupported ? new UnixFDArray() : null;

            int read;

            //16 bytes is the size of the fixed part of the header
            if (readBuffer == null)
            {
                readBuffer = new byte[16];
            }
            byte[] hbuf = readBuffer;

            read = Read(hbuf, 0, 16, fdArray);

            if (read == 0)
            {
                return(null);
            }

            if (read != 16)
            {
                throw new Exception("Header read length mismatch: " + read + " of expected " + "16");
            }

            EndianFlag    endianness = (EndianFlag)hbuf[0];
            MessageReader reader     = new MessageReader(endianness, hbuf);

            //discard endian byte, message type and flags, which we don't care about here
            reader.Seek(3);

            byte version = reader.ReadByte();

            if (version < ProtocolInformation.MinVersion || version > ProtocolInformation.MaxVersion)
            {
                throw new NotSupportedException("Protocol version '" + version.ToString() + "' is not supported");
            }

            if (ProtocolInformation.Verbose)
            {
                if (version != ProtocolInformation.Version)
                {
                    Console.Error.WriteLine("Warning: Protocol version '" + version.ToString() + "' is not explicitly supported but may be compatible");
                }
            }

            uint bodyLength = reader.ReadUInt32();

            //discard serial
            reader.ReadUInt32();
            uint headerLength = reader.ReadUInt32();

            int bodyLen = (int)bodyLength;
            int toRead  = (int)headerLength;

            //we fixup to include the padding following the header
            toRead = ProtocolInformation.Padded(toRead, 8);

            long msgLength = toRead + bodyLen;

            if (msgLength > ProtocolInformation.MaxMessageLength)
            {
                throw new Exception("Message length " + msgLength + " exceeds maximum allowed " + ProtocolInformation.MaxMessageLength + " bytes");
            }

            header = new byte[16 + toRead];
            Array.Copy(hbuf, header, 16);

            read = Read(header, 16, toRead, fdArray);

            if (read != toRead)
            {
                throw new Exception("Message header length mismatch: " + read + " of expected " + toRead);
            }

            //read the body
            if (bodyLen != 0)
            {
                body = new byte[bodyLen];

                read = Read(body, 0, bodyLen, fdArray);

                if (read != bodyLen)
                {
                    throw new Exception("Message body length mismatch: " + read + " of expected " + bodyLen);
                }
            }

            Message msg = Message.FromReceivedBytes(Connection, header, body, fdArray);

            return(msg);
        }
        public void UploadDataWithUncontactableEndpoint()
        {
            var endpoints = new Mock <IStoreInformationAboutEndpoints>();
            {
                endpoints.Setup(e => e.CanCommunicateWithEndpoint(It.IsAny <EndpointId>()))
                .Returns(false);
            }

            var protocolInfo = new ProtocolInformation(
                new Version(1, 0),
                new Uri("net.pipe://localhost/protocol/message/invalid"),
                new Uri("net.pipe://localhost/protocol/data/invalid"));
            var endpoint = new EndpointId("A");
            var file     = "B";
            var channel  = new Mock <IProtocolChannel>();
            {
                channel.Setup(c => c.OpenChannel())
                .Verifiable();
                channel.Setup(c => c.LocalConnectionPointForVersion(It.IsAny <Version>()))
                .Returns(protocolInfo);
                channel.Setup(
                    c => c.TransferData(
                        It.IsAny <ProtocolInformation>(),
                        It.IsAny <string>(),
                        It.IsAny <CancellationToken>(),
                        It.IsAny <TaskScheduler>(),
                        It.IsAny <int>()))
                .Callback <ProtocolInformation, string, CancellationToken, TaskScheduler, int>(
                    (e, p, c, s, r) =>
                {
                    Assert.AreSame(protocolInfo, e);
                    Assert.AreSame(file, p);
                })
                .Returns <EndpointId, string, CancellationToken, TaskScheduler>(
                    (e, p, c, s) => Task.Factory.StartNew(() => { }, c, TaskCreationOptions.None, s))
                .Verifiable();
            }

            var pipe = new Mock <IDirectIncomingMessages>();
            Func <ChannelTemplate, EndpointId, Tuple <IProtocolChannel, IDirectIncomingMessages> > channelBuilder =
                (template, id) =>
            {
                return(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();

            Assert.Throws <EndpointNotContactableException>(
                () => layer.UploadData(endpoint, file, new CancellationToken(), new CurrentThreadTaskScheduler(), 1));
            channel.Verify(c => c.OpenChannel(), Times.Once());
            channel.Verify(
                c => c.TransferData(
                    It.IsAny <ProtocolInformation>(),
                    It.IsAny <string>(),
                    It.IsAny <CancellationToken>(),
                    It.IsAny <TaskScheduler>(),
                    It.IsAny <int>()),
                Times.Never());
        }
示例#28
0
        /// <summary>
        /// Convert Major/Minor version info in the ProtocolInformation object to a known R2000ProtocolVersion
        /// </summary>
        /// <param name="pi"></param>
        /// <returns></returns>
        public static R2000ProtocolVersion GetProtocolVersion(this ProtocolInformation pi)
        {
            var asInt = pi.VersionMajor * 100 + pi.VersionMinor;

            return((R2000ProtocolVersion)asInt);
        }
 private IDataTransferingEndpoint BuildDataTransferProxy(ProtocolInformation info)
 {
     return(m_VersionedDataSenderBuilder(info.Version, info.DataAddress));
 }
 private IMessageSendingEndpoint BuildMessageSendingProxy(ProtocolInformation info)
 {
     return(m_VersionedMessageSenderBuilder(info.Version, info.MessageAddress));
 }