//------------------------------------------------------------------------------ // Copyright (c) 2020-2022 EMQ Technologies Co., Ltd. All Rights Reserved. // // 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. //------------------------------------------------------------------------------ syntax = "proto3"; option csharp_namespace = "Emqx.Exhook.V2"; option go_package = "emqx.io/grpc/exhook"; option java_multiple_files = true; option java_package = "io.emqx.exhook"; option java_outer_classname = "EmqxExHookProto"; // The exhook proto version should be fixed as `v2` in EMQX v5.x // to make sure the exhook proto version is compatible package emqx.exhook.v2; service HookProvider { rpc OnProviderLoaded(ProviderLoadedRequest) returns (LoadedResponse) {}; rpc OnProviderUnloaded(ProviderUnloadedRequest) returns (EmptySuccess) {}; rpc OnClientConnect(ClientConnectRequest) returns (EmptySuccess) {}; rpc OnClientConnack(ClientConnackRequest) returns (EmptySuccess) {}; rpc OnClientConnected(ClientConnectedRequest) returns (EmptySuccess) {}; rpc OnClientDisconnected(ClientDisconnectedRequest) returns (EmptySuccess) {}; rpc OnClientAuthenticate(ClientAuthenticateRequest) returns (ValuedResponse) {}; rpc OnClientAuthorize(ClientAuthorizeRequest) returns (ValuedResponse) {}; rpc OnClientSubscribe(ClientSubscribeRequest) returns (EmptySuccess) {}; rpc OnClientUnsubscribe(ClientUnsubscribeRequest) returns (EmptySuccess) {}; rpc OnSessionCreated(SessionCreatedRequest) returns (EmptySuccess) {}; rpc OnSessionSubscribed(SessionSubscribedRequest) returns (EmptySuccess) {}; rpc OnSessionUnsubscribed(SessionUnsubscribedRequest) returns (EmptySuccess) {}; rpc OnSessionResumed(SessionResumedRequest) returns (EmptySuccess) {}; rpc OnSessionDiscarded(SessionDiscardedRequest) returns (EmptySuccess) {}; rpc OnSessionTakenover(SessionTakenoverRequest) returns (EmptySuccess) {}; rpc OnSessionTerminated(SessionTerminatedRequest) returns (EmptySuccess) {}; rpc OnMessagePublish(MessagePublishRequest) returns (ValuedResponse) {}; rpc OnMessageDelivered(MessageDeliveredRequest) returns (EmptySuccess) {}; rpc OnMessageDropped(MessageDroppedRequest) returns (EmptySuccess) {}; rpc OnMessageAcked(MessageAckedRequest) returns (EmptySuccess) {}; } //------------------------------------------------------------------------------ // Request //------------------------------------------------------------------------------ message ProviderLoadedRequest { BrokerInfo broker = 1; RequestMeta meta = 2; } message ProviderUnloadedRequest { RequestMeta meta = 1; } message ClientConnectRequest { ConnInfo conninfo = 1; // MQTT CONNECT packet's properties (MQTT v5.0) // // It should be empty on MQTT v3.1.1/v3.1 or others protocol repeated Property props = 2; RequestMeta meta = 3; } message ClientConnackRequest { ConnInfo conninfo = 1; string result_code = 2; repeated Property props = 3; RequestMeta meta = 4; } message ClientConnectedRequest { ClientInfo clientinfo = 1; RequestMeta meta = 2; } message ClientDisconnectedRequest { ClientInfo clientinfo = 1; string reason = 2; RequestMeta meta = 3; } message ClientAuthenticateRequest { ClientInfo clientinfo = 1; bool result = 2; RequestMeta meta = 3; } message ClientAuthorizeRequest { ClientInfo clientinfo = 1; enum AuthorizeReqType { PUBLISH = 0; SUBSCRIBE = 1; } AuthorizeReqType type = 2; string topic = 3; bool result = 4; RequestMeta meta = 5; } message ClientSubscribeRequest { ClientInfo clientinfo = 1; repeated Property props = 2; repeated TopicFilter topic_filters = 3; RequestMeta meta = 4; } message ClientUnsubscribeRequest { ClientInfo clientinfo = 1; repeated Property props = 2; repeated TopicFilter topic_filters = 3; RequestMeta meta = 4; } message SessionCreatedRequest { ClientInfo clientinfo = 1; RequestMeta meta = 2; } message SessionSubscribedRequest { ClientInfo clientinfo = 1; string topic = 2; SubOpts subopts = 3; RequestMeta meta = 4; } message SessionUnsubscribedRequest { ClientInfo clientinfo = 1; string topic = 2; RequestMeta meta = 3; } message SessionResumedRequest { ClientInfo clientinfo = 1; RequestMeta meta = 2; } message SessionDiscardedRequest { ClientInfo clientinfo = 1; RequestMeta meta = 2; } message SessionTakenoverRequest { ClientInfo clientinfo = 1; RequestMeta meta = 2; } message SessionTerminatedRequest { ClientInfo clientinfo = 1; string reason = 2; RequestMeta meta = 3; } message MessagePublishRequest { Message message = 1; RequestMeta meta = 2; } message MessageDeliveredRequest { ClientInfo clientinfo = 1; Message message = 2; RequestMeta meta = 3; } message MessageDroppedRequest { Message message = 1; string reason = 2; RequestMeta meta = 3; } message MessageAckedRequest { ClientInfo clientinfo = 1; Message message = 2; RequestMeta meta = 3; } //------------------------------------------------------------------------------ // Response //------------------------------------------------------------------------------ // Responsed by `ProviderLoadedRequest` message LoadedResponse { repeated HookSpec hooks = 1; } // Responsed by `ClientAuthenticateRequest` `ClientAuthorizeRequest` `MessagePublishRequest` message ValuedResponse { // The responded value type // - contiune: Use the responded value and execute the next hook // - ignore: Ignore the responded value // - stop_and_return: Use the responded value and stop the chain executing enum ResponsedType { CONTINUE = 0; IGNORE = 1; STOP_AND_RETURN = 2; } ResponsedType type = 1; oneof value { // Boolean result, used on the 'client.authenticate', 'client.authorize' hooks bool bool_result = 3; // Message result, used on the 'message.*' hooks Message message = 4; } } // no Response by other Requests message EmptySuccess { } //------------------------------------------------------------------------------ // Basic data types //------------------------------------------------------------------------------ message BrokerInfo { string version = 1; string sysdescr = 2; int64 uptime = 3; string datetime = 4; } message HookSpec { // The registered hooks name // // Available value: // "client.connect", "client.connack" // "client.connected", "client.disconnected" // "client.authenticate", "client.authorize" // "client.subscribe", "client.unsubscribe" // // "session.created", "session.subscribed" // "session.unsubscribed", "session.resumed" // "session.discarded", "session.takenover" // "session.terminated" // // "message.publish", "message.delivered" // "message.acked", "message.dropped" string name = 1; // The topic filters for message hooks repeated string topics = 2; } message ConnInfo { string node = 1; string clientid = 2; string username = 3; string peerhost = 4; uint32 sockport = 5; string proto_name = 6; string proto_ver = 7; uint32 keepalive = 8; } message ClientInfo { string node = 1; string clientid = 2; string username = 3; string password = 4; string peerhost = 5; uint32 sockport = 6; string protocol = 7; string mountpoint = 8; bool is_superuser = 9; bool anonymous = 10; // common name of client TLS cert string cn = 11; // subject of client TLS cert string dn = 12; } message Message { string node = 1; string id = 2; uint32 qos = 3; string from = 4; string topic = 5; bytes payload = 6; uint64 timestamp = 7; // The key of header can be: // - username: // * Readonly // * The username of sender client // * Value type: utf8 string // - protocol: // * Readonly // * The protocol name of sender client // * Value type: string enum with "mqtt", "mqtt-sn", ... // - peerhost: // * Readonly // * The peerhost of sender client // * Value type: ip address string // - allow_publish: // * Writable // * Whether to allow the message to be published by emqx // * Value type: string enum with "true", "false", default is "true" // // Notes: All header may be missing, which means that the message does not // carry these headers. We can guarantee that clients coming from MQTT, // MQTT-SN, CoAP, LwM2M and other natively supported protocol clients will // carry these headers, but there is no guarantee that messages published // by other means will do, e.g. messages published by HTTP-API map headers = 8; } message Property { string name = 1; string value = 2; } message TopicFilter { string name = 1; uint32 qos = 2; } message SubOpts { // The QoS level uint32 qos = 1; // The group name for shared subscription string share = 2; // The Retain Handling option (MQTT v5.0) // // 0 = Send retained messages at the time of the subscribe // 1 = Send retained messages at subscribe only if the subscription does // not currently exist // 2 = Do not send retained messages at the time of the subscribe uint32 rh = 3; // The Retain as Published option (MQTT v5.0) // // If 1, Application Messages forwarded using this subscription keep the // RETAIN flag they were published with. // If 0, Application Messages forwarded using this subscription have the // RETAIN flag set to 0. // Retained messages sent when the subscription is established have the RETAIN flag set to 1. uint32 rap = 4; // The No Local option (MQTT v5.0) // // If the value is 1, Application Messages MUST NOT be forwarded to a // connection with a ClientID equal to the ClientID of the publishing uint32 nl = 5; } message RequestMeta { string node = 1; string version = 2; string sysdescr = 3; string cluster_name = 4; }