From 2f438f1ea706f5bbd4b27c89a8b9ca8ecd624766 Mon Sep 17 00:00:00 2001 From: Steve Wagner Date: Thu, 6 May 2010 09:39:15 +0200 Subject: [PATCH] Refactored ISerializationFactory to use GetBsonWriterSettings instead of GetBsonDescriptor directly. --- .../Connections/TestConnection.cs | 124 +++++++++--------- .../UnitTests/IO/TestQueryMessage.cs | 93 +++++++------ source/MongoDB/Connections/Connection.cs | 4 +- source/MongoDB/Cursor_1.cs | 16 ++- source/MongoDB/MongoCollection_1.cs | 35 ++--- source/MongoDB/Protocol/DeleteMessage.cs | 6 +- source/MongoDB/Protocol/GetMoreMessage.cs | 2 +- source/MongoDB/Protocol/InsertMessage.cs | 16 ++- source/MongoDB/Protocol/KillCursorsMessage.cs | 2 +- source/MongoDB/Protocol/MsgMessage.cs | 2 +- source/MongoDB/Protocol/QueryMessage.cs | 24 ++-- source/MongoDB/Protocol/RequestMessageBase.cs | 16 ++- source/MongoDB/Protocol/UpdateMessage.cs | 6 +- .../Serialization/ISerializationFactory.cs | 9 +- 14 files changed, 181 insertions(+), 174 deletions(-) diff --git a/source/MongoDB.Tests/IntegrationTests/Connections/TestConnection.cs b/source/MongoDB.Tests/IntegrationTests/Connections/TestConnection.cs index d0bd832d..adf3150b 100644 --- a/source/MongoDB.Tests/IntegrationTests/Connections/TestConnection.cs +++ b/source/MongoDB.Tests/IntegrationTests/Connections/TestConnection.cs @@ -1,68 +1,72 @@ -using System; using System.IO; +using System.Text; using MongoDB.Bson; using MongoDB.Connections; using MongoDB.Protocol; using NUnit.Framework; -namespace MongoDB.IntegrationTests.Connections -{ - [TestFixture()] - public class TestConnection - { - [Test] - public void TestSendQueryMessage(){ - //Connection conn = new Connection("10.141.153.2"); - Connection conn = ConnectionFactory.GetConnection(string.Empty); - conn.Open(); - - var qmsg = generateQueryMessage(); - conn.SendTwoWayMessage(qmsg); - - conn.Close(); - } - - [Test] - public void TestReconnectOnce(){ - Connection conn = ConnectionFactory.GetConnection(string.Empty); - conn.Open(); - - WriteBadMessage(conn); - try{ - var qmsg = generateQueryMessage(); - conn.SendTwoWayMessage(qmsg); - - }catch(IOException){ - //Should be able to resend. - Assert.IsTrue(conn.State == ConnectionState.Opened); - var qmsg = generateQueryMessage(); - ReplyMessage rmsg = conn.SendTwoWayMessage(qmsg); - Assert.IsNotNull(rmsg); - - } - } - - protected void WriteBadMessage(Connection conn){ - //Write a bad message to the socket to force mongo to shut down our connection. - BinaryWriter writer = new BinaryWriter(conn.GetStream()); - System.Text.UTF8Encoding encoding=new System.Text.UTF8Encoding(); - Byte[] msg = encoding.GetBytes("Goodbye MongoDB!"); - writer.Write(16 + msg.Length + 1); - writer.Write(1); - writer.Write(1); - writer.Write(1001); - writer.Write(msg); - writer.Write((byte)0); - } - - protected QueryMessage generateQueryMessage(){ - Document qdoc = new Document(); - qdoc.Add("listDatabases", 1.0); +namespace MongoDB.IntegrationTests.Connections +{ + [TestFixture] + public class TestConnection + { + protected void WriteBadMessage(Connection conn) + { + //Write a bad message to the socket to force mongo to shut down our connection. + var writer = new BinaryWriter(conn.GetStream()); + var encoding = new UTF8Encoding(); + var msg = encoding.GetBytes("Goodbye MongoDB!"); + writer.Write(16 + msg.Length + 1); + writer.Write(1); + writer.Write(1); + writer.Write(1001); + writer.Write(msg); + writer.Write((byte)0); + } + + protected QueryMessage GenerateQueryMessage() + { + var qdoc = new Document {{"listDatabases", 1.0}}; //QueryMessage qmsg = new QueryMessage(qdoc,"system.namespaces"); - var qmsg = new QueryMessage(new BsonDocumentDescriptor(), qdoc, "admin.$cmd"); - qmsg.NumberToReturn = -1; - - return qmsg; - } - } + return new QueryMessage(new BsonWriterSettings(), qdoc, "admin.$cmd") + { + NumberToReturn = -1 + }; + } + + [Test] + public void TestReconnectOnce() + { + var conn = ConnectionFactory.GetConnection(string.Empty); + conn.Open(); + + WriteBadMessage(conn); + try + { + var qmsg = GenerateQueryMessage(); + conn.SendTwoWayMessage(qmsg); + } + catch(IOException) + { + //Should be able to resend. + Assert.IsTrue(conn.State == ConnectionState.Opened); + var qmsg = GenerateQueryMessage(); + var rmsg = conn.SendTwoWayMessage(qmsg); + Assert.IsNotNull(rmsg); + } + } + + [Test] + public void TestSendQueryMessage() + { + //Connection conn = new Connection("10.141.153.2"); + var conn = ConnectionFactory.GetConnection(string.Empty); + conn.Open(); + + var qmsg = GenerateQueryMessage(); + conn.SendTwoWayMessage(qmsg); + + conn.Close(); + } + } } \ No newline at end of file diff --git a/source/MongoDB.Tests/UnitTests/IO/TestQueryMessage.cs b/source/MongoDB.Tests/UnitTests/IO/TestQueryMessage.cs index 805dfc10..89407b50 100644 --- a/source/MongoDB.Tests/UnitTests/IO/TestQueryMessage.cs +++ b/source/MongoDB.Tests/UnitTests/IO/TestQueryMessage.cs @@ -4,52 +4,51 @@ using MongoDB.Protocol; using NUnit.Framework; -namespace MongoDB.UnitTests.IO -{ - [TestFixture] - public class TestQueryMessage - { - [Test] - public void TestAllBytesWritten() - { - Document query = new Document(); - query.Add("col1", 1); - - var msg = new QueryMessage(new BsonDocumentDescriptor(),query,"TestDB.TestCol"); - MemoryStream buffer = new MemoryStream(); - msg.Write(buffer); - - Byte[] output = buffer.ToArray(); - String hexdump = BitConverter.ToString(output); - //Console.WriteLine("Dump: " + hexdump); - - Assert.IsTrue(output.Length > 0); - Assert.AreEqual("3A-00-00-00-00-00-00-00-00-00-00-00-D4-07-00-00-00-00-00-00-54-65-73-74-44-42-2E-54-65-73-74-43-6F-6C-00-00-00-00-00-00-00-00-00-0F-00-00-00-10-63-6F-6C-31-00-01-00-00-00-00", hexdump); - - } - - [Test] - public void TestWriteMessageTwice(){ - string expectedHex = "3A-00-00-00-00-00-00-00-00-00-00-00-D4-07-00-00-00-00-00-00-54-65-73-74-44-42-2E-54-65-73-74-43-6F-6C-00-00-00-00-00-00-00-00-00-0F-00-00-00-10-63-6F-6C-31-00-01-00-00-00-00"; - Document query = new Document(); +namespace MongoDB.UnitTests.IO +{ + [TestFixture] + public class TestQueryMessage + { + [Test] + public void TestAllBytesWritten() + { + var query = new Document {{"col1", 1}}; + + var msg = new QueryMessage(new BsonWriterSettings(), query, "TestDB.TestCol"); + var buffer = new MemoryStream(); + msg.Write(buffer); + + var output = buffer.ToArray(); + var hexdump = BitConverter.ToString(output); + //Console.WriteLine("Dump: " + hexdump); + + Assert.IsTrue(output.Length > 0); + Assert.AreEqual("3A-00-00-00-00-00-00-00-00-00-00-00-D4-07-00-00-00-00-00-00-54-65-73-74-44-42-2E-54-65-73-74-43-6F-6C-00-00-00-00-00-00-00-00-00-0F-00-00-00-10-63-6F-6C-31-00-01-00-00-00-00", + hexdump); + } + + [Test] + public void TestWriteMessageTwice() + { + const string expectedHex = "3A-00-00-00-00-00-00-00-00-00-00-00-D4-07-00-00-00-00-00-00-54-65-73-74-44-42-2E-54-65-73-74-43-6F-6C-00-00-00-00-00-00-00-00-00-0F-00-00-00-10-63-6F-6C-31-00-01-00-00-00-00"; + var query = new Document(); query.Add("col1", 1); - - var msg = new QueryMessage(new BsonDocumentDescriptor(),query,"TestDB.TestCol"); - MemoryStream buffer = new MemoryStream(); - msg.Write(buffer); - - Byte[] output = buffer.ToArray(); - String hexdump = BitConverter.ToString(output); - - MemoryStream buffer2 = new MemoryStream(); - msg.Write(buffer2); - - Byte[] output2 = buffer.ToArray(); - String hexdump2 = BitConverter.ToString(output2); - - Assert.AreEqual(expectedHex,hexdump); - Assert.AreEqual(hexdump,hexdump2); - - } - } + + var msg = new QueryMessage(new BsonWriterSettings(), query, "TestDB.TestCol"); + var buffer = new MemoryStream(); + msg.Write(buffer); + + var output = buffer.ToArray(); + var hexdump = BitConverter.ToString(output); + + var buffer2 = new MemoryStream(); + msg.Write(buffer2); + + var output2 = buffer.ToArray(); + var hexdump2 = BitConverter.ToString(output2); + + Assert.AreEqual(expectedHex, hexdump); + Assert.AreEqual(hexdump, hexdump2); + } + } } \ No newline at end of file diff --git a/source/MongoDB/Connections/Connection.cs b/source/MongoDB/Connections/Connection.cs index df7d618f..4b13efdb 100644 --- a/source/MongoDB/Connections/Connection.cs +++ b/source/MongoDB/Connections/Connection.cs @@ -234,9 +234,9 @@ public T SendCommand(ISerializationFactory factory, string database, Type roo private T SendCommandCore(ISerializationFactory factory, string database, Type rootType, object command) where T : class { - var descriptor = factory.GetBsonDescriptor(rootType); + var writerSettings = factory.GetBsonWriterSettings(rootType); - var query = new QueryMessage(descriptor) + var query = new QueryMessage(writerSettings) { FullCollectionName = database + ".$cmd", NumberToReturn = -1, diff --git a/source/MongoDB/Cursor_1.cs b/source/MongoDB/Cursor_1.cs index 2a113140..edce7d43 100644 --- a/source/MongoDB/Cursor_1.cs +++ b/source/MongoDB/Cursor_1.cs @@ -262,11 +262,17 @@ public Cursor(ISerializationFactory serializationFactory, Connection connection, /// /// Retrieves the data. /// - private void RetrieveData(){ - var descriptor = _serializationFactory.GetBsonDescriptor(typeof(T)); - - var query = new QueryMessage(descriptor) { FullCollectionName = FullCollectionName, Query = BuildSpec(), - NumberToReturn = _limit, NumberToSkip = _skip, Options = _options }; + private void RetrieveData(){ + var writerSettings = _serializationFactory.GetBsonWriterSettings(typeof(T)); + + var query = new QueryMessage(writerSettings) + { + FullCollectionName = FullCollectionName, + Query = BuildSpec(), + NumberToReturn = _limit, + NumberToSkip = _skip, + Options = _options + }; if (_fields != null) query.ReturnFieldSelector = _fields; diff --git a/source/MongoDB/MongoCollection_1.cs b/source/MongoDB/MongoCollection_1.cs index 8596a682..4a390ebf 100644 --- a/source/MongoDB/MongoCollection_1.cs +++ b/source/MongoDB/MongoCollection_1.cs @@ -304,9 +304,9 @@ public MongoCollection(MongoConfiguration configuration, Connection connection, } var rootType = typeof(T); - var bsonDescriptor = _configuration.SerializationFactory.GetBsonDescriptor(rootType); + var writerSettings = _configuration.SerializationFactory.GetBsonWriterSettings(rootType); - var insertMessage = new InsertMessage(bsonDescriptor) + var insertMessage = new InsertMessage(writerSettings) { FullCollectionName = FullName }; @@ -353,12 +353,14 @@ public MongoCollection(MongoConfiguration configuration, Connection connection, /// An empty document will match all documents in the collection and effectively truncate it. /// public void Delete(object selector){ - var descriptor = _configuration.SerializationFactory.GetBsonDescriptor(typeof(T)); - - var deleteMessage = new DeleteMessage(descriptor) { FullCollectionName = FullName, Selector = selector }; - + var writerSettings = _configuration.SerializationFactory.GetBsonWriterSettings(typeof(T)); + try { - _connection.SendMessage(deleteMessage); + _connection.SendMessage(new DeleteMessage(writerSettings) + { + FullCollectionName = FullName, + Selector = selector + }); } catch (IOException exception) { throw new MongoConnectionException("Could not delete document, communication failure", _connection, exception); } @@ -427,17 +429,16 @@ public void Update(object document, bool safemode) /// The query spec to find the document to update. /// public void Update(object document, object selector, UpdateFlags flags){ - var descriptor = _configuration.SerializationFactory.GetBsonDescriptor(typeof(T)); - - var updateMessage = new UpdateMessage(descriptor){ - FullCollectionName = FullName, - Selector = selector, - Document = document, - Flags = (int)flags - }; - + var writerSettings = _configuration.SerializationFactory.GetBsonWriterSettings(typeof(T)); + try { - _connection.SendMessage(updateMessage); + _connection.SendMessage(new UpdateMessage(writerSettings) + { + FullCollectionName = FullName, + Selector = selector, + Document = document, + Flags = (int)flags + }); } catch (IOException exception) { throw new MongoConnectionException("Could not update document, communication failure", _connection, exception); } diff --git a/source/MongoDB/Protocol/DeleteMessage.cs b/source/MongoDB/Protocol/DeleteMessage.cs index ef046071..97ae7277 100644 --- a/source/MongoDB/Protocol/DeleteMessage.cs +++ b/source/MongoDB/Protocol/DeleteMessage.cs @@ -19,9 +19,9 @@ public class DeleteMessage : RequestMessageBase /// /// Initializes a new instance of the class. /// - /// The object descriptor. - public DeleteMessage(IBsonObjectDescriptor objectDescriptor) - : base(objectDescriptor){ + /// The bson writer settings. + public DeleteMessage(BsonWriterSettings bsonWriterSettings) + : base(bsonWriterSettings){ Header = new MessageHeader(OpCode.Delete); } diff --git a/source/MongoDB/Protocol/GetMoreMessage.cs b/source/MongoDB/Protocol/GetMoreMessage.cs index 5d8d337b..39e75881 100644 --- a/source/MongoDB/Protocol/GetMoreMessage.cs +++ b/source/MongoDB/Protocol/GetMoreMessage.cs @@ -33,7 +33,7 @@ public GetMoreMessage(string fullCollectionName, long cursorId) /// The cursor id. /// The number to return. public GetMoreMessage(string fullCollectionName, long cursorId, int numberToReturn) - : base(new BsonDocumentDescriptor()) + : base(new BsonWriterSettings()) { Header = new MessageHeader(OpCode.GetMore); FullCollectionName = fullCollectionName; diff --git a/source/MongoDB/Protocol/InsertMessage.cs b/source/MongoDB/Protocol/InsertMessage.cs index a46c3b39..7db25e0c 100644 --- a/source/MongoDB/Protocol/InsertMessage.cs +++ b/source/MongoDB/Protocol/InsertMessage.cs @@ -18,16 +18,18 @@ namespace MongoDB.Protocol /// public class InsertMessage : MessageBase, IRequestMessage { - private readonly IBsonObjectDescriptor _objectDescriptor; + private readonly BsonWriterSettings _bsonWriterSettings; private readonly List _chunks = new List(); /// /// Initializes a new instance of the class. /// - public InsertMessage(IBsonObjectDescriptor objectDescriptor){ - if(objectDescriptor == null) - throw new ArgumentNullException("objectDescriptor"); - _objectDescriptor = objectDescriptor; + public InsertMessage(BsonWriterSettings bsonWriterSettings) + { + if(bsonWriterSettings == null) + throw new ArgumentNullException("bsonWriterSettings"); + + _bsonWriterSettings = bsonWriterSettings; Header = new MessageHeader(OpCode.Insert); } @@ -49,7 +51,7 @@ public class InsertMessage : MessageBase, IRequestMessage /// The stream. public void Write(Stream stream){ var bstream = new BufferedStream(stream); - var bwriter = new BsonWriter(bstream, _objectDescriptor); + var bwriter = new BsonWriter(bstream, _bsonWriterSettings); ChunkMessage(bwriter); @@ -103,7 +105,7 @@ public class InsertMessage : MessageBase, IRequestMessage protected void WriteChunk(Stream stream, MessageChunk chunk){ WriteHeader(new BinaryWriter(stream), chunk.Size); - var writer = new BsonWriter(stream, _objectDescriptor); + var writer = new BsonWriter(stream, _bsonWriterSettings); writer.WriteValue(BsonType.Integer, 0); writer.Write(FullCollectionName, false); diff --git a/source/MongoDB/Protocol/KillCursorsMessage.cs b/source/MongoDB/Protocol/KillCursorsMessage.cs index efafd312..f4877445 100644 --- a/source/MongoDB/Protocol/KillCursorsMessage.cs +++ b/source/MongoDB/Protocol/KillCursorsMessage.cs @@ -21,7 +21,7 @@ public class KillCursorsMessage : RequestMessageBase /// Initializes a new instance of the class. /// public KillCursorsMessage() - :base(new BsonDocumentDescriptor()){ + :base(new BsonWriterSettings()){ Header = new MessageHeader(OpCode.KillCursors); } diff --git a/source/MongoDB/Protocol/MsgMessage.cs b/source/MongoDB/Protocol/MsgMessage.cs index d4895705..28e41f47 100644 --- a/source/MongoDB/Protocol/MsgMessage.cs +++ b/source/MongoDB/Protocol/MsgMessage.cs @@ -18,7 +18,7 @@ public class MsgMessage : RequestMessageBase /// Initializes a new instance of the class. /// public MsgMessage() - : base(new BsonDocumentDescriptor()){ + : base(new BsonWriterSettings()){ Header = new MessageHeader(OpCode.Msg); } diff --git a/source/MongoDB/Protocol/QueryMessage.cs b/source/MongoDB/Protocol/QueryMessage.cs index 3da0a448..d9ef58d4 100644 --- a/source/MongoDB/Protocol/QueryMessage.cs +++ b/source/MongoDB/Protocol/QueryMessage.cs @@ -22,51 +22,51 @@ public class QueryMessage : RequestMessageBase /// /// Initializes a new instance of the class. /// - /// The object descriptor. - public QueryMessage(IBsonObjectDescriptor objectDescriptor) - : base(objectDescriptor){ + /// The bson writer settings. + public QueryMessage(BsonWriterSettings bsonWriterSettings) + : base(bsonWriterSettings){ Header = new MessageHeader(OpCode.Query); } /// /// Initializes a new instance of the class. /// - /// The object descriptor. + /// The bson writer settings. /// The query. /// Full name of the collection. - public QueryMessage(IBsonObjectDescriptor objectDescriptor, object query, String fullCollectionName) - : this(objectDescriptor, query, fullCollectionName, 0, 0){ + public QueryMessage(BsonWriterSettings bsonWriterSettings, object query, String fullCollectionName) + : this(bsonWriterSettings, query, fullCollectionName, 0, 0){ } /// /// Initializes a new instance of the class. /// - /// The object descriptor. + /// The bson writer settings. /// The query. /// Full name of the collection. /// The number to return. /// The number to skip. - public QueryMessage(IBsonObjectDescriptor objectDescriptor, object query, String fullCollectionName, Int32 numberToReturn, Int32 numberToSkip) - : this(objectDescriptor, query, fullCollectionName, numberToReturn, numberToSkip, null) + public QueryMessage(BsonWriterSettings bsonWriterSettings, object query, String fullCollectionName, Int32 numberToReturn, Int32 numberToSkip) + : this(bsonWriterSettings, query, fullCollectionName, numberToReturn, numberToSkip, null) { } /// /// Initializes a new instance of the class. /// - /// The object descriptor. + /// The bson writer settings. /// The query. /// Full name of the collection. /// The number to return. /// The number to skip. /// The return field selector. - public QueryMessage(IBsonObjectDescriptor objectDescriptor, + public QueryMessage(BsonWriterSettings bsonWriterSettings, object query, String fullCollectionName, Int32 numberToReturn, Int32 numberToSkip, object returnFieldSelector) - : base(objectDescriptor) + : base(bsonWriterSettings) { Header = new MessageHeader(OpCode.Query); Query = query; diff --git a/source/MongoDB/Protocol/RequestMessageBase.cs b/source/MongoDB/Protocol/RequestMessageBase.cs index 8380ca6d..11864467 100644 --- a/source/MongoDB/Protocol/RequestMessageBase.cs +++ b/source/MongoDB/Protocol/RequestMessageBase.cs @@ -9,16 +9,17 @@ namespace MongoDB.Protocol /// public abstract class RequestMessageBase : MessageBase, IRequestMessage { - private readonly IBsonObjectDescriptor _objectDescriptor; + private readonly BsonWriterSettings _bsonWriterSettings; /// /// Initializes a new instance of the class. /// - /// The object descriptor. - protected RequestMessageBase(IBsonObjectDescriptor objectDescriptor){ - if(objectDescriptor == null) - throw new ArgumentNullException("objectDescriptor"); - _objectDescriptor = objectDescriptor; + /// The bson writer settings. + protected RequestMessageBase(BsonWriterSettings bsonWriterSettings){ + if(bsonWriterSettings == null) + throw new ArgumentNullException("bsonWriterSettings"); + + _bsonWriterSettings = bsonWriterSettings; } /// @@ -29,11 +30,12 @@ public abstract class RequestMessageBase : MessageBase, IRequestMessage var header = Header; var bstream = new BufferedStream(stream); var writer = new BinaryWriter(bstream); - var bwriter = new BsonWriter(bstream, _objectDescriptor); + var bwriter = new BsonWriter(bstream, _bsonWriterSettings); Header.MessageLength += CalculateBodySize(bwriter); if(Header.MessageLength > MaximumMessageSize) throw new MongoException("Maximum message length exceeded"); + writer.Write(header.MessageLength); writer.Write(header.RequestId); writer.Write(header.ResponseTo); diff --git a/source/MongoDB/Protocol/UpdateMessage.cs b/source/MongoDB/Protocol/UpdateMessage.cs index 8157612c..8495a8aa 100644 --- a/source/MongoDB/Protocol/UpdateMessage.cs +++ b/source/MongoDB/Protocol/UpdateMessage.cs @@ -20,9 +20,9 @@ public class UpdateMessage : RequestMessageBase /// /// Initializes a new instance of the class. /// - /// The object descriptor. - public UpdateMessage(IBsonObjectDescriptor objectDescriptor) - : base(objectDescriptor){ + /// The bson writer settings. + public UpdateMessage(BsonWriterSettings bsonWriterSettings) + : base(bsonWriterSettings){ Header = new MessageHeader(OpCode.Update); } diff --git a/source/MongoDB/Serialization/ISerializationFactory.cs b/source/MongoDB/Serialization/ISerializationFactory.cs index 7de1c784..008eaa00 100644 --- a/source/MongoDB/Serialization/ISerializationFactory.cs +++ b/source/MongoDB/Serialization/ISerializationFactory.cs @@ -28,14 +28,7 @@ public interface ISerializationFactory /// The type. /// IObjectDescriptor GetObjectDescriptor(Type type); - - /// - /// Gets the descriptor. - /// - /// Type of the root. - /// - IBsonObjectDescriptor GetBsonDescriptor(Type rootType); - + /// /// Gets the bson reader settings. ///