4/FBSP - Firebird Butler Service Protocol

domain:github.com/FirebirdSQL/Butler
shortname:4/FBSP
name:Firebird Butler Service Protocol
status:raw
editor:Pavel Císař <pcisar@users.sourceforge.net>

The Firebird Butler Service Protocol (FBSP) defines formal rules for exchanging messages between Butler Service and its Client.

License

Copyright (c) 2018 The Firebird Butler Project.

This Specification is distributed under Creative Commons Attribution-ShareAlike 4.0 International license.

You should have received a copy of the CC BY-SA 4.0 along with this document; if not, see https://creativecommons.org/licenses/by-sa/4.0/

Change Process

This Specification is a free and open standard and is governed by the Consensus-Oriented Specification System (COSS) (see “2/COSS - Consensus-Oriented Specification System”).

Important

This specification is still incomplete (work in progress), hence the COSS change process is not yet fully applicable. All ideas and change proposals SHOULD be presented and discussed first in the Firebird Butler forum.

Language

The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC2119.

1. Goals

The purpose of this specification is to define formal rules for exchanging messages between Butler Service and its Client. Its goals are:

  1. Define the uniform structure of messages passed between the service and its client.
  2. Define a uniform method and the minimum scope of integration of separate components (acting as services and clients) into an adaptable and reliable integrated system.
  3. Standardize the format of the application interface between otherwise independent components.
  4. Provide the resources necessary to implement efficient asynchronous communication between components with both tight and loose bindings in diverse operating environments.

2. Implementation

2.1 Overall Behavior

The specification requires the existence of a transport channel capable of asynchronously transmitting messages in both directions (referred to as Transport Channel), where individual messages are constituted by one or more uniquely separate data blocks (referred to as Frames). The Transport Channel must also conform to following rules:

  1. A message SHALL NOT be delivered more than once to any peer.
  2. All messages between two immediate peers SHALL be delivered in order.

Tip

Such transmissions are provided by ZeroMQ Message Transfer Protocol (ZMTP) over ROUTER (and DEALER) sockets.

Exchange of messages on the Transport Channel is implemented as a Connection between the Service and the Client where the connection has the following stages:

  1. The Client MUST initiate the connection by sending the HELLO message.
  2. The Service MUST reply to the HELLO message by sending a WELCOME message to confirm the connection. If the Service can not receive the connection, it MUST send the ERROR message instead.
  3. After confirming a successful Connection, the Client can start sending messages to which the Service responds by sending one or more messages of its own.
  4. The Client or Service can terminate the Connection at any time by sending a CLOSE message, or by closing the Transport Channel. However, the peer initiating the connection termination SHOULD send the CLOSE message before it closes the Transport Channel to the other peer.

Important

The conversation is always managed by the Client, that is, each message sent by the Service is always part of the response to some previous message sent by Client.

2.2 Client and Service Identity

Both the Client and the Service must be uniquely identified. For this purpose, the specification introduces the concepts of Client Identity and Service Identity, collectively as Identity.

  1. The content of the Identity MAY be arbitrary.
  2. There MUST be a canonical string Identity representation.
  3. Both the Client Identity and the Service Identity MUST be unique in the same namespace.
  4. Both the Client and the Service MUST use the Identity for all identification purposes.
  5. If Service acts as a Client to another Service, then MUST use its own Service Identity as the Client Identity to the another Service.
  6. It is RECOMMENDED that both the Client and the Service use the Identity for routing purposes.
  7. It is RECOMMENDED to use UUID as Identity.

Tip

When implementing FBSP using ZeroMQ sockets as a Transport Channel, it is RECOMMENDED that the Client or Service assign their Identity as the identity of all ZeroMQ sockets used for FBSP protocol messaging.

2.3 The Connection and the Transport Channel

2.3.1 Using one Channel for multiple Connections

A single Transport channel MAY be used for message transmission for several concurrently active Connections. This specification does not define how the message routing for individual connections should be done, neither the necessary encapsulation of the FBSP protocol messages into the messages transmitted by the multi-transport channel. However, the possible implementation of the multi-transport channel MUST be completely transparent from the point of view of the FBSP.

Note

For example, if transmission is implemented using ZeroMQ ROUTER socket, all FBSP messages flowing through it are / must be prefixed with extra Data Frame with routing address.

2.3.2 Bound and unbound Connections

This specification assumes that message transfer provided by Transport Channel is implemented via Transport Connection established between the Client and the Service. In such a case, the FBSP Connection MAY be bound or not to the Transport Connection. This means that:

  1. A bound Connection SHALL be terminated automatically when the Transport Connection functionality is interrupted. An unbound Connection assumes a mechanism exists for restoring an interrupted Transport Connection, and SHALL be terminated only if this mechanism fails.
  2. For unbound Connection the Transport Connection does not need to be closed together with closing Connection, and MAY be reused to carry another subsequent Connection between the same Client and Service. For bound Connection the Transport Connection SHOULD be closed together with closing Connection.

