/* Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */ #ifndef GCS_PLUGIN_MESSAGES_INCLUDED #define GCS_PLUGIN_MESSAGES_INCLUDED #include #include /* Since this file is used on unit tests, through member_info.h, includes must set here and not through plugin_server_include.h. */ #include /** This is the base GCS plugin message. It is composed by a fixed header and 1 or more payload items. The on-the-wire layout looks like this: +-----------------------------------+ | fixed header | payload | +-----------------------------------+ The on-the-wire representation of the message is: +-------------------+-----------+--------------------------------------+ | field | wire size | description | +===================+===========+======================================+ | version | 4 bytes | protocol version | | fixed_hdr_len | 2 bytes | length of the fixed header | | message_len | 8 bytes | length of the message | | cargo_type | 2 bytes | the cargo type in the payload | +-------------------+-----------+--------------------------------------+ | payload_item_type | 2 bytes | the item type in the payload | | payload_item_len | 8 bytes | length of the payload item | | payload_item | X bytes | payload item | +-------------------+-----------+--------------------------------------+ The last tree lines can occur one or more times. */ class Plugin_gcs_message { public: /** The protocol version number. */ static const int PLUGIN_GCS_MESSAGE_VERSION; /** The protocol version number. */ static const unsigned int WIRE_VERSION_SIZE; /** The on-the-wire size of the header length field. */ static const unsigned int WIRE_HD_LEN_SIZE; /** The on-the-wire size of the message size field. */ static const unsigned int WIRE_MSG_LEN_SIZE; /** The on-the-wire size of the cargo type field. */ static const unsigned int WIRE_CARGO_TYPE_SIZE; /** The on-the-wire size of the fixed header. */ static const unsigned int WIRE_FIXED_HEADER_SIZE; /** The on-the-wire size of the each payload item type field. */ static const unsigned int WIRE_PAYLOAD_ITEM_TYPE_SIZE; /** The on-the-wire size of the each payload item size field. */ static const unsigned int WIRE_PAYLOAD_ITEM_LEN_SIZE; /** The on-the-wire size of the payload item header. */ static const unsigned int WIRE_PAYLOAD_ITEM_HEADER_SIZE; /** The different cargo type codes. NOTE: all type values must fit into WIRE_CARGO_TYPE_SIZE bytes storage. */ enum enum_cargo_type { // This type should not be used anywhere. CT_UNKNOWN= 0, // This cargo type is used for certification events, GTID_EXECUTED broadcast. CT_CERTIFICATION_MESSAGE= 1, // This cargo type is used for transaction data. CT_TRANSACTION_MESSAGE= 2, // This cargo type is used for recovery events, signal when a given member // becomes online. CT_RECOVERY_MESSAGE= 3, // This cargo type is used for messaging related to stage exchanges, // on which it represents one member. CT_MEMBER_INFO_MESSAGE= 4, // This cargo type is used for messaging related to stage exchanges, // on which it represents a set of members. CT_MEMBER_INFO_MANAGER_MESSAGE= 5, // This cargo type is used for messaging related to members pipeline // stats. CT_PIPELINE_STATS_MEMBER_MESSAGE= 6, // This cargo type is used for messaging related to single primary // mode. CT_SINGLE_PRIMARY_MESSAGE= 7, // No valid type codes can appear after this one. CT_MAX= 8 }; private: /** This header instance protocol version. */ int m_version; /** This header instance length. */ unsigned short m_fixed_header_len; /** This is the message length field. */ unsigned long long m_msg_len; /** The cargo type code. */ enum_cargo_type m_cargo_type; public: virtual ~Plugin_gcs_message() {} /** @return the value of the version field. */ int get_version() { return m_version; } /** @return the value of the header length field value. */ unsigned short get_header_length() { return m_fixed_header_len; } /** @return the cargo type. */ enum_cargo_type get_cargo_type() { return m_cargo_type; } /** @return the message length field value. */ unsigned long long get_msg_length() { return m_msg_len; } /** Encodes the contents of this instance into the buffer. @param[out] buffer the buffer to encode to. */ void encode(std::vector* buffer) const; /** Decodes the contents of the buffer and sets the field values according to the values decoded. @param[in] buffer the buffer to decode from. @param[in] length the length of the buffer. */ void decode(const unsigned char* buffer, uint64 length); /** Return the cargo type of a given message buffer, without decode the complete message. @param[in] buffer the buffer to decode from. @return the cargo type of a given message buffer */ static enum_cargo_type get_cargo_type(const unsigned char* buffer); /** Return the raw data of the first payload item of a given message buffer, without decode the complete message. @param[out] buffer the buffer to decode from. @param[out] payload_item_data the data. @param[out] payload_item_length the length of the data. @return the raw data of the first payload item */ static void get_first_payload_item_raw_data(const unsigned char* buffer, const unsigned char** payload_item_data, uint64* payload_item_length); protected: /** Plugin_gcs_message constructor. Only to be called by derivative classes @param[in] cargo_type Message type to be sent */ explicit Plugin_gcs_message(enum_cargo_type cargo_type); /** Encodes the contents of this instance payload into the buffer. @param[out] buffer the buffer to encode to. */ virtual void encode_payload(std::vector* buffer) const = 0; /** Decodes the contents of the buffer and sets the payload field values according to the values decoded. @param[in] buffer the buffer to decode from. @param[in] end the end of the buffer. */ virtual void decode_payload(const unsigned char* buffer, const unsigned char* end)= 0; /** Encodes the given payload item type and length into the buffer. @param[out] buffer the buffer to encode to @param[in] payload_item_type the type of the payload item @param[in] payload_item_length the length of the payload item */ void encode_payload_item_type_and_length(std::vector* buffer, uint16 payload_item_type, unsigned long long payload_item_length) const; /** Decodes the given payload item type and length from the buffer. @param[in] buffer the buffer to encode from @param[out] payload_item_type the type of the payload item @param[out] payload_item_length the length of the payload item */ void decode_payload_item_type_and_length(const unsigned char** buffer, uint16* payload_item_type, unsigned long long* payload_item_length); /** Encodes the given payload item (type, length and value) into the buffer as a char (1 byte). @param[out] buffer the buffer to encode to @param[in] type the type of the payload item @param[in] value the value of the payload item */ void encode_payload_item_char(std::vector* buffer, uint16 type, unsigned char value) const; /** Decodes the given payload item (type, length and value) from the buffer as a char (1 byte). @param[in] buffer the buffer to encode from @param[out] type the type of the payload item @param[out] value the value of the payload item */ void decode_payload_item_char(const unsigned char** buffer, uint16* type, unsigned char* value); /** Encodes the given payload item (type, length and value) into the buffer as a 2 bytes integer. @param[out] buffer the buffer to encode to @param[in] type the type of the payload item @param[in] value the value of the payload item */ void encode_payload_item_int2(std::vector* buffer, uint16 type, uint16 value) const; /** Decodes the given payload item (type, length and value) from the buffer as a 2 bytes integer. @param[in] buffer the buffer to encode from @param[out] type the type of the payload item @param[out] value the value of the payload item */ void decode_payload_item_int2(const unsigned char** buffer, uint16* type, uint16* value); /** Encodes the given payload item (type, length and value) into the buffer as a 4 bytes integer. @param[out] buffer the buffer to encode to @param[in] type the type of the payload item @param[in] value the value of the payload item */ void encode_payload_item_int4(std::vector* buffer, uint16 type, uint32 value) const; /** Decodes the given payload item (type, length and value) from the buffer as a 4 bytes integer. @param[in] buffer the buffer to encode from @param[out] type the type of the payload item @param[out] value the value of the payload item */ void decode_payload_item_int4(const unsigned char** buffer, uint16* type, uint32* value); /** Encodes the given payload item (type, length and value) into the buffer as a 8 bytes integer. @param[out] buffer the buffer to encode to @param[in] type the type of the payload item @param[in] value the value of the payload item */ void encode_payload_item_int8(std::vector* buffer, uint16 type, ulonglong value) const; /** Decodes the given payload item (type, length and value) from the buffer as a 8 bytes integer. @param[in] buffer the buffer to encode from @param[out] type the type of the payload item @param[out] value the value of the payload item */ void decode_payload_item_int8(const unsigned char** buffer, uint16* type, ulonglong* value); /** Encodes the given payload item (type, length and value) into the buffer as a char array (variable size). @param[out] buffer the buffer to encode to @param[in] type the type of the payload item @param[in] value the value of the payload item @param[in] length the length of the payload item */ void encode_payload_item_string(std::vector* buffer, uint16 type, const char* value, unsigned long long length) const; /** Decodes the given payload item (type, length and value) from the buffer as a char array (variable size). @param[in] buffer the buffer to encode from @param[out] type the type of the payload item @param[out] value the value of the payload item @param[out] length the length of the payload item */ void decode_payload_item_string(const unsigned char** buffer, uint16* type, std::string* value, unsigned long long* length); }; #endif /* GCS_PLUGIN_MESSAGES_INCLUDED */