/* * Copyright 2014 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.mongodb.connection; import org.bson.BsonBinaryReader; import org.bson.BsonBinaryWriter; import org.bson.BsonDocument; import org.bson.ByteBuf; import org.bson.ByteBufNIO; import org.bson.codecs.BsonDocumentCodec; import org.bson.codecs.DecoderContext; import org.bson.codecs.EncoderContext; import org.bson.io.BasicOutputBuffer; import org.bson.io.BsonInput; import org.bson.io.ByteBufferBsonInput; import org.bson.io.OutputBuffer; import org.bson.json.JsonReader; import java.nio.ByteBuffer; import java.nio.ByteOrder; final class MessageHelper { private MessageHelper() { } public static ResponseBuffers buildSuccessfulReply(final String json) { return buildSuccessfulReply(0, json); } public static ResponseBuffers buildSuccessfulReply(final int responseTo, final String json) { return buildReply(responseTo, json, 0); } public static ResponseBuffers buildFailedReply(final String json) { return buildFailedReply(0, json); } public static ResponseBuffers buildFailedReply(final int responseTo, final String json) { return buildReply(responseTo, json, 2); } public static ResponseBuffers buildReply(final int responseTo, final String json, final int responseFlags) { ByteBuf body = encodeJson(json); body.flip(); ReplyHeader header = buildReplyHeader(responseTo, 1, body.remaining(), responseFlags); return new ResponseBuffers(header, body); } private static ReplyHeader buildReplyHeader(final int responseTo, final int numDocuments, final int documentsSize, final int responseFlags) { ByteBuffer headerByteBuffer = ByteBuffer.allocate(36); headerByteBuffer.order(ByteOrder.LITTLE_ENDIAN); headerByteBuffer.putInt(36 + documentsSize); // length headerByteBuffer.putInt(2456); //request id headerByteBuffer.putInt(responseTo); // response to headerByteBuffer.putInt(1); // opcode headerByteBuffer.putInt(responseFlags); // responseFlags headerByteBuffer.putLong(0); // cursorId headerByteBuffer.putInt(0); // startingFrom headerByteBuffer.putInt(numDocuments); //numberReturned headerByteBuffer.flip(); ByteBufferBsonInput headerInputBuffer = new ByteBufferBsonInput(new ByteBufNIO(headerByteBuffer)); return new ReplyHeader(headerInputBuffer, ConnectionDescription.getDefaultMaxMessageSize()); } public static BsonDocument decodeCommand(final BsonInput bsonInput) { bsonInput.readInt32(); // length bsonInput.readInt32(); //requestId bsonInput.readInt32(); //responseTo bsonInput.readInt32(); // opcode bsonInput.readInt32(); // flags bsonInput.readCString(); //collectionName bsonInput.readInt32(); // numToSkip bsonInput.readInt32(); // numToReturn BsonBinaryReader reader = new BsonBinaryReader(bsonInput); return new BsonDocumentCodec().decode(reader, DecoderContext.builder().build()); } public static String decodeCommandAsJson(final BsonInput bsonInput) { return decodeCommand(bsonInput).toJson(); } private static ByteBuf encodeJson(final String json) { OutputBuffer outputBuffer = new BasicOutputBuffer(); JsonReader jsonReader = new JsonReader(json); BsonDocumentCodec codec = new BsonDocumentCodec(); BsonDocument document = codec.decode(jsonReader, DecoderContext.builder().build()); BsonBinaryWriter writer = new BsonBinaryWriter(outputBuffer); codec.encode(writer, document, EncoderContext.builder().build()); ByteBuffer documentByteBuffer = ByteBuffer.allocate(outputBuffer.size()); documentByteBuffer.put(outputBuffer.toByteArray()); return new ByteBufNIO(documentByteBuffer); } }