The method of agreement between the Client and the Service to use the bound or unbound Connection mechanism is not defined by this specification and MUST be provided by other means. If such other means are not used, the Connection MUST be bound to the Transport Connection.

2.4 FBSP Messages

The traffic between Client and Service consists of Messages in a unified format sent in both directions via a Transport Channel.

FBSP is designed to carry arbitrary Service API in unified message format. This is achieved by dividing the contents of the messages into a structural part (Control Frame) and a data (Data Frames). In addition to the basic structural information, the Control Frame also includes a space for the transmission of control data for the Service API. The API’s main point is the Request Code that uniquely identifies the required functionality (API call). FBSP defines (and reserves) some Request Codes for itself, while unused ones are reserved for use by Service. With few exceptions, all Data Frames are considered as part of the Service API, and are not regulated by this specification.

2.4.1 Formal message grammar

The following ABNF grammar defines the message format used by FBSP protocol:

fbsp          = *message

; The message consists of a control frame, and zero or more data frames
message       = control-frame *data-frame

; The control frame consists of a signature, control byte, flags, message-type data, and message token
control-frame = signature control-byte flags type-data token

; The protocol signature is a FourCC
signature     = "FBSP" ; %x46 %x42 %x53 %x50

; The control byte encodes a message type, and protocol version. Both are decimal numbers.
; msg-type on upper (leftmost) 5 bits, version on lower (rightmost) 3 bits
control-byte  = 1OCTET

; Flags consists of a single octet containing various control flags as individual bits.
; Bit 0 is the least significant bit (rightmost bit)
flags         = 1OCTET

; Message-type specific data are two bytes
type-data     = 2OCTET

; Message token is 8 bytes
token         = 8OCTET

; A data frame consists from zero or more octets
data-frame    = *OCTETS

2.4.2 Message token

The FBSP allows asynchronous communication between the Client and the Service, and also allows the Service to send several messages in response to one message sent by the Client. Message Token is a client-specified data block that is sent back to the Client by a Service without change, in each message that is a logical response to that message.

Processing of the token is governed by the following rules:

  1. The content of the Message Token MAY be arbitrary.
  2. The content of the Message Token SHALL be specified by Client only.
  3. The Message Token MUST be returned without change in any message sent by the Service, which is a logical response to the original message sent by the Client containing that token.
  4. Messages sent by a Service that can not be uniquely identified as a logical response to a previous message sent by a Client (such as unexpected general ERROR, CLOSE, or NOOP sent to check the client’s availability) MUST contain the Message Token passed by the Client in the HELLO message.

Important

This specification does not define in any way how the Client should use the Message Token, nor does it prescribe that it should be used at all. However, the Message Token SHOULD be used by the Client whenever there is a need to assign messages sent by the Service to the original request source (for example for internal routing purposes or reliable implementation of parallel Client requests).

2.4.3 Message types

The message type is an integer in the range of 1..31 stored in 5 upper (leftmost) bits of the control-byte. This protocol revision defines the next message types:

unused      = 0      ; not a valid message type
HELLO       = 1      ; initial message from client
WELCOME     = 2      ; initial message from service
NOOP        = 3      ; no operation, used for keep-alive & ping purposes
REQUEST     = 4      ; client request
REPLY       = 5      ; service response to client request
DATA        = 6      ; separate data sent by either client or service
CANCEL      = 7      ; cancel request
STATE       = 8      ; operating state information
CLOSE       = 9      ; sent by peer that is going to close the connection
reserved    = 10..30 ; reserved for future use
ERROR       = 31     ; error reported by service

The Client SHALL send only messages of following types:

HELLO       : must be the first message in conversation
NOOP        : presence check
REQUEST     : request to service
CANCEL      : cancel previous request
DATA        : data package sent to service
CLOSE       : client is about to close the connection

The Service SHALL send only messages of following types:

ERROR       : error is always an error
WELCOME     : must be the first message in conversation
NOOP        : presence check
REPLY       : reply to REQUEST message
DATA        : data package sent to client
STATE       : operating state information
CLOSE       : service is about to close the connection
HELLO

The HELLO message is a Client request to open a Connection to the Service. The message includes basic information about the Client and Connection parameters required by the Client.

  1. This message MUST be the first message sent by the Client.
  2. The Service MUST reply to this message with WELCOME or ERROR message.
  3. The first data-frame of this message MUST contain the Client Identity.
  4. If the Service records an open Connection for a Client with the same Client Identity, it MUST respond with ERROR message, and refuse the connection.
  5. The content of type-data field in this message is not significant. [RAW NOTE: Should we use it for something? HELLO protobuf format version? bitmap of requested common connection parameters?]
WELCOME

The WELCOME message is the response of the Service to the HELLO message sent by the Client, which confirms the successful creation of the required Connection and announces basic parameters of the Service and the Connection.

  1. The first data-frame of this message MUST contain the Service Identity.
  2. The content of type-data field in this message is not significant. [RAW NOTE: Should we use it for something? WELCOME protobuf format version? bitmap of available common service abilities?]
