예제 #1
0
        /// <summary>
        /// Gets the versions.
        /// </summary>
        /// <returns>
        /// Returns an enumerable with the MongoDb versions.
        /// </returns>
        /// <exception cref="NAMEException">Thrown when an unexpected exception happens.</exception>
        public override async Task <IEnumerable <DependencyVersion> > GetVersions()
        {
            var versions = new List <DependencyVersion>();

            if (!this.connectionStringProvider.TryGetConnectionString(out string connectionString))
            {
                throw new ConnectionStringNotFoundException(this.connectionStringProvider.ToString());
            }

            var connectionStringBuilder = new MongoConnectionStringBuilder(connectionString);

            byte[] message = this.CreateServerStatusMessagePayload(connectionStringBuilder);

            foreach (var mongoEndpoint in connectionStringBuilder.Servers)
            {
                using (var client = await this.OpenTcpClient(mongoEndpoint.Host, mongoEndpoint.Port, SupportedDependencies.MongoDb.ToString()))
                {
                    await client.GetStream().WriteAsync(message, 0, message.Length, default(CancellationToken)).ConfigureAwait(false);

                    await Task.Delay(100).ConfigureAwait(false);

                    BSONObject obj = ExtractServerStatusFromResponse(client);
                    versions.Add(DependencyVersionParser.Parse(obj["version"].stringValue, false));
                }
            }

            return(versions);
        }
예제 #2
0
        private byte[] CreateServerStatusMessagePayload(MongoConnectionStringBuilder connectionStringBuilder)
        {
            byte[] message;
            int    commandLength;

            //Write the message first because we need the it's length
            using (var commandMemoryStream = new MemoryStream())
                using (var commandWriter = new BinaryWriter(commandMemoryStream, new UTF8Encoding(), true))
                {
                    //Query options
                    commandWriter.Write(0);
                    //Collection name
                    commandWriter.Write($"{connectionStringBuilder.Database}.$cmd".ToArray());
                    //cstring's require a \x00 at the end.
                    commandWriter.Write('\x00');
                    //Number to skip
                    commandWriter.Write(0);
                    //Number to return
                    commandWriter.Write(-1);

                    var commandBSON = new BSONObject
                    {
                        ["serverStatus"] = 1.0
                    };
                    commandWriter.Write(SimpleBSON.Dump(commandBSON));
                    commandWriter.Flush();

                    commandLength = (int)commandMemoryStream.Length;
                    message       = new byte[16 + commandLength];
                    Array.Copy(commandMemoryStream.ToArray(), 0, message, 16, commandLength);
                }

            using (var messageMemoryStream = new MemoryStream(message))
                using (var completeMessageWriter = new BinaryWriter(messageMemoryStream, new UTF8Encoding(), true))
                {
                    //Message length
                    completeMessageWriter.Write(16 + commandLength);
                    //Request Id
                    completeMessageWriter.Write(0);
                    //Response To
                    completeMessageWriter.Write(0);
                    //Operation Code
                    completeMessageWriter.Write(2004);
                    completeMessageWriter.Flush();
                }
            return(message);
        }