blob: cedf51d90dbbc59289f963e80606188012c0c448 [file] [log] [blame]
// ==================================================================================
// Copyright (c) 2000-2019 Ericsson Telecom AB AB
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v2.0
// which accompanies this distribution, and is available at
// https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html
// ==================================================================================
// Contributors:
// Krisztian Gulyas - initial implementation and initial documentation
//
// File: MongoDBProtocol.ttcn
// Rev: R1A
// Prodnr: CNL 0
// ==================================================================================
module MongoDB_Types
{
// ==============================================================================
//
// mongoDB wire protocol definitions
// reference: https://docs.mongodb.com/manual/reference/mongodb-wire-protocol/
// version: mongoDB version 3.4
//
// ==============================================================================
// ------------------------------------------------------------------------------
// general definitions
// ------------------------------------------------------------------------------
// 32 bit integer (little endian encoding) and decoding function
type integer int32 with { variant "FIELDLENGTH(32), COMP(signbit), BYTEORDER(first)" };
// decoding int32 value from octetstring
external function decInt32 (in octetstring stream) return int32 with { extension "prototype(convert) decode(RAW)" }
// 64 bit integer (little endian encoding)
type integer int64 with { variant "FIELDLENGTH(64), COMP(signbit), BYTEORDER(first)" };
// record of int64 type
type record of int64 roInt64;
/// null terminaged string
type universal charstring cstring with { variant "FIELDLENGTH(null_terminated)"};
// different size of bit fields
type bitstring BIT1 with { variant "BITORDER(lsb), FIELDLENGTH(1)" };
type bitstring BIT24 with { variant "BITORDER(lsb), FIELDLENGTH(24)" };
type bitstring BIT28 with { variant "BITORDER(lsb), FIELDLENGTH(28)" };
type bitstring BIT30 with { variant "BITORDER(lsb), FIELDLENGTH(30)" };
type bitstring BIT31 with { variant "BITORDER(lsb), FIELDLENGTH(31)" };
// record of JSON documents
type record of universal charstring JSONRecords;
// ------------------------------------------------------------------------------
// mongoDB message header definitions (common part of the message)
// ------------------------------------------------------------------------------
// code of the operations: 32 bit integer (little endian encoding)
type enumerated OpCode
{
OP_REPLY (1), // Reply to a client request. responseTo is set.
OP_MSG (1000), // Generic msg command followed by a string.
OP_UPDATE (2001), // Update document.
OP_INSERT (2002), // Insert new document.
OP_QUERY (2004), // Query a collection.
OP_GET_MORE (2005), // Get more data from a query. See Cursors.
OP_DELETE (2006), // Delete documents.
OP_KILL_CURSORS (2007), // Notify database that the client has finished with the cursor.
OP_COMMAND (2010), // Cluster internal protocol representing a command request.
OP_COMMANDREPLY (2011), // Cluster internal protocol representing a reply to an OP_COMMAND.
OP_UNDEFINED (0) // Undefined value for ttcn test cases
} with { variant "BYTEORDER(first), FIELDLENGTH(32)" };
// header structure
type record MsgHeader
{
// The total size of the message in bytes. This total includes the 4 bytes that holds the message length.
int32 messageLength,
// A client or database-generated identifier that uniquely identifies this message.
// For the case of client-generated messages (e.g. OP_QUERY and OP_GET_MORE), it will be returned in the responseTo
// field of the OP_REPLY message. Clients can use the requestID and the responseTo fields to associate query
// responses with the originating query.
int32 requestId,
// In the case of a message from the database, this will be the requestID taken from the OP_QUERY or OP_GET_MORE
// messages from the client. Clients can use the requestID and the responseTo fields to associate query responses
// with the originating query.
int32 responseTo,
// Type of message. See Request Opcodes above
OpCode opCode
} with { variant "" }
// ==============================================================================
//
// mongoDB client request messages
//
// ==============================================================================
// ------------------------------------------------------------------------------
// mongoDB insert message,
// ------------------------------------------------------------------------------
// flags: definitions of bits
type record InsertMsgFlagsBits {
// If set, the database will not stop processing a bulk insert if one fails (eg due to duplicate IDs).
// This makes bulk insert behave similarly to a series of single inserts, except lastError will be set
// if any insert fails, not just the last one. If multiple errors occur, only the most recent will be
// reported by getLastError. (new in 1.9.1)
BIT1 ContinueOnError,
// 1-31 bits are reserved. Must be set to 0
BIT31 Reserved0
} with { variant "" }
// flags can be accessed via bits or value
type union InsertMsgFlags {
InsertMsgFlagsBits bits,
int32 bytes
} with { variant "FIELDLENGTH(32), COMP(signbit), BYTEORDER(first)" };
// message structure
type record InsertMsg
{
MsgHeader header, // standard message header
InsertMsgFlags flags, // bit vector of insert options.
cstring fullCollectionName, // "dbname.collectionname"
octetstring documents // one or more BSON documents to insert into the collection
} with {
variant "TAG (header, opCode = OP_INSERT)";
variant (header) "LENGTHTO(header, flags, fullCollectionName, documents)";
variant (header) "LENGTHINDEX(messageLength)"
}
// ------------------------------------------------------------------------------
// mongoDB update message,
// ------------------------------------------------------------------------------
// flags: definitions of bits
type record UpdateMsgFlagsBits {
// If set, the database will insert the supplied object into the collection if no matching document is found.
BIT1 Upsert,
// If set, the database will update all matching objects in the collection. Otherwise only updates first matching document.
BIT1 MultiUpdate,
// 2-31 bits are reserved. Must be set to 0
BIT30 Reserved0
} with { variant "" }
// flags can be accessed via bits or value
type union UpdateMsgFlags {
UpdateMsgFlagsBits bits,
int32 bytes
} with { variant "FIELDLENGTH(32), COMP(signbit), BYTEORDER(first)" };
// message structure
type record UpdateMsg
{
MsgHeader header, // standard message header
int32 ZERO, // 0 - reserved for future use
cstring fullCollectionName, // "dbname.collectionname"
UpdateMsgFlags flags, // bit vector of update options.
octetstring selector, // BSON document that specifies the query for selection of the document to update
octetstring update // BSON document that specifies the update to be performed
} with {
variant "TAG (header, opCode = OP_UPDATE)";
variant (header) "LENGTHTO(header, ZERO, fullCollectionName, flags, selector, update)";
variant (header) "LENGTHINDEX(messageLength)"
}
// ------------------------------------------------------------------------------
// mongoDB query message,
// ------------------------------------------------------------------------------
// flags: definitions of bits
type record QueryMsgFlagsBits {
// Reserved. Must be set to 0.
BIT1 Reserved0,
// Tailable means cursor is not closed when the last data is retrieved. Rather, the cursor marks the final
// object’s position. You can resume using the cursor later, from where it was located, if more data were received.
// Like any “latent cursor”, the cursor may become invalid at some point (CursorNotFound) – for example if the
// final object it references were deleted.
BIT1 TailableCursor,
// Allow query of replica slave. Normally these return an error except for namespace “local”.
BIT1 SlaveOK,
// Internal replication use only - driver should not set.
BIT1 OplogReplay,
// The server normally times out idle cursors after an inactivity period (10 minutes) to prevent excess memory use.
// Set this option to prevent that.The server normally times out idle cursors after an inactivity period (10 minutes)
// to prevent excess memory use. Set this option to prevent that.
BIT1 NoCursorTimeout,
// Use with TailableCursor. If we are at the end of the data, block for a while rather than returning no data.
// After a timeout period, we do return as normal.
BIT1 AwaitData,
// Stream the data down full blast in multiple “more” packages, on the assumption that the client will fully read all
// data queried. Faster when you are pulling a lot of data and know you want to pull it all down. Note: the client is
// not allowed to not read all the data unless it closes the connection.Stream the data down full blast in multiple “more” packages,
// on the assumption that the client will fully read all data queried. Faster when you are pulling a lot of data and know you want
// to pull it all down. Note: the client is not allowed to not read all the data unless it closes the connection.
BIT1 Exhaust,
// Get partial results from a mongos if some shards are down (instead of throwing an error)
BIT1 Partial,
// 8-31 bits are reserved. Must be set to 0.
BIT24 Reserved1
} with { variant "" }
// flags can be accessed via bits or value
type union QueryMsgFlags {
QueryMsgFlagsBits bits,
int32 bytes
} with { variant "FIELDLENGTH(32), COMP(signbit), BYTEORDER(first)" };
// message structure
type record QueryMsg
{
MsgHeader header, // standard message header
QueryMsgFlags flags, // bit vector of query options.
cstring fullCollectionName, // "dbname.collectionname"
int32 numberToSkip, // number of documents to skip
int32 numberToReturn, // number of documents to return in the first OP_REPLY batch
octetstring query, // BSON document that represents the query
octetstring returnFieldsSelector optional // BSON document that limits the fields in the returned documents.
} with {
variant "TAG (header, opCode = OP_QUERY)";
variant (header) "LENGTHTO(header, flags, fullCollectionName, numberToSkip, numberToReturn, query, returnFieldsSelector)";
variant (header) "LENGTHINDEX(messageLength)"
}
// ------------------------------------------------------------------------------
// mongoDB get more message,
// ------------------------------------------------------------------------------
// message structure
type record GetMoreMsg
{
MsgHeader header, // standard message header
int32 ZERO, // 0 - reserved for future use
cstring fullCollectionName, // "dbname.collectionname"
int32 numberToReturn, // number of documents to return
int64 cursorID // cursor id from OP_REPLY
} with {
variant "TAG (header, opCode = OP_GET_MORE)";
variant (header) "LENGTHTO(header, ZERO, fullCollectionName, numberToReturn, cursorID)";
variant (header) "LENGTHINDEX(messageLength)"
}
// ------------------------------------------------------------------------------
// mongoDB delete message,
// ------------------------------------------------------------------------------
// flags: definitions of bits
type record DeleteMsgFlagsBits {
// If set, the database will remove only the first matching document in the collection.
// Otherwise all matching documents will be removed.
BIT1 SingleRemove,
// 1-31 bits are reserved. Must be set to 0.
BIT31 Reserved1
} with { variant "" }
// flags can be accessed via bits or value
type union DeleteMsgFlags {
DeleteMsgFlagsBits bits,
int32 bytes
} with { variant "FIELDLENGTH(32), COMP(signbit), BYTEORDER(first)" };
// message structure
type record DeleteMsg
{
MsgHeader header, // standard message header
int32 ZERO, // 0 - reserved for future use
cstring fullCollectionName, // "dbname.collectionname"
DeleteMsgFlags flags, // bit vector of delete options.
octetstring selector // BSON document that represent the query used to select the documents to be removed
} with {
variant "TAG (header, opCode = OP_DELETE)";
variant (header) "LENGTHTO(header, ZERO, fullCollectionName, flags, selector)";
variant (header) "LENGTHINDEX(messageLength)"
}
// ------------------------------------------------------------------------------
// mongoDB kill cursor message
// ------------------------------------------------------------------------------
// message structure
type record KillCursorMsg
{
MsgHeader header, // standard message header
int32 ZERO, // 0 - reserved for future use
int32 numberOfCursorIDs, // number of cursorIDs in message
roInt64 cursorIDs // sequence of cursorIDs
} with {
variant "TAG (header, opCode = OP_KILL_CURSORS)";
variant (header) "LENGTHTO(header, ZERO, numberOfCursorIDs, cursorIDs)";
variant (header) "LENGTHINDEX(messageLength)"
}
// ------------------------------------------------------------------------------
// mongoDB command message,
// ------------------------------------------------------------------------------
// command message structure
type record CommandMsg
{
MsgHeader header, // standard message header
cstring database,
cstring commandName,
octetstring metadata,
octetstring commandArgs,
octetstring inputDocs optional
}
with {
variant "TAG (header, opCode = OP_COMMAND)";
variant (header) "LENGTHTO(header, database, commandName, metadata, commandArgs, inputDocs)";
variant (header) "LENGTHINDEX(messageLength)"
}
// ==============================================================================
//
// mongoDB response messages
//
// ==============================================================================
// ------------------------------------------------------------------------------
// mongoDB reply message,
// ------------------------------------------------------------------------------
// flags: definitions of bits
type record ReplyMsgFlagsBits {
// Is set when getMore is called but the cursor id is not valid at the server. Returned with zero results.
BIT1 CursorNotFound,
// Is set when query failed. Results consist of one document containing an “$err” field describing the failure.
BIT1 QueryFailure,
// Drivers should ignore this. Only mongos will ever see this set, in which case, it needs to update config from the server.
BIT1 ShardConfigStale,
// Is set when the server supports the AwaitData Query option. If it doesn’t, a client should sleep a little
// between getMore’s of a Tailable cursor. Mongod version 1.6 supports AwaitData and thus always sets AwaitCapable.
BIT1 AwaitCapable,
// 4-31 bits are reserved. Ignore.
BIT28 Reserved
} with { variant "" }
// flags can be accessed via bits or value
type union ReplyMsgFlags {
ReplyMsgFlagsBits bits,
int32 bytes
} with { variant "FIELDLENGTH(32), COMP(signbit), BYTEORDER(first)" };
type union ReplyMsgDocuments {
octetstring octets,
JSONRecords json
} with { variant "" };
// command message structure
type record ReplyMsg
{
MsgHeader header, // standard message header
ReplyMsgFlags responseFlags, // bit vector - see details below
int64 cursorID, // cursor id if client needs to do get more's
int32 startingFrom, // where in the cursor this reply is starting
int32 numberReturned, // number of documents in the reply
ReplyMsgDocuments documents // documents
} with {
variant "TAG (header, opCode = OP_REPLY)";
}
// ------------------------------------------------------------------------------
// mongoDB command reply message
// ------------------------------------------------------------------------------
type record CommandReplyMsg
{
MsgHeader header, // standard message header
octetstring metadata, // A BSON document containing any required metadata
octetstring commandArgs, // A BSON document containing the command reply
octetstring inputDocs optional // A variable number of BSON documents
}
with { variant "" }
// ==============================================================================
//
// Generic mongoDB message definitions
//
// ==============================================================================
// ------------------------------------------------------------------------------
// generic mongoDB message (union of all message types)
// ------------------------------------------------------------------------------
type union Msg {
InsertMsg insert,
UpdateMsg update,
QueryMsg query,
GetMoreMsg getMore,
DeleteMsg delete,
KillCursorMsg killCursor,
CommandMsg command,
ReplyMsg reply_,
CommandReplyMsg commandReply,
octetstring octects
} with {
variant (insert) "TAG (header, opCode = OP_INSERT)";
variant (update) "TAG (header, opCode = OP_UPDATE)";
variant (query) "TAG (header, opCode = OP_QUERY)";
variant (getMore) "TAG (header, opCode = OP_GET_MORE)";
variant (delete) "TAG (header, opCode = OP_DELETE)";
variant (killCursor) "TAG (header, opCode = OP_KILL_CURSORS)";
variant (command) "TAG (header, opCode = OP_COMMAND)";
variant (reply_) "TAG (header, opCode = OP_REPLY)";
variant (commandReply) "TAG (header, opCode = OP_COMMANDREPLY)";
}
// ------------------------------------------------------------------------------
// generic encode and decode function for generic message type
// ------------------------------------------------------------------------------
external function encMsg (in Msg msg) return octetstring
with { extension "prototype(convert) encode(RAW)" }
external function decMsg (in octetstring octets) return Msg
with { extension "prototype(convert) decode(RAW)" }
} with { encode "RAW" }