NOOP

The NOOP message means no operation. It’s intended for keep alive purposes and peer availability checks.

  1. The receiving peer SHALL NOT respond to this message.
  2. The sole exception to rule 1. is the case when ACK-REQUEST flag is set in received NOOP message. In such a case the receiving peer MUST respond according to rules for ACK-REQUEST flag handling.
  3. The content of type-data field in this message is not significant. However, because it’s returned by receiver without changes (when ACK-REQUEST flag is set), it MAY be used by sender for any purpose.
  4. This message SHALL NOT have any data-frame.
REQUEST

The REQUEST message is a Client request to the Service.

  1. The type-data field of the control-frame MUST contain a Request Code.
  2. The message MAY contain one or more data-frame that MUST conform to the API defined for particular Request Code.
  3. The Service MUST respond to this message by sending REPLY or ERROR message with the same Request Code in type-data field.
  4. The Service MAY send additional subsequent messages in response to the same REQUEST message.
  5. The type and number of messages in reply to particular request, as well as method for indicating the end of the message stream to the Client SHALL be defined by the API for particular Request Code.
  6. When ACK-REQUEST flag is set in received REQUEST message, the Service MUST respond according to rules for ACK-REQUEST flag handling. This ACK response MUST be immediate, before further processing of the request.
REPLY

The REPLY message is a Service reply to the REQUEST message previously sent by Client.

  1. The type-data field of the control-frame MUST contain the Request Code from Client REQUEST message.
  2. The message MAY contain one or more data-frame that MUST conform to the API defined for particular Request Code.
  3. The Service SHOULD NOT send more than one REPLY message to any single REQUEST message received. If reply requires more than single message, the REPLY message SHALL be the first message sent and subsequent messages SHOULD be of type DATA or STATE.
  4. The Client SHALL NOT respond to this message.
  5. The sole exception to rule 4. is the case when ACK-REQUEST flag is set in received REPLY message. In such a case the Client MUST respond according to rules for ACK-REQUEST flag handling.
DATA

The DATA message is intended for delivery of arbitrary data between connected peers.

  1. The type-data field of the control-frame MAY have arbitrary content, and is fully available for the Service API.
  2. The message SHOULD contain one or more data-frame that MUST conform to the API defined for particular Request Code.
  3. The FBSP does not provide any means to pair DATA messages sent by Client to the request they are related to. If Service API requires such assignment, it MUST be handled by API itself via content of transmitted data-frame parts of the message, or by type-data field of the control-frame.
  4. The receiver SHALL NOT respond to this message, with sole exceptions defined by rules 5. and 6.
  5. When ACK-REQUEST flag is set in received DATA message, receiver MUST respond according to rules for ACK-REQUEST flag handling.
  6. The Service MAY reply to received DATA message with ERROR message.
CANCEL

The CANCEL message represents a request for a Service to stop processing the previous request from the Client.

  1. One CANCEL message is a request to end the processing of one active request.
  2. The content of type-data field in this message is not significant.
  3. The message MUST have a data-frame with specification of the request whose processing is to be terminated. The data-frame MAY contain additional information.
  4. The Service SHALL terminate specified active request of the Client, and send the REPLY message to the Client when cancellation is successfully finished. The REPLY message MAY have a data-frame with additional information.
  5. If the Service can not stop processing the request whose cancellation is requested, it MUST respond with the ERROR message.
STATE

The STATE message is sent by Service to report its operating state to the Client.

  1. The Service SHALL NOT send the STATE message on its own discretion, but only in relation to REQUEST message previously sent by Client.
  2. The type-data field of the control-frame MUST contain the Request Code from Client REQUEST message this STATE message relates to.
  3. The message MUST contain a data-frame with state information that conforms to the API defined for particular Request Code.
  4. The Client SHALL NOT respond to this message.
  5. The sole exception to rule 4. is the case when ACK-REQUEST flag is set in received STATE message. In such a case the Client MUST respond according to rules for ACK-REQUEST flag handling.
CLOSE

The CLOSE message notifies the receiver that sender is going to close the Connection.

  1. The receiver SHALL NOT respond to this message.
  2. The receiver SHALL NOT use the Connection to send further messages to the sender.
  3. For bound connections, the receiver SHALL close its end of the Transport Channel immediately.
ERROR

The ERROR message notifies the Client about error condition detected by Service.

  1. The type-data field of the control-frame MUST contain the Error Code.
  2. The message MAY contain one or more data-frame that MUST conform to the API defined for reporting Service errors. Those data-frame parts MAY be ignored by Client.
  3. The Client SHALL NOT respond to this message.

2.4.4 Flags

Flags are encoded as individual bits in flags field of the control-frame.

Flags
Name Bit Mask
ACK-REQUEST 0 1
ACK-REPLY 1 2
MORE 3 4
ACK-REQUEST

The ACK-REQUEST flag is intended for verification and synchronization purposes.

  1. Any received control-frame of message-type NOOP, REQUEST, REPLY, DATA, STATE or CANCEL that have ACK-REQUEST flag set SHALL be sent back to the sender as confirmation of accepted message, unless the receiver is a Service and an error condition occurs. In such a case the ERROR message SHALL be sent by Service instead confirmation message.
  2. Returned confirmatory message SHALL consists only from the received control-frame with ACK-REQUEST flag cleared, and with ACK-REPLY flag set (ie the control-frame MUST be otherwise unchanged).
  3. The ACK-REQUEST flag SHALL be ignored for all message-type values not listed in rule 1.

Rules for ACK-REQUEST received by Service:

  1. NOOP message SHALL be acknowledged without any delay.
  2. REQUEST and CANCEL messages SHALL be acknowledged at the time the Service has positively decided to accept the client’s request and before commencing the fulfillment of the client’s request.
  3. DATA message SHALL be acknowledged without any delay, unless a previous agreement between the Client and the Service exists to handle it differently (for example to send it when DATA message is actually processed and Service is able to accept another DATA message).

Rules for ACK-REQUEST received by Client:

  1. NOOP and STATE message SHALL be acknowledged without any delay.
  2. REPLY and DATA messages SHALL be acknowledged without any delay, unless a previous agreement between the Client and the Service exists to handle it differently (for example when Client is prepared to accept subsequent DATA or other messages from Service).
ACK-REPLY

The ACK-REPLY flag indicates that message is a confirmation of the message previously sent by receiver.

  1. The ACK-REPLY flag SHALL NOT be set for any message that is not a confirmation of previous message received with ACK-REQUEST flag set.
  2. The message with ACK-REPLY flag set MUST conform to the rules defined for ACK-REQUEST flag handling.
MORE

The MORE flag is intended to signal the end of the logical message stream to the receiver.

  1. The MORE flag SHALL be set for all messages that are a part of logical message stream, and are not the terminal message of this stream. If the message stream is a response to Client request, the MORE flag SHALL be set in the REPLY message as well.
  2. The MORE flag SHALL be cleared for all messages that are not part of the logical message stream, or are the terminal message of such stream.
  3. The receiver SHALL ignore the MORE flag for all messages of message-type HELLO, WELCOME, NOOP, REQUEST, CANCEL, CLOSE and ERROR.

2.4.5 Protocol versioning

General rules

All revisions of this specification SHALL conform to following rules:

  1. All revisions SHALL preserve next parts of this revision:
    1. reqirements defined for Transport Channel
    2. the existence of control-frame
    3. the position, content and meaning of first five bytes of control-frame, ie. the signature and the control-byte
    4. the existence of message token
  2. All revisions SHALL preserve next parts of all previous revisions:
    1. defined Message types
    2. defined Flags
    3. defined Request Codes
    4. defined Error Codes
Version negotiation
  1. Both the Client and the Service SHALL use the same protocol version for all messages transmitted as part of a single Connection.
  2. The protocol version used for the Connection is defined by the Client in his HELLO message sent to the Service.
  3. The Service SHALL use the same protocol version as the Client.
  4. If Service cannot handle Connection in protocol version used by the Client, it SHOULD respond with appropriate ERROR message in format defined by this revision. The Service MAY respond to this condition by closing the Transport Connection associated with the Connection request.
  5. The Client using different revision of this protocol than revision 1 SHOULD be able to handle ERROR message in format defined by this revision that would be send as response to his HELLO message.
  6. The Client SHALL eventually interpret the closing of the Transport Channel to the Service without response to his HELLO message as rejection of his request to create the Connection.

2.5 Handling of client requests

The Client SHALL send its requests to the Service as REQUEST messages with Request Code indicating the required functionality (an API call).

The handling of Client request has following general rules:

  1. The Service MUST always respond to the REQUEST message in one from following formats:
    1. Send the ERROR message describing the error status detected by the Service that prevents successful completion of the request.
    2. Send the REPLY message as an indication of successful completion of the request, or as indication that Service started to fulfill the request. The actual meaning of this reply is defined by Service API.
  2. An ERROR message sent to the Client SHALL always end the processing of the request.
  3. The fulfillment of particular request MAY require multiple messages to be sent by Service. In such a case, service MUST send the REPLY message first, before any additional message would be sent.
  4. The subsequent messages after REPLY message SHALL be only of message-type DATA, STATE or ERROR.
  5. The Service API for particular Request Code that requires multiple messages to be send by Service SHALL use one from the following methods to indicate the end of request processing to the Client:
    1. Using MORE flag in REPLY, DATA and STATE messages sent to the Client. It is RECOMMENDED to use it as preferred method for organization of the message stream.
    2. Using STATE message with information that indicates the end of request processing.
    3. Continuous processing terminated on Client request by CANCEL message or until Connection is not closed.
  6. The service MAY accept a new request from the client before the initial request has been fully processed. However, all parallel request messages MUST have different (unique) Message token value.
  7. The processing of any active request can be terminated prematurely at the client’s request via the CANCEL message.

2.6 Request codes

The Request Code uniquely identifies the Service functionality (an API call). This specification define following rules for request codes:

  1. A Request Code SHALL be two-byte unsigned integer value (0 to 65,535) passed in type-data field in network byte order.
  2. Values in range 0..999 SHALL be reserved for FBSP (including all future FBSP revisions).
  3. Values in range 1000..65535 SHALL be reserved for free use in Service API.
  4. Any single value from the range defined by rule 3. SHALL NOT be reserved for any single Service API, ie. any API MAY use the same value as another API. This effectively means that the Service must properly announce its API to the Client and therefore the meaning of the specific values before they could be used in REQUEST messages.
  5. The Service MUST process all Request Codes in accordance with the FBSP revision that the Service uses to communicate with a specific Client.

2.6.1 FBSP Request Codes

This specification defines following Request Codes:

FBSP Request Codes
Name Value Implementation Action
UNKNOWN 0 REQUIRED Illegal request. Service SHALL respond with ERROR.
SVC_ABILITIES 1 REQUIRED SHALL return Service abilities
SVC_CONFIG 2 REQUIRED SHALL return current Service configuration
SVC_STATE 3 REQUIRED SHALL return current Service operational state
SVC_SET_CONFIG 4 OPTIONAL SHALL change current Service configuration
SVC_SET_STATE 5 OPTIONAL SHALL change current Service operational state
SVC_CONTROL 6 OPTIONAL SHALL perform Service Control Action
  7..19   Reserved
CON_REPEAT 20 OPTIONAL SHALL repeat last message(s) sent
CON_CONFIG 21 REQUIRED SHALL return current Connection configuration
CON_STATE 22 REQUIRED SHALL return current Connection operational state
CON_SET_CONFIG 23 OPTIONAL SHALL change current Connection configuration
CON_SET_STATE 24 OPTIONAL SHALL change current Connection operational state
CON_CONTROL 25 OPTIONAL SHALL perform Connection Control Action
  26..999   Reserved

Important

Service MUST support and properly handle all request codes marked as required. The status of implementation of optional request codes MUST be properly reported by the service in response to the SVC_ABILITIES request.

UNKNOWN

UNKNOWN is an illegal request and the Service SHALL respond with ERROR message.

SVC_ABILITIES

The Service SHALL reply with single REPLY message that describe its abilities in the data-frame that MUST conform to the protocol-buffer format defined for this Request Code.

SVC_CONFIG

The Service SHALL reply with single REPLY message that describe its current configuration in the data-frame that MUST conform to the protocol-buffer format defined for this Request Code.

See also

SVC_CONFIG data

SVC_STATE

The Service SHALL reply with single REPLY message that describe its current operational state in the data-frame that MUST conform to the protocol-buffer format defined for this Request Code.

See also

SVC_STATE data

SVC_SET_CONFIG

The Service SHALL reply with single REPLY message that describe its abilities in the data-frame that MUST conform to the protocol-buffer format defined for this Request Code.

SVC_SET_STATE
  1. The Service SHALL change its operational state to the one described in data-frame passed in the received REQUEST message.
  2. The Service SHALL reply with single REPLY message that indicates the result in the data-frame.
  3. Both REQUEST and REPLY data-frame MUST conform to the protocol-buffer format defined for this Request Code.
SVC_CONTROL
  1. The Service SHALL perform the Service Control Action described in data-frame passed in the received REQUEST message.
  2. The Service SHALL reply with single REPLY message that indicates the result in the data-frame.
  3. Both REQUEST and REPLY data-frame MUST conform to the protocol-buffer format defined for this Request Code.

See also

SVC_CONTROL data

CON_REPEAT
  1. The Client MUST describe the requested messages in data-frame passed in the REQUEST message, that MUST conform to the protocol-buffer format defined for this Request Code.
  2. The Service SHALL reply with single REPLY message that indicates that request was accepted and Service will start sending requested messages.
  3. The Service SHALL send messages requested by Client as DATA messages related to original REQUEST with one or more data-frame parts that hold the requested message (the control-frame of the requested message is thus the first data-frame of DATA message sent to the Client).
  4. The requested messages SHALL be resent in original order.
  5. The Service SHALL use MORE flag to organize the DATA message stream for the Client.

See also

CON_REPEAT data

CON_CONFIG

The Service SHALL reply with single REPLY message that describe the current configuration of active Connection in the data-frame that MUST conform to the protocol-buffer format defined for this Request Code.

See also

CON_CONFIG data

CON_STATE

The Service SHALL reply with single REPLY message that describe the actual operational state of active Connection in the data-frame that MUST conform to the protocol-buffer format defined for this Request Code.

See also

CON_STATE data

CON_SET_CONFIG
  1. The Service SHALL change the configuration of the Connection to the one described in data-frame passed in the received REQUEST message.
  2. The Service SHALL reply with single REPLY message that indicates the result in the data-frame.
  3. Both REQUEST and REPLY data-frame MUST conform to the protocol-buffer format defined for this Request Code.
CON_SET_STATE
  1. The Service SHALL change the operational state of the Connection to the one described in data-frame passed in the received REQUEST message.
  2. The Service SHALL reply with single REPLY message that indicates the result in the data-frame.
  3. Both REQUEST and REPLY data-frame MUST conform to the protocol-buffer format defined for this Request Code.
CON_CONTROL
  1. The Service SHALL perform the Connection Control Action described in data-frame passed in the received REQUEST message.
  2. The Service SHALL reply with single REPLY message that indicates the result in the data-frame.
  3. Both REQUEST and REPLY data-frame MUST conform to the protocol-buffer format defined for this Request Code.

See also

CON_CONTROL data

2.7 Data frames

Where control-frame contains semantic specification of the message, individual data-frame parts of the message carry data associated with given API call or response.

Number, content and structure of individual data-frames SHALL be defined by API specification for particular message-type and/or Request Code.

2.7.1 General rules

All API and other specifications that define data-frame contents SHALL conform to following rules:

  1. The message SHALL have minimal necessary number of data-frames.
  2. The total size of all data-frames in single message SHOULD NOT exceed 50MB.
  3. Any peer MAY set a Connection limit on total size (in bytes) for any single message transmitted that SHALL NOT be smaller than 1MB. Such limit SHALL be announced to other peer in HELLO and WELCOME message. Such limit MAY be negotiable between peers after Connection is successfully established.
  4. All structured data in data-frames defined by this specification are serialized as single Protocol Buffers message.
  5. All API and other specifications that define rules for data-frame contents SHOULD use serialization to store structured data into data-frame. The RECOMMENDED serialization methods are Protocol Buffers (preferred) or Flat Buffers (in case the direct access to parts of serialized data is required). It is NOT RECOMMENDED to use any verbose serialization format such as JSON or XML. The whole Service API SHOULD use only one serialization method. Serialization method MAY be negotiable between peers.

2.7.2 Common protobuf specifications

All Protocol Buffer specifications use proto3 syntax. This syntax variant does not support required fields, and all fields are optional (basic types will have the default “empty” value when they are not serialized). However, some fields in FBSP specification are considered as mandatory (as “required” in proto2), and should be validated as such by receiver.

State enumeration
enum State {
  option allow_alias = true ;

  UNKNOWN         = 0 ;
  READY           = 1 ;
  RUNNING         = 2 ;
  WAITING         = 3 ;
  SUSPENDED       = 4 ;
  FINISHED        = 5 ;
  ABORTED         = 6 ;

  // Aliases

  CREATED         = 1 ;
  BLOCKED         = 3 ;
  STOPPED         = 4 ;
}
Service handler types
enum ServiceHandlerType {
  PROVIDER = 0 ; Provides the service
  CONSUMER = 1 ; Uses the service
}
Data handler types
enum DataHandlerType {
  NONE       = 0 ; // Does not work with data
  B_PROVIDER = 1 ; // Sends data via bind REP/ROUTER/DEALER/SERVER/STREAM socket
  B_CONSUMER = 2 ; // Accepts data via bind REQ/ROUTER/DEALER/CLIENT/STREAM socket
  C_PROVIDER = 3 ; // Sends data via connected REP/ROUTER/DEALER/SERVER/STREAM socket
  C_CONSUMER = 4 ; // Accepts data via connected REQ/ROUTER/DEALER/CLIENT/STREAM socket
  PUBLISHER  = 5 ; // Broadcasts data via PUB/XPUB/RADIO socket
  SUBSCRIBER = 6 ; // Subscribes to data stream via SUB/XSUB/DISH socket
  FAN_IN     = 7 ; // Collects data via PULL socket
  FAN_OUT    = 8 ; // Distributes data via PUSH socket
}
Protocol description
message ProtocolDescription {
   string uid                = 1
   string version            = 2
   uint32 level              = 3
   repeated string supports  = 4
}
uid:MANDATORY unique protocol ID. It’s RECOMMENDED to use abbreviated protocol name.
version:MANDATORY protocol version. MUST conform to major[.minor] pattern, where major and minor are numbers.
level:Implemented protocol level.
supports:List of implemented optional features. It’s RECOMMENDED to use feature keywords.
Platform identification
message PlatformId {
  string uid     = 1 ;
  string version = 2 ;
}
uid:MANDATORY unique platform ID. It’s RECOMMENDED to use uuid version 5 - SHA1, namespace OID.
version:MANDATORY platform version. MUST conform to major[.minor[.build[-tag]]] pattern, where major, minor and build are numbers, and tag is alphanumeric.
Vendor identification
message VendorId {
  string uid = 1 ;
}
uid:MANDATORY unique vendor ID. It’s RECOMMENDED to use uuid version 5 - SHA1, namespace OID.
Agent identification

A data structure that describes the identity of the Client or Service.

message AgentIdentification {
  string uid            = 1 ;
  string name           = 2 ;
  string version        = 3 ;
  VendorId vendor       = 4 ;
  PlatformId platform   = 5 ;
  string classification = 6 ;
}
uid:MANDATORY unique Agent ID. It’s RECOMMENDED to use uuid version 5 - SHA1, namespace OID.
name:Agent name assigned by vendor. MANDATORY for Service. It’s RECOMMENDED that uid and name make a stable pair, i.e. there should not be agents with the same name but different uid and vice versa.
version:MANDATORY agent version. MUST conform to major[.minor[.build[-tag]]] pattern, where major, minor and build are numbers, and tag is alphanumeric.
vendor:Vendor identification. MANDATORY for Service.
platform:Platform identification. MANDATORY for Service.
classification:Agent classification. It’s RECOMMENDED to use domain/category schema, for example database/backup.
Peer Identification

A data structure that describes the identity of the peer within the FBSP Connection.

import "google/protobuf/any.proto";

message PeerIdentification {
  string uid                              = 1 ;
  string host                             = 2 ;
  uint32 pid                              = 3 ;
  AgentIdentification identity            = 4 ;
  repeated google.protobuf.Any supplement = 5 ;
}
uid:

MANDATORY unique peer ID. It’s RECOMMENDED to use uuid version 1.

host:

MANDATORY host Id

pid:

MANDATORY process Id

identity:

MANDATORY Agent identification

supplement:

Any additional information about peer.

Error Description

A data structure that describes an error.

import "google/protobuf/struct.proto";

message ErrorDescription {
  uint64 code                       = 1 ;
  string description                = 2 ;
  google.protobuf.Struct context    = 3 ;
  google.protobuf.Struct annotation = 4 ;
}
code:MANDATORY service-specific error code.
description:MANDATORY short text description of the error.
context:Structured error context information. The context is for information that accurately identifies the source of the error by the Client.
annotation:Additional structured error information. Annotations are intended for debugging and other internal purposes and MAY be ignored by the Client.

2.7.3 FBSP Data Frames for message types

HELLO data

Data Frame must contain Peer Identification message.

WELCOME data

Data Frame must contain Peer Identification message.

CANCEL data
import "google/protobuf/any.proto";

message CancelRequests {
  string token                            = 1 ;
  repeated google.protobuf.Any supplement = 2 ;
}
token:MANDATORY message-token of the message to be canceled.
supplement:Any additional information required or supported by Service API specification for cancellation of particular message.
STATE data
import "google/protobuf/any.proto";

message StateInformation {
  State state                             = 1 ;
  repeated google.protobuf.Any supplement = 2 ;
}
state:MANDATORY State enumeration
supplement:Any additional state information supported by Service API specification.
ERROR data

Each Data Frame must contain Error Description message.

2.7.4 FBSP Data Frames for Request Codes

SVC_ABILITIES data
message RqSvcAbilities {
  sint32 can_repeat_messages              = 1 ;
  ProtocolDescription service_state       = 2 ;
  ProtocolDescription service_config      = 3 ;
  ProtocolDescription service_control     = 4 ;
  map<string, ServiceAbility> abilities   = 5 ;
}
can_repeat_messages:
 

MANDATORY number of messages that service previously sent to the client that could be resend (see CON_REPEAT Request Code).

Value Meaning
0 Service can’t resend any message
X Service can resend last X messages sent
-1 Service can resend all messages
service_state:

MANDATORY description of the Service State Protocol supported by service.

service_config:

MANDATORY description of the Service Configuration Protocol supported by service.

service_control:
 

MANDATORY description of the Service Control Protocol supported by service.

abilities:

Map of other abilities.

Key = Ability ID. It’s RECOMMENDED to use uuid version 5 - SHA1, namespace OID.

Value = Ability descriptor

message ServiceAbility {
  ServiceHandlerType service_type         = 1 ;
  repeated DataHandlerType data_handler   = 2 ;
  repeated ProtocolDescription protocol   = 3 ;
  repeated google.protobuf.Any supplement = 4 ;
}
service_type:MANDATORY type of service (Provider / Consumer)
data_handler:MANDATORY list of supported data I/O patterns
protocol:MANDATORY list of supported protocols
supplement:List of additional vendor-specific information about service ability
SVC_CONFIG data

The data-frame SHALL conform to 7/RSCFG - Remote Service Configuration Protocol specification.

SVC_STATE data

The data-frame SHALL conform to 6/SSTP - Service State Protocol specification.

SVC_SET_CONFIG data

The data-frame SHALL conform to 7/RSCFG - Remote Service Configuration Protocol specification.

SVC_SET_STATE data

The data-frame SHALL conform to 6/SSTP - Service State Protocol specification.

SVC_CONTROL data

The data-frame SHALL conform to 8/RSCTRL - Remote Service Control Protocol specification.

CON_REPEAT data
message RqConRepeat {
  sint32 last = 1 ;
}
last:MANDATORY number of last messages to resend.
CON_CONFIG data

The data-frame SHALL conform to 7/RSCFG - Remote Service Configuration Protocol specification.

CON_STATE data

The data-frame SHALL conform to 6/SSTP - Service State Protocol specification.

CON_SET_CONFIG data

The data-frame SHALL conform to 7/RSCFG - Remote Service Configuration Protocol specification.

CON_SET_STATE data

The data-frame SHALL conform to 6/SSTP - Service State Protocol specification.

CON_CONTROL data

The data-frame SHALL conform to 8/RSCTRL - Remote Service Control Protocol specification.

2.8 Error codes

Errors are transmitted in type-data field of the ERROR message.

  1. The Error Code is a 11-bit unsigned integer number encoded in upper (leftmost) bits of the type-data field of ERROR message. The Error Code is thus a value in range 0..2047.

  2. The lower (rightmost) 5 bits of type-data field encode the message-type this particular error relates to (the bitmask is 31). The “zero” value represents general, out-of-band error reported by Service.

  3. The Error Code range (0..2047) is divided into next categories:

    1..999     : Reserved by FBSP for general errors indicating that particular request cannot be satisfied ("soft" errors)
    1000..1999 : Reserved for use by Service API
    2000..2047 : Reserved by FBSP for general errors indicating that connection would or should be terminated (severe errors)
    

2.8.1 Error codes defined by FBSP

Todo

Finalize the list of error codes.

Errors indicating that particular request cannot be satisfied
1 - Bad Request:
 The service cannot or will not process the request due to something that is perceived to be a client error (e.g., malformed request syntax, invalid request message framing etc.).
2 - Not Implemented:
 The server does not support the functionality required to fulfill the request.
3 - Protocol Version Not Supported:
 The server does not support, or refuses to support, the version of protocol that was used in the request message. The protocol to which this error refers is any protocol used for a specific request, not the FBSP itself.
4 - Internal Service Error:
 The server encountered an unexpected condition that prevented it from fulfilling the request.
5 - Too Many Requests:
 The client has sent too many requests in a given amount of time (“rate limiting”).
6 - Failed Dependency:
 The request could not be performed because the requested action depended on another action and that action failed.
7 - Gone:The target resource is no longer available and this condition is likely to be permanent.
8 - Conflict:The request could not be completed due to a conflict with the current state of the target resource. This code is used in situations where the user might be able to resolve the conflict and resubmit the request.
9 - Request Timeout:
 The server did not receive a complete request message within the time that it was prepared to wait.
10 - Not Found:The service did not find the target resource or is not willing to disclose that one exists.
11 - Forbidden:The service understood the request but refuses to authorize it.
12 - Unauthorized:
 The request has not been applied because it lacks valid authentication credentials for the target resource.
13 - Payload Too Large:
 The service is refusing to process a request because the request payload is larger than the service is willing or able to process.
14 - Insufficient Storage:
 The service is unable to store data needed to successfully complete the request.
Fatal errors indicating that connection would/should be terminated
2000 - Service Unavailable:
 The server is currently unable to handle the request due to a temporary overload or scheduled maintenance, which will likely be alleviated after some delay.
2001 - FBSP Version Not Supported:
 The server does not support, or refuses to support, the version of FBSP that was used in the HELLO message.

3. Reference Implementations

None at this time. In future, the Saturnin-SDK will act as the prime reference implementation for FBSP.



Appendix A. Transmission patterns

Keep alive

../../_images/aafig-5120da8fe355ebe246abcdfe3e6f435e39c59198.svg

Peer availability check

../../_images/aafig-3f1fe9a5ea5aef5884d3fc36514da3c0463c8295.svg

Failed Client request

../../_images/aafig-22f17fb3ee9415c9ea0359b6c7accb674394edb9.svg

Simple Client request

../../_images/aafig-28743dac85469d8363342dbbabcb910aa6dee34c.svg

Client request with message stream

Using MORE flag for Service -> Client transfer:

../../_images/aafig-27f8a3ac47f01a9d287f1de54cf28222e36f5a4f.svg

Using MORE flag for Client -> Service transfer:

../../_images/aafig-6463c85d79dbb637e3334b31e2c717dd5efaf1eb.svg

Using STATE message (only for Service -> Client transfer):

../../_images/aafig-cca37a03c71605dc5f97894e41cb07f9b8dacb1a.svg

Using CANCEL message (only for Service -> Client transfer):

../../_images/aafig-fbe0a7e6a226f5ffee96abd47c66543ea078b702.svg

Important

There is no guarantee that Service will not send more stream messages in time between CANCEL is sent, and REPLY to cancel request is received by the Client. However, the Service SHALL NOT send any stream message after it sends the REPLY to the CANCEL request.

Synchronous Service -> Client data transfer using ACK-REQUEST/ACK-REPLY flags:

../../_images/aafig-862338a37a5a6f0d1b2e3b8dac31f3559e3e4d8b.svg

Synchronous Client -> Service data transfer using ACK-REQUEST/ACK-REPLY flags:

../../_images/aafig-715159e5d06d10ec97978ad0486f58ea7bd7a9f8.svg

Todo

Describe additional transmission patterns.