diff --git a/docs/web-mob-contacts.png b/docs/web-mob-contacts.png index e69de29..1ffdc4b 100644 Binary files a/docs/web-mob-contacts.png and b/docs/web-mob-contacts.png differ diff --git a/docs/web-mob-video-call.png b/docs/web-mob-video-call.png index e69de29..77be440 100644 Binary files a/docs/web-mob-video-call.png and b/docs/web-mob-video-call.png differ diff --git a/go.sum b/go.sum index 8431f7a..5459efb 100644 --- a/go.sum +++ b/go.sum @@ -1,110 +1,215 @@ +cel.dev/expr v0.25.2 h1:K6j46C81hXtZQfuX60cVWQFBJahKSE2gfRbNuvr5bFs= cel.dev/expr v0.25.2/go.mod h1:hrXvqGP6G6gyx8UAHSHJ5RGk//1Oj5nXQ2NI02Nrsg4= +cloud.google.com/go v0.123.0 h1:2NAUJwPR47q+E35uaJeYoNhuNEM9kM8SjgRgdeOJUSE= cloud.google.com/go v0.123.0/go.mod h1:xBoMV08QcqUGuPW65Qfm1o9Y4zKZBpGS+7bImXLTAZU= +cloud.google.com/go/auth v0.20.0 h1:kXTssoVb4azsVDoUiF8KvxAqrsQcQtB53DcSgta74CA= cloud.google.com/go/auth v0.20.0/go.mod h1:942/yi/itH1SsmpyrbnTMDgGfdy2BUqIKyd0cyYLc5Q= +cloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIiLpZnkHRbnc= cloud.google.com/go/auth/oauth2adapt v0.2.8/go.mod h1:XQ9y31RkqZCcwJWNSx2Xvric3RrU88hAYYbjDWYDL+c= +cloud.google.com/go/compute/metadata v0.9.0 h1:pDUj4QMoPejqq20dK0Pg2N4yG9zIkYGdBtwLoEkH9Zs= cloud.google.com/go/compute/metadata v0.9.0/go.mod h1:E0bWwX5wTnLPedCKqk3pJmVgCBSM6qQI1yTBdEb3C10= +cloud.google.com/go/firestore v1.22.0 h1:avooeboIq37vKXobrbPUFhFBxS/c3FqmWoX0xs8dO6E= cloud.google.com/go/firestore v1.22.0/go.mod h1:PaM4i7i7ruALSKmlpHXXZaPObcZw0W7ie5UOPr72iTU= +cloud.google.com/go/iam v1.11.0 h1:KieQ9Pb+LLPak1O3Rv3GgCxhnmkYf7Xyh0P5HfF1jFM= cloud.google.com/go/iam v1.11.0/go.mod h1:KP+nKGugNJW4LcLx1uEZcq1ok5sQHFaQehQNl4QDgV4= +cloud.google.com/go/logging v1.18.0 h1:KhzZq+1cSkPH9YUaKLLhLtQxIHitVayBmk0sGfoM9+k= +cloud.google.com/go/logging v1.18.0/go.mod h1:ZGKnpBaURITh+g/uom2VhbiFoFWvejcrHPDhxFtU/gI= +cloud.google.com/go/longrunning v1.1.0 h1:qJ0R0IA8ONaRCNWTRPAS0iAmt1bj3TVgJ40z7ZGRslE= cloud.google.com/go/longrunning v1.1.0/go.mod h1:tH+A/6UvNypiPJWAQaKCsh+xiGbB23wUO8egwUXlD2E= +cloud.google.com/go/monitoring v1.29.0 h1:AHhDsFaSax1/4k+qlIDX/SDGe6hggnfXJ9dkgD9qBPY= cloud.google.com/go/monitoring v1.29.0/go.mod h1:72NOVjJXHY/HBfoLT0+qlCZBT059+9VXLeAnL2PeeVM= +cloud.google.com/go/storage v1.63.0 h1:hvXF2xfg9I32bjujggxgkEZn/Ej6sJ9pieFgeueBLrQ= cloud.google.com/go/storage v1.63.0/go.mod h1:tirWVptrFNo5GEX2DQ47JooF7yaweJdAJ1hYAVMvKzE= +cloud.google.com/go/trace v1.16.0 h1:GmQovzFc5F0CNfl0VLgL64aoTtu7xsM0YajW2GlG9+E= +cloud.google.com/go/trace v1.16.0/go.mod h1:r+bdAn16dKLSV1G2D5v3e58IlQlizfxWrUfjx7kM7X0= filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= +filippo.io/edwards25519 v1.2.0 h1:crnVqOiS4jqYleHd9vaKZ+HKtHfllngJIiOpNpoJsjo= filippo.io/edwards25519 v1.2.0/go.mod h1:xzAOLCNug/yB62zG1bQ8uziwrIqIuxhctzJT18Q77mc= +firebase.google.com/go v3.13.0+incompatible h1:3TdYC3DDi6aHn20qoRkxwGqNgdjtblwVAyRLQwGn/+4= firebase.google.com/go v3.13.0+incompatible/go.mod h1:xlah6XbEyW6tbfSklcfe5FHJIwjt8toICdV5Wh9ptHs= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.33.0 h1:l7+6kwRMJNwdCvYdDl7Eax+wzEYHSnNY7zrrfbhDdTA= github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.33.0/go.mod h1:pJTkW8hEUIIi3Pf65lPZOnn4Y81yCllX6IWk2jNXdkM= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.57.0 h1:jLdiS1vO+XJFyDSWRHBx56r4s/NNtcl5J6KyCcWUX/w= github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.57.0/go.mod h1:8lmpHY+1VRoteiOwyrQMDt1YGXOrFKCz+1wJW7n3ODY= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock v0.57.0 h1:cSjUzZ7KU8hicTgzaSv9NmSyM9fTVK3y5lsBUl3wOis= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock v0.57.0/go.mod h1:dzcEjy1WJ0Q4u9twNR3LcLhNoYMRCrMCMafpxa0TjPQ= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.57.0 h1:RoO5+d7uCmDqovLrHCr2/BuViUXvdcrNxyNM1pN9dDQ= github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.57.0/go.mod h1:YqwkQPrWSC7+byyc1VlKbWLBF5JsW5IoL6xUkemYSXk= +github.com/aws/aws-sdk-go-v2 v1.42.1 h1:9eOTgu1z/dVtYpNZ3/8/XbbaX0x/BqE3HUzAzs6K0ek= github.com/aws/aws-sdk-go-v2 v1.42.1/go.mod h1:5pKeft2eJj+gElQ38Jqg4ibCqh+/AK33/0X3hip7IjM= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.14 h1:3IZY0XAJquT3aHzbkHfPzy4ACPcEjVG0x87KOwtpqGY= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.14/go.mod h1:zwM6veDkhGgQFqkBy+uT28AAYpLu+uFMlPl+rCg/73E= +github.com/aws/aws-sdk-go-v2/config v1.32.27 h1:SJwJ9Q4kM7v5QVSYYyXj3znRr6lNyZEhSgAXmXXcVbI= github.com/aws/aws-sdk-go-v2/config v1.32.27/go.mod h1:uBfrzTRedDmB2u+b6+UlaKJy2O6VSH5un2jP24t/KvQ= +github.com/aws/aws-sdk-go-v2/credentials v1.19.26 h1:Si8kk1kyJnuJWCEgiwpBtTdtgSdR7i611596NnC0YIQ= github.com/aws/aws-sdk-go-v2/credentials v1.19.26/go.mod h1:lBckz+W9SAdNtSDw3pYgQUJDJFcBBWry0GSzw+bK0TY= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.30 h1:/hi1JADLEW9YYryEz1w4GQu0EtP23pP553Cf9KgsDV4= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.30/go.mod h1:/3AOgy4K17Dm4ucMZVC/MJkzy5kmfKUcINRHZyo0koQ= +github.com/aws/aws-sdk-go-v2/feature/s3/transfermanager v0.2.13 h1:zHi0z+ZT207/QPyaCmTr4JksQ0Ty0DM+WXW0xsfckXQ= github.com/aws/aws-sdk-go-v2/feature/s3/transfermanager v0.2.13/go.mod h1:ycxBs1ztF7RbxNWiJoIegPCvsfuO7dCvtyyloQvRgNs= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.30 h1:xM/Is9cKMHa8Jj8zkvWhvrFkZsXJV9E+BB4g0HW0duQ= github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.30/go.mod h1:WueJeNDZvK1fMYEWJIkcivBfEzUkTpBhzlrUKKY8EuA= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.30 h1:jn46zC9LdsVR/ZpMIJqMqb8hHv31BlLx3ulVqNspUOk= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.30/go.mod h1:1hTMsAgbdS/AtUi4bw8+gUuh1pceo+eXRLfpSuSQj3M= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.31 h1:3GUprIsfmGcC5SACIyB0e7E0BM1O1b3Erl5CePYIAeQ= github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.31/go.mod h1:7PuV1yl5e2xnUbm+RqvVg5i2iBM8EyijZNoI9wsOoOc= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.13 h1:mbRIur/BiHK6SKPjoBIXSE/hJ6g6JGRLuxQy1jGjlN4= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.13/go.mod h1:ITg9em2KbJx1s0y4aqRX5OYWG6HBZ5TVR//OdpEZ2CQ= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.23 h1:9Fjh6fi/U5JEStVZijmaMpUwE/gvBJj7x2B/PjbO9To= github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.23/go.mod h1:iMoT2f1tClxrWAAnKCXjZQ6LOmfLrMG14wmnWpM+F14= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.30 h1:/Z5jmNrKsSD7EmDjzAPsm/3L9IuOkzaynklJZ1qX7S4= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.30/go.mod h1:lEzEZnOosE7zi8Z6royW1cFJTD9fpab4Ul1SBrllewk= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.31 h1:uao4A3QZ5UmB326V6KF+qRpv9Tjz7IlnlnTbbANntlU= github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.31/go.mod h1:I/1+z0VwL1GhQyLgkoHDlygpUZ+iTAwOQ/NsftiUL2I= +github.com/aws/aws-sdk-go-v2/service/s3 v1.104.2 h1:bAY6O/TDv1HQnvylh9E247IyIKsUWUt2G965S7qX110= github.com/aws/aws-sdk-go-v2/service/s3 v1.104.2/go.mod h1:zdmCoFO/dSI7GlrwsPqFJI+WlFnSU4Tc8TJnlXrM1Do= +github.com/aws/aws-sdk-go-v2/service/signin v1.2.2 h1:69JEZSDTQ+UNbTWQJCZMmbpQb5sfc79KUt0O7Pyfjmo= github.com/aws/aws-sdk-go-v2/service/signin v1.2.2/go.mod h1:mxC0nT/C8wMMS97DemZPzvUZxvIt+2Iq+eS3JdFZGgg= +github.com/aws/aws-sdk-go-v2/service/sso v1.31.5 h1:xlK3Tdc8FO7Tq1k0+hL+otF33glj+dE+qeM5iINiDvU= github.com/aws/aws-sdk-go-v2/service/sso v1.31.5/go.mod h1:u8af9Nqkmqnr96f7v9nHqzZT9XBwbXEkTiqT4ROuJSE= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.36.8 h1:yX1IbiBfC7SdEgDwIGnRaZyPPDRbQPDOJxl8102PcGk= github.com/aws/aws-sdk-go-v2/service/ssooidc v1.36.8/go.mod h1:DMPWJBjYs6+3+f/qhBFEFPPlQ6NlhWjai3dJNvipJ84= +github.com/aws/aws-sdk-go-v2/service/sts v1.43.5 h1:T3ANO8QWDbzQD8f4+UaX+fvJlyGnOFMKLbW+NGBHg04= github.com/aws/aws-sdk-go-v2/service/sts v1.43.5/go.mod h1:9gdl4RrflIdpDb2TlXshWgR1F9TeCkvqDx77Vpr4Z/Q= +github.com/aws/smithy-go v1.27.3 h1:F3Zb497UhhskkfpJmfkXswyo+t0sh9OTBnIHjogWbVY= github.com/aws/smithy-go v1.27.3/go.mod h1:YE2RhdIuDbA5E5bTdciG9KrW3+TiEONeUWCqxX9i1Fc= +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/bitly/go-hostpool v0.1.0 h1:XKmsF6k5el6xHG3WPJ8U0Ku/ye7njX7W81Ng7O2ioR0= github.com/bitly/go-hostpool v0.1.0/go.mod h1:4gOCgp6+NZnVqlKyZ/iBZFTAJKembaVENUpMkpg42fw= +github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY= github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cncf/xds/go v0.0.0-20260202195803-dba9d589def2 h1:aBangftG7EVZoUb69Os8IaYg++6uMOdKK83QtkkvJik= github.com/cncf/xds/go v0.0.0-20260202195803-dba9d589def2/go.mod h1:qwXFYgsP6T7XnJtbKlf1HP8AjxZZyzxMmc+Lq5GjlU4= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/envoyproxy/go-control-plane v0.14.0 h1:hbG2kr4RuFj222B6+7T83thSPqLjwBIfQawTkC++2HA= +github.com/envoyproxy/go-control-plane v0.14.0/go.mod h1:NcS5X47pLl/hfqxU70yPwL9ZMkUlwlKxtAohpi2wBEU= +github.com/envoyproxy/go-control-plane/envoy v1.37.0 h1:u3riX6BoYRfF4Dr7dwSOroNfdSbEPe9Yyl09/B6wBrQ= github.com/envoyproxy/go-control-plane/envoy v1.37.0/go.mod h1:DReE9MMrmecPy+YvQOAOHNYMALuowAnbjjEMkkWOi6A= +github.com/envoyproxy/go-control-plane/ratelimit v0.1.0 h1:/G9QYbddjL25KvtKTv3an9lx6VBE2cnb8wp1vEGNYGI= +github.com/envoyproxy/go-control-plane/ratelimit v0.1.0/go.mod h1:Wk+tMFAFbCXaJPzVVHnPgRKdUdwW/KdbRt94AzgRee4= +github.com/envoyproxy/protoc-gen-validate v1.3.3 h1:MVQghNeW+LZcmXe7SY1V36Z+WFMDjpqGAGacLe2T0ds= github.com/envoyproxy/protoc-gen-validate v1.3.3/go.mod h1:TsndJ/ngyIdQRhMcVVGDDHINPLWB7C82oDArY51KfB0= +github.com/felixge/httpsnoop v1.1.0 h1:3YtUj32ZZkqZtt3sZZsClsymw/QDuVfpNhoA31zeORc= github.com/felixge/httpsnoop v1.1.0/go.mod h1:Zqxgdd+1Rkcz8euOqdr7lqgCRJztwr5hp9vDSi5UZCE= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/go-jose/go-jose/v4 v4.1.4 h1:moDMcTHmvE6Groj34emNPLs/qtYXRVcd6S7NHbHz3kA= github.com/go-jose/go-jose/v4 v4.1.4/go.mod h1:x4oUasVrzR7071A4TnHLGSPpNOm2a21K9Kf04k1rs08= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= +github.com/go-sql-driver/mysql v1.10.0 h1:Q+1LV8DkHJvSYAdR83XzuhDaTykuDx0l6fkXxoWCWfw= github.com/go-sql-driver/mysql v1.10.0/go.mod h1:M+cqaI7+xxXGG9swrdeUIoPG3Y3KCkF0pZej+SK+nWk= +github.com/golang-jwt/jwt/v5 v5.3.1 h1:kYf81DTWFe7t+1VvL7eS+jKFVWaUnK9cB1qbwn63YCY= github.com/golang-jwt/jwt/v5 v5.3.1/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE= +github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +github.com/golang/snappy v1.0.0 h1:Oy607GVXHs7RtbggtPBnr2RmDArIsAefDwvrdWvRhGs= github.com/golang/snappy v1.0.0/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/google/martian/v3 v3.3.3 h1:DIhPTQrbPkgs2yJYdXU/eNACCG5DVQjySNRNlflZ9Fc= +github.com/google/martian/v3 v3.3.3/go.mod h1:iEPrYcgCF7jA9OtScMFQyAlZZ4YXTKEtJ1E6RWzmBA0= +github.com/google/s2a-go v0.1.9 h1:LGD7gtMgezd8a/Xak7mEWL0PjoTQFvpRudN895yqKW0= github.com/google/s2a-go v0.1.9/go.mod h1:YA0Ei2ZQL3acow2O62kdp9UlnvMmU7kA6Eutn0dXayM= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/enterprise-certificate-proxy v0.3.17 h1:73NfMHdiqo9JFU9+7a5ExpVa10/R29pXfZIaW559nrg= github.com/googleapis/enterprise-certificate-proxy v0.3.17/go.mod h1:rSEsBUemEBZEexP2y6jPp16LUmUbjmSbcPMQizR0o4k= +github.com/googleapis/gax-go/v2 v2.22.0 h1:PjIWBpgGIVKGoCXuiCoP64altEJCj3/Ei+kSU5vlZD4= github.com/googleapis/gax-go/v2 v2.22.0/go.mod h1:irWBbALSr0Sk3qlqb9SyJ1h68WjgeFuiOzI4Rqw5+aY= +github.com/gorilla/handlers v1.5.2 h1:cLTUSsNkgcwhgRqvCNmdbRWG0A3N4F+M2nWKdScwyEE= github.com/gorilla/handlers v1.5.2/go.mod h1:dX+xVpaxdSw+q0Qek8SSsl3dfMk3jNddUkMzo0GtH0w= +github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed h1:5upAirOpQc1Q53c0bnx2ufif5kANL7bfZWcc6VJWJd8= github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= +github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo= github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= +github.com/jackc/pgx/v5 v5.10.0 h1:VhSvgU2jSli8o3AqIEOTJr7rZwAEUVo4E4XhR94Zfr0= github.com/jackc/pgx/v5 v5.10.0/go.mod h1:mal1tBGAFfLHvZzaYh77YS/eC6IX9OWbRV1QIIM0Jn4= +github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo= github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= +github.com/jmoiron/sqlx v1.4.0 h1:1PLqN7S1UYp5t4SrVVnt4nUVNemrDAtxlulVe+Qgm3o= github.com/jmoiron/sqlx v1.4.0/go.mod h1:ZrZ7UsYB/weZdl2Bxg6jCRO9c3YHl8r3ahlKmRT4JLY= +github.com/klauspost/compress v1.19.0 h1:sXLILfc9jV2QYWkzFOPWStmcUVH2RHEB1JCdY2oVvCQ= github.com/klauspost/compress v1.19.0/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/localtunnel/go-localtunnel v0.0.0-20170326223115-8a804488f275 h1:IZycmTpoUtQK3PD60UYBwjaCUHUP7cML494ao9/O8+Q= +github.com/localtunnel/go-localtunnel v0.0.0-20170326223115-8a804488f275/go.mod h1:zt6UU74K6Z6oMOYJbJzYpYucqdcQwSMPBEdSvGiaUMw= +github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU= github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= +github.com/montanaflynn/stats v0.9.0 h1:tsBJ0RXwph9BmAuFoCmqGv6e8xa0MENQ8m0ptKq29mQ= github.com/montanaflynn/stats v0.9.0/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/nyaruka/phonenumbers v1.8.0 h1:TrXNJmbwcAHajzDqin3mLWw57vqLUA6ZjVdeNds0heQ= github.com/nyaruka/phonenumbers v1.8.0/go.mod h1:fsKPJ70O9JetEA4ggnJadYTFWwtGPvu/lETTXNXq6Cs= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgmp0tecUJ0sJuv4pzYCqS9+RGSn52M3FUwPs+uo= github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o= github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg= +github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= +github.com/prometheus/common v0.69.0 h1:OA85nJQS/T/MaYh/Q2CcgDKSGWqNIgrBDvDH85CuiNk= github.com/prometheus/common v0.69.0/go.mod h1:ZzL3f6u94qUxh9p+tJTrF+FvBS1XXbbRAZCQkytAL0Y= +github.com/prometheus/procfs v0.21.1 h1:GljZCt+zSTS+NZq88cyQ1LjZ+RCHp3uVuabBWA5+OJI= github.com/prometheus/procfs v0.21.1/go.mod h1:aB55Cww9pdSJVHk0hUf0inxWyyjPogFIjmHKYgMKmtY= +github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= +github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= +github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= +github.com/sirupsen/logrus v1.9.4 h1:TsZE7l11zFCLZnZ+teH4Umoq5BhEIfIzfRDZ1Uzql2w= github.com/sirupsen/logrus v1.9.4/go.mod h1:ftWc9WdOfJ0a92nsE2jF5u5ZwH8Bv2zdeOC42RjbV2g= +github.com/spiffe/go-spiffe/v2 v2.8.1 h1:eXZMLsu+3MLEPJyGJkolqtVrteZfQdUpOWj6LTiDl/E= github.com/spiffe/go-spiffe/v2 v2.8.1/go.mod h1:47Q0Q9/AqGha8QLHp+kxpH4Wca7X7EnOtlIJy3mxZ3U= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= @@ -112,29 +217,57 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5 github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= +github.com/tinode/jsonco v1.0.0 h1:zVcpjzDvjuA1G+HLrckI5EiiRyq9jgV3x37OQl6e5FE= github.com/tinode/jsonco v1.0.0/go.mod h1:Bnavu3302Qfn2pILMNwASkelodgeew3IvDrbdzU84u8= +github.com/tinode/snowflake v1.0.0 h1:YciQ9ZKn1TrnvpS8yZErt044XJaxWVtR9aMO9rOZVOE= github.com/tinode/snowflake v1.0.0/go.mod h1:5JiaCe3o7QdDeyRcAeZBGVghwRS+ygt2CF/hxmAoptQ= +github.com/twilio/twilio-go v1.30.9 h1:4W4GEV2q0sLQ9xsr1N/97JQlt0c82hZ0ij4qTErstv8= github.com/twilio/twilio-go v1.30.9/go.mod h1:QbitvbvtkV77Jn4BABAKVmxabYSjMyQG4tHey9gfPqg= +github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c= github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= +github.com/xdg-go/scram v1.2.0 h1:bYKF2AEwG5rqd1BumT4gAnvwU/M9nBp2pTSxeZw7Wvs= github.com/xdg-go/scram v1.2.0/go.mod h1:3dlrS0iBaWKYVt2ZfA4cj48umJZ+cAEbR6/SjLA88I8= +github.com/xdg-go/stringprep v1.0.4 h1:XLI/Ng3O1Atzq0oBs3TWm+5ZVgkq2aqdlvP9JtoZ6c8= github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM= +github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 h1:ilQV1hzziu+LLM3zUTJ0trRztfwgjqKnBWNtSRkbmwM= github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78/go.mod h1:aL8wCCfTfSfmXjznFBSZNN13rSJjlIOI1fUNAtF7rmI= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +go.mongodb.org/mongo-driver v1.17.9 h1:IexDdCuuNJ3BHrELgBlyaH9p60JXAvdzWR128q+U5tU= go.mongodb.org/mongo-driver v1.17.9/go.mod h1:LlOhpH5NUEfhxcAwG0UEkMqwYcc4JU18gtCdGudk/tQ= +go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= +go.opentelemetry.io/contrib/detectors/gcp v1.44.0 h1:NmLfL734pJhM0JKaYd2Y28+nY9dPRWYAAbxhRCrKXPw= go.opentelemetry.io/contrib/detectors/gcp v1.44.0/go.mod h1:tNAsgd8avTGke1+MndXlU5Cru4PQ9Ai/cCNWQv/ZJ/s= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.69.0 h1:2yEATaop1/a1I4psnSLgWVPLWwCzkqWakgJy7xTDVy0= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.69.0/go.mod h1:D7J12YRapIekYyPWgGPlA/23pRmpSEZC5xJC/TTLI9U= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.69.0 h1:8tvICD4vSTOOsNrsI4Ljf6C+6UKvpTEH5XY3JMoyPoo= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.69.0/go.mod h1:z9+yiacE0IHRqM4qFfkbt/JYlmYXgss8GY/jXoNuPJI= +go.opentelemetry.io/otel v1.44.0 h1:JjwHmHpA4iZ3wBxluu2fbbE7j4kqlE8jXyAyPXH7HqU= go.opentelemetry.io/otel v1.44.0/go.mod h1:BMgjTHL9WPRlRjL2oZCBTL4whCGtXch2H4BhOPIAyYc= +go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.44.0 h1:hqxVTu/GtBF+vJ8d1fzW7fRxZFvgoDjWcxwwCaFDYpU= +go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.44.0/go.mod h1:z5fVEF4X5v0ESvlJqBrrFlBVoj5EQuefZpzsu7R+x5Q= +go.opentelemetry.io/otel/metric v1.44.0 h1:1w0gILTcHdr3YI+ixLyjemwrVnsMURbTZFrSYCdDdmc= go.opentelemetry.io/otel/metric v1.44.0/go.mod h1:8O7hanEPBNgEMmybD3s2VBKcgWOCsA6tzHBPODAiquo= +go.opentelemetry.io/otel/metric/x v0.66.0 h1:YkCrx1zLOChi9ZcZ6euupOcsgzbVlec7D/xoEU1+cTA= +go.opentelemetry.io/otel/metric/x v0.66.0/go.mod h1:d1+BDj9t96do0/1LoU1ayfCv79ZgNE41qbhBvnMOBZk= +go.opentelemetry.io/otel/sdk v1.44.0 h1:nHYwb9lK+fJPU/dnT6s7W7Z8itMWyqrnVfbheVYrZ58= go.opentelemetry.io/otel/sdk v1.44.0/go.mod h1:Osuydd3Se74nqjAKxid74N5eC+jfEqfTegHRnq58oK0= +go.opentelemetry.io/otel/sdk/metric v1.44.0 h1:3LlKgI+VjbVsjNRFZJZAJ30WjXC5VkNRks6si09iEfI= go.opentelemetry.io/otel/sdk/metric v1.44.0/go.mod h1:5B5pMARnXxKhltooO4xUuCBorl65a4EpnTalObqOigA= +go.opentelemetry.io/otel/trace v1.44.0 h1:jxF5CsGYCe74MCRx2X4g7WsY/VBKRqqpNvXlX/6gtIk= go.opentelemetry.io/otel/trace v1.44.0/go.mod h1:oLl1jrMQAVo6v3GAggN+1VH9VIz9iUSvW53sW1Q8PIE= +go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= +go.yaml.in/yaml/v2 v2.4.4 h1:tuyd0P+2Ont/d6e2rl3be67goVK4R6deVxCUX5vyPaQ= +go.yaml.in/yaml/v2 v2.4.4/go.mod h1:gMZqIpDtDqOfM0uNfy0SkpRhvUryYH0Z6wdMYcacYXQ= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.53.0 h1:QZ4Muo8THX6CizN2vPPd5fBGHyogrdK9fG4wLPFUsto= golang.org/x/crypto v0.53.0/go.mod h1:DNLU434OwVakk9PzuwV8w62mAJpRJL3vsgcfp4Qnsio= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= @@ -144,12 +277,15 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.56.0 h1:Rw8j/hFzGvJUZwNBXnAtf5sVDVt+65SK2C7IxCxZt5o= golang.org/x/net v0.56.0/go.mod h1:D3Ku6r+V6JROoZK144D2XfMHFcMq/0zSfLelVTCFKec= +golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs= golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.21.0 h1:HLII4xRRTtCRkxYp4HNFF0Js/Og6q2i++KXbg0gHCwM= golang.org/x/sync v0.21.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -161,6 +297,7 @@ golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.46.0 h1:noSf2Fq6F8DBgS+LysIkx7rIExoNHJsxOAtPp4rthXw= golang.org/x/sys v0.46.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -168,7 +305,9 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= +golang.org/x/text v0.38.0 h1:sXmwo9DwP3OK9EZ7PqAdaooSGozfl/3a6/xJcbzPRhE= golang.org/x/text v0.38.0/go.mod h1:YXZt3QhHUKYT53r2lLKFIVi6Ao1jdzrTR/KQ09qyxF4= +golang.org/x/time v0.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U= golang.org/x/time v0.15.0/go.mod h1:Y4YMaQmXwGQZoFaVFk4YpCt4FLQMYKZe9oeV/f4MSno= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -178,25 +317,39 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4= +gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E= +google.golang.org/api v0.287.0 h1:CQDMqUiqZZ0U/Yge3zyjAhNQ0OSYEH0PaA7l4xtEen4= google.golang.org/api v0.287.0/go.mod h1:pPW85yt3Iuc3unkpaMhFtMmOqnTdCwCqEOaUlnuxRlQ= +google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= +google.golang.org/genproto v0.0.0-20260630182238-925bb5da69e7 h1:lQG76ePMKmtujel4VIVMiFoHVWVNtJdawbCZJtWlVXU= google.golang.org/genproto v0.0.0-20260630182238-925bb5da69e7/go.mod h1:LwlOWYBU335L+sR55UuR5fbbU8KmEX+3tUHf3SwMmhM= +google.golang.org/genproto/googleapis/api v0.0.0-20260630182238-925bb5da69e7 h1:jQ9p21COKWjP3VwuFrNRiiOTMh3mPpN45R7SLrH/HUU= google.golang.org/genproto/googleapis/api v0.0.0-20260630182238-925bb5da69e7/go.mod h1:KqHwBx2upmfa1XSi1WuRvC+2VGCLtooKkfmyvRbUmqA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260630182238-925bb5da69e7 h1:eM/YSd5bBFagF51o1E745Ta7RwzpW0h+z+QDNZOgmQ8= google.golang.org/genproto/googleapis/rpc v0.0.0-20260630182238-925bb5da69e7/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= +google.golang.org/grpc v1.82.0 h1:vguDnZUPjE26w09A63VoxZPnvPjB5Riyc0mkXPFmAIU= google.golang.org/grpc v1.82.0/go.mod h1:yzTZ1TB1Z3SG+LIYaI+WiE8D5+PZ3ArnrSp8zF3+/ZA= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= +gopkg.in/cenkalti/backoff.v2 v2.2.1 h1:eJ9UAg01/HIHG987TwxvnzK2MgxXq97YY6rYDpY9aII= gopkg.in/cenkalti/backoff.v2 v2.2.1/go.mod h1:S0QdOvT2AlerfSBkp0O+dk+bbIMaNbEmVk876gPCthU= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo= +gopkg.in/rethinkdb/rethinkdb-go.v6 v6.2.2 h1:tczPZjdz6soV2thcuq1IFOuNLrBUGonFyUXBbIWXWis= gopkg.in/rethinkdb/rethinkdb-go.v6 v6.2.2/go.mod h1:c7Wo0IjB7JL9B9Avv0UZKorYJCUhiergpj3u1WtGT1E= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/keygen/README.md b/keygen/README.md index e69de29..d2a5bce 100644 --- a/keygen/README.md +++ b/keygen/README.md @@ -0,0 +1,40 @@ +# keygen: API key generator + +A command-line utility to generate an API key for [Tinode server](../server/) + +**Parameters:** + + * `sequence`: Sequential number of the API key. This value can be used to reject previously issued keys. + * `isroot`: Currently unused. Intended to designate key of a system administrator. + * `validate`: Key to validate: check previously issued key for validity. + * `salt`: [HMAC](https://en.wikipedia.org/wiki/HMAC) salt, 32 random bytes base64 standard encoded; must be present for key validation; optional when generating the key: if missing, a cryptographically-strong salt will be automatically generated. + + +## Usage + +The API key is used to provide some protection from automatic scraping of server API and for identification of client applications. + +* `API key` is used on the client side. +* `HMAC salt` is used on the server side to verify the API key. + +Run the generator: + +```sh +./keygen +``` + +Sample output: + +```text +API key v1 seq1 [ordinary]: AQAAAAABAACGOIyP2vh5avSff5oVvMpk +HMAC salt: TC0Jzr8f28kAspXrb4UYccJUJ63b7CSA16n1qMxxGpw= +``` + +Copy `HMAC salt` to `api_key_salt` parameter in your server [config file](https://github.com/tinode/chat/blob/master/server/tinode.conf). +Copy `API key` to the client applications: + + * TinodeWeb: `API_KEY` in [config.js](https://github.com/tinode/webapp/blob/master/src/config.js) + * Tindroid: `API_KEY` in [Cache.java](https://github.com/tinode/tindroid/blob/master/app/src/main/java/co/tinode/tindroid/Cache.java) + * Tinodious: `kApiKey` in [SharedUtils.swift](https://github.com/tinode/ios/blob/master/TinodiosDB/SharedUtils.swift) + +Rebuild the clients after changing the API key. diff --git a/keygen/keygen.go b/keygen/keygen.go index e69de29..4b3b329 100644 --- a/keygen/keygen.go +++ b/keygen/keygen.go @@ -0,0 +1,174 @@ +package main + +import ( + "bytes" + "crypto/hmac" + "crypto/md5" + "crypto/rand" + "encoding/base64" + "encoding/binary" + "flag" + "fmt" + "log" + "os" +) + +// Generate API key +// Composition: +// +// [1:algorithm version][4:deprecated (used to be application ID)][2:key sequence][1:isRoot][16:signature] = 24 bytes +// +// convertible to base64 without padding. +// All integers are little-endian. +func main() { + version := flag.Int("sequence", 1, "Sequential number of the API key") + isRoot := flag.Int("isroot", 0, "Is this a root API key?") + apikey := flag.String("validate", "", "API key to validate") + hmacSalt := flag.String("salt", "", "HMAC salt, 32 random bytes base64-encoded") + + flag.Parse() + + if *apikey != "" { + if *hmacSalt == "" { + log.Println("Error: must provide HMAC salt for key validation") + os.Exit(1) + } + os.Exit(validate(*apikey, *hmacSalt)) + } else { + os.Exit(generate(*version, *isRoot, *hmacSalt)) + } +} + +const ( + // APIKEY_VERSION is algorithm version. + APIKEY_VERSION = 1 + // APIKEY_APPID is deprecated. + APIKEY_APPID = 4 + // APIKEY_SEQUENCE key serial number. + APIKEY_SEQUENCE = 2 + // APIKEY_WHO is a Root user designator. + APIKEY_WHO = 1 + // APIKEY_SIGNATURE is cryptographic signature. + APIKEY_SIGNATURE = 16 + // APIKEY_LENGTH is total length of the key. + APIKEY_LENGTH = APIKEY_VERSION + APIKEY_APPID + APIKEY_SEQUENCE + APIKEY_WHO + APIKEY_SIGNATURE +) + +func generate(sequence, isRoot int, hmacSaltB64 string) int { + var data [APIKEY_LENGTH]byte + var hmacSalt []byte + + if hmacSaltB64 == "" { + hmacSalt = make([]byte, 32) + _, err := rand.Read(hmacSalt) + if err != nil { + log.Println("Error: Failed to generate HMAC salt", err) + + return 1 + } + } else { + var err error + hmacSalt, err = base64.URLEncoding.DecodeString(hmacSaltB64) + if err != nil { + // Try standard base64 decoding + hmacSalt, err = base64.StdEncoding.DecodeString(hmacSaltB64) + } + if err != nil { + log.Println("Error: Failed to decode HMAC salt", err) + + return 1 + } + } + // Make sure the salt is base64std encoded: tinode.conf requires std encoding. + hmacSaltB64 = base64.StdEncoding.EncodeToString(hmacSalt) + + // [1:algorithm version][4:appid][2:key sequence][1:isRoot] + data[0] = 1 // default algorithm + // deprecated + binary.LittleEndian.PutUint32(data[APIKEY_VERSION:], uint32(0)) + binary.LittleEndian.PutUint16(data[APIKEY_VERSION+APIKEY_APPID:], uint16(sequence)) + data[APIKEY_VERSION+APIKEY_APPID+APIKEY_SEQUENCE] = uint8(isRoot) + + hasher := hmac.New(md5.New, hmacSalt) + hasher.Write(data[:APIKEY_VERSION+APIKEY_APPID+APIKEY_SEQUENCE+APIKEY_WHO]) + signature := hasher.Sum(nil) + + copy(data[APIKEY_VERSION+APIKEY_APPID+APIKEY_SEQUENCE+APIKEY_WHO:], signature) + + var strIsRoot string + if isRoot == 1 { + strIsRoot = "ROOT" + } else { + strIsRoot = "ordinary" + } + + fmt.Printf("API key v%d seq%d [%s]: %s\nHMAC salt: %s\n", 1, sequence, strIsRoot, + base64.URLEncoding.EncodeToString(data[:]), hmacSaltB64) + + return 0 +} + +func validate(apikey string, hmacSaltB64 string) int { + var version uint8 + var deprecated uint32 + var sequence uint16 + var isRoot uint8 + + var strIsRoot string + + hmacSalt, err := base64.URLEncoding.DecodeString(hmacSaltB64) + if err != nil { + // Try standard base64 decoding. + hmacSalt, err = base64.StdEncoding.DecodeString(hmacSaltB64) + } + if err != nil { + log.Println("Error: Failed to decode HMAC salt", err) + + return 1 + } + + if declen := base64.URLEncoding.DecodedLen(len(apikey)); declen != APIKEY_LENGTH { + log.Printf("Error: Invalid key length %d, expecting %d", declen, APIKEY_LENGTH) + + return 1 + } + + data, err := base64.URLEncoding.DecodeString(apikey) + if err != nil { + log.Println("Error: Failed to decode key as base64-URL-encoded", err) + + return 1 + } + + buf := bytes.NewReader(data) + binary.Read(buf, binary.LittleEndian, &version) + + if version != 1 { + log.Println("Error: Unknown signature algorithm ", version) + + return 1 + } + + hasher := hmac.New(md5.New, hmacSalt) + hasher.Write(data[:APIKEY_VERSION+APIKEY_APPID+APIKEY_SEQUENCE+APIKEY_WHO]) + + if signature := hasher.Sum(nil); !bytes.Equal(data[APIKEY_VERSION+APIKEY_APPID+APIKEY_SEQUENCE+APIKEY_WHO:], signature) { + log.Println("Error: Invalid signature ", data, signature) + + return 1 + } + // [1:algorithm version][4:deprecated][2:key sequence][1:isRoot] + binary.Read(buf, binary.LittleEndian, &deprecated) + binary.Read(buf, binary.LittleEndian, &sequence) + binary.Read(buf, binary.LittleEndian, &isRoot) + + if isRoot == 1 { + strIsRoot = "ROOT" + } else { + strIsRoot = "ordinary" + } + + fmt.Printf("Valid v%d seq%d, [%s]\n", version, sequence, strIsRoot) + + return 0 +} diff --git a/loadtest/LICENSE b/loadtest/LICENSE index e69de29..eadd668 100644 --- a/loadtest/LICENSE +++ b/loadtest/LICENSE @@ -0,0 +1,2 @@ +Code in this folder is licensed under Apache 2.0 +http://www.apache.org/licenses/LICENSE-2.0 diff --git a/loadtest/README.md b/loadtest/README.md index e69de29..1c0889f 100644 --- a/loadtest/README.md +++ b/loadtest/README.md @@ -0,0 +1,65 @@ +# Tinode Load Testing + +Content of this directory is for running rudimentary load tests of Tinode server. You need this only if you want to run your own load tests. + +## Tsung + +The `tsung.xml` is a configuration for [Tsung](http://tsung.erlang-projects.org/). The `tinode.beam` is an erlang binary required by the test to generate base64-encoded user-password pairs. The `tinode.erl` is the source for `tinode.beam` (`erlc tinode.erl` -> `tinode.beam`). + +[Install Tsung](http://tsung.erlang-projects.org/user_manual/installation.html), then run the test +``` +tsung -f ./tsung.xml start +``` + +## Gatling + +A similar loadtest scenario is also available in Gatling. The configuration file is `loadtest.scala`. +Run it with (after [installing Gatling](https://gatling.io/docs/current/installation/)): +``` +gatling.sh -sf . -rsf . -rd "na" -s tinode.Loadtest +``` + +Currently, three tests are available: + +* `tinode.Loadtest`: after connecting to server, retrieves user's subscriptions, and publishes a few messages to them one by one. +* `tinode.MeLoadtest`: attempts to max out `me` topic connections. +* `tinode.SingleTopicLoadtest`: connects to and publishes messages to the specified topic (typically, a group topic). + +The script supports passing params via the `JAVA_OPTS` envvar. + +Parameter name | Default value | Description +-------------- | ------------- | ------------- +`num_sessions` | 10000 | Total number of sessions to connect to the server +`ramp` | 300 | Time period in seconds over which to ramp up the load (`0` to `num_sessions`). +`publish_count` | 10 | Number of messages that a user will publish to a topic it subscribes to. +`publish_interval` | 100 | Maximum period of time a user will wait between publishing subsequent messages to a topic. +`accounts` | users.csv | `tinode.Loadtest` and `tinode.SingleTopicLoadtest` only: Path to CSV file containing user accounts to use in loadtest (in format `username,password[,token]` (`token` field is optional). +`topic` | | `tinode.SingleTopicLoadtest` only: topic name to send load to. +`username` | | `tinode.MeLoadtest` only: user to subscribe to `me` topic. +`password` | | `tinode.MeLoadtest` only: user password. + +Examples: +```shell +JAVA_OPTS="-Daccounts=users.csv -Dnum_sessions=100 -Dramp=10" gatling.sh -sf . -rsf . -rd "na" -s tinode.Loadtest +``` +Ramps up load to 100 sessions listed in `users.csv` file over 10 seconds. + +```shell +JAVA_OPTS="-Dusername=user1 -Dpassword=user1123 -Dnum_sessions=10000 -Dramp=600" gatling.sh -sf . -rsf . -rd "na" -s tinode.MeLoadtest +``` +Connects 10000 sessions to `me` topic for `user1` with password `user1123` over 600 seconds. + +```shell +JAVA_OPTS="-Dtopic=grpYOrcDwORhPg -Daccounts=users.csv -Dnum_sessions=10000 -Dramp=1000 -Dpublish_count=2 -Dpublish_interval=300" gatling.sh -sf . -rsf . -rd "na" -s tinode.SingleTopicLoadtest +``` +Connects 10000 users (specified in `users.csv` file) to `grpYOrcDwORhPg` topic over 1000 seconds. Each user will publish 2 messages with interval up to 300 seconds. + +This will be eventually packaged into a docker container. + +### Experiments + +We have tested our single-server Tinode synthetic setup with 50000 accounts on a standard `t3.xlarge` AWS box (4 vCPUs, 16GiB, 5Gbps network) with the `mysql` backend. +As the load increases, before starting to drop: + +* The server can sustain 50000 concurrently connected sessions. +* An individual group topic was able to sustain 1500 concurrent sessions. diff --git a/loadtest/loadtest.scala b/loadtest/loadtest.scala index e69de29..9540e1e 100644 --- a/loadtest/loadtest.scala +++ b/loadtest/loadtest.scala @@ -0,0 +1,133 @@ +package tinode + +import java.util.Base64 +import java.util.concurrent.ConcurrentHashMap + +import scala.collection.JavaConverters._ +import scala.collection._ +import scala.concurrent.duration._ + +import io.gatling.core.Predef._ +import io.gatling.http.Predef._ + +class Loadtest extends TinodeBase { + // Input file can be set with the "accounts" java option. + // E.g. JAVA_OPTS="-Daccounts=/tmp/z.csv" gatling.sh -sf . -rsf . -rd "na" -s tinode.Loadtest + val feeder = csv(System.getProperty("accounts", "users.csv")).random + + val scn = scenario("WebSocket") + .exec(ws("Connect WS").connect("/v0/channels?apikey=AQEAAAABAAD_rAp4DJh05a1HAwFT3A6K")) + .exec(session => session.set("id", "tn-" + session.userId)) + .pause(1) + .exec(hello) + .pause(1) + .feed(feeder) + .doIfOrElse({session => + val uname = session("username").as[String] + var token = session("token").asOption[String] + if (token == None) { + token = tokenCache.get(uname) + } + token == None + }) { loginBasic } { loginToken } + .exitHereIfFailed + .exec(subMe) + .exitHereIfFailed + .exec(getSubs) + .exitHereIfFailed + .doIf({session => + session.attributes.contains("subs") + }) { + exec { session => + // Shuffle subscriptions. + val subs = session("subs").as[Vector[String]] + val shuffled = scala.util.Random.shuffle(subs.toList) + session.set("subs", shuffled) + } + .foreach("${subs}", "sub") { + exec(subTopic) + .exitHereIfFailed + .pause(0, 2) + .doIfOrElse({session => + val topic = session("sub").as[String] + !topic.startsWith("chn") + }) { publish } { pause(5) } + .exec(leaveTopic) + .pause(0, 3) + } + } + .exec(ws("close-ws").close) + + setUp(scn.inject(rampUsers(numSessions) during (rampPeriod.seconds))).protocols(httpProtocol) +} + +class MeLoadtest extends TinodeBase { + val username = System.getProperty("username", "user0") + val password = System.getProperty("password", "user0123") + + val scn = scenario("WebSocket") + .exec(ws("Connect WS").connect("/v0/channels?apikey=AQEAAAABAAD_rAp4DJh05a1HAwFT3A6K")) + .exec(session => session.set("id", "tn-" + session.userId)) + .exec(session => session.set("username", username)) + .exec(session => session.set("password", password)) + .pause(1) + .exec(hello) + .pause(1) + .doIfOrElse({session => + val uname = session("username").as[String] + val token = tokenCache.get(username) + token == None + }) { loginBasic } { loginToken } + .exitHereIfFailed + .exec(subMe) + .exitHereIfFailed + .exec(getSubs) + .exitHereIfFailed + .pause(1000) + .exec(ws("close-ws").close) + + setUp(scn.inject(rampUsers(numSessions) during (rampPeriod.seconds))).protocols(httpProtocol) +} + +class SingleTopicLoadtest extends TinodeBase { + // Input file can be set with the "accounts" java option. + // E.g. JAVA_OPTS="-Daccounts=/tmp/z.csv" gatling.sh -sf . -rsf . -rd "na" -s tinode.Loadtest + val feeder = csv(System.getProperty("accounts", "users.csv")).random + val topic = System.getProperty("topic", "TOPIC_NAME") + + val scn = scenario("WebSocket") + .exec(ws("Connect WS").connect("/v0/channels?apikey=AQEAAAABAAD_rAp4DJh05a1HAwFT3A6K")) + .exec(session => session.set("id", "tn-" + session.userId)) + .pause(1) + .exec(hello) + .pause(1) + .feed(feeder) + .doIfOrElse({session => + val uname = session("username").as[String] + var token = session("token").asOption[String] + if (token == None) { + token = tokenCache.get(uname) + } + token == None + }) { loginBasic } { loginToken } + .exitHereIfFailed + .exec(subMe) + .exitHereIfFailed + .exec(getSubs) + .exitHereIfFailed + .doIf({session => + session.attributes.contains("subs") + }) { + exec(session => session.set("sub", topic)) + .exec(subTopic) + .exitHereIfFailed + .pause(0, 10) + .exec(publish) + .pause(15) + .exec(leaveTopic) + .pause(0, 3) + } + .exec(ws("close-ws").close) + + setUp(scn.inject(rampUsers(numSessions) during (rampPeriod.seconds))).protocols(httpProtocol) +} diff --git a/loadtest/tinode.beam b/loadtest/tinode.beam index e69de29..abb78eb 100644 Binary files a/loadtest/tinode.beam and b/loadtest/tinode.beam differ diff --git a/loadtest/tinode.erl b/loadtest/tinode.erl index e69de29..7662a2f 100644 --- a/loadtest/tinode.erl +++ b/loadtest/tinode.erl @@ -0,0 +1,45 @@ +%% Support module for Tinode load testing with Tsung. +%% Compile using erlc then copy resulting .beam to +%% /usr/local/lib/erlang/lib/tsung-1.7.0/ebin/ +%% Alternatively you can just leave it in the current +%% directory. + +-module(tinode). +-export([rand_user_secret/1, shuffle/1, cache_token/2, read_token/1]). + +%% Produces a secret for use in basic login. +rand_user_secret({Pid, DynData}) -> + base64:encode_to_string(get_rand_secret()). + + +%% Unexported. Picks a random user from a pre-defined list. +get_rand_secret() -> + case rand:uniform(6) of + 1 -> "alice:alice123"; + 2 -> "bob:bob123"; + 3 -> "carol:carol123"; + 4 -> "dave:dave123"; + 5 -> "eve:eve123"; + 6 -> "frank:frank123" + end. + +%% Shuffles a list randomly. +shuffle(L) -> + RandomList=[{rand:uniform(), X} || X <- L], + [X || {_,X} <- lists:sort(RandomList)]. + +%% Reads previously cached auth token for the specified user. +read_token(Uid) -> + {ok, LogDir} = application:get_env(tsung_controller, log_dir_real), + case file:read_file(filename:join(LogDir, Uid)) of + {ok, Data} -> string:trim(Data); + {error, _} -> "" + end. + +%% Saves auth token for the specified user in the log directory. +cache_token(Uid, Token) -> + {ok, LogDir} = application:get_env(tsung_controller, log_dir_real), + {ok, File} = file:open(filename:join(LogDir, Uid), [write]), + file:write(File, Token), + file:close(File), + ok. diff --git a/loadtest/tinode.scala b/loadtest/tinode.scala index e69de29..a083b01 100644 --- a/loadtest/tinode.scala +++ b/loadtest/tinode.scala @@ -0,0 +1,154 @@ +package tinode + +import java.util.Base64 +import java.util.concurrent.ConcurrentHashMap + +import scala.collection.JavaConverters._ +import scala.collection._ +import scala.concurrent.duration._ + +import io.gatling.core.Predef._ +import io.gatling.http.Predef._ + +class TinodeBase extends Simulation { + val httpProtocol = http + .baseUrl("http://localhost:6060") + .wsBaseUrl("ws://localhost:6060") + + // Auth tokens to share between sessions. + val tokenCache : concurrent.Map[String, String] = new ConcurrentHashMap() asScala + // Total number of messages to publish to a topic. + val publishCount = Integer.getInteger("publish_count", 10).toInt + // Maximum interval between publishing messages to a topic. + val publishInterval = Integer.getInteger("publish_interval", 100).toInt + // Total number of sessions. + val numSessions = Integer.getInteger("num_sessions", 10000) + // Ramp up period (0 to numSessions) in seconds. + val rampPeriod = java.lang.Long.getLong("ramp", 300L) + + val hello = exitBlockOnFail { + exec { + ws("hi").sendText( + """{"hi":{"id":"afabb3","ver":"0.22.8","ua":"Gatling-Loadtest/1.0; gatling/1.7.0"}}""" + ) + .await(15 seconds)( + ws.checkTextMessage("hi") + .matching(jsonPath("$.ctrl").find.exists) + ) + } + } + + val loginBasic = exitBlockOnFail { + exec { session => + val uname = session("username").as[String] + val password = session("password").as[String] + val secret = new String(java.util.Base64.getEncoder.encode((uname + ":" + password).getBytes())) + session.set("secret", secret) + } + .exec { + ws("login").sendText( + """{"login":{"id":"${id}-login","scheme":"basic","secret":"${secret}"}}""" + ) + .await(15 seconds)( + ws.checkTextMessage("login-ctrl") + .matching(jsonPath("$.ctrl").find.exists) + .check(jsonPath("$.ctrl.params.token").saveAs("token")) + ) + } + .exec { session => + val uname = session("username").as[String] + val token = session("token").as[String] + tokenCache.put(uname, token) + session + } + } + + val loginToken = exitBlockOnFail { + exec { session => + val uname = session("username").as[String] + var token = session("token").asOption[String] + if (token == None) { + token = tokenCache.get(uname) + } + session.set("token", token.getOrElse("")) + } + .exec { + ws("login-token").sendText( + """{"login":{"id":"${id}-login2","scheme":"token","secret":"${token}"}}""" + ) + .await(15 seconds)( + ws.checkTextMessage("login-ctrl") + .matching(jsonPath("$.ctrl").find.exists) + ) + } + } + + val subMe = exitBlockOnFail { + exec { + ws("sub-me").sendText( + """{"sub":{"id":"${id}-sub-me","topic":"me","get":{"what":"desc"}}}""" + ) + .await(15 seconds)( + ws.checkTextMessage("sub-me-desc") + .matching(jsonPath("$.ctrl").find.exists) + .check(jsonPath("$.ctrl.code").ofType[Int].in(200 to 299)) + ) + } + } + + val subTopic = exitBlockOnFail { + exec { + ws("sub-topic").sendText( + """{"sub":{"id":"${id}-sub-${sub}","topic":"${sub}","get":{"what":"desc sub data del"}}}""" + ) + .await(15 seconds)( + ws.checkTextMessage("sub-topic-ctrl") + .matching(jsonPath("$.ctrl").find.exists) + .check(jsonPath("$.ctrl.code").ofType[Int].in(200 to 299)) + ) + } + } + + val publish = exitBlockOnFail { + exec { + repeat(publishCount, "i") { + exec { + ws("pub-topic").sendText( + """{"pub":{"id":"${id}-pub-${sub}-${i}","topic":"${sub}","content":"This is a Gatling test ${i}"}}""" + ) + .await(15 seconds)( + ws.checkTextMessage("pub-topic-ctrl") + .matching(jsonPath("$.ctrl").find.exists) + .check(jsonPath("$.ctrl.code").ofType[Int].in(200 to 299)) + ) + } + .pause(0, publishInterval) + } + } + } + + val getSubs = exitBlockOnFail { + exec { + ws("get-subs").sendText( + """{"get":{"id":"${id}-get-subs","topic":"me","what":"sub"}}""" + ) + .await(15 seconds)( + ws.checkTextMessage("save-subs") + .matching(jsonPath("$.meta.sub").find.exists) + .check(jsonPath("$.meta.sub[*].topic").findAll.saveAs("subs")) + ) + } + } + + val leaveTopic = exitBlockOnFail { + exec { + ws("leave-topic").sendText( + """{"leave":{"id":"${id}-leave-${sub}","topic":"${sub}"}}""" + ) + .await(15 seconds)( + ws.checkTextMessage("sub-topic-ctrl") + .matching(jsonPath("$.ctrl").find.exists) + ) + } + } +} diff --git a/loadtest/tsung.xml b/loadtest/tsung.xml index e69de29..a1ab44a 100644 --- a/loadtest/tsung.xml +++ b/loadtest/tsung.xml @@ -0,0 +1,136 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {"hi":{"id":"%%_baseid%%01","ver":"0.15","ua":"Tsung-Loadtest/1.0; tsung/1.7.0"}} + + + + + + + + + + + + + + + + {"ctrl":.*"code":200.*} + {"login":{"id":"%%_baseid%%02","scheme":"token","secret":"%%_token%%"}} + + + + + + + {"ctrl":.*"code":200.*} + + {"login":{"id":"%%_baseid%%02","scheme":"basic","secret":"%%_secret%%"}} + + + + + + + + + + {"sub":{"id":"%%_baseid%%03","topic":"me","get":{"what":"desc"}}} + + + + + + + + {"get":{"id":"%%_baseid%%04","topic":"me","what":"sub"}} + + + + + + + + + + + + + + {"sub":{"id":"%%_baseid%%%%_topicx%%%%_ctr%%","topic":"%%_topicx%%","get":{"what":"desc sub data del"}}} + + + + + + + + {"pub":{"id":"%%_baseid%%%%_topicx%%%%_ctr%%%%_counter%%","topic":"%%_topicx%%","content":"This is a Tsung test %%_baseid%% %%_counter%%"}} + + + + + + {"leave":{"id":"%%_baseid%%%%_topicx%%%%_ctr%%","topic":"%%_topicx%%"}} + + + + + + + + + + + + diff --git a/loadtest/users.csv b/loadtest/users.csv index e69de29..4707705 100644 --- a/loadtest/users.csv +++ b/loadtest/users.csv @@ -0,0 +1,7 @@ +username,password +alice,alice123 +bob,bob123 +carol,carol123 +dave,dave123 +eve,eve123 +frank,frank123 diff --git a/monitoring/LICENSE b/monitoring/LICENSE index e69de29..15460df 100644 --- a/monitoring/LICENSE +++ b/monitoring/LICENSE @@ -0,0 +1,2 @@ +Code in this folder and nested folders is licensed under Apache 2.0 +http://www.apache.org/licenses/LICENSE-2.0 diff --git a/monitoring/README.md b/monitoring/README.md index e69de29..cf18679 100644 --- a/monitoring/README.md +++ b/monitoring/README.md @@ -0,0 +1,7 @@ +# Monitoring Support + +This directory contains code related to monitoring Tinode server. Supported monitoring services are +* [Prometheus](https://prometheus.io/) +* [InfluxDB](https://www.influxdata.com/) + +See [exporter/README](./exporter/README.md) for more details. diff --git a/monitoring/exporter/README.md b/monitoring/exporter/README.md index e69de29..8a08527 100644 --- a/monitoring/exporter/README.md +++ b/monitoring/exporter/README.md @@ -0,0 +1,69 @@ +# Tinode Metric Exporter + +This is a simple service which reads JSON monitoring data exposed by Tinode server using [expvar](https://golang.org/pkg/expvar/) and re-publishes it in other formats. Currently the supported formats are: + +* [InfluxDB](https://www.influxdata.com/) [exporter](https://docs.influxdata.com/influxdb/v1.7/tools/api/#write-http-endpoint) **pushes** data to its target backend. This is the default mode. +* [Prometheus](https://prometheus.io/) [exporter](https://prometheus.io/docs/instrumenting/exporters/) which exports data in [prometheus format](https://prometheus.io/docs/concepts/data_model/). The Prometheus monitoring service is expected to **pull/scrape** data from the exporter. + +## Usage + +Exporters are intended to run next to (pair with) Tinode servers: one Exporter per one Tinode server, i.e. a single Exporter provides metrics from a single Tinode server. + +## Configuration + +The exporters are configured by command-line flags: + +### Common flags +* `serve_for` specifies which monitoring service the Exporter will gather metrics for; accepted values: `influxdb`, `prometheus`; default: `influxdb`. +* `tinode_addr` is the address where the Tinode instance publishes `expvar` data to scrape; default: `http://localhost:6060/stats/expvar`. +* `listen_at` is the hostname to bind to for serving the metrics; default: `:6222`. +* `instance` is the Exporter instance name (it may be exported to the upstream backend); default: `exporter`. +* `metric_list` is a comma-separated list of metrics to export; default: `Version,LiveTopics,TotalTopics,LiveSessions,ClusterLeader,TotalClusterNodes,LiveClusterNodes,memstats.Alloc`. + +### InfluxDB +* `influx_push_addr` is the address of InfluxDB target server where the data gets sent; default: `http://localhost:9999/write`. +* `influx_db_version` is the version of InfluxDB (only 1.7 and 2.0 are supported); default: `1.7`. +* `influx_organization` specifies InfluxDB organization to push metrics as; default: `test`; +* `influx_bucket` is the name of InfluxDB storage bucket to store data in (used only in InfluxDB 2.0); default: `test`. +* `influx_auth_token` - InfluxDB authentication token; no default value. +* `influx_push_interval` - InfluxDB push interval in seconds; default: `30`. + +#### Example + +Run InfluxDB Exporter as +``` +./exporter \ + --serve_for=influxdb \ + --tinode_addr=http://localhost:6060/stats/expvar \ + --listen_at=:6222 \ + --instance=exp-0 \ + --influx_push_addr=http://my-influxdb-backend.net/write \ + --influx_db_version=1.7 \ + --influx_organization=myOrg \ + --influx_auth_token=myAuthToken123 \ + --influx_push_interval=30 +``` + +This exporter will push the collected metrics to the specified backend once every 30 seconds. + + +### Prometheus +* `prom_namespace` is a prefix to use for metrics names. If you are monitoring multiple tinode instances you may want to use different namespaces; default: `tinode`. +* `prom_metrics_path` is the path under which to expose the metrics for scraping; default: `/metrics`. +* `prom_timeout` is the Tinode connection timeout in seconds in response to Prometheus scrapes; default: `15`. + +#### Example +Run Prometheus Exporter as +``` +./exporter \ + --serve_for=prometheus \ + --tinode_addr=http://localhost:6060/stats/expvar \ + --listen_at=:6222 \ + --instance=exp-0 \ + --prom_namespace=tinode \ + --prom_metrics_path=/metrics \ + --prom_timeout=15 +``` + +This exporter will serve data at path /metrics, on port 6222. +Once running, configure your Prometheus monitoring installation to collect data from this exporter. diff --git a/monitoring/exporter/build.sh b/monitoring/exporter/build.sh old mode 100644 new mode 100755 index e69de29..3c836f7 --- a/monitoring/exporter/build.sh +++ b/monitoring/exporter/build.sh @@ -0,0 +1,68 @@ +#!/bin/bash + +# This scripts build and archives binaries and supporting files. + +# Supported OSs: mac (darwin), windows, linux. +goplat=( darwin darwin windows linux ) + +# CPUs architectures: amd64 and arm64. The same order as OSs. +goarc=( amd64 arm64 amd64 amd64 ) + +# Number of platform+architectures. +buildCount=${#goplat[@]} + +for line in $@; do + eval "$line" +done + +# Strip 'v' prefix as in v0.16.4 -> 0.16.4. +version=${tag#?} + +if [ -z "$version" ]; then + # Get last git tag as release version. Tag looks like 'v.1.2.3', so strip 'v'. + version=`git describe --tags` + version=${version#?} +fi + +echo "Releasing exporter $version" + +GOSRC=${GOPATH}/src/github.com/tinode + +pushd ${GOSRC}/chat > /dev/null + +# Make sure earlier builds are deleted. +rm -f ./releases/${version}/exporter* + +for (( i=0; i<${buildCount}; i++ )); +do + plat="${goplat[$i]}" + arc="${goarc[$i]}" + + echo "Building ${plat}/${arc}..." + + # Remove possibly existing binaries from earlier builds. + rm -f ./releases/tmp/exporter* + + # Environment to cros-compile for the platform. + env GOOS="${plat}" GOARCH="${arc}" go build \ + -ldflags "-s -w -X main.buildstamp=`git describe --tags`" \ + -o ./releases/tmp/exporter ./monitoring/exporter > /dev/null + + # Build archive. All platforms but Windows use tar for archiving. Windows uses zip. + if [ "$plat" = "windows" ]; then + # Just copy the binary with .exe appended. + cp ./releases/tmp/exporter ./releases/${version}/exporter."${plat}-${arc}".exe + else + plat2=$plat + # Rename 'darwin' tp 'mac' + if [ "$plat" = "darwin" ]; then + plat2=mac + fi + + # Just copy the binary. + cp ./releases/tmp/exporter ./releases/${version}/exporter."${plat2}-${arc}" + fi + +done + +popd > /dev/null diff --git a/monitoring/exporter/main.go b/monitoring/exporter/main.go index e69de29..e64105a 100644 --- a/monitoring/exporter/main.go +++ b/monitoring/exporter/main.go @@ -0,0 +1,211 @@ +package main + +import ( + "flag" + "fmt" + "log" + "net/http" + "strings" + "time" + + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promhttp" + "github.com/prometheus/common/version" +) + +type monitoringService int + +const ( + promService monitoringService = 1 + influxService monitoringService = 2 +) + +const ( + // Minimum interval between InfluxDB pushes in seconds. + minPushInterval = 10 +) + +type promHTTPLogger struct{} + +func (l promHTTPLogger) Println(v ...interface{}) { + log.Println(v...) +} + +func parseMetricList(list string) []string { + metrics := strings.Split(list, ",") + for i, m := range metrics { + metrics[i] = strings.TrimSpace(m) + } + return metrics +} + +// Build version number defined by the compiler: +// +// -ldflags "-X main.buildstamp=value_to_assign_to_buildstamp" +// +// Reported to clients in response to {hi} message. +// For instance, to define the buildstamp as a timestamp of when the server was built add a +// flag to compiler command line: +// +// -ldflags "-X main.buildstamp=`date -u '+%Y%m%dT%H:%M:%SZ'`" +// +// or to set it to git tag: +// +// -ldflags "-X main.buildstamp=`git describe --tags`" +var buildstamp = "undef" + +func main() { + log.Printf("Tinode metrics exporter.") + + var ( + serveFor = flag.String("serve_for", "influxdb", + "Monitoring service to gather metrics for. Available: influxdb, prometheus.") + tinodeAddr = flag.String("tinode_addr", "http://localhost:6060/stats/expvar", + "Address of the Tinode instance to scrape.") + listenAt = flag.String("listen_at", ":6222", + "Host name and port to listen for incoming requests on.") + metricList = flag.String("metric_list", + "Version,LiveTopics,TotalTopics,LiveSessions,ClusterLeader,TotalClusterNodes,LiveClusterNodes,memstats.Alloc", + "Comma-separated list of numeric metrics to scrape and export.") + histoMetricList = flag.String("histo_metric_list", + "RequestLatency,OutgoingMessageSize", + "Comma-separated list of histogram metrics to scrape and export.") + instance = flag.String("instance", "exporter", + "Exporter instance name.") + + // Prometheus-specific arguments. + promNamespace = flag.String("prom_namespace", "tinode", "Prometheus namespace for metrics '_...'") + promMetricsPath = flag.String("prom_metrics_path", "/metrics", "Path under which to expose metrics for Prometheus scrapes.") + promTimeout = flag.Int("prom_timeout", 15, "Tinode connection timeout in seconds in response to Prometheus scrapes.") + + // InfluxDB-specific arguments. + influxPushAddr = flag.String("influx_push_addr", "http://localhost:9999/write", + "Address of InfluxDB target server where the data gets sent.") + influxDBVersion = flag.String("influx_db_version", "1.7", + "Version of InfluxDB (only 1.7 and 2.0 are supported).") + influxOrganization = flag.String("influx_organization", "test", + "InfluxDB organization to push metrics as.") + influxBucket = flag.String("influx_bucket", "test", + "InfluxDB storage bucket to store data in (used only in InfluxDB 2.0).") + influxAuthToken = flag.String("influx_auth_token", "", + "InfluxDB authentication token.") + influxPushInterval = flag.Int("influx_push_interval", 30, + "InfluxDB push interval in seconds.") + ) + flag.Parse() + + var service monitoringService + if *serveFor == "prometheus" { + service = promService + } else if *serveFor == "influxdb" { + service = influxService + } else { + log.Fatal("Invalid monitoring service:" + *serveFor + "; must be either \"prometheus\" or \"influxdb\"") + } + // Validate flags. + switch service { + case promService: + if *promMetricsPath == "/" { + log.Fatal("Serving metrics from / is not supported") + } + case influxService: + if *influxOrganization == "" { + log.Fatal("Must specify --influx_organization") + } + if *influxAuthToken == "" { + log.Fatal("Must specify --influx_auth_token") + } + if *influxBucket == "" { + log.Fatal("Must specify --influx_bucket") + } + if *influxDBVersion != "1.7" && *influxDBVersion != "2.0" { + log.Fatal("The --influx_db_version must be either 1.7 or 2.0") + } + if *influxPushInterval > 0 && *influxPushInterval < minPushInterval { + *influxPushInterval = minPushInterval + log.Println("The --influx_push_interval is too low, reset to", minPushInterval) + } + } + + // Index page at web root. + http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { + var servingPath string + switch service { + case promService: + servingPath = "

Prometheus exporter path: Metrics

" + case influxService: + servingPath = "

InfluxDB push path: Push

" + } + + w.Write([]byte(`Tinode Exporter +

Tinode Exporter

+

Server type` + *serveFor + `

` + servingPath + + `

Build

+
` + version.Info() + ` ` + version.BuildContext() + `
+`)) + }) + + metrics := parseMetricList(*metricList) + histoMetrics := parseMetricList(*histoMetricList) + scraper := Scraper{address: *tinodeAddr, simpleMetrics: metrics, histogramMetrics: histoMetrics} + var serverTypeString string + // Create exporters. + switch service { + case promService: + serverTypeString = *serveFor + promExporter := NewPromExporter(*tinodeAddr, *promNamespace, time.Duration(*promTimeout)*time.Second, &scraper) + registry := prometheus.NewRegistry() + registry.MustRegister(promExporter) + http.Handle(*promMetricsPath, + promhttp.InstrumentMetricHandler( + registry, + promhttp.HandlerFor( + registry, + promhttp.HandlerOpts{ + ErrorLog: &promHTTPLogger{}, + Timeout: time.Duration(*promTimeout) * time.Second, + }, + ), + ), + ) + case influxService: + serverTypeString = fmt.Sprintf("%s, version %s", *serveFor, *influxDBVersion) + influxDBExporter := NewInfluxDBExporter(*influxDBVersion, *influxPushAddr, *influxOrganization, *influxBucket, + *influxAuthToken, *instance, &scraper) + if *influxPushInterval > 0 { + go func() { + interval := time.Duration(*influxPushInterval) * time.Second + ch := time.Tick(interval) + for { + if _, ok := <-ch; ok { + if err := influxDBExporter.Push(); err != nil { + log.Println("InfluxDB push failed:", err) + } + } else { + return + } + } + }() + } else { + log.Println("InfluxDB push interval is zero. Will not push data automatically.") + } + // Forces a data push. + http.HandleFunc("/push", func(w http.ResponseWriter, r *http.Request) { + var msg string + if err := influxDBExporter.Push(); err == nil { + msg = "HTTP 200 OK" + } else { + msg = err.Error() + } + + w.Write([]byte(`Tinode Push +

Tinode Push

+
` + msg + `
+`)) + }) + } + + log.Println("Reading Tinode expvar from", *tinodeAddr) + log.Printf("Exporter running at %s. Server type %s", *listenAt, serverTypeString) + log.Fatalln(http.ListenAndServe(*listenAt, nil)) +} diff --git a/monitoring/exporter/prom_exporter.go b/monitoring/exporter/prom_exporter.go index e69de29..210030d 100644 --- a/monitoring/exporter/prom_exporter.go +++ b/monitoring/exporter/prom_exporter.go @@ -0,0 +1,330 @@ +package main + +import ( + "log" + "time" + + "github.com/prometheus/client_golang/prometheus" +) + +// PromExporter collects metrics in Prometheus format from a Tinode server. +type PromExporter struct { + address string + timeout time.Duration + namespace string + + scraper *Scraper + + up *prometheus.Desc + version *prometheus.Desc + topicsLive *prometheus.Desc + topicsTotal *prometheus.Desc + sessionsLive *prometheus.Desc + sessionsTotal *prometheus.Desc + + numGoroutines *prometheus.Desc + + incomingMessagesWebsockTotal *prometheus.Desc + outgoingMessagesWebsockTotal *prometheus.Desc + + incomingMessagesLongpollTotal *prometheus.Desc + outgoingMessagesLongpollTotal *prometheus.Desc + + incomingMessagesGrpcTotal *prometheus.Desc + outgoingMessagesGrpcTotal *prometheus.Desc + + fileDownloadsTotal *prometheus.Desc + fileUploadsTotal *prometheus.Desc + + ctrlCodesTotal2xx *prometheus.Desc + ctrlCodesTotal3xx *prometheus.Desc + ctrlCodesTotal4xx *prometheus.Desc + ctrlCodesTotal5xx *prometheus.Desc + + clusterLeader *prometheus.Desc + clusterSize *prometheus.Desc + clusterNodesLive *prometheus.Desc + malloced *prometheus.Desc + requestLatencyMsCount *prometheus.Desc + outgoingMessageBytesCount *prometheus.Desc +} + +// NewPromExporter returns an initialized Prometheus exporter. +func NewPromExporter(server, namespace string, timeout time.Duration, scraper *Scraper) *PromExporter { + return &PromExporter{ + address: server, + timeout: timeout, + namespace: namespace, + scraper: scraper, + up: prometheus.NewDesc( + prometheus.BuildFQName(namespace, "", "up"), + "If tinode instance is reachable.", + nil, + nil, + ), + version: prometheus.NewDesc( + prometheus.BuildFQName(namespace, "", "version"), + "The version of this tinode instance.", + nil, + nil, + ), + topicsLive: prometheus.NewDesc( + prometheus.BuildFQName(namespace, "", "topics_live_count"), + "Number of currently active topics.", + nil, + nil, + ), + topicsTotal: prometheus.NewDesc( + prometheus.BuildFQName(namespace, "", "topics_total"), + "Total number of topics used during instance lifetime.", + nil, + nil, + ), + sessionsLive: prometheus.NewDesc( + prometheus.BuildFQName(namespace, "", "sessions_live_count"), + "Number of currently active sessions.", + nil, + nil, + ), + sessionsTotal: prometheus.NewDesc( + prometheus.BuildFQName(namespace, "", "sessions_total"), + "Total number of sessions since instance start.", + nil, + nil, + ), + numGoroutines: prometheus.NewDesc( + prometheus.BuildFQName(namespace, "", "num_goroutines"), + "Number of currently spawned goroutines.", + nil, + nil, + ), + incomingMessagesWebsockTotal: prometheus.NewDesc( + prometheus.BuildFQName(namespace, "", "incoming_messages_websock_total"), + "Total number of incoming messages via websocket.", + nil, + nil, + ), + outgoingMessagesWebsockTotal: prometheus.NewDesc( + prometheus.BuildFQName(namespace, "", "outgoing_messages_websock_total"), + "Total number of outgoiing messages via websocket.", + nil, + nil, + ), + incomingMessagesLongpollTotal: prometheus.NewDesc( + prometheus.BuildFQName(namespace, "", "incoming_messages_longpoll_total"), + "Total number of incoming messages via longpoll.", + nil, + nil, + ), + outgoingMessagesLongpollTotal: prometheus.NewDesc( + prometheus.BuildFQName(namespace, "", "outgoing_messages_longpoll_total"), + "Total number of outgoiing messages via longpoll.", + nil, + nil, + ), + incomingMessagesGrpcTotal: prometheus.NewDesc( + prometheus.BuildFQName(namespace, "", "incoming_messages_grpc_total"), + "Total number of incoming messages via grpc.", + nil, + nil, + ), + outgoingMessagesGrpcTotal: prometheus.NewDesc( + prometheus.BuildFQName(namespace, "", "outgoing_messages_grpc_total"), + "Total number of outgoiing messages via grpc.", + nil, + nil, + ), + fileDownloadsTotal: prometheus.NewDesc( + prometheus.BuildFQName(namespace, "", "file_downloads_total"), + "Total number of large file downloads.", + nil, + nil, + ), + fileUploadsTotal: prometheus.NewDesc( + prometheus.BuildFQName(namespace, "", "file_uploads_total"), + "Total number of large file uploads.", + nil, + nil, + ), + ctrlCodesTotal2xx: prometheus.NewDesc( + prometheus.BuildFQName(namespace, "", "ctrl_codes_total_2xx"), + "Total number of 2xx ctrl response codes.", + nil, + nil, + ), + ctrlCodesTotal3xx: prometheus.NewDesc( + prometheus.BuildFQName(namespace, "", "ctrl_codes_total_3xx"), + "Total number of 3xx ctrl response codes.", + nil, + nil, + ), + ctrlCodesTotal4xx: prometheus.NewDesc( + prometheus.BuildFQName(namespace, "", "ctrl_codes_total_4xx"), + "Total number of 4xx ctrl response codes.", + nil, + nil, + ), + ctrlCodesTotal5xx: prometheus.NewDesc( + prometheus.BuildFQName(namespace, "", "ctrl_codes_total_5xx"), + "Total number of 5xx ctrl response codes.", + nil, + nil, + ), + clusterLeader: prometheus.NewDesc( + prometheus.BuildFQName(namespace, "", "cluster_leader"), + "If this cluster node is the cluster leader.", + nil, + nil, + ), + clusterSize: prometheus.NewDesc( + prometheus.BuildFQName(namespace, "", "cluster_size"), + "Configured number of cluster nodes.", + nil, + nil, + ), + clusterNodesLive: prometheus.NewDesc( + prometheus.BuildFQName(namespace, "", "cluster_nodes_live"), + "Number of cluster nodes believed to be live by the current node.", + nil, + nil, + ), + malloced: prometheus.NewDesc( + prometheus.BuildFQName(namespace, "", "malloced_bytes"), + "Number of bytes of memory allocated and in use.", + nil, + nil, + ), + requestLatencyMsCount: prometheus.NewDesc( + prometheus.BuildFQName(namespace, "", "request_latency_ms_count"), + "Request latency histogram (in ms).", + nil, + nil, + ), + outgoingMessageBytesCount: prometheus.NewDesc( + prometheus.BuildFQName(namespace, "", "outgoing_message_bytes"), + "Response size histogram (in bytes).", + nil, + nil, + ), + } +} + +// Describe describes all the metrics exported by the memcached exporter. It +// implements prometheus.Collector. +func (e *PromExporter) Describe(ch chan<- *prometheus.Desc) { + ch <- e.up + ch <- e.version + ch <- e.topicsLive + ch <- e.topicsTotal + ch <- e.sessionsLive + ch <- e.sessionsTotal + ch <- e.numGoroutines + + ch <- e.incomingMessagesWebsockTotal + ch <- e.outgoingMessagesWebsockTotal + + ch <- e.incomingMessagesLongpollTotal + ch <- e.outgoingMessagesLongpollTotal + + ch <- e.incomingMessagesGrpcTotal + ch <- e.outgoingMessagesGrpcTotal + + ch <- e.fileDownloadsTotal + ch <- e.fileUploadsTotal + + ch <- e.ctrlCodesTotal2xx + ch <- e.ctrlCodesTotal3xx + ch <- e.ctrlCodesTotal4xx + ch <- e.ctrlCodesTotal5xx + + ch <- e.clusterLeader + ch <- e.clusterSize + ch <- e.clusterNodesLive + ch <- e.malloced + + ch <- e.requestLatencyMsCount + ch <- e.outgoingMessageBytesCount +} + +// Collect fetches statistics from the configured Tinode instance, and +// delivers them as Prometheus metrics. It implements prometheus.Collector. +func (e *PromExporter) Collect(ch chan<- prometheus.Metric) { + up := float64(1) + if stats, err := e.scraper.Scrape(); err != nil { + log.Println("Failed to fetch or parse response", err) + up = 0 + } else { + if err := e.parseStats(ch, stats); err != nil { + up = 0 + } + } + + ch <- prometheus.MustNewConstMetric(e.up, prometheus.GaugeValue, up) +} + +func (e *PromExporter) parseStats(ch chan<- prometheus.Metric, stats map[string]interface{}) error { + err := firstError( + e.parseAndUpdate(ch, e.version, prometheus.GaugeValue, stats, "Version"), + e.parseAndUpdate(ch, e.topicsLive, prometheus.GaugeValue, stats, "LiveTopics"), + e.parseAndUpdate(ch, e.topicsTotal, prometheus.CounterValue, stats, "TotalTopics"), + e.parseAndUpdate(ch, e.sessionsLive, prometheus.GaugeValue, stats, "LiveSessions"), + e.parseAndUpdate(ch, e.sessionsTotal, prometheus.CounterValue, stats, "TotalSessions"), + e.parseAndUpdate(ch, e.numGoroutines, prometheus.GaugeValue, stats, "NumGoroutines"), + + e.parseAndUpdate(ch, e.incomingMessagesWebsockTotal, prometheus.CounterValue, stats, "IncomingMessagesWebsockTotal"), + e.parseAndUpdate(ch, e.outgoingMessagesWebsockTotal, prometheus.CounterValue, stats, "OutgoingMessagesWebsockTotal"), + + e.parseAndUpdate(ch, e.incomingMessagesLongpollTotal, prometheus.CounterValue, stats, "IncomingMessagesLongpollTotal"), + e.parseAndUpdate(ch, e.outgoingMessagesLongpollTotal, prometheus.CounterValue, stats, "OutgoingMessagesLongpollTotal"), + + e.parseAndUpdate(ch, e.incomingMessagesGrpcTotal, prometheus.CounterValue, stats, "IncomingMessagesGrpcTotal"), + e.parseAndUpdate(ch, e.outgoingMessagesGrpcTotal, prometheus.CounterValue, stats, "OutgoingMessagesGrpcTotal"), + + e.parseAndUpdate(ch, e.fileDownloadsTotal, prometheus.CounterValue, stats, "FileDownloadsTotal"), + e.parseAndUpdate(ch, e.fileUploadsTotal, prometheus.CounterValue, stats, "FileUploadsTotal"), + + e.parseAndUpdate(ch, e.ctrlCodesTotal2xx, prometheus.CounterValue, stats, "CtrlCodesTotal2xx"), + e.parseAndUpdate(ch, e.ctrlCodesTotal3xx, prometheus.CounterValue, stats, "CtrlCodesTotal3xx"), + e.parseAndUpdate(ch, e.ctrlCodesTotal4xx, prometheus.CounterValue, stats, "CtrlCodesTotal4xx"), + e.parseAndUpdate(ch, e.ctrlCodesTotal5xx, prometheus.CounterValue, stats, "CtrlCodesTotal5xx"), + + e.parseAndUpdate(ch, e.clusterLeader, prometheus.GaugeValue, stats, "ClusterLeader"), + e.parseAndUpdate(ch, e.clusterSize, prometheus.GaugeValue, stats, "TotalClusterNodes"), + e.parseAndUpdate(ch, e.clusterNodesLive, prometheus.GaugeValue, stats, "LiveClusterNodes"), + e.parseAndUpdate(ch, e.malloced, prometheus.GaugeValue, stats, "memstats.Alloc"), + + e.parseAndUpdateHisto(ch, e.requestLatencyMsCount, stats, "RequestLatency"), + e.parseAndUpdateHisto(ch, e.outgoingMessageBytesCount, stats, "OutgoingMessageSize"), + ) + + return err +} + +func (e *PromExporter) parseAndUpdate(ch chan<- prometheus.Metric, desc *prometheus.Desc, valueType prometheus.ValueType, + stats map[string]interface{}, key string) error { + v, err := parseNumeric(stats, key) + if err != nil { + return err + } + ch <- prometheus.MustNewConstMetric(desc, valueType, v) + return nil +} + +func (e *PromExporter) parseAndUpdateHisto(ch chan<- prometheus.Metric, desc *prometheus.Desc, + stats map[string]interface{}, key string) error { + h, err := parseHisto(stats, key) + if err != nil { + return err + } + ch <- prometheus.MustNewConstHistogram(desc, h.count, h.sum, h.buckets) + return nil +} + +func firstError(errs ...error) error { + for _, v := range errs { + if v != nil { + return v + } + } + return nil +} diff --git a/monitoring/exporter/scraper.go b/monitoring/exporter/scraper.go index e69de29..5745377 100644 --- a/monitoring/exporter/scraper.go +++ b/monitoring/exporter/scraper.go @@ -0,0 +1,166 @@ +package main + +import ( + "encoding/json" + "errors" + "log" + "net/http" + "strings" +) + +// Scraper collects metrics from a tinode server. +type Scraper struct { + // Target Tinode server address. + address string + // List of simple numeric metrics to scrape. + simpleMetrics []string + // List of histogram metrics to scrape. + histogramMetrics []string +} + +// Histogram struct. +type histogram struct { + count uint64 + sum float64 + buckets map[float64]uint64 +} + +var errKeyNotFound = errors.New("key not found") +var errMalformed = errors.New("input malformed") + +// CollectRaw gathers all metrics from the configured Tinode instance, +// and returns them as a map. +func (s *Scraper) CollectRaw() (map[string]interface{}, error) { + stats, err := s.Scrape() + if err != nil { + log.Println("Failed to fetch or parse response", err) + return nil, err + } + metrics, err := s.parseStatsRaw(stats) + if err != nil { + return nil, err + } + metrics["up"] = 1.0 + return metrics, nil +} + +// Scrape fetches the data from Tinode server using HTTP GET then decodes the response. +func (s *Scraper) Scrape() (map[string]interface{}, error) { + resp, err := http.Get(s.address) + if err != nil { + log.Println("Failed to connect to server", err) + return nil, err + } + defer resp.Body.Close() + + var stats map[string]interface{} + err = json.NewDecoder(resp.Body).Decode(&stats) + return stats, err +} + +func (s *Scraper) parseStatsRaw(stats map[string]interface{}) (map[string]interface{}, error) { + metrics := make(map[string]interface{}) + for _, key := range s.simpleMetrics { + if val, err := parseNumeric(stats, key); err == nil { + metrics[key] = val + } else { + return nil, err + } + } + for _, key := range s.histogramMetrics { + if val, err := parseHisto(stats, key); err == nil { + metrics[key] = val + } else { + return nil, err + } + } + return metrics, nil +} + +// Extracts a simple histogram from `stats` and returns a cumulative histogram +// corresponding to the simple histogram. +// Returns: (count, sum, buckets, error) tuple. +func parseHisto(stats map[string]interface{}, key string) (*histogram, error) { + // Histogram is presented as a json with the predefined fields: count, sum, count_per_bucket, bounds. + count, err := parseNumeric(stats, key+".count") + if err != nil { + return nil, err + } + sum, err := parseNumeric(stats, key+".sum") + if err != nil { + return nil, err + } + buckets, err := parseList(stats, key+".count_per_bucket") + if err != nil { + return nil, err + } + bounds, err := parseList(stats, key+".bounds") + if err != nil { + return nil, err + } + n := len(buckets) + if n != len(bounds)+1 { + return nil, errMalformed + } + result := make(map[float64]uint64) + s := uint64(0) + for i, v := range bounds { + s += uint64(buckets[i]) + result[v] = s + } + return &histogram{count: uint64(count), sum: sum, buckets: result}, nil +} + +// Extracts a list of numerics from `stats` for the given path. +func parseList(stats map[string]interface{}, path string) ([]float64, error) { + value, err := parseMetric(stats, path) + if err != nil { + return nil, err + } + listval, ok := value.([]interface{}) + if !ok { + log.Println("Value at path is not a float64 array:", path, value) + return nil, errMalformed + } + result := []float64{} + for _, v := range listval { + result = append(result, v.(float64)) + } + return result, nil +} + +// Extracts a numeric from `stats` for the given path. +func parseNumeric(stats map[string]interface{}, path string) (float64, error) { + value, err := parseMetric(stats, path) + if err != nil { + return 0, err + } + floatval, ok := value.(float64) + if !ok { + log.Println("Value at path is not a float64:", path, value) + return 0, errKeyNotFound + } + return floatval, nil +} + +// Extracts a metric from `stats` for the given path. +func parseMetric(stats map[string]interface{}, path string) (interface{}, error) { + parts := strings.Split(path, ".") + var value interface{} + var found bool + value = stats + for i := 0; i < len(parts); i++ { + subset, ok := value.(map[string]interface{}) + if !ok { + log.Println("Invalid key path:", path) + return 0, errKeyNotFound + } + value, found = subset[parts[i]] + if !found { + log.Println("Invalid key path:", path, "(", parts[i], ")") + return 0, errKeyNotFound + } + } + + return value, nil +} diff --git a/pbx/README.md b/pbx/README.md index e69de29..43d4e42 100644 --- a/pbx/README.md +++ b/pbx/README.md @@ -0,0 +1,23 @@ +# Protocol Buffer and gRPC definitions + +Definitions for Tinode [gRPC](https://grpc.io/) client and plugins. + +Tinode gRPC clients must implement rpc service `Node`, Tinode plugins `Plugin`. + +Generated `Go` and `Python` code is included. For a sample `Python` implementation of a command line client see [tn-cli](../tn-cli/). +For a partial plugin implementation see [chatbot](../chatbot/). + +If you want to make changes, you have to install protobuffers tool chain and gRPC: +``` +$ python -m pip install grpcio grpcio-tools googleapis-common-protos +``` + +To generate `Go` bindings add the following comment to your code and run `go generate` (your actual path to `/pbx` may be different): +``` +//go:generate protoc --proto_path=../pbx --go_out=plugins=grpc:../pbx ../pbx/model.proto +``` + +To generate `Python` bindings: +``` +python -m grpc_tools.protoc -I../pbx --python_out=. --grpc_python_out=. ../pbx/model.proto +``` diff --git a/pbx/go-generate.sh b/pbx/go-generate.sh old mode 100644 new mode 100755 index e69de29..a50d099 --- a/pbx/go-generate.sh +++ b/pbx/go-generate.sh @@ -0,0 +1,2 @@ +#!/bin/bash +protoc --go_out=../pbx --go_opt=paths=source_relative --go-grpc_out=../pbx --go-grpc_opt=paths=source_relative model.proto diff --git a/pbx/model.pb.go b/pbx/model.pb.go index e69de29..78e7162 100644 --- a/pbx/model.pb.go +++ b/pbx/model.pb.go @@ -0,0 +1,5846 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.27.1 +// protoc v7.34.1 +// source: model.proto + +package pbx + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// Authentication level +type AuthLevel int32 + +const ( + AuthLevel_NONE AuthLevel = 0 + AuthLevel_ANON AuthLevel = 10 + AuthLevel_AUTH AuthLevel = 20 + AuthLevel_ROOT AuthLevel = 30 +) + +// Enum value maps for AuthLevel. +var ( + AuthLevel_name = map[int32]string{ + 0: "NONE", + 10: "ANON", + 20: "AUTH", + 30: "ROOT", + } + AuthLevel_value = map[string]int32{ + "NONE": 0, + "ANON": 10, + "AUTH": 20, + "ROOT": 30, + } +) + +func (x AuthLevel) Enum() *AuthLevel { + p := new(AuthLevel) + *p = x + return p +} + +func (x AuthLevel) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (AuthLevel) Descriptor() protoreflect.EnumDescriptor { + return file_model_proto_enumTypes[0].Descriptor() +} + +func (AuthLevel) Type() protoreflect.EnumType { + return &file_model_proto_enumTypes[0] +} + +func (x AuthLevel) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use AuthLevel.Descriptor instead. +func (AuthLevel) EnumDescriptor() ([]byte, []int) { + return file_model_proto_rawDescGZIP(), []int{0} +} + +type InfoNote int32 + +const ( + // Invalid value. The name must be globally unique. + InfoNote_X1 InfoNote = 0 + InfoNote_READ InfoNote = 1 + InfoNote_RECV InfoNote = 2 + InfoNote_KP InfoNote = 3 + InfoNote_CALL InfoNote = 4 +) + +// Enum value maps for InfoNote. +var ( + InfoNote_name = map[int32]string{ + 0: "X1", + 1: "READ", + 2: "RECV", + 3: "KP", + 4: "CALL", + } + InfoNote_value = map[string]int32{ + "X1": 0, + "READ": 1, + "RECV": 2, + "KP": 3, + "CALL": 4, + } +) + +func (x InfoNote) Enum() *InfoNote { + p := new(InfoNote) + *p = x + return p +} + +func (x InfoNote) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (InfoNote) Descriptor() protoreflect.EnumDescriptor { + return file_model_proto_enumTypes[1].Descriptor() +} + +func (InfoNote) Type() protoreflect.EnumType { + return &file_model_proto_enumTypes[1] +} + +func (x InfoNote) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use InfoNote.Descriptor instead. +func (InfoNote) EnumDescriptor() ([]byte, []int) { + return file_model_proto_rawDescGZIP(), []int{1} +} + +type CallEvent int32 + +const ( + // Invalid value. The name must be globally unique. + CallEvent_X2 CallEvent = 0 + CallEvent_ACCEPT CallEvent = 1 + CallEvent_ANSWER CallEvent = 2 + CallEvent_HANG_UP CallEvent = 3 + CallEvent_ICE_CANDIDATE CallEvent = 4 + CallEvent_INVITE CallEvent = 5 + CallEvent_OFFER CallEvent = 6 + CallEvent_RINGING CallEvent = 7 +) + +// Enum value maps for CallEvent. +var ( + CallEvent_name = map[int32]string{ + 0: "X2", + 1: "ACCEPT", + 2: "ANSWER", + 3: "HANG_UP", + 4: "ICE_CANDIDATE", + 5: "INVITE", + 6: "OFFER", + 7: "RINGING", + } + CallEvent_value = map[string]int32{ + "X2": 0, + "ACCEPT": 1, + "ANSWER": 2, + "HANG_UP": 3, + "ICE_CANDIDATE": 4, + "INVITE": 5, + "OFFER": 6, + "RINGING": 7, + } +) + +func (x CallEvent) Enum() *CallEvent { + p := new(CallEvent) + *p = x + return p +} + +func (x CallEvent) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (CallEvent) Descriptor() protoreflect.EnumDescriptor { + return file_model_proto_enumTypes[2].Descriptor() +} + +func (CallEvent) Type() protoreflect.EnumType { + return &file_model_proto_enumTypes[2] +} + +func (x CallEvent) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use CallEvent.Descriptor instead. +func (CallEvent) EnumDescriptor() ([]byte, []int) { + return file_model_proto_rawDescGZIP(), []int{2} +} + +// Plugin response codes +type RespCode int32 + +const ( + // Instruct Tinode server to continue with default processing of the client request. + RespCode_CONTINUE RespCode = 0 + // Drop the request as if the client did not send it + RespCode_DROP RespCode = 1 + // Send the the provided srvmsg response to the client. ServerResp must contain non-zero + // srvmsg. + RespCode_RESPOND RespCode = 2 + // Replace client's original request with the provided clmsg request then continue with + // processing. ServerResp must contain non-zero clmsg. + RespCode_REPLACE RespCode = 3 +) + +// Enum value maps for RespCode. +var ( + RespCode_name = map[int32]string{ + 0: "CONTINUE", + 1: "DROP", + 2: "RESPOND", + 3: "REPLACE", + } + RespCode_value = map[string]int32{ + "CONTINUE": 0, + "DROP": 1, + "RESPOND": 2, + "REPLACE": 3, + } +) + +func (x RespCode) Enum() *RespCode { + p := new(RespCode) + *p = x + return p +} + +func (x RespCode) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (RespCode) Descriptor() protoreflect.EnumDescriptor { + return file_model_proto_enumTypes[3].Descriptor() +} + +func (RespCode) Type() protoreflect.EnumType { + return &file_model_proto_enumTypes[3] +} + +func (x RespCode) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use RespCode.Descriptor instead. +func (RespCode) EnumDescriptor() ([]byte, []int) { + return file_model_proto_rawDescGZIP(), []int{3} +} + +type Crud int32 + +const ( + Crud_CREATE Crud = 0 + Crud_UPDATE Crud = 1 + Crud_DELETE Crud = 2 +) + +// Enum value maps for Crud. +var ( + Crud_name = map[int32]string{ + 0: "CREATE", + 1: "UPDATE", + 2: "DELETE", + } + Crud_value = map[string]int32{ + "CREATE": 0, + "UPDATE": 1, + "DELETE": 2, + } +) + +func (x Crud) Enum() *Crud { + p := new(Crud) + *p = x + return p +} + +func (x Crud) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (Crud) Descriptor() protoreflect.EnumDescriptor { + return file_model_proto_enumTypes[4].Descriptor() +} + +func (Crud) Type() protoreflect.EnumType { + return &file_model_proto_enumTypes[4] +} + +func (x Crud) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use Crud.Descriptor instead. +func (Crud) EnumDescriptor() ([]byte, []int) { + return file_model_proto_rawDescGZIP(), []int{4} +} + +// What to delete, either "msg" to delete messages (default) or "topic" to delete the topic or "sub" +// to delete a subscription to topic. +type ClientDel_What int32 + +const ( + // Invalid value. The name must be globally unique. + ClientDel_X0 ClientDel_What = 0 + ClientDel_MSG ClientDel_What = 1 + ClientDel_TOPIC ClientDel_What = 2 + ClientDel_SUB ClientDel_What = 3 + ClientDel_USER ClientDel_What = 4 + ClientDel_CRED ClientDel_What = 5 +) + +// Enum value maps for ClientDel_What. +var ( + ClientDel_What_name = map[int32]string{ + 0: "X0", + 1: "MSG", + 2: "TOPIC", + 3: "SUB", + 4: "USER", + 5: "CRED", + } + ClientDel_What_value = map[string]int32{ + "X0": 0, + "MSG": 1, + "TOPIC": 2, + "SUB": 3, + "USER": 4, + "CRED": 5, + } +) + +func (x ClientDel_What) Enum() *ClientDel_What { + p := new(ClientDel_What) + *p = x + return p +} + +func (x ClientDel_What) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ClientDel_What) Descriptor() protoreflect.EnumDescriptor { + return file_model_proto_enumTypes[5].Descriptor() +} + +func (ClientDel_What) Type() protoreflect.EnumType { + return &file_model_proto_enumTypes[5] +} + +func (x ClientDel_What) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use ClientDel_What.Descriptor instead. +func (ClientDel_What) EnumDescriptor() ([]byte, []int) { + return file_model_proto_rawDescGZIP(), []int{18, 0} +} + +type ServerPres_What int32 + +const ( + // Invalid value. The name must be globally unique. + ServerPres_X3 ServerPres_What = 0 + ServerPres_ON ServerPres_What = 1 + ServerPres_OFF ServerPres_What = 2 + ServerPres_UA ServerPres_What = 3 + ServerPres_UPD ServerPres_What = 4 + ServerPres_GONE ServerPres_What = 5 + ServerPres_ACS ServerPres_What = 6 + ServerPres_TERM ServerPres_What = 7 + ServerPres_MSG ServerPres_What = 8 + ServerPres_READ ServerPres_What = 9 + ServerPres_RECV ServerPres_What = 10 + ServerPres_DEL ServerPres_What = 11 + ServerPres_TAGS ServerPres_What = 12 + ServerPres_AUX ServerPres_What = 13 +) + +// Enum value maps for ServerPres_What. +var ( + ServerPres_What_name = map[int32]string{ + 0: "X3", + 1: "ON", + 2: "OFF", + 3: "UA", + 4: "UPD", + 5: "GONE", + 6: "ACS", + 7: "TERM", + 8: "MSG", + 9: "READ", + 10: "RECV", + 11: "DEL", + 12: "TAGS", + 13: "AUX", + } + ServerPres_What_value = map[string]int32{ + "X3": 0, + "ON": 1, + "OFF": 2, + "UA": 3, + "UPD": 4, + "GONE": 5, + "ACS": 6, + "TERM": 7, + "MSG": 8, + "READ": 9, + "RECV": 10, + "DEL": 11, + "TAGS": 12, + "AUX": 13, + } +) + +func (x ServerPres_What) Enum() *ServerPres_What { + p := new(ServerPres_What) + *p = x + return p +} + +func (x ServerPres_What) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ServerPres_What) Descriptor() protoreflect.EnumDescriptor { + return file_model_proto_enumTypes[6].Descriptor() +} + +func (ServerPres_What) Type() protoreflect.EnumType { + return &file_model_proto_enumTypes[6] +} + +func (x ServerPres_What) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use ServerPres_What.Descriptor instead. +func (ServerPres_What) EnumDescriptor() ([]byte, []int) { + return file_model_proto_rawDescGZIP(), []int{28, 0} +} + +// Dummy placeholder message. +type Unused struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *Unused) Reset() { + *x = Unused{} + if protoimpl.UnsafeEnabled { + mi := &file_model_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Unused) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Unused) ProtoMessage() {} + +func (x *Unused) ProtoReflect() protoreflect.Message { + mi := &file_model_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Unused.ProtoReflect.Descriptor instead. +func (*Unused) Descriptor() ([]byte, []int) { + return file_model_proto_rawDescGZIP(), []int{0} +} + +// Topic default access mode +type DefaultAcsMode struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Auth string `protobuf:"bytes,1,opt,name=auth,proto3" json:"auth,omitempty"` + Anon string `protobuf:"bytes,2,opt,name=anon,proto3" json:"anon,omitempty"` +} + +func (x *DefaultAcsMode) Reset() { + *x = DefaultAcsMode{} + if protoimpl.UnsafeEnabled { + mi := &file_model_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DefaultAcsMode) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DefaultAcsMode) ProtoMessage() {} + +func (x *DefaultAcsMode) ProtoReflect() protoreflect.Message { + mi := &file_model_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DefaultAcsMode.ProtoReflect.Descriptor instead. +func (*DefaultAcsMode) Descriptor() ([]byte, []int) { + return file_model_proto_rawDescGZIP(), []int{1} +} + +func (x *DefaultAcsMode) GetAuth() string { + if x != nil { + return x.Auth + } + return "" +} + +func (x *DefaultAcsMode) GetAnon() string { + if x != nil { + return x.Anon + } + return "" +} + +// Actual access mode +type AccessMode struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Access mode requested by the user + Want string `protobuf:"bytes,1,opt,name=want,proto3" json:"want,omitempty"` + // Access mode granted to the user by the admin + Given string `protobuf:"bytes,2,opt,name=given,proto3" json:"given,omitempty"` +} + +func (x *AccessMode) Reset() { + *x = AccessMode{} + if protoimpl.UnsafeEnabled { + mi := &file_model_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AccessMode) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AccessMode) ProtoMessage() {} + +func (x *AccessMode) ProtoReflect() protoreflect.Message { + mi := &file_model_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AccessMode.ProtoReflect.Descriptor instead. +func (*AccessMode) Descriptor() ([]byte, []int) { + return file_model_proto_rawDescGZIP(), []int{2} +} + +func (x *AccessMode) GetWant() string { + if x != nil { + return x.Want + } + return "" +} + +func (x *AccessMode) GetGiven() string { + if x != nil { + return x.Given + } + return "" +} + +// SetSub: payload in set.sub request to update current subscription or invite another user, {sub.what} == "sub" +type SetSub struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // User affected by this request. Default (empty): current user + UserId string `protobuf:"bytes,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` + // Access mode change, either Given or Want depending on context + Mode string `protobuf:"bytes,2,opt,name=mode,proto3" json:"mode,omitempty"` +} + +func (x *SetSub) Reset() { + *x = SetSub{} + if protoimpl.UnsafeEnabled { + mi := &file_model_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SetSub) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SetSub) ProtoMessage() {} + +func (x *SetSub) ProtoReflect() protoreflect.Message { + mi := &file_model_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SetSub.ProtoReflect.Descriptor instead. +func (*SetSub) Descriptor() ([]byte, []int) { + return file_model_proto_rawDescGZIP(), []int{3} +} + +func (x *SetSub) GetUserId() string { + if x != nil { + return x.UserId + } + return "" +} + +func (x *SetSub) GetMode() string { + if x != nil { + return x.Mode + } + return "" +} + +// Credentials such as email or phone number +type ClientCred struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Credential type, i.e. `email` or `tel`. + Method string `protobuf:"bytes,1,opt,name=method,proto3" json:"method,omitempty"` + // Value to verify, i.e. `user@example.com` or `+18003287448` + Value string `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` + // Verification response + Response string `protobuf:"bytes,3,opt,name=response,proto3" json:"response,omitempty"` + // Request parameters, such as preferences or country code. + Params map[string][]byte `protobuf:"bytes,4,rep,name=params,proto3" json:"params,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *ClientCred) Reset() { + *x = ClientCred{} + if protoimpl.UnsafeEnabled { + mi := &file_model_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ClientCred) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ClientCred) ProtoMessage() {} + +func (x *ClientCred) ProtoReflect() protoreflect.Message { + mi := &file_model_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ClientCred.ProtoReflect.Descriptor instead. +func (*ClientCred) Descriptor() ([]byte, []int) { + return file_model_proto_rawDescGZIP(), []int{4} +} + +func (x *ClientCred) GetMethod() string { + if x != nil { + return x.Method + } + return "" +} + +func (x *ClientCred) GetValue() string { + if x != nil { + return x.Value + } + return "" +} + +func (x *ClientCred) GetResponse() string { + if x != nil { + return x.Response + } + return "" +} + +func (x *ClientCred) GetParams() map[string][]byte { + if x != nil { + return x.Params + } + return nil +} + +// SetDesc: C2S in set.what == "desc" and sub.init message +type SetDesc struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + DefaultAcs *DefaultAcsMode `protobuf:"bytes,1,opt,name=default_acs,json=defaultAcs,proto3" json:"default_acs,omitempty"` + Public []byte `protobuf:"bytes,2,opt,name=public,proto3" json:"public,omitempty"` + Private []byte `protobuf:"bytes,3,opt,name=private,proto3" json:"private,omitempty"` + Trusted []byte `protobuf:"bytes,4,opt,name=trusted,proto3" json:"trusted,omitempty"` +} + +func (x *SetDesc) Reset() { + *x = SetDesc{} + if protoimpl.UnsafeEnabled { + mi := &file_model_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SetDesc) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SetDesc) ProtoMessage() {} + +func (x *SetDesc) ProtoReflect() protoreflect.Message { + mi := &file_model_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SetDesc.ProtoReflect.Descriptor instead. +func (*SetDesc) Descriptor() ([]byte, []int) { + return file_model_proto_rawDescGZIP(), []int{5} +} + +func (x *SetDesc) GetDefaultAcs() *DefaultAcsMode { + if x != nil { + return x.DefaultAcs + } + return nil +} + +func (x *SetDesc) GetPublic() []byte { + if x != nil { + return x.Public + } + return nil +} + +func (x *SetDesc) GetPrivate() []byte { + if x != nil { + return x.Private + } + return nil +} + +func (x *SetDesc) GetTrusted() []byte { + if x != nil { + return x.Trusted + } + return nil +} + +type SeqRange struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Low int32 `protobuf:"varint,1,opt,name=low,proto3" json:"low,omitempty"` + Hi int32 `protobuf:"varint,2,opt,name=hi,proto3" json:"hi,omitempty"` +} + +func (x *SeqRange) Reset() { + *x = SeqRange{} + if protoimpl.UnsafeEnabled { + mi := &file_model_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SeqRange) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SeqRange) ProtoMessage() {} + +func (x *SeqRange) ProtoReflect() protoreflect.Message { + mi := &file_model_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SeqRange.ProtoReflect.Descriptor instead. +func (*SeqRange) Descriptor() ([]byte, []int) { + return file_model_proto_rawDescGZIP(), []int{6} +} + +func (x *SeqRange) GetLow() int32 { + if x != nil { + return x.Low + } + return 0 +} + +func (x *SeqRange) GetHi() int32 { + if x != nil { + return x.Hi + } + return 0 +} + +type GetOpts struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Timestamp in milliseconds since epoch 01/01/1970 + IfModifiedSince int64 `protobuf:"varint,1,opt,name=if_modified_since,json=ifModifiedSince,proto3" json:"if_modified_since,omitempty"` + // Limit search to this user ID + User string `protobuf:"bytes,2,opt,name=user,proto3" json:"user,omitempty"` + // Limit search results to one topic; + Topic string `protobuf:"bytes,3,opt,name=topic,proto3" json:"topic,omitempty"` + // Load messages with seq id equal or greater than this + SinceId int32 `protobuf:"varint,4,opt,name=since_id,json=sinceId,proto3" json:"since_id,omitempty"` + // Load messages with seq id lower than this + BeforeId int32 `protobuf:"varint,5,opt,name=before_id,json=beforeId,proto3" json:"before_id,omitempty"` + // Maximum number of results to return + Limit int32 `protobuf:"varint,6,opt,name=limit,proto3" json:"limit,omitempty"` + // Load messages by id or ranges of ids + Ranges []*SeqRange `protobuf:"bytes,7,rep,name=ranges,proto3" json:"ranges,omitempty"` +} + +func (x *GetOpts) Reset() { + *x = GetOpts{} + if protoimpl.UnsafeEnabled { + mi := &file_model_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetOpts) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetOpts) ProtoMessage() {} + +func (x *GetOpts) ProtoReflect() protoreflect.Message { + mi := &file_model_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetOpts.ProtoReflect.Descriptor instead. +func (*GetOpts) Descriptor() ([]byte, []int) { + return file_model_proto_rawDescGZIP(), []int{7} +} + +func (x *GetOpts) GetIfModifiedSince() int64 { + if x != nil { + return x.IfModifiedSince + } + return 0 +} + +func (x *GetOpts) GetUser() string { + if x != nil { + return x.User + } + return "" +} + +func (x *GetOpts) GetTopic() string { + if x != nil { + return x.Topic + } + return "" +} + +func (x *GetOpts) GetSinceId() int32 { + if x != nil { + return x.SinceId + } + return 0 +} + +func (x *GetOpts) GetBeforeId() int32 { + if x != nil { + return x.BeforeId + } + return 0 +} + +func (x *GetOpts) GetLimit() int32 { + if x != nil { + return x.Limit + } + return 0 +} + +func (x *GetOpts) GetRanges() []*SeqRange { + if x != nil { + return x.Ranges + } + return nil +} + +type GetQuery struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + What string `protobuf:"bytes,1,opt,name=what,proto3" json:"what,omitempty"` + // Parameters of "desc" request + Desc *GetOpts `protobuf:"bytes,2,opt,name=desc,proto3" json:"desc,omitempty"` + // Parameters of "sub" request + Sub *GetOpts `protobuf:"bytes,3,opt,name=sub,proto3" json:"sub,omitempty"` + // Parameters of "data" request + Data *GetOpts `protobuf:"bytes,4,opt,name=data,proto3" json:"data,omitempty"` +} + +func (x *GetQuery) Reset() { + *x = GetQuery{} + if protoimpl.UnsafeEnabled { + mi := &file_model_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetQuery) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetQuery) ProtoMessage() {} + +func (x *GetQuery) ProtoReflect() protoreflect.Message { + mi := &file_model_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetQuery.ProtoReflect.Descriptor instead. +func (*GetQuery) Descriptor() ([]byte, []int) { + return file_model_proto_rawDescGZIP(), []int{8} +} + +func (x *GetQuery) GetWhat() string { + if x != nil { + return x.What + } + return "" +} + +func (x *GetQuery) GetDesc() *GetOpts { + if x != nil { + return x.Desc + } + return nil +} + +func (x *GetQuery) GetSub() *GetOpts { + if x != nil { + return x.Sub + } + return nil +} + +func (x *GetQuery) GetData() *GetOpts { + if x != nil { + return x.Data + } + return nil +} + +type SetQuery struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Topic metadata, new topic & new subscriptions only + Desc *SetDesc `protobuf:"bytes,1,opt,name=desc,proto3" json:"desc,omitempty"` + // Subscription parameters + Sub *SetSub `protobuf:"bytes,2,opt,name=sub,proto3" json:"sub,omitempty"` + // Indexable tags + Tags []string `protobuf:"bytes,3,rep,name=tags,proto3" json:"tags,omitempty"` + // Credential being updated. + Cred *ClientCred `protobuf:"bytes,4,opt,name=cred,proto3" json:"cred,omitempty"` + // Auxiliary data. + Aux map[string][]byte `protobuf:"bytes,5,rep,name=aux,proto3" json:"aux,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *SetQuery) Reset() { + *x = SetQuery{} + if protoimpl.UnsafeEnabled { + mi := &file_model_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SetQuery) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SetQuery) ProtoMessage() {} + +func (x *SetQuery) ProtoReflect() protoreflect.Message { + mi := &file_model_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SetQuery.ProtoReflect.Descriptor instead. +func (*SetQuery) Descriptor() ([]byte, []int) { + return file_model_proto_rawDescGZIP(), []int{9} +} + +func (x *SetQuery) GetDesc() *SetDesc { + if x != nil { + return x.Desc + } + return nil +} + +func (x *SetQuery) GetSub() *SetSub { + if x != nil { + return x.Sub + } + return nil +} + +func (x *SetQuery) GetTags() []string { + if x != nil { + return x.Tags + } + return nil +} + +func (x *SetQuery) GetCred() *ClientCred { + if x != nil { + return x.Cred + } + return nil +} + +func (x *SetQuery) GetAux() map[string][]byte { + if x != nil { + return x.Aux + } + return nil +} + +// Client handshake +type ClientHi struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + UserAgent string `protobuf:"bytes,2,opt,name=user_agent,json=userAgent,proto3" json:"user_agent,omitempty"` + Ver string `protobuf:"bytes,3,opt,name=ver,proto3" json:"ver,omitempty"` + DeviceId string `protobuf:"bytes,4,opt,name=device_id,json=deviceId,proto3" json:"device_id,omitempty"` + Lang string `protobuf:"bytes,5,opt,name=lang,proto3" json:"lang,omitempty"` + Platform string `protobuf:"bytes,6,opt,name=platform,proto3" json:"platform,omitempty"` + Background bool `protobuf:"varint,7,opt,name=background,proto3" json:"background,omitempty"` + Tenant string `protobuf:"bytes,8,opt,name=tenant,proto3" json:"tenant,omitempty"` +} + +func (x *ClientHi) Reset() { + *x = ClientHi{} + if protoimpl.UnsafeEnabled { + mi := &file_model_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ClientHi) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ClientHi) ProtoMessage() {} + +func (x *ClientHi) ProtoReflect() protoreflect.Message { + mi := &file_model_proto_msgTypes[10] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ClientHi.ProtoReflect.Descriptor instead. +func (*ClientHi) Descriptor() ([]byte, []int) { + return file_model_proto_rawDescGZIP(), []int{10} +} + +func (x *ClientHi) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *ClientHi) GetUserAgent() string { + if x != nil { + return x.UserAgent + } + return "" +} + +func (x *ClientHi) GetVer() string { + if x != nil { + return x.Ver + } + return "" +} + +func (x *ClientHi) GetDeviceId() string { + if x != nil { + return x.DeviceId + } + return "" +} + +func (x *ClientHi) GetLang() string { + if x != nil { + return x.Lang + } + return "" +} + +func (x *ClientHi) GetPlatform() string { + if x != nil { + return x.Platform + } + return "" +} + +func (x *ClientHi) GetBackground() bool { + if x != nil { + return x.Background + } + return false +} + +func (x *ClientHi) GetTenant() string { + if x != nil { + return x.Tenant + } + return "" +} + +// User creation message {acc} +type ClientAcc struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + // User being created or updated + UserId string `protobuf:"bytes,2,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` + // The initial authentication scheme the account can use + Scheme string `protobuf:"bytes,3,opt,name=scheme,proto3" json:"scheme,omitempty"` + // Shared secret + Secret []byte `protobuf:"bytes,4,opt,name=secret,proto3" json:"secret,omitempty"` + // Authenticate session with the newly created account + Login bool `protobuf:"varint,5,opt,name=login,proto3" json:"login,omitempty"` + // Indexable tags for user discovery + Tags []string `protobuf:"bytes,6,rep,name=tags,proto3" json:"tags,omitempty"` + // User initialization data when creating a new user, otherwise ignored + Desc *SetDesc `protobuf:"bytes,7,opt,name=desc,proto3" json:"desc,omitempty"` + // Credentials for verification. + Cred []*ClientCred `protobuf:"bytes,8,rep,name=cred,proto3" json:"cred,omitempty"` + // Authentication token used for resetting a password. + Token []byte `protobuf:"bytes,9,opt,name=token,proto3" json:"token,omitempty"` + // Account state: normal ("ok"), suspended + State string `protobuf:"bytes,10,opt,name=state,proto3" json:"state,omitempty"` + // AuthLevel + AuthLevel AuthLevel `protobuf:"varint,11,opt,name=auth_level,json=authLevel,proto3,enum=pbx.AuthLevel" json:"auth_level,omitempty"` + // Temporary auth params for one-off actions like password reset. + TmpScheme string `protobuf:"bytes,12,opt,name=tmp_scheme,json=tmpScheme,proto3" json:"tmp_scheme,omitempty"` + TmpSecret []byte `protobuf:"bytes,13,opt,name=tmp_secret,json=tmpSecret,proto3" json:"tmp_secret,omitempty"` +} + +func (x *ClientAcc) Reset() { + *x = ClientAcc{} + if protoimpl.UnsafeEnabled { + mi := &file_model_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ClientAcc) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ClientAcc) ProtoMessage() {} + +func (x *ClientAcc) ProtoReflect() protoreflect.Message { + mi := &file_model_proto_msgTypes[11] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ClientAcc.ProtoReflect.Descriptor instead. +func (*ClientAcc) Descriptor() ([]byte, []int) { + return file_model_proto_rawDescGZIP(), []int{11} +} + +func (x *ClientAcc) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *ClientAcc) GetUserId() string { + if x != nil { + return x.UserId + } + return "" +} + +func (x *ClientAcc) GetScheme() string { + if x != nil { + return x.Scheme + } + return "" +} + +func (x *ClientAcc) GetSecret() []byte { + if x != nil { + return x.Secret + } + return nil +} + +func (x *ClientAcc) GetLogin() bool { + if x != nil { + return x.Login + } + return false +} + +func (x *ClientAcc) GetTags() []string { + if x != nil { + return x.Tags + } + return nil +} + +func (x *ClientAcc) GetDesc() *SetDesc { + if x != nil { + return x.Desc + } + return nil +} + +func (x *ClientAcc) GetCred() []*ClientCred { + if x != nil { + return x.Cred + } + return nil +} + +func (x *ClientAcc) GetToken() []byte { + if x != nil { + return x.Token + } + return nil +} + +func (x *ClientAcc) GetState() string { + if x != nil { + return x.State + } + return "" +} + +func (x *ClientAcc) GetAuthLevel() AuthLevel { + if x != nil { + return x.AuthLevel + } + return AuthLevel_NONE +} + +func (x *ClientAcc) GetTmpScheme() string { + if x != nil { + return x.TmpScheme + } + return "" +} + +func (x *ClientAcc) GetTmpSecret() []byte { + if x != nil { + return x.TmpSecret + } + return nil +} + +// Login {login} message +type ClientLogin struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + // Authentication scheme + Scheme string `protobuf:"bytes,2,opt,name=scheme,proto3" json:"scheme,omitempty"` + // Shared secret + Secret []byte `protobuf:"bytes,3,opt,name=secret,proto3" json:"secret,omitempty"` + // Credentials for verification. + Cred []*ClientCred `protobuf:"bytes,4,rep,name=cred,proto3" json:"cred,omitempty"` +} + +func (x *ClientLogin) Reset() { + *x = ClientLogin{} + if protoimpl.UnsafeEnabled { + mi := &file_model_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ClientLogin) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ClientLogin) ProtoMessage() {} + +func (x *ClientLogin) ProtoReflect() protoreflect.Message { + mi := &file_model_proto_msgTypes[12] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ClientLogin.ProtoReflect.Descriptor instead. +func (*ClientLogin) Descriptor() ([]byte, []int) { + return file_model_proto_rawDescGZIP(), []int{12} +} + +func (x *ClientLogin) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *ClientLogin) GetScheme() string { + if x != nil { + return x.Scheme + } + return "" +} + +func (x *ClientLogin) GetSecret() []byte { + if x != nil { + return x.Secret + } + return nil +} + +func (x *ClientLogin) GetCred() []*ClientCred { + if x != nil { + return x.Cred + } + return nil +} + +// Subscription request {sub} message +type ClientSub struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Topic string `protobuf:"bytes,2,opt,name=topic,proto3" json:"topic,omitempty"` + // mirrors {set} + SetQuery *SetQuery `protobuf:"bytes,3,opt,name=set_query,json=setQuery,proto3" json:"set_query,omitempty"` + // mirrors {get} + GetQuery *GetQuery `protobuf:"bytes,4,opt,name=get_query,json=getQuery,proto3" json:"get_query,omitempty"` +} + +func (x *ClientSub) Reset() { + *x = ClientSub{} + if protoimpl.UnsafeEnabled { + mi := &file_model_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ClientSub) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ClientSub) ProtoMessage() {} + +func (x *ClientSub) ProtoReflect() protoreflect.Message { + mi := &file_model_proto_msgTypes[13] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ClientSub.ProtoReflect.Descriptor instead. +func (*ClientSub) Descriptor() ([]byte, []int) { + return file_model_proto_rawDescGZIP(), []int{13} +} + +func (x *ClientSub) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *ClientSub) GetTopic() string { + if x != nil { + return x.Topic + } + return "" +} + +func (x *ClientSub) GetSetQuery() *SetQuery { + if x != nil { + return x.SetQuery + } + return nil +} + +func (x *ClientSub) GetGetQuery() *GetQuery { + if x != nil { + return x.GetQuery + } + return nil +} + +// Unsubscribe {leave} request message +type ClientLeave struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Topic string `protobuf:"bytes,2,opt,name=topic,proto3" json:"topic,omitempty"` + Unsub bool `protobuf:"varint,3,opt,name=unsub,proto3" json:"unsub,omitempty"` +} + +func (x *ClientLeave) Reset() { + *x = ClientLeave{} + if protoimpl.UnsafeEnabled { + mi := &file_model_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ClientLeave) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ClientLeave) ProtoMessage() {} + +func (x *ClientLeave) ProtoReflect() protoreflect.Message { + mi := &file_model_proto_msgTypes[14] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ClientLeave.ProtoReflect.Descriptor instead. +func (*ClientLeave) Descriptor() ([]byte, []int) { + return file_model_proto_rawDescGZIP(), []int{14} +} + +func (x *ClientLeave) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *ClientLeave) GetTopic() string { + if x != nil { + return x.Topic + } + return "" +} + +func (x *ClientLeave) GetUnsub() bool { + if x != nil { + return x.Unsub + } + return false +} + +// ClientPub is client's request to publish data to topic subscribers {pub} +type ClientPub struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Topic string `protobuf:"bytes,2,opt,name=topic,proto3" json:"topic,omitempty"` + NoEcho bool `protobuf:"varint,3,opt,name=no_echo,json=noEcho,proto3" json:"no_echo,omitempty"` + Head map[string][]byte `protobuf:"bytes,4,rep,name=head,proto3" json:"head,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + Content []byte `protobuf:"bytes,5,opt,name=content,proto3" json:"content,omitempty"` +} + +func (x *ClientPub) Reset() { + *x = ClientPub{} + if protoimpl.UnsafeEnabled { + mi := &file_model_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ClientPub) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ClientPub) ProtoMessage() {} + +func (x *ClientPub) ProtoReflect() protoreflect.Message { + mi := &file_model_proto_msgTypes[15] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ClientPub.ProtoReflect.Descriptor instead. +func (*ClientPub) Descriptor() ([]byte, []int) { + return file_model_proto_rawDescGZIP(), []int{15} +} + +func (x *ClientPub) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *ClientPub) GetTopic() string { + if x != nil { + return x.Topic + } + return "" +} + +func (x *ClientPub) GetNoEcho() bool { + if x != nil { + return x.NoEcho + } + return false +} + +func (x *ClientPub) GetHead() map[string][]byte { + if x != nil { + return x.Head + } + return nil +} + +func (x *ClientPub) GetContent() []byte { + if x != nil { + return x.Content + } + return nil +} + +// Query topic state {get} +type ClientGet struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Topic string `protobuf:"bytes,2,opt,name=topic,proto3" json:"topic,omitempty"` + Query *GetQuery `protobuf:"bytes,3,opt,name=query,proto3" json:"query,omitempty"` +} + +func (x *ClientGet) Reset() { + *x = ClientGet{} + if protoimpl.UnsafeEnabled { + mi := &file_model_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ClientGet) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ClientGet) ProtoMessage() {} + +func (x *ClientGet) ProtoReflect() protoreflect.Message { + mi := &file_model_proto_msgTypes[16] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ClientGet.ProtoReflect.Descriptor instead. +func (*ClientGet) Descriptor() ([]byte, []int) { + return file_model_proto_rawDescGZIP(), []int{16} +} + +func (x *ClientGet) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *ClientGet) GetTopic() string { + if x != nil { + return x.Topic + } + return "" +} + +func (x *ClientGet) GetQuery() *GetQuery { + if x != nil { + return x.Query + } + return nil +} + +// Update topic state {set} +type ClientSet struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Topic string `protobuf:"bytes,2,opt,name=topic,proto3" json:"topic,omitempty"` + Query *SetQuery `protobuf:"bytes,3,opt,name=query,proto3" json:"query,omitempty"` +} + +func (x *ClientSet) Reset() { + *x = ClientSet{} + if protoimpl.UnsafeEnabled { + mi := &file_model_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ClientSet) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ClientSet) ProtoMessage() {} + +func (x *ClientSet) ProtoReflect() protoreflect.Message { + mi := &file_model_proto_msgTypes[17] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ClientSet.ProtoReflect.Descriptor instead. +func (*ClientSet) Descriptor() ([]byte, []int) { + return file_model_proto_rawDescGZIP(), []int{17} +} + +func (x *ClientSet) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *ClientSet) GetTopic() string { + if x != nil { + return x.Topic + } + return "" +} + +func (x *ClientSet) GetQuery() *SetQuery { + if x != nil { + return x.Query + } + return nil +} + +// ClientDel delete messages or topic +type ClientDel struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Topic string `protobuf:"bytes,2,opt,name=topic,proto3" json:"topic,omitempty"` + What ClientDel_What `protobuf:"varint,3,opt,name=what,proto3,enum=pbx.ClientDel_What" json:"what,omitempty"` + // Delete messages by id or range of ids + DelSeq []*SeqRange `protobuf:"bytes,4,rep,name=del_seq,json=delSeq,proto3" json:"del_seq,omitempty"` + // User ID of the subscription to delete + UserId string `protobuf:"bytes,5,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` + // Credential to delete. + Cred *ClientCred `protobuf:"bytes,6,opt,name=cred,proto3" json:"cred,omitempty"` + // Request to hard-delete messages for all users, if such option is available. + Hard bool `protobuf:"varint,7,opt,name=hard,proto3" json:"hard,omitempty"` +} + +func (x *ClientDel) Reset() { + *x = ClientDel{} + if protoimpl.UnsafeEnabled { + mi := &file_model_proto_msgTypes[18] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ClientDel) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ClientDel) ProtoMessage() {} + +func (x *ClientDel) ProtoReflect() protoreflect.Message { + mi := &file_model_proto_msgTypes[18] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ClientDel.ProtoReflect.Descriptor instead. +func (*ClientDel) Descriptor() ([]byte, []int) { + return file_model_proto_rawDescGZIP(), []int{18} +} + +func (x *ClientDel) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *ClientDel) GetTopic() string { + if x != nil { + return x.Topic + } + return "" +} + +func (x *ClientDel) GetWhat() ClientDel_What { + if x != nil { + return x.What + } + return ClientDel_X0 +} + +func (x *ClientDel) GetDelSeq() []*SeqRange { + if x != nil { + return x.DelSeq + } + return nil +} + +func (x *ClientDel) GetUserId() string { + if x != nil { + return x.UserId + } + return "" +} + +func (x *ClientDel) GetCred() *ClientCred { + if x != nil { + return x.Cred + } + return nil +} + +func (x *ClientDel) GetHard() bool { + if x != nil { + return x.Hard + } + return false +} + +// ClientNote is a client-generated notification for topic subscribers +type ClientNote struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Topic string `protobuf:"bytes,1,opt,name=topic,proto3" json:"topic,omitempty"` + // what is being reported: "recv" - message received, "read" - message read, + // "kp" - typing notification, "call" - voice/video call + What InfoNote `protobuf:"varint,2,opt,name=what,proto3,enum=pbx.InfoNote" json:"what,omitempty"` + // Server-issued message ID being reported + SeqId int32 `protobuf:"varint,3,opt,name=seq_id,json=seqId,proto3" json:"seq_id,omitempty"` + // Client's count of unread messages to report back to the server. Used in push notifications on iOS. + Unread int32 `protobuf:"varint,4,opt,name=unread,proto3" json:"unread,omitempty"` + // Call event. + Event CallEvent `protobuf:"varint,5,opt,name=event,proto3,enum=pbx.CallEvent" json:"event,omitempty"` + // Arbitrary json payload (used in video calls). + Payload []byte `protobuf:"bytes,6,opt,name=payload,proto3" json:"payload,omitempty"` +} + +func (x *ClientNote) Reset() { + *x = ClientNote{} + if protoimpl.UnsafeEnabled { + mi := &file_model_proto_msgTypes[19] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ClientNote) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ClientNote) ProtoMessage() {} + +func (x *ClientNote) ProtoReflect() protoreflect.Message { + mi := &file_model_proto_msgTypes[19] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ClientNote.ProtoReflect.Descriptor instead. +func (*ClientNote) Descriptor() ([]byte, []int) { + return file_model_proto_rawDescGZIP(), []int{19} +} + +func (x *ClientNote) GetTopic() string { + if x != nil { + return x.Topic + } + return "" +} + +func (x *ClientNote) GetWhat() InfoNote { + if x != nil { + return x.What + } + return InfoNote_X1 +} + +func (x *ClientNote) GetSeqId() int32 { + if x != nil { + return x.SeqId + } + return 0 +} + +func (x *ClientNote) GetUnread() int32 { + if x != nil { + return x.Unread + } + return 0 +} + +func (x *ClientNote) GetEvent() CallEvent { + if x != nil { + return x.Event + } + return CallEvent_X2 +} + +func (x *ClientNote) GetPayload() []byte { + if x != nil { + return x.Payload + } + return nil +} + +type ClientExtra struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Attachments []string `protobuf:"bytes,1,rep,name=attachments,proto3" json:"attachments,omitempty"` + // Root user may send messages on behalf of other users. + OnBehalfOf string `protobuf:"bytes,2,opt,name=on_behalf_of,json=onBehalfOf,proto3" json:"on_behalf_of,omitempty"` + AuthLevel AuthLevel `protobuf:"varint,3,opt,name=auth_level,json=authLevel,proto3,enum=pbx.AuthLevel" json:"auth_level,omitempty"` +} + +func (x *ClientExtra) Reset() { + *x = ClientExtra{} + if protoimpl.UnsafeEnabled { + mi := &file_model_proto_msgTypes[20] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ClientExtra) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ClientExtra) ProtoMessage() {} + +func (x *ClientExtra) ProtoReflect() protoreflect.Message { + mi := &file_model_proto_msgTypes[20] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ClientExtra.ProtoReflect.Descriptor instead. +func (*ClientExtra) Descriptor() ([]byte, []int) { + return file_model_proto_rawDescGZIP(), []int{20} +} + +func (x *ClientExtra) GetAttachments() []string { + if x != nil { + return x.Attachments + } + return nil +} + +func (x *ClientExtra) GetOnBehalfOf() string { + if x != nil { + return x.OnBehalfOf + } + return "" +} + +func (x *ClientExtra) GetAuthLevel() AuthLevel { + if x != nil { + return x.AuthLevel + } + return AuthLevel_NONE +} + +type ClientMsg struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Types that are assignable to Message: + // + // *ClientMsg_Hi + // *ClientMsg_Acc + // *ClientMsg_Login + // *ClientMsg_Sub + // *ClientMsg_Leave + // *ClientMsg_Pub + // *ClientMsg_Get + // *ClientMsg_Set + // *ClientMsg_Del + // *ClientMsg_Note + Message isClientMsg_Message `protobuf_oneof:"Message"` + // Additional message parameters. + Extra *ClientExtra `protobuf:"bytes,13,opt,name=extra,proto3" json:"extra,omitempty"` +} + +func (x *ClientMsg) Reset() { + *x = ClientMsg{} + if protoimpl.UnsafeEnabled { + mi := &file_model_proto_msgTypes[21] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ClientMsg) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ClientMsg) ProtoMessage() {} + +func (x *ClientMsg) ProtoReflect() protoreflect.Message { + mi := &file_model_proto_msgTypes[21] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ClientMsg.ProtoReflect.Descriptor instead. +func (*ClientMsg) Descriptor() ([]byte, []int) { + return file_model_proto_rawDescGZIP(), []int{21} +} + +func (m *ClientMsg) GetMessage() isClientMsg_Message { + if m != nil { + return m.Message + } + return nil +} + +func (x *ClientMsg) GetHi() *ClientHi { + if x, ok := x.GetMessage().(*ClientMsg_Hi); ok { + return x.Hi + } + return nil +} + +func (x *ClientMsg) GetAcc() *ClientAcc { + if x, ok := x.GetMessage().(*ClientMsg_Acc); ok { + return x.Acc + } + return nil +} + +func (x *ClientMsg) GetLogin() *ClientLogin { + if x, ok := x.GetMessage().(*ClientMsg_Login); ok { + return x.Login + } + return nil +} + +func (x *ClientMsg) GetSub() *ClientSub { + if x, ok := x.GetMessage().(*ClientMsg_Sub); ok { + return x.Sub + } + return nil +} + +func (x *ClientMsg) GetLeave() *ClientLeave { + if x, ok := x.GetMessage().(*ClientMsg_Leave); ok { + return x.Leave + } + return nil +} + +func (x *ClientMsg) GetPub() *ClientPub { + if x, ok := x.GetMessage().(*ClientMsg_Pub); ok { + return x.Pub + } + return nil +} + +func (x *ClientMsg) GetGet() *ClientGet { + if x, ok := x.GetMessage().(*ClientMsg_Get); ok { + return x.Get + } + return nil +} + +func (x *ClientMsg) GetSet() *ClientSet { + if x, ok := x.GetMessage().(*ClientMsg_Set); ok { + return x.Set + } + return nil +} + +func (x *ClientMsg) GetDel() *ClientDel { + if x, ok := x.GetMessage().(*ClientMsg_Del); ok { + return x.Del + } + return nil +} + +func (x *ClientMsg) GetNote() *ClientNote { + if x, ok := x.GetMessage().(*ClientMsg_Note); ok { + return x.Note + } + return nil +} + +func (x *ClientMsg) GetExtra() *ClientExtra { + if x != nil { + return x.Extra + } + return nil +} + +type isClientMsg_Message interface { + isClientMsg_Message() +} + +type ClientMsg_Hi struct { + Hi *ClientHi `protobuf:"bytes,1,opt,name=hi,proto3,oneof"` +} + +type ClientMsg_Acc struct { + Acc *ClientAcc `protobuf:"bytes,2,opt,name=acc,proto3,oneof"` +} + +type ClientMsg_Login struct { + Login *ClientLogin `protobuf:"bytes,3,opt,name=login,proto3,oneof"` +} + +type ClientMsg_Sub struct { + Sub *ClientSub `protobuf:"bytes,4,opt,name=sub,proto3,oneof"` +} + +type ClientMsg_Leave struct { + Leave *ClientLeave `protobuf:"bytes,5,opt,name=leave,proto3,oneof"` +} + +type ClientMsg_Pub struct { + Pub *ClientPub `protobuf:"bytes,6,opt,name=pub,proto3,oneof"` +} + +type ClientMsg_Get struct { + Get *ClientGet `protobuf:"bytes,7,opt,name=get,proto3,oneof"` +} + +type ClientMsg_Set struct { + Set *ClientSet `protobuf:"bytes,8,opt,name=set,proto3,oneof"` +} + +type ClientMsg_Del struct { + Del *ClientDel `protobuf:"bytes,9,opt,name=del,proto3,oneof"` +} + +type ClientMsg_Note struct { + Note *ClientNote `protobuf:"bytes,10,opt,name=note,proto3,oneof"` +} + +func (*ClientMsg_Hi) isClientMsg_Message() {} + +func (*ClientMsg_Acc) isClientMsg_Message() {} + +func (*ClientMsg_Login) isClientMsg_Message() {} + +func (*ClientMsg_Sub) isClientMsg_Message() {} + +func (*ClientMsg_Leave) isClientMsg_Message() {} + +func (*ClientMsg_Pub) isClientMsg_Message() {} + +func (*ClientMsg_Get) isClientMsg_Message() {} + +func (*ClientMsg_Set) isClientMsg_Message() {} + +func (*ClientMsg_Del) isClientMsg_Message() {} + +func (*ClientMsg_Note) isClientMsg_Message() {} + +// Credentials +type ServerCred struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Credential type, i.e. `email` or `tel`. + Method string `protobuf:"bytes,1,opt,name=method,proto3" json:"method,omitempty"` + // Value to verify, i.e. `user@example.com` or `+18003287448` + Value string `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` + // Indicator that the credential is validated + Done bool `protobuf:"varint,3,opt,name=done,proto3" json:"done,omitempty"` +} + +func (x *ServerCred) Reset() { + *x = ServerCred{} + if protoimpl.UnsafeEnabled { + mi := &file_model_proto_msgTypes[22] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ServerCred) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ServerCred) ProtoMessage() {} + +func (x *ServerCred) ProtoReflect() protoreflect.Message { + mi := &file_model_proto_msgTypes[22] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ServerCred.ProtoReflect.Descriptor instead. +func (*ServerCred) Descriptor() ([]byte, []int) { + return file_model_proto_rawDescGZIP(), []int{22} +} + +func (x *ServerCred) GetMethod() string { + if x != nil { + return x.Method + } + return "" +} + +func (x *ServerCred) GetValue() string { + if x != nil { + return x.Value + } + return "" +} + +func (x *ServerCred) GetDone() bool { + if x != nil { + return x.Done + } + return false +} + +// Topic description, S2C in Meta message +type TopicDesc struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + CreatedAt int64 `protobuf:"varint,1,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` + UpdatedAt int64 `protobuf:"varint,2,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"` + TouchedAt int64 `protobuf:"varint,3,opt,name=touched_at,json=touchedAt,proto3" json:"touched_at,omitempty"` + Defacs *DefaultAcsMode `protobuf:"bytes,4,opt,name=defacs,proto3" json:"defacs,omitempty"` + Acs *AccessMode `protobuf:"bytes,5,opt,name=acs,proto3" json:"acs,omitempty"` + SeqId int32 `protobuf:"varint,6,opt,name=seq_id,json=seqId,proto3" json:"seq_id,omitempty"` + ReadId int32 `protobuf:"varint,7,opt,name=read_id,json=readId,proto3" json:"read_id,omitempty"` + RecvId int32 `protobuf:"varint,8,opt,name=recv_id,json=recvId,proto3" json:"recv_id,omitempty"` + DelId int32 `protobuf:"varint,9,opt,name=del_id,json=delId,proto3" json:"del_id,omitempty"` + Public []byte `protobuf:"bytes,10,opt,name=public,proto3" json:"public,omitempty"` + Private []byte `protobuf:"bytes,11,opt,name=private,proto3" json:"private,omitempty"` + State string `protobuf:"bytes,12,opt,name=state,proto3" json:"state,omitempty"` + StateAt int64 `protobuf:"varint,13,opt,name=state_at,json=stateAt,proto3" json:"state_at,omitempty"` + Trusted []byte `protobuf:"bytes,14,opt,name=trusted,proto3" json:"trusted,omitempty"` + IsChan bool `protobuf:"varint,17,opt,name=is_chan,json=isChan,proto3" json:"is_chan,omitempty"` // 17! + Online bool `protobuf:"varint,18,opt,name=online,proto3" json:"online,omitempty"` + // P2P only: other user's last online timestamp & user agent + LastSeenTime int64 `protobuf:"varint,15,opt,name=last_seen_time,json=lastSeenTime,proto3" json:"last_seen_time,omitempty"` + LastSeenUserAgent string `protobuf:"bytes,16,opt,name=last_seen_user_agent,json=lastSeenUserAgent,proto3" json:"last_seen_user_agent,omitempty"` +} + +func (x *TopicDesc) Reset() { + *x = TopicDesc{} + if protoimpl.UnsafeEnabled { + mi := &file_model_proto_msgTypes[23] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *TopicDesc) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TopicDesc) ProtoMessage() {} + +func (x *TopicDesc) ProtoReflect() protoreflect.Message { + mi := &file_model_proto_msgTypes[23] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TopicDesc.ProtoReflect.Descriptor instead. +func (*TopicDesc) Descriptor() ([]byte, []int) { + return file_model_proto_rawDescGZIP(), []int{23} +} + +func (x *TopicDesc) GetCreatedAt() int64 { + if x != nil { + return x.CreatedAt + } + return 0 +} + +func (x *TopicDesc) GetUpdatedAt() int64 { + if x != nil { + return x.UpdatedAt + } + return 0 +} + +func (x *TopicDesc) GetTouchedAt() int64 { + if x != nil { + return x.TouchedAt + } + return 0 +} + +func (x *TopicDesc) GetDefacs() *DefaultAcsMode { + if x != nil { + return x.Defacs + } + return nil +} + +func (x *TopicDesc) GetAcs() *AccessMode { + if x != nil { + return x.Acs + } + return nil +} + +func (x *TopicDesc) GetSeqId() int32 { + if x != nil { + return x.SeqId + } + return 0 +} + +func (x *TopicDesc) GetReadId() int32 { + if x != nil { + return x.ReadId + } + return 0 +} + +func (x *TopicDesc) GetRecvId() int32 { + if x != nil { + return x.RecvId + } + return 0 +} + +func (x *TopicDesc) GetDelId() int32 { + if x != nil { + return x.DelId + } + return 0 +} + +func (x *TopicDesc) GetPublic() []byte { + if x != nil { + return x.Public + } + return nil +} + +func (x *TopicDesc) GetPrivate() []byte { + if x != nil { + return x.Private + } + return nil +} + +func (x *TopicDesc) GetState() string { + if x != nil { + return x.State + } + return "" +} + +func (x *TopicDesc) GetStateAt() int64 { + if x != nil { + return x.StateAt + } + return 0 +} + +func (x *TopicDesc) GetTrusted() []byte { + if x != nil { + return x.Trusted + } + return nil +} + +func (x *TopicDesc) GetIsChan() bool { + if x != nil { + return x.IsChan + } + return false +} + +func (x *TopicDesc) GetOnline() bool { + if x != nil { + return x.Online + } + return false +} + +func (x *TopicDesc) GetLastSeenTime() int64 { + if x != nil { + return x.LastSeenTime + } + return 0 +} + +func (x *TopicDesc) GetLastSeenUserAgent() string { + if x != nil { + return x.LastSeenUserAgent + } + return "" +} + +// MsgTopicSub: topic subscription details, sent in Meta message +type TopicSub struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + UpdatedAt int64 `protobuf:"varint,1,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"` + DeletedAt int64 `protobuf:"varint,2,opt,name=deleted_at,json=deletedAt,proto3" json:"deleted_at,omitempty"` + Online bool `protobuf:"varint,3,opt,name=online,proto3" json:"online,omitempty"` + Acs *AccessMode `protobuf:"bytes,4,opt,name=acs,proto3" json:"acs,omitempty"` + ReadId int32 `protobuf:"varint,5,opt,name=read_id,json=readId,proto3" json:"read_id,omitempty"` + RecvId int32 `protobuf:"varint,6,opt,name=recv_id,json=recvId,proto3" json:"recv_id,omitempty"` + Public []byte `protobuf:"bytes,7,opt,name=public,proto3" json:"public,omitempty"` + Trusted []byte `protobuf:"bytes,16,opt,name=trusted,proto3" json:"trusted,omitempty"` // 16! + Private []byte `protobuf:"bytes,8,opt,name=private,proto3" json:"private,omitempty"` + // Uid of the subscribed user + UserId string `protobuf:"bytes,9,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` + // Topic name of this subscription + Topic string `protobuf:"bytes,10,opt,name=topic,proto3" json:"topic,omitempty"` + TouchedAt int64 `protobuf:"varint,11,opt,name=touched_at,json=touchedAt,proto3" json:"touched_at,omitempty"` + // ID of the last {data} message in a topic + SeqId int32 `protobuf:"varint,12,opt,name=seq_id,json=seqId,proto3" json:"seq_id,omitempty"` + // Messages are deleted up to this ID + DelId int32 `protobuf:"varint,13,opt,name=del_id,json=delId,proto3" json:"del_id,omitempty"` + // Other user's last online timestamp & user agent + LastSeenTime int64 `protobuf:"varint,14,opt,name=last_seen_time,json=lastSeenTime,proto3" json:"last_seen_time,omitempty"` + LastSeenUserAgent string `protobuf:"bytes,15,opt,name=last_seen_user_agent,json=lastSeenUserAgent,proto3" json:"last_seen_user_agent,omitempty"` +} + +func (x *TopicSub) Reset() { + *x = TopicSub{} + if protoimpl.UnsafeEnabled { + mi := &file_model_proto_msgTypes[24] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *TopicSub) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TopicSub) ProtoMessage() {} + +func (x *TopicSub) ProtoReflect() protoreflect.Message { + mi := &file_model_proto_msgTypes[24] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TopicSub.ProtoReflect.Descriptor instead. +func (*TopicSub) Descriptor() ([]byte, []int) { + return file_model_proto_rawDescGZIP(), []int{24} +} + +func (x *TopicSub) GetUpdatedAt() int64 { + if x != nil { + return x.UpdatedAt + } + return 0 +} + +func (x *TopicSub) GetDeletedAt() int64 { + if x != nil { + return x.DeletedAt + } + return 0 +} + +func (x *TopicSub) GetOnline() bool { + if x != nil { + return x.Online + } + return false +} + +func (x *TopicSub) GetAcs() *AccessMode { + if x != nil { + return x.Acs + } + return nil +} + +func (x *TopicSub) GetReadId() int32 { + if x != nil { + return x.ReadId + } + return 0 +} + +func (x *TopicSub) GetRecvId() int32 { + if x != nil { + return x.RecvId + } + return 0 +} + +func (x *TopicSub) GetPublic() []byte { + if x != nil { + return x.Public + } + return nil +} + +func (x *TopicSub) GetTrusted() []byte { + if x != nil { + return x.Trusted + } + return nil +} + +func (x *TopicSub) GetPrivate() []byte { + if x != nil { + return x.Private + } + return nil +} + +func (x *TopicSub) GetUserId() string { + if x != nil { + return x.UserId + } + return "" +} + +func (x *TopicSub) GetTopic() string { + if x != nil { + return x.Topic + } + return "" +} + +func (x *TopicSub) GetTouchedAt() int64 { + if x != nil { + return x.TouchedAt + } + return 0 +} + +func (x *TopicSub) GetSeqId() int32 { + if x != nil { + return x.SeqId + } + return 0 +} + +func (x *TopicSub) GetDelId() int32 { + if x != nil { + return x.DelId + } + return 0 +} + +func (x *TopicSub) GetLastSeenTime() int64 { + if x != nil { + return x.LastSeenTime + } + return 0 +} + +func (x *TopicSub) GetLastSeenUserAgent() string { + if x != nil { + return x.LastSeenUserAgent + } + return "" +} + +type DelValues struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + DelId int32 `protobuf:"varint,1,opt,name=del_id,json=delId,proto3" json:"del_id,omitempty"` + DelSeq []*SeqRange `protobuf:"bytes,2,rep,name=del_seq,json=delSeq,proto3" json:"del_seq,omitempty"` +} + +func (x *DelValues) Reset() { + *x = DelValues{} + if protoimpl.UnsafeEnabled { + mi := &file_model_proto_msgTypes[25] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DelValues) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DelValues) ProtoMessage() {} + +func (x *DelValues) ProtoReflect() protoreflect.Message { + mi := &file_model_proto_msgTypes[25] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DelValues.ProtoReflect.Descriptor instead. +func (*DelValues) Descriptor() ([]byte, []int) { + return file_model_proto_rawDescGZIP(), []int{25} +} + +func (x *DelValues) GetDelId() int32 { + if x != nil { + return x.DelId + } + return 0 +} + +func (x *DelValues) GetDelSeq() []*SeqRange { + if x != nil { + return x.DelSeq + } + return nil +} + +// {ctrl} message +type ServerCtrl struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Topic string `protobuf:"bytes,2,opt,name=topic,proto3" json:"topic,omitempty"` + Code int32 `protobuf:"varint,3,opt,name=code,proto3" json:"code,omitempty"` + Text string `protobuf:"bytes,4,opt,name=text,proto3" json:"text,omitempty"` + Params map[string][]byte `protobuf:"bytes,5,rep,name=params,proto3" json:"params,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *ServerCtrl) Reset() { + *x = ServerCtrl{} + if protoimpl.UnsafeEnabled { + mi := &file_model_proto_msgTypes[26] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ServerCtrl) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ServerCtrl) ProtoMessage() {} + +func (x *ServerCtrl) ProtoReflect() protoreflect.Message { + mi := &file_model_proto_msgTypes[26] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ServerCtrl.ProtoReflect.Descriptor instead. +func (*ServerCtrl) Descriptor() ([]byte, []int) { + return file_model_proto_rawDescGZIP(), []int{26} +} + +func (x *ServerCtrl) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *ServerCtrl) GetTopic() string { + if x != nil { + return x.Topic + } + return "" +} + +func (x *ServerCtrl) GetCode() int32 { + if x != nil { + return x.Code + } + return 0 +} + +func (x *ServerCtrl) GetText() string { + if x != nil { + return x.Text + } + return "" +} + +func (x *ServerCtrl) GetParams() map[string][]byte { + if x != nil { + return x.Params + } + return nil +} + +// {data} message +type ServerData struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Topic string `protobuf:"bytes,1,opt,name=topic,proto3" json:"topic,omitempty"` + // ID of the user who originated the message as {pub}, could be empty if sent by the system + FromUserId string `protobuf:"bytes,2,opt,name=from_user_id,json=fromUserId,proto3" json:"from_user_id,omitempty"` + // Timestamp when the message was sent. + Timestamp int64 `protobuf:"varint,7,opt,name=timestamp,proto3" json:"timestamp,omitempty"` + // Timestamp when the message was deleted or 0. Milliseconds since the epoch 01/01/1970 + DeletedAt int64 `protobuf:"varint,3,opt,name=deleted_at,json=deletedAt,proto3" json:"deleted_at,omitempty"` + SeqId int32 `protobuf:"varint,4,opt,name=seq_id,json=seqId,proto3" json:"seq_id,omitempty"` + Head map[string][]byte `protobuf:"bytes,5,rep,name=head,proto3" json:"head,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + Content []byte `protobuf:"bytes,6,opt,name=content,proto3" json:"content,omitempty"` +} + +func (x *ServerData) Reset() { + *x = ServerData{} + if protoimpl.UnsafeEnabled { + mi := &file_model_proto_msgTypes[27] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ServerData) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ServerData) ProtoMessage() {} + +func (x *ServerData) ProtoReflect() protoreflect.Message { + mi := &file_model_proto_msgTypes[27] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ServerData.ProtoReflect.Descriptor instead. +func (*ServerData) Descriptor() ([]byte, []int) { + return file_model_proto_rawDescGZIP(), []int{27} +} + +func (x *ServerData) GetTopic() string { + if x != nil { + return x.Topic + } + return "" +} + +func (x *ServerData) GetFromUserId() string { + if x != nil { + return x.FromUserId + } + return "" +} + +func (x *ServerData) GetTimestamp() int64 { + if x != nil { + return x.Timestamp + } + return 0 +} + +func (x *ServerData) GetDeletedAt() int64 { + if x != nil { + return x.DeletedAt + } + return 0 +} + +func (x *ServerData) GetSeqId() int32 { + if x != nil { + return x.SeqId + } + return 0 +} + +func (x *ServerData) GetHead() map[string][]byte { + if x != nil { + return x.Head + } + return nil +} + +func (x *ServerData) GetContent() []byte { + if x != nil { + return x.Content + } + return nil +} + +// {pres} message +type ServerPres struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Topic string `protobuf:"bytes,1,opt,name=topic,proto3" json:"topic,omitempty"` + Src string `protobuf:"bytes,2,opt,name=src,proto3" json:"src,omitempty"` + What ServerPres_What `protobuf:"varint,3,opt,name=what,proto3,enum=pbx.ServerPres_What" json:"what,omitempty"` + UserAgent string `protobuf:"bytes,4,opt,name=user_agent,json=userAgent,proto3" json:"user_agent,omitempty"` + SeqId int32 `protobuf:"varint,5,opt,name=seq_id,json=seqId,proto3" json:"seq_id,omitempty"` + DelId int32 `protobuf:"varint,6,opt,name=del_id,json=delId,proto3" json:"del_id,omitempty"` + DelSeq []*SeqRange `protobuf:"bytes,7,rep,name=del_seq,json=delSeq,proto3" json:"del_seq,omitempty"` + TargetUserId string `protobuf:"bytes,8,opt,name=target_user_id,json=targetUserId,proto3" json:"target_user_id,omitempty"` + ActorUserId string `protobuf:"bytes,9,opt,name=actor_user_id,json=actorUserId,proto3" json:"actor_user_id,omitempty"` + Acs *AccessMode `protobuf:"bytes,10,opt,name=acs,proto3" json:"acs,omitempty"` +} + +func (x *ServerPres) Reset() { + *x = ServerPres{} + if protoimpl.UnsafeEnabled { + mi := &file_model_proto_msgTypes[28] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ServerPres) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ServerPres) ProtoMessage() {} + +func (x *ServerPres) ProtoReflect() protoreflect.Message { + mi := &file_model_proto_msgTypes[28] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ServerPres.ProtoReflect.Descriptor instead. +func (*ServerPres) Descriptor() ([]byte, []int) { + return file_model_proto_rawDescGZIP(), []int{28} +} + +func (x *ServerPres) GetTopic() string { + if x != nil { + return x.Topic + } + return "" +} + +func (x *ServerPres) GetSrc() string { + if x != nil { + return x.Src + } + return "" +} + +func (x *ServerPres) GetWhat() ServerPres_What { + if x != nil { + return x.What + } + return ServerPres_X3 +} + +func (x *ServerPres) GetUserAgent() string { + if x != nil { + return x.UserAgent + } + return "" +} + +func (x *ServerPres) GetSeqId() int32 { + if x != nil { + return x.SeqId + } + return 0 +} + +func (x *ServerPres) GetDelId() int32 { + if x != nil { + return x.DelId + } + return 0 +} + +func (x *ServerPres) GetDelSeq() []*SeqRange { + if x != nil { + return x.DelSeq + } + return nil +} + +func (x *ServerPres) GetTargetUserId() string { + if x != nil { + return x.TargetUserId + } + return "" +} + +func (x *ServerPres) GetActorUserId() string { + if x != nil { + return x.ActorUserId + } + return "" +} + +func (x *ServerPres) GetAcs() *AccessMode { + if x != nil { + return x.Acs + } + return nil +} + +// {meta} message +type ServerMeta struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Topic string `protobuf:"bytes,2,opt,name=topic,proto3" json:"topic,omitempty"` + Desc *TopicDesc `protobuf:"bytes,3,opt,name=desc,proto3" json:"desc,omitempty"` + Sub []*TopicSub `protobuf:"bytes,4,rep,name=sub,proto3" json:"sub,omitempty"` + Del *DelValues `protobuf:"bytes,5,opt,name=del,proto3" json:"del,omitempty"` + Tags []string `protobuf:"bytes,6,rep,name=tags,proto3" json:"tags,omitempty"` + Cred []*ServerCred `protobuf:"bytes,7,rep,name=cred,proto3" json:"cred,omitempty"` + Aux map[string][]byte `protobuf:"bytes,8,rep,name=aux,proto3" json:"aux,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *ServerMeta) Reset() { + *x = ServerMeta{} + if protoimpl.UnsafeEnabled { + mi := &file_model_proto_msgTypes[29] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ServerMeta) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ServerMeta) ProtoMessage() {} + +func (x *ServerMeta) ProtoReflect() protoreflect.Message { + mi := &file_model_proto_msgTypes[29] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ServerMeta.ProtoReflect.Descriptor instead. +func (*ServerMeta) Descriptor() ([]byte, []int) { + return file_model_proto_rawDescGZIP(), []int{29} +} + +func (x *ServerMeta) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *ServerMeta) GetTopic() string { + if x != nil { + return x.Topic + } + return "" +} + +func (x *ServerMeta) GetDesc() *TopicDesc { + if x != nil { + return x.Desc + } + return nil +} + +func (x *ServerMeta) GetSub() []*TopicSub { + if x != nil { + return x.Sub + } + return nil +} + +func (x *ServerMeta) GetDel() *DelValues { + if x != nil { + return x.Del + } + return nil +} + +func (x *ServerMeta) GetTags() []string { + if x != nil { + return x.Tags + } + return nil +} + +func (x *ServerMeta) GetCred() []*ServerCred { + if x != nil { + return x.Cred + } + return nil +} + +func (x *ServerMeta) GetAux() map[string][]byte { + if x != nil { + return x.Aux + } + return nil +} + +// {info} message: server-side copy of ClientNote with From and optional Src added. +type ServerInfo struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Topic string `protobuf:"bytes,1,opt,name=topic,proto3" json:"topic,omitempty"` + FromUserId string `protobuf:"bytes,2,opt,name=from_user_id,json=fromUserId,proto3" json:"from_user_id,omitempty"` + What InfoNote `protobuf:"varint,3,opt,name=what,proto3,enum=pbx.InfoNote" json:"what,omitempty"` + SeqId int32 `protobuf:"varint,4,opt,name=seq_id,json=seqId,proto3" json:"seq_id,omitempty"` + Src string `protobuf:"bytes,5,opt,name=src,proto3" json:"src,omitempty"` + Event CallEvent `protobuf:"varint,6,opt,name=event,proto3,enum=pbx.CallEvent" json:"event,omitempty"` + Payload []byte `protobuf:"bytes,7,opt,name=payload,proto3" json:"payload,omitempty"` +} + +func (x *ServerInfo) Reset() { + *x = ServerInfo{} + if protoimpl.UnsafeEnabled { + mi := &file_model_proto_msgTypes[30] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ServerInfo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ServerInfo) ProtoMessage() {} + +func (x *ServerInfo) ProtoReflect() protoreflect.Message { + mi := &file_model_proto_msgTypes[30] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ServerInfo.ProtoReflect.Descriptor instead. +func (*ServerInfo) Descriptor() ([]byte, []int) { + return file_model_proto_rawDescGZIP(), []int{30} +} + +func (x *ServerInfo) GetTopic() string { + if x != nil { + return x.Topic + } + return "" +} + +func (x *ServerInfo) GetFromUserId() string { + if x != nil { + return x.FromUserId + } + return "" +} + +func (x *ServerInfo) GetWhat() InfoNote { + if x != nil { + return x.What + } + return InfoNote_X1 +} + +func (x *ServerInfo) GetSeqId() int32 { + if x != nil { + return x.SeqId + } + return 0 +} + +func (x *ServerInfo) GetSrc() string { + if x != nil { + return x.Src + } + return "" +} + +func (x *ServerInfo) GetEvent() CallEvent { + if x != nil { + return x.Event + } + return CallEvent_X2 +} + +func (x *ServerInfo) GetPayload() []byte { + if x != nil { + return x.Payload + } + return nil +} + +// Cumulative message +type ServerMsg struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Types that are assignable to Message: + // + // *ServerMsg_Ctrl + // *ServerMsg_Data + // *ServerMsg_Pres + // *ServerMsg_Meta + // *ServerMsg_Info + Message isServerMsg_Message `protobuf_oneof:"Message"` + // DEPRECATED. Will be removed soon. + // When response is sent to Root, send internal topic name too. + // + // Deprecated: Do not use. + Topic string `protobuf:"bytes,6,opt,name=topic,proto3" json:"topic,omitempty"` +} + +func (x *ServerMsg) Reset() { + *x = ServerMsg{} + if protoimpl.UnsafeEnabled { + mi := &file_model_proto_msgTypes[31] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ServerMsg) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ServerMsg) ProtoMessage() {} + +func (x *ServerMsg) ProtoReflect() protoreflect.Message { + mi := &file_model_proto_msgTypes[31] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ServerMsg.ProtoReflect.Descriptor instead. +func (*ServerMsg) Descriptor() ([]byte, []int) { + return file_model_proto_rawDescGZIP(), []int{31} +} + +func (m *ServerMsg) GetMessage() isServerMsg_Message { + if m != nil { + return m.Message + } + return nil +} + +func (x *ServerMsg) GetCtrl() *ServerCtrl { + if x, ok := x.GetMessage().(*ServerMsg_Ctrl); ok { + return x.Ctrl + } + return nil +} + +func (x *ServerMsg) GetData() *ServerData { + if x, ok := x.GetMessage().(*ServerMsg_Data); ok { + return x.Data + } + return nil +} + +func (x *ServerMsg) GetPres() *ServerPres { + if x, ok := x.GetMessage().(*ServerMsg_Pres); ok { + return x.Pres + } + return nil +} + +func (x *ServerMsg) GetMeta() *ServerMeta { + if x, ok := x.GetMessage().(*ServerMsg_Meta); ok { + return x.Meta + } + return nil +} + +func (x *ServerMsg) GetInfo() *ServerInfo { + if x, ok := x.GetMessage().(*ServerMsg_Info); ok { + return x.Info + } + return nil +} + +// Deprecated: Do not use. +func (x *ServerMsg) GetTopic() string { + if x != nil { + return x.Topic + } + return "" +} + +type isServerMsg_Message interface { + isServerMsg_Message() +} + +type ServerMsg_Ctrl struct { + Ctrl *ServerCtrl `protobuf:"bytes,1,opt,name=ctrl,proto3,oneof"` +} + +type ServerMsg_Data struct { + Data *ServerData `protobuf:"bytes,2,opt,name=data,proto3,oneof"` +} + +type ServerMsg_Pres struct { + Pres *ServerPres `protobuf:"bytes,3,opt,name=pres,proto3,oneof"` +} + +type ServerMsg_Meta struct { + Meta *ServerMeta `protobuf:"bytes,4,opt,name=meta,proto3,oneof"` +} + +type ServerMsg_Info struct { + Info *ServerInfo `protobuf:"bytes,5,opt,name=info,proto3,oneof"` +} + +func (*ServerMsg_Ctrl) isServerMsg_Message() {} + +func (*ServerMsg_Data) isServerMsg_Message() {} + +func (*ServerMsg_Pres) isServerMsg_Message() {} + +func (*ServerMsg_Meta) isServerMsg_Message() {} + +func (*ServerMsg_Info) isServerMsg_Message() {} + +type ServerResp struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Status RespCode `protobuf:"varint,1,opt,name=status,proto3,enum=pbx.RespCode" json:"status,omitempty"` + Srvmsg *ServerMsg `protobuf:"bytes,2,opt,name=srvmsg,proto3" json:"srvmsg,omitempty"` + Clmsg *ClientMsg `protobuf:"bytes,3,opt,name=clmsg,proto3" json:"clmsg,omitempty"` +} + +func (x *ServerResp) Reset() { + *x = ServerResp{} + if protoimpl.UnsafeEnabled { + mi := &file_model_proto_msgTypes[32] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ServerResp) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ServerResp) ProtoMessage() {} + +func (x *ServerResp) ProtoReflect() protoreflect.Message { + mi := &file_model_proto_msgTypes[32] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ServerResp.ProtoReflect.Descriptor instead. +func (*ServerResp) Descriptor() ([]byte, []int) { + return file_model_proto_rawDescGZIP(), []int{32} +} + +func (x *ServerResp) GetStatus() RespCode { + if x != nil { + return x.Status + } + return RespCode_CONTINUE +} + +func (x *ServerResp) GetSrvmsg() *ServerMsg { + if x != nil { + return x.Srvmsg + } + return nil +} + +func (x *ServerResp) GetClmsg() *ClientMsg { + if x != nil { + return x.Clmsg + } + return nil +} + +// Context message +type Session struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + SessionId string `protobuf:"bytes,1,opt,name=session_id,json=sessionId,proto3" json:"session_id,omitempty"` + UserId string `protobuf:"bytes,2,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` + AuthLevel AuthLevel `protobuf:"varint,3,opt,name=auth_level,json=authLevel,proto3,enum=pbx.AuthLevel" json:"auth_level,omitempty"` + RemoteAddr string `protobuf:"bytes,4,opt,name=remote_addr,json=remoteAddr,proto3" json:"remote_addr,omitempty"` + UserAgent string `protobuf:"bytes,5,opt,name=user_agent,json=userAgent,proto3" json:"user_agent,omitempty"` + DeviceId string `protobuf:"bytes,6,opt,name=device_id,json=deviceId,proto3" json:"device_id,omitempty"` + Language string `protobuf:"bytes,7,opt,name=language,proto3" json:"language,omitempty"` +} + +func (x *Session) Reset() { + *x = Session{} + if protoimpl.UnsafeEnabled { + mi := &file_model_proto_msgTypes[33] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Session) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Session) ProtoMessage() {} + +func (x *Session) ProtoReflect() protoreflect.Message { + mi := &file_model_proto_msgTypes[33] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Session.ProtoReflect.Descriptor instead. +func (*Session) Descriptor() ([]byte, []int) { + return file_model_proto_rawDescGZIP(), []int{33} +} + +func (x *Session) GetSessionId() string { + if x != nil { + return x.SessionId + } + return "" +} + +func (x *Session) GetUserId() string { + if x != nil { + return x.UserId + } + return "" +} + +func (x *Session) GetAuthLevel() AuthLevel { + if x != nil { + return x.AuthLevel + } + return AuthLevel_NONE +} + +func (x *Session) GetRemoteAddr() string { + if x != nil { + return x.RemoteAddr + } + return "" +} + +func (x *Session) GetUserAgent() string { + if x != nil { + return x.UserAgent + } + return "" +} + +func (x *Session) GetDeviceId() string { + if x != nil { + return x.DeviceId + } + return "" +} + +func (x *Session) GetLanguage() string { + if x != nil { + return x.Language + } + return "" +} + +type ClientReq struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Msg *ClientMsg `protobuf:"bytes,1,opt,name=msg,proto3" json:"msg,omitempty"` + Sess *Session `protobuf:"bytes,2,opt,name=sess,proto3" json:"sess,omitempty"` +} + +func (x *ClientReq) Reset() { + *x = ClientReq{} + if protoimpl.UnsafeEnabled { + mi := &file_model_proto_msgTypes[34] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ClientReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ClientReq) ProtoMessage() {} + +func (x *ClientReq) ProtoReflect() protoreflect.Message { + mi := &file_model_proto_msgTypes[34] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ClientReq.ProtoReflect.Descriptor instead. +func (*ClientReq) Descriptor() ([]byte, []int) { + return file_model_proto_rawDescGZIP(), []int{34} +} + +func (x *ClientReq) GetMsg() *ClientMsg { + if x != nil { + return x.Msg + } + return nil +} + +func (x *ClientReq) GetSess() *Session { + if x != nil { + return x.Sess + } + return nil +} + +type SearchQuery struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + UserId string `protobuf:"bytes,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` + Query string `protobuf:"bytes,2,opt,name=query,proto3" json:"query,omitempty"` +} + +func (x *SearchQuery) Reset() { + *x = SearchQuery{} + if protoimpl.UnsafeEnabled { + mi := &file_model_proto_msgTypes[35] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SearchQuery) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SearchQuery) ProtoMessage() {} + +func (x *SearchQuery) ProtoReflect() protoreflect.Message { + mi := &file_model_proto_msgTypes[35] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SearchQuery.ProtoReflect.Descriptor instead. +func (*SearchQuery) Descriptor() ([]byte, []int) { + return file_model_proto_rawDescGZIP(), []int{35} +} + +func (x *SearchQuery) GetUserId() string { + if x != nil { + return x.UserId + } + return "" +} + +func (x *SearchQuery) GetQuery() string { + if x != nil { + return x.Query + } + return "" +} + +type SearchFound struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Status RespCode `protobuf:"varint,1,opt,name=status,proto3,enum=pbx.RespCode" json:"status,omitempty"` + // New search query If status == REPLACE, otherwise unset. + Query string `protobuf:"bytes,2,opt,name=query,proto3" json:"query,omitempty"` + // Search results. + Result []*TopicSub `protobuf:"bytes,3,rep,name=result,proto3" json:"result,omitempty"` +} + +func (x *SearchFound) Reset() { + *x = SearchFound{} + if protoimpl.UnsafeEnabled { + mi := &file_model_proto_msgTypes[36] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SearchFound) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SearchFound) ProtoMessage() {} + +func (x *SearchFound) ProtoReflect() protoreflect.Message { + mi := &file_model_proto_msgTypes[36] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SearchFound.ProtoReflect.Descriptor instead. +func (*SearchFound) Descriptor() ([]byte, []int) { + return file_model_proto_rawDescGZIP(), []int{36} +} + +func (x *SearchFound) GetStatus() RespCode { + if x != nil { + return x.Status + } + return RespCode_CONTINUE +} + +func (x *SearchFound) GetQuery() string { + if x != nil { + return x.Query + } + return "" +} + +func (x *SearchFound) GetResult() []*TopicSub { + if x != nil { + return x.Result + } + return nil +} + +type TopicEvent struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Action Crud `protobuf:"varint,1,opt,name=action,proto3,enum=pbx.Crud" json:"action,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + Desc *TopicDesc `protobuf:"bytes,3,opt,name=desc,proto3" json:"desc,omitempty"` +} + +func (x *TopicEvent) Reset() { + *x = TopicEvent{} + if protoimpl.UnsafeEnabled { + mi := &file_model_proto_msgTypes[37] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *TopicEvent) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TopicEvent) ProtoMessage() {} + +func (x *TopicEvent) ProtoReflect() protoreflect.Message { + mi := &file_model_proto_msgTypes[37] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TopicEvent.ProtoReflect.Descriptor instead. +func (*TopicEvent) Descriptor() ([]byte, []int) { + return file_model_proto_rawDescGZIP(), []int{37} +} + +func (x *TopicEvent) GetAction() Crud { + if x != nil { + return x.Action + } + return Crud_CREATE +} + +func (x *TopicEvent) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *TopicEvent) GetDesc() *TopicDesc { + if x != nil { + return x.Desc + } + return nil +} + +type AccountEvent struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Action Crud `protobuf:"varint,1,opt,name=action,proto3,enum=pbx.Crud" json:"action,omitempty"` + UserId string `protobuf:"bytes,2,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` + DefaultAcs *DefaultAcsMode `protobuf:"bytes,3,opt,name=default_acs,json=defaultAcs,proto3" json:"default_acs,omitempty"` + Public []byte `protobuf:"bytes,4,opt,name=public,proto3" json:"public,omitempty"` + // Indexable tags for user discovery + Tags []string `protobuf:"bytes,8,rep,name=tags,proto3" json:"tags,omitempty"` +} + +func (x *AccountEvent) Reset() { + *x = AccountEvent{} + if protoimpl.UnsafeEnabled { + mi := &file_model_proto_msgTypes[38] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AccountEvent) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AccountEvent) ProtoMessage() {} + +func (x *AccountEvent) ProtoReflect() protoreflect.Message { + mi := &file_model_proto_msgTypes[38] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AccountEvent.ProtoReflect.Descriptor instead. +func (*AccountEvent) Descriptor() ([]byte, []int) { + return file_model_proto_rawDescGZIP(), []int{38} +} + +func (x *AccountEvent) GetAction() Crud { + if x != nil { + return x.Action + } + return Crud_CREATE +} + +func (x *AccountEvent) GetUserId() string { + if x != nil { + return x.UserId + } + return "" +} + +func (x *AccountEvent) GetDefaultAcs() *DefaultAcsMode { + if x != nil { + return x.DefaultAcs + } + return nil +} + +func (x *AccountEvent) GetPublic() []byte { + if x != nil { + return x.Public + } + return nil +} + +func (x *AccountEvent) GetTags() []string { + if x != nil { + return x.Tags + } + return nil +} + +type SubscriptionEvent struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Action Crud `protobuf:"varint,1,opt,name=action,proto3,enum=pbx.Crud" json:"action,omitempty"` + Topic string `protobuf:"bytes,2,opt,name=topic,proto3" json:"topic,omitempty"` + UserId string `protobuf:"bytes,3,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` + DelId int32 `protobuf:"varint,4,opt,name=del_id,json=delId,proto3" json:"del_id,omitempty"` + ReadId int32 `protobuf:"varint,5,opt,name=read_id,json=readId,proto3" json:"read_id,omitempty"` + RecvId int32 `protobuf:"varint,6,opt,name=recv_id,json=recvId,proto3" json:"recv_id,omitempty"` + Mode *AccessMode `protobuf:"bytes,7,opt,name=mode,proto3" json:"mode,omitempty"` + Private []byte `protobuf:"bytes,8,opt,name=private,proto3" json:"private,omitempty"` +} + +func (x *SubscriptionEvent) Reset() { + *x = SubscriptionEvent{} + if protoimpl.UnsafeEnabled { + mi := &file_model_proto_msgTypes[39] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SubscriptionEvent) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SubscriptionEvent) ProtoMessage() {} + +func (x *SubscriptionEvent) ProtoReflect() protoreflect.Message { + mi := &file_model_proto_msgTypes[39] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SubscriptionEvent.ProtoReflect.Descriptor instead. +func (*SubscriptionEvent) Descriptor() ([]byte, []int) { + return file_model_proto_rawDescGZIP(), []int{39} +} + +func (x *SubscriptionEvent) GetAction() Crud { + if x != nil { + return x.Action + } + return Crud_CREATE +} + +func (x *SubscriptionEvent) GetTopic() string { + if x != nil { + return x.Topic + } + return "" +} + +func (x *SubscriptionEvent) GetUserId() string { + if x != nil { + return x.UserId + } + return "" +} + +func (x *SubscriptionEvent) GetDelId() int32 { + if x != nil { + return x.DelId + } + return 0 +} + +func (x *SubscriptionEvent) GetReadId() int32 { + if x != nil { + return x.ReadId + } + return 0 +} + +func (x *SubscriptionEvent) GetRecvId() int32 { + if x != nil { + return x.RecvId + } + return 0 +} + +func (x *SubscriptionEvent) GetMode() *AccessMode { + if x != nil { + return x.Mode + } + return nil +} + +func (x *SubscriptionEvent) GetPrivate() []byte { + if x != nil { + return x.Private + } + return nil +} + +type MessageEvent struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Action Crud `protobuf:"varint,1,opt,name=action,proto3,enum=pbx.Crud" json:"action,omitempty"` + Msg *ServerData `protobuf:"bytes,2,opt,name=msg,proto3" json:"msg,omitempty"` +} + +func (x *MessageEvent) Reset() { + *x = MessageEvent{} + if protoimpl.UnsafeEnabled { + mi := &file_model_proto_msgTypes[40] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *MessageEvent) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MessageEvent) ProtoMessage() {} + +func (x *MessageEvent) ProtoReflect() protoreflect.Message { + mi := &file_model_proto_msgTypes[40] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MessageEvent.ProtoReflect.Descriptor instead. +func (*MessageEvent) Descriptor() ([]byte, []int) { + return file_model_proto_rawDescGZIP(), []int{40} +} + +func (x *MessageEvent) GetAction() Crud { + if x != nil { + return x.Action + } + return Crud_CREATE +} + +func (x *MessageEvent) GetMsg() *ServerData { + if x != nil { + return x.Msg + } + return nil +} + +type Auth struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Scheme string `protobuf:"bytes,1,opt,name=scheme,proto3" json:"scheme,omitempty"` + Secret string `protobuf:"bytes,2,opt,name=secret,proto3" json:"secret,omitempty"` +} + +func (x *Auth) Reset() { + *x = Auth{} + if protoimpl.UnsafeEnabled { + mi := &file_model_proto_msgTypes[41] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Auth) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Auth) ProtoMessage() {} + +func (x *Auth) ProtoReflect() protoreflect.Message { + mi := &file_model_proto_msgTypes[41] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Auth.ProtoReflect.Descriptor instead. +func (*Auth) Descriptor() ([]byte, []int) { + return file_model_proto_rawDescGZIP(), []int{41} +} + +func (x *Auth) GetScheme() string { + if x != nil { + return x.Scheme + } + return "" +} + +func (x *Auth) GetSecret() string { + if x != nil { + return x.Secret + } + return "" +} + +// File description. +type FileMeta struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + MimeType string `protobuf:"bytes,2,opt,name=mime_type,json=mimeType,proto3" json:"mime_type,omitempty"` + Etag string `protobuf:"bytes,3,opt,name=etag,proto3" json:"etag,omitempty"` + Size int64 `protobuf:"varint,4,opt,name=size,proto3" json:"size,omitempty"` +} + +func (x *FileMeta) Reset() { + *x = FileMeta{} + if protoimpl.UnsafeEnabled { + mi := &file_model_proto_msgTypes[42] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *FileMeta) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FileMeta) ProtoMessage() {} + +func (x *FileMeta) ProtoReflect() protoreflect.Message { + mi := &file_model_proto_msgTypes[42] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use FileMeta.ProtoReflect.Descriptor instead. +func (*FileMeta) Descriptor() ([]byte, []int) { + return file_model_proto_rawDescGZIP(), []int{42} +} + +func (x *FileMeta) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *FileMeta) GetMimeType() string { + if x != nil { + return x.MimeType + } + return "" +} + +func (x *FileMeta) GetEtag() string { + if x != nil { + return x.Etag + } + return "" +} + +func (x *FileMeta) GetSize() int64 { + if x != nil { + return x.Size + } + return 0 +} + +// File upload request. +type FileUpReq struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Request ID. + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + // Request authentication credentials. + Auth *Auth `protobuf:"bytes,2,opt,name=auth,proto3" json:"auth,omitempty"` + // The topic this upload belongs to. + Topic string `protobuf:"bytes,3,opt,name=topic,proto3" json:"topic,omitempty"` + // Uploaded metadata. + Meta *FileMeta `protobuf:"bytes,4,opt,name=meta,proto3" json:"meta,omitempty"` + // File bytes being uploaded. + Content []byte `protobuf:"bytes,5,opt,name=content,proto3" json:"content,omitempty"` +} + +func (x *FileUpReq) Reset() { + *x = FileUpReq{} + if protoimpl.UnsafeEnabled { + mi := &file_model_proto_msgTypes[43] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *FileUpReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FileUpReq) ProtoMessage() {} + +func (x *FileUpReq) ProtoReflect() protoreflect.Message { + mi := &file_model_proto_msgTypes[43] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use FileUpReq.ProtoReflect.Descriptor instead. +func (*FileUpReq) Descriptor() ([]byte, []int) { + return file_model_proto_rawDescGZIP(), []int{43} +} + +func (x *FileUpReq) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *FileUpReq) GetAuth() *Auth { + if x != nil { + return x.Auth + } + return nil +} + +func (x *FileUpReq) GetTopic() string { + if x != nil { + return x.Topic + } + return "" +} + +func (x *FileUpReq) GetMeta() *FileMeta { + if x != nil { + return x.Meta + } + return nil +} + +func (x *FileUpReq) GetContent() []byte { + if x != nil { + return x.Content + } + return nil +} + +// Response to file upload. +type FileUpResp struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Response ID. + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + // Response code. + Code int32 `protobuf:"varint,2,opt,name=code,proto3" json:"code,omitempty"` + // Response text. + Text string `protobuf:"bytes,3,opt,name=text,proto3" json:"text,omitempty"` + Meta *FileMeta `protobuf:"bytes,4,opt,name=meta,proto3" json:"meta,omitempty"` + // New upload location. + RedirUrl string `protobuf:"bytes,5,opt,name=redir_url,json=redirUrl,proto3" json:"redir_url,omitempty"` +} + +func (x *FileUpResp) Reset() { + *x = FileUpResp{} + if protoimpl.UnsafeEnabled { + mi := &file_model_proto_msgTypes[44] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *FileUpResp) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FileUpResp) ProtoMessage() {} + +func (x *FileUpResp) ProtoReflect() protoreflect.Message { + mi := &file_model_proto_msgTypes[44] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use FileUpResp.ProtoReflect.Descriptor instead. +func (*FileUpResp) Descriptor() ([]byte, []int) { + return file_model_proto_rawDescGZIP(), []int{44} +} + +func (x *FileUpResp) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *FileUpResp) GetCode() int32 { + if x != nil { + return x.Code + } + return 0 +} + +func (x *FileUpResp) GetText() string { + if x != nil { + return x.Text + } + return "" +} + +func (x *FileUpResp) GetMeta() *FileMeta { + if x != nil { + return x.Meta + } + return nil +} + +func (x *FileUpResp) GetRedirUrl() string { + if x != nil { + return x.RedirUrl + } + return "" +} + +// File download request. +type FileDownReq struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Request ID + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + // Request authentication credentials. + Auth *Auth `protobuf:"bytes,2,opt,name=auth,proto3" json:"auth,omitempty"` + // File URI to download. + Uri string `protobuf:"bytes,3,opt,name=uri,proto3" json:"uri,omitempty"` + // ETag + IfModified string `protobuf:"bytes,4,opt,name=if_modified,json=ifModified,proto3" json:"if_modified,omitempty"` +} + +func (x *FileDownReq) Reset() { + *x = FileDownReq{} + if protoimpl.UnsafeEnabled { + mi := &file_model_proto_msgTypes[45] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *FileDownReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FileDownReq) ProtoMessage() {} + +func (x *FileDownReq) ProtoReflect() protoreflect.Message { + mi := &file_model_proto_msgTypes[45] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use FileDownReq.ProtoReflect.Descriptor instead. +func (*FileDownReq) Descriptor() ([]byte, []int) { + return file_model_proto_rawDescGZIP(), []int{45} +} + +func (x *FileDownReq) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *FileDownReq) GetAuth() *Auth { + if x != nil { + return x.Auth + } + return nil +} + +func (x *FileDownReq) GetUri() string { + if x != nil { + return x.Uri + } + return "" +} + +func (x *FileDownReq) GetIfModified() string { + if x != nil { + return x.IfModified + } + return "" +} + +// Response to file download. +type FileDownResp struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Response ID. + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + // Response code. + Code int32 `protobuf:"varint,2,opt,name=code,proto3" json:"code,omitempty"` + // Response text. + Text string `protobuf:"bytes,3,opt,name=text,proto3" json:"text,omitempty"` + Meta *FileMeta `protobuf:"bytes,4,opt,name=meta,proto3" json:"meta,omitempty"` + // File location. + RedirUrl string `protobuf:"bytes,5,opt,name=redir_url,json=redirUrl,proto3" json:"redir_url,omitempty"` + // File bytes. + Content []byte `protobuf:"bytes,6,opt,name=content,proto3" json:"content,omitempty"` +} + +func (x *FileDownResp) Reset() { + *x = FileDownResp{} + if protoimpl.UnsafeEnabled { + mi := &file_model_proto_msgTypes[46] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *FileDownResp) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FileDownResp) ProtoMessage() {} + +func (x *FileDownResp) ProtoReflect() protoreflect.Message { + mi := &file_model_proto_msgTypes[46] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use FileDownResp.ProtoReflect.Descriptor instead. +func (*FileDownResp) Descriptor() ([]byte, []int) { + return file_model_proto_rawDescGZIP(), []int{46} +} + +func (x *FileDownResp) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *FileDownResp) GetCode() int32 { + if x != nil { + return x.Code + } + return 0 +} + +func (x *FileDownResp) GetText() string { + if x != nil { + return x.Text + } + return "" +} + +func (x *FileDownResp) GetMeta() *FileMeta { + if x != nil { + return x.Meta + } + return nil +} + +func (x *FileDownResp) GetRedirUrl() string { + if x != nil { + return x.RedirUrl + } + return "" +} + +func (x *FileDownResp) GetContent() []byte { + if x != nil { + return x.Content + } + return nil +} + +var File_model_proto protoreflect.FileDescriptor + +var file_model_proto_rawDesc = []byte{ + 0x0a, 0x0b, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x03, 0x70, + 0x62, 0x78, 0x22, 0x08, 0x0a, 0x06, 0x55, 0x6e, 0x75, 0x73, 0x65, 0x64, 0x22, 0x38, 0x0a, 0x0e, + 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x41, 0x63, 0x73, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x12, + 0x0a, 0x04, 0x61, 0x75, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x61, 0x75, + 0x74, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x61, 0x6e, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x61, 0x6e, 0x6f, 0x6e, 0x22, 0x36, 0x0a, 0x0a, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x77, 0x61, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x77, 0x61, 0x6e, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x67, 0x69, 0x76, 0x65, + 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x67, 0x69, 0x76, 0x65, 0x6e, 0x22, 0x35, + 0x0a, 0x06, 0x53, 0x65, 0x74, 0x53, 0x75, 0x62, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, + 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, + 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x22, 0xc6, 0x01, 0x0a, 0x0a, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, + 0x43, 0x72, 0x65, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x14, 0x0a, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x33, + 0x0a, 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, + 0x2e, 0x70, 0x62, 0x78, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x72, 0x65, 0x64, 0x2e, + 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x70, 0x61, 0x72, + 0x61, 0x6d, 0x73, 0x1a, 0x39, 0x0a, 0x0b, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x8b, + 0x01, 0x0a, 0x07, 0x53, 0x65, 0x74, 0x44, 0x65, 0x73, 0x63, 0x12, 0x34, 0x0a, 0x0b, 0x64, 0x65, + 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x61, 0x63, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x13, 0x2e, 0x70, 0x62, 0x78, 0x2e, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x41, 0x63, 0x73, + 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x0a, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x41, 0x63, 0x73, + 0x12, 0x16, 0x0a, 0x06, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x06, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x69, 0x76, + 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x70, 0x72, 0x69, 0x76, 0x61, + 0x74, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x74, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x07, 0x74, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x22, 0x2c, 0x0a, 0x08, + 0x53, 0x65, 0x71, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6c, 0x6f, 0x77, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x6c, 0x6f, 0x77, 0x12, 0x0e, 0x0a, 0x02, 0x68, 0x69, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x68, 0x69, 0x22, 0xd4, 0x01, 0x0a, 0x07, 0x47, + 0x65, 0x74, 0x4f, 0x70, 0x74, 0x73, 0x12, 0x2a, 0x0a, 0x11, 0x69, 0x66, 0x5f, 0x6d, 0x6f, 0x64, + 0x69, 0x66, 0x69, 0x65, 0x64, 0x5f, 0x73, 0x69, 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x03, 0x52, 0x0f, 0x69, 0x66, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x53, 0x69, 0x6e, + 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x12, 0x19, 0x0a, 0x08, + 0x73, 0x69, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, + 0x73, 0x69, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x62, 0x65, 0x66, 0x6f, 0x72, + 0x65, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x62, 0x65, 0x66, 0x6f, + 0x72, 0x65, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x05, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x25, 0x0a, 0x06, 0x72, 0x61, + 0x6e, 0x67, 0x65, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x70, 0x62, 0x78, + 0x2e, 0x53, 0x65, 0x71, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x06, 0x72, 0x61, 0x6e, 0x67, 0x65, + 0x73, 0x22, 0x82, 0x01, 0x0a, 0x08, 0x47, 0x65, 0x74, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x12, + 0x0a, 0x04, 0x77, 0x68, 0x61, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x77, 0x68, + 0x61, 0x74, 0x12, 0x20, 0x0a, 0x04, 0x64, 0x65, 0x73, 0x63, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x0c, 0x2e, 0x70, 0x62, 0x78, 0x2e, 0x47, 0x65, 0x74, 0x4f, 0x70, 0x74, 0x73, 0x52, 0x04, + 0x64, 0x65, 0x73, 0x63, 0x12, 0x1e, 0x0a, 0x03, 0x73, 0x75, 0x62, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x0c, 0x2e, 0x70, 0x62, 0x78, 0x2e, 0x47, 0x65, 0x74, 0x4f, 0x70, 0x74, 0x73, 0x52, + 0x03, 0x73, 0x75, 0x62, 0x12, 0x20, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x70, 0x62, 0x78, 0x2e, 0x47, 0x65, 0x74, 0x4f, 0x70, 0x74, 0x73, + 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0xe6, 0x01, 0x0a, 0x08, 0x53, 0x65, 0x74, 0x51, 0x75, + 0x65, 0x72, 0x79, 0x12, 0x20, 0x0a, 0x04, 0x64, 0x65, 0x73, 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x0c, 0x2e, 0x70, 0x62, 0x78, 0x2e, 0x53, 0x65, 0x74, 0x44, 0x65, 0x73, 0x63, 0x52, + 0x04, 0x64, 0x65, 0x73, 0x63, 0x12, 0x1d, 0x0a, 0x03, 0x73, 0x75, 0x62, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x70, 0x62, 0x78, 0x2e, 0x53, 0x65, 0x74, 0x53, 0x75, 0x62, 0x52, + 0x03, 0x73, 0x75, 0x62, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x61, 0x67, 0x73, 0x18, 0x03, 0x20, 0x03, + 0x28, 0x09, 0x52, 0x04, 0x74, 0x61, 0x67, 0x73, 0x12, 0x23, 0x0a, 0x04, 0x63, 0x72, 0x65, 0x64, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x70, 0x62, 0x78, 0x2e, 0x43, 0x6c, 0x69, + 0x65, 0x6e, 0x74, 0x43, 0x72, 0x65, 0x64, 0x52, 0x04, 0x63, 0x72, 0x65, 0x64, 0x12, 0x28, 0x0a, + 0x03, 0x61, 0x75, 0x78, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x70, 0x62, 0x78, + 0x2e, 0x53, 0x65, 0x74, 0x51, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x41, 0x75, 0x78, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x52, 0x03, 0x61, 0x75, 0x78, 0x1a, 0x36, 0x0a, 0x08, 0x41, 0x75, 0x78, 0x45, 0x6e, + 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, + 0xd0, 0x01, 0x0a, 0x08, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x48, 0x69, 0x12, 0x0e, 0x0a, 0x02, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1d, 0x0a, 0x0a, + 0x75, 0x73, 0x65, 0x72, 0x5f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x09, 0x75, 0x73, 0x65, 0x72, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x76, + 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x76, 0x65, 0x72, 0x12, 0x1b, 0x0a, + 0x09, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x08, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x61, + 0x6e, 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x1a, + 0x0a, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x12, 0x1e, 0x0a, 0x0a, 0x62, 0x61, + 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, + 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x65, + 0x6e, 0x61, 0x6e, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x74, 0x65, 0x6e, 0x61, + 0x6e, 0x74, 0x22, 0xee, 0x02, 0x0a, 0x09, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x41, 0x63, 0x63, + 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, + 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x63, 0x68, + 0x65, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, + 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x6f, 0x67, + 0x69, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x12, + 0x12, 0x0a, 0x04, 0x74, 0x61, 0x67, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x74, + 0x61, 0x67, 0x73, 0x12, 0x20, 0x0a, 0x04, 0x64, 0x65, 0x73, 0x63, 0x18, 0x07, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x0c, 0x2e, 0x70, 0x62, 0x78, 0x2e, 0x53, 0x65, 0x74, 0x44, 0x65, 0x73, 0x63, 0x52, + 0x04, 0x64, 0x65, 0x73, 0x63, 0x12, 0x23, 0x0a, 0x04, 0x63, 0x72, 0x65, 0x64, 0x18, 0x08, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x70, 0x62, 0x78, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, + 0x43, 0x72, 0x65, 0x64, 0x52, 0x04, 0x63, 0x72, 0x65, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, + 0x6b, 0x65, 0x6e, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, + 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x2d, 0x0a, 0x0a, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x6c, + 0x65, 0x76, 0x65, 0x6c, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0e, 0x2e, 0x70, 0x62, 0x78, + 0x2e, 0x41, 0x75, 0x74, 0x68, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x52, 0x09, 0x61, 0x75, 0x74, 0x68, + 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x6d, 0x70, 0x5f, 0x73, 0x63, 0x68, + 0x65, 0x6d, 0x65, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x6d, 0x70, 0x53, 0x63, + 0x68, 0x65, 0x6d, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x6d, 0x70, 0x5f, 0x73, 0x65, 0x63, 0x72, + 0x65, 0x74, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x74, 0x6d, 0x70, 0x53, 0x65, 0x63, + 0x72, 0x65, 0x74, 0x22, 0x72, 0x0a, 0x0b, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x4c, 0x6f, 0x67, + 0x69, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, + 0x69, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x65, + 0x63, 0x72, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x73, 0x65, 0x63, 0x72, + 0x65, 0x74, 0x12, 0x23, 0x0a, 0x04, 0x63, 0x72, 0x65, 0x64, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x0f, 0x2e, 0x70, 0x62, 0x78, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x72, 0x65, + 0x64, 0x52, 0x04, 0x63, 0x72, 0x65, 0x64, 0x22, 0x89, 0x01, 0x0a, 0x09, 0x43, 0x6c, 0x69, 0x65, + 0x6e, 0x74, 0x53, 0x75, 0x62, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x12, 0x2a, 0x0a, 0x09, 0x73, + 0x65, 0x74, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, + 0x2e, 0x70, 0x62, 0x78, 0x2e, 0x53, 0x65, 0x74, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x08, 0x73, + 0x65, 0x74, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x2a, 0x0a, 0x09, 0x67, 0x65, 0x74, 0x5f, 0x71, + 0x75, 0x65, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x70, 0x62, 0x78, + 0x2e, 0x47, 0x65, 0x74, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x08, 0x67, 0x65, 0x74, 0x51, 0x75, + 0x65, 0x72, 0x79, 0x22, 0x49, 0x0a, 0x0b, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x4c, 0x65, 0x61, + 0x76, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, + 0x69, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x05, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x12, 0x14, 0x0a, 0x05, 0x75, 0x6e, 0x73, 0x75, + 0x62, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x75, 0x6e, 0x73, 0x75, 0x62, 0x22, 0xcb, + 0x01, 0x0a, 0x09, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x50, 0x75, 0x62, 0x12, 0x0e, 0x0a, 0x02, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x05, + 0x74, 0x6f, 0x70, 0x69, 0x63, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x70, + 0x69, 0x63, 0x12, 0x17, 0x0a, 0x07, 0x6e, 0x6f, 0x5f, 0x65, 0x63, 0x68, 0x6f, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x06, 0x6e, 0x6f, 0x45, 0x63, 0x68, 0x6f, 0x12, 0x2c, 0x0a, 0x04, 0x68, + 0x65, 0x61, 0x64, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x70, 0x62, 0x78, 0x2e, + 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x50, 0x75, 0x62, 0x2e, 0x48, 0x65, 0x61, 0x64, 0x45, 0x6e, + 0x74, 0x72, 0x79, 0x52, 0x04, 0x68, 0x65, 0x61, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, + 0x74, 0x65, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, + 0x65, 0x6e, 0x74, 0x1a, 0x37, 0x0a, 0x09, 0x48, 0x65, 0x61, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, + 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, + 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x56, 0x0a, 0x09, + 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x47, 0x65, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x70, + 0x69, 0x63, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x12, + 0x23, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, + 0x2e, 0x70, 0x62, 0x78, 0x2e, 0x47, 0x65, 0x74, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x05, 0x71, + 0x75, 0x65, 0x72, 0x79, 0x22, 0x56, 0x0a, 0x09, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x53, 0x65, + 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, + 0x64, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x12, 0x23, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x70, 0x62, 0x78, 0x2e, 0x53, 0x65, 0x74, + 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x22, 0x95, 0x02, 0x0a, + 0x09, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x44, 0x65, 0x6c, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, + 0x70, 0x69, 0x63, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x70, 0x69, 0x63, + 0x12, 0x27, 0x0a, 0x04, 0x77, 0x68, 0x61, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x13, + 0x2e, 0x70, 0x62, 0x78, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x44, 0x65, 0x6c, 0x2e, 0x57, + 0x68, 0x61, 0x74, 0x52, 0x04, 0x77, 0x68, 0x61, 0x74, 0x12, 0x26, 0x0a, 0x07, 0x64, 0x65, 0x6c, + 0x5f, 0x73, 0x65, 0x71, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x70, 0x62, 0x78, + 0x2e, 0x53, 0x65, 0x71, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x06, 0x64, 0x65, 0x6c, 0x53, 0x65, + 0x71, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x23, 0x0a, 0x04, 0x63, 0x72, + 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x70, 0x62, 0x78, 0x2e, 0x43, + 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x72, 0x65, 0x64, 0x52, 0x04, 0x63, 0x72, 0x65, 0x64, 0x12, + 0x12, 0x0a, 0x04, 0x68, 0x61, 0x72, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x68, + 0x61, 0x72, 0x64, 0x22, 0x3f, 0x0a, 0x04, 0x57, 0x68, 0x61, 0x74, 0x12, 0x06, 0x0a, 0x02, 0x58, + 0x30, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x4d, 0x53, 0x47, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, + 0x54, 0x4f, 0x50, 0x49, 0x43, 0x10, 0x02, 0x12, 0x07, 0x0a, 0x03, 0x53, 0x55, 0x42, 0x10, 0x03, + 0x12, 0x08, 0x0a, 0x04, 0x55, 0x53, 0x45, 0x52, 0x10, 0x04, 0x12, 0x08, 0x0a, 0x04, 0x43, 0x52, + 0x45, 0x44, 0x10, 0x05, 0x22, 0xb4, 0x01, 0x0a, 0x0a, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x4e, + 0x6f, 0x74, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x12, 0x21, 0x0a, 0x04, 0x77, 0x68, 0x61, + 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0d, 0x2e, 0x70, 0x62, 0x78, 0x2e, 0x49, 0x6e, + 0x66, 0x6f, 0x4e, 0x6f, 0x74, 0x65, 0x52, 0x04, 0x77, 0x68, 0x61, 0x74, 0x12, 0x15, 0x0a, 0x06, + 0x73, 0x65, 0x71, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x73, 0x65, + 0x71, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x75, 0x6e, 0x72, 0x65, 0x61, 0x64, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x05, 0x52, 0x06, 0x75, 0x6e, 0x72, 0x65, 0x61, 0x64, 0x12, 0x24, 0x0a, 0x05, 0x65, + 0x76, 0x65, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0e, 0x2e, 0x70, 0x62, 0x78, + 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x05, 0x65, 0x76, 0x65, 0x6e, + 0x74, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x22, 0x80, 0x01, 0x0a, 0x0b, + 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x45, 0x78, 0x74, 0x72, 0x61, 0x12, 0x20, 0x0a, 0x0b, 0x61, + 0x74, 0x74, 0x61, 0x63, 0x68, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, + 0x52, 0x0b, 0x61, 0x74, 0x74, 0x61, 0x63, 0x68, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x20, 0x0a, + 0x0c, 0x6f, 0x6e, 0x5f, 0x62, 0x65, 0x68, 0x61, 0x6c, 0x66, 0x5f, 0x6f, 0x66, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6f, 0x6e, 0x42, 0x65, 0x68, 0x61, 0x6c, 0x66, 0x4f, 0x66, 0x12, + 0x2d, 0x0a, 0x0a, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x0e, 0x32, 0x0e, 0x2e, 0x70, 0x62, 0x78, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x4c, 0x65, + 0x76, 0x65, 0x6c, 0x52, 0x09, 0x61, 0x75, 0x74, 0x68, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x22, 0xb2, + 0x03, 0x0a, 0x09, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x4d, 0x73, 0x67, 0x12, 0x1f, 0x0a, 0x02, + 0x68, 0x69, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x70, 0x62, 0x78, 0x2e, 0x43, + 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x48, 0x69, 0x48, 0x00, 0x52, 0x02, 0x68, 0x69, 0x12, 0x22, 0x0a, + 0x03, 0x61, 0x63, 0x63, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x62, 0x78, + 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x41, 0x63, 0x63, 0x48, 0x00, 0x52, 0x03, 0x61, 0x63, + 0x63, 0x12, 0x28, 0x0a, 0x05, 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x10, 0x2e, 0x70, 0x62, 0x78, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x4c, 0x6f, 0x67, + 0x69, 0x6e, 0x48, 0x00, 0x52, 0x05, 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x12, 0x22, 0x0a, 0x03, 0x73, + 0x75, 0x62, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x62, 0x78, 0x2e, 0x43, + 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x53, 0x75, 0x62, 0x48, 0x00, 0x52, 0x03, 0x73, 0x75, 0x62, 0x12, + 0x28, 0x0a, 0x05, 0x6c, 0x65, 0x61, 0x76, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, + 0x2e, 0x70, 0x62, 0x78, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x4c, 0x65, 0x61, 0x76, 0x65, + 0x48, 0x00, 0x52, 0x05, 0x6c, 0x65, 0x61, 0x76, 0x65, 0x12, 0x22, 0x0a, 0x03, 0x70, 0x75, 0x62, + 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x62, 0x78, 0x2e, 0x43, 0x6c, 0x69, + 0x65, 0x6e, 0x74, 0x50, 0x75, 0x62, 0x48, 0x00, 0x52, 0x03, 0x70, 0x75, 0x62, 0x12, 0x22, 0x0a, + 0x03, 0x67, 0x65, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x62, 0x78, + 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x47, 0x65, 0x74, 0x48, 0x00, 0x52, 0x03, 0x67, 0x65, + 0x74, 0x12, 0x22, 0x0a, 0x03, 0x73, 0x65, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, + 0x2e, 0x70, 0x62, 0x78, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x53, 0x65, 0x74, 0x48, 0x00, + 0x52, 0x03, 0x73, 0x65, 0x74, 0x12, 0x22, 0x0a, 0x03, 0x64, 0x65, 0x6c, 0x18, 0x09, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x62, 0x78, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x44, + 0x65, 0x6c, 0x48, 0x00, 0x52, 0x03, 0x64, 0x65, 0x6c, 0x12, 0x25, 0x0a, 0x04, 0x6e, 0x6f, 0x74, + 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x70, 0x62, 0x78, 0x2e, 0x43, 0x6c, + 0x69, 0x65, 0x6e, 0x74, 0x4e, 0x6f, 0x74, 0x65, 0x48, 0x00, 0x52, 0x04, 0x6e, 0x6f, 0x74, 0x65, + 0x12, 0x26, 0x0a, 0x05, 0x65, 0x78, 0x74, 0x72, 0x61, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x10, 0x2e, 0x70, 0x62, 0x78, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x45, 0x78, 0x74, 0x72, + 0x61, 0x52, 0x05, 0x65, 0x78, 0x74, 0x72, 0x61, 0x42, 0x09, 0x0a, 0x07, 0x4d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x22, 0x4e, 0x0a, 0x0a, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x43, 0x72, 0x65, + 0x64, 0x12, 0x16, 0x0a, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, + 0x12, 0x0a, 0x04, 0x64, 0x6f, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x64, + 0x6f, 0x6e, 0x65, 0x22, 0x9d, 0x04, 0x0a, 0x09, 0x54, 0x6f, 0x70, 0x69, 0x63, 0x44, 0x65, 0x73, + 0x63, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, + 0x12, 0x1d, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, + 0x1d, 0x0a, 0x0a, 0x74, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x64, 0x41, 0x74, 0x12, 0x2b, + 0x0a, 0x06, 0x64, 0x65, 0x66, 0x61, 0x63, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, + 0x2e, 0x70, 0x62, 0x78, 0x2e, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x41, 0x63, 0x73, 0x4d, + 0x6f, 0x64, 0x65, 0x52, 0x06, 0x64, 0x65, 0x66, 0x61, 0x63, 0x73, 0x12, 0x21, 0x0a, 0x03, 0x61, + 0x63, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x70, 0x62, 0x78, 0x2e, 0x41, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x03, 0x61, 0x63, 0x73, 0x12, 0x15, + 0x0a, 0x06, 0x73, 0x65, 0x71, 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, + 0x73, 0x65, 0x71, 0x49, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x72, 0x65, 0x61, 0x64, 0x5f, 0x69, 0x64, + 0x18, 0x07, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x72, 0x65, 0x61, 0x64, 0x49, 0x64, 0x12, 0x17, + 0x0a, 0x07, 0x72, 0x65, 0x63, 0x76, 0x5f, 0x69, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x05, 0x52, + 0x06, 0x72, 0x65, 0x63, 0x76, 0x49, 0x64, 0x12, 0x15, 0x0a, 0x06, 0x64, 0x65, 0x6c, 0x5f, 0x69, + 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x64, 0x65, 0x6c, 0x49, 0x64, 0x12, 0x16, + 0x0a, 0x06, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, + 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, + 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, + 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, + 0x61, 0x74, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x73, 0x74, 0x61, 0x74, 0x65, 0x41, + 0x74, 0x12, 0x18, 0x0a, 0x07, 0x74, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x18, 0x0e, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x07, 0x74, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x69, + 0x73, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x18, 0x11, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x69, 0x73, + 0x43, 0x68, 0x61, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x12, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x6f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x24, 0x0a, 0x0e, + 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x65, 0x6e, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x0f, + 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x6c, 0x61, 0x73, 0x74, 0x53, 0x65, 0x65, 0x6e, 0x54, 0x69, + 0x6d, 0x65, 0x12, 0x2f, 0x0a, 0x14, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x65, 0x6e, 0x5f, + 0x75, 0x73, 0x65, 0x72, 0x5f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x18, 0x10, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x11, 0x6c, 0x61, 0x73, 0x74, 0x53, 0x65, 0x65, 0x6e, 0x55, 0x73, 0x65, 0x72, 0x41, 0x67, + 0x65, 0x6e, 0x74, 0x22, 0xd4, 0x03, 0x0a, 0x08, 0x54, 0x6f, 0x70, 0x69, 0x63, 0x53, 0x75, 0x62, + 0x12, 0x1d, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, + 0x1d, 0x0a, 0x0a, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x03, 0x52, 0x09, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x16, + 0x0a, 0x06, 0x6f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, + 0x6f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x21, 0x0a, 0x03, 0x61, 0x63, 0x73, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x70, 0x62, 0x78, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x03, 0x61, 0x63, 0x73, 0x12, 0x17, 0x0a, 0x07, 0x72, 0x65, 0x61, + 0x64, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x72, 0x65, 0x61, 0x64, + 0x49, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x72, 0x65, 0x63, 0x76, 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x05, 0x52, 0x06, 0x72, 0x65, 0x63, 0x76, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x70, + 0x75, 0x62, 0x6c, 0x69, 0x63, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x70, 0x75, 0x62, + 0x6c, 0x69, 0x63, 0x12, 0x18, 0x0a, 0x07, 0x74, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x18, 0x10, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x74, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x12, 0x18, 0x0a, + 0x07, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, + 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, + 0x69, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, + 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x05, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x6f, 0x75, 0x63, 0x68, 0x65, + 0x64, 0x5f, 0x61, 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x6f, 0x75, 0x63, + 0x68, 0x65, 0x64, 0x41, 0x74, 0x12, 0x15, 0x0a, 0x06, 0x73, 0x65, 0x71, 0x5f, 0x69, 0x64, 0x18, + 0x0c, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x73, 0x65, 0x71, 0x49, 0x64, 0x12, 0x15, 0x0a, 0x06, + 0x64, 0x65, 0x6c, 0x5f, 0x69, 0x64, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x64, 0x65, + 0x6c, 0x49, 0x64, 0x12, 0x24, 0x0a, 0x0e, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x65, 0x6e, + 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x6c, 0x61, 0x73, + 0x74, 0x53, 0x65, 0x65, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x2f, 0x0a, 0x14, 0x6c, 0x61, 0x73, + 0x74, 0x5f, 0x73, 0x65, 0x65, 0x6e, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x61, 0x67, 0x65, 0x6e, + 0x74, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x6c, 0x61, 0x73, 0x74, 0x53, 0x65, 0x65, + 0x6e, 0x55, 0x73, 0x65, 0x72, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x22, 0x4a, 0x0a, 0x09, 0x44, 0x65, + 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x15, 0x0a, 0x06, 0x64, 0x65, 0x6c, 0x5f, 0x69, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x64, 0x65, 0x6c, 0x49, 0x64, 0x12, 0x26, + 0x0a, 0x07, 0x64, 0x65, 0x6c, 0x5f, 0x73, 0x65, 0x71, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x0d, 0x2e, 0x70, 0x62, 0x78, 0x2e, 0x53, 0x65, 0x71, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x06, + 0x64, 0x65, 0x6c, 0x53, 0x65, 0x71, 0x22, 0xca, 0x01, 0x0a, 0x0a, 0x53, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x43, 0x74, 0x72, 0x6c, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x12, 0x12, 0x0a, 0x04, 0x63, + 0x6f, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, + 0x12, 0x0a, 0x04, 0x74, 0x65, 0x78, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, + 0x65, 0x78, 0x74, 0x12, 0x33, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, 0x05, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x70, 0x62, 0x78, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x43, 0x74, 0x72, 0x6c, 0x2e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, + 0x52, 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x1a, 0x39, 0x0a, 0x0b, 0x50, 0x61, 0x72, 0x61, + 0x6d, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, + 0x02, 0x38, 0x01, 0x22, 0x9a, 0x02, 0x0a, 0x0a, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x44, 0x61, + 0x74, 0x61, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x05, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x12, 0x20, 0x0a, 0x0c, 0x66, 0x72, 0x6f, 0x6d, + 0x5f, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, + 0x66, 0x72, 0x6f, 0x6d, 0x55, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, + 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, + 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x1d, 0x0a, 0x0a, 0x64, 0x65, 0x6c, 0x65, + 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x64, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x15, 0x0a, 0x06, 0x73, 0x65, 0x71, 0x5f, 0x69, + 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x73, 0x65, 0x71, 0x49, 0x64, 0x12, 0x2d, + 0x0a, 0x04, 0x68, 0x65, 0x61, 0x64, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x70, + 0x62, 0x78, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x2e, 0x48, 0x65, + 0x61, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x04, 0x68, 0x65, 0x61, 0x64, 0x12, 0x18, 0x0a, + 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, + 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x1a, 0x37, 0x0a, 0x09, 0x48, 0x65, 0x61, 0x64, 0x45, + 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, + 0x22, 0xc9, 0x03, 0x0a, 0x0a, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x50, 0x72, 0x65, 0x73, 0x12, + 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, + 0x74, 0x6f, 0x70, 0x69, 0x63, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x72, 0x63, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x03, 0x73, 0x72, 0x63, 0x12, 0x28, 0x0a, 0x04, 0x77, 0x68, 0x61, 0x74, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x14, 0x2e, 0x70, 0x62, 0x78, 0x2e, 0x53, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x50, 0x72, 0x65, 0x73, 0x2e, 0x57, 0x68, 0x61, 0x74, 0x52, 0x04, 0x77, 0x68, 0x61, + 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x75, 0x73, 0x65, 0x72, 0x41, 0x67, 0x65, 0x6e, 0x74, + 0x12, 0x15, 0x0a, 0x06, 0x73, 0x65, 0x71, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, + 0x52, 0x05, 0x73, 0x65, 0x71, 0x49, 0x64, 0x12, 0x15, 0x0a, 0x06, 0x64, 0x65, 0x6c, 0x5f, 0x69, + 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x64, 0x65, 0x6c, 0x49, 0x64, 0x12, 0x26, + 0x0a, 0x07, 0x64, 0x65, 0x6c, 0x5f, 0x73, 0x65, 0x71, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x0d, 0x2e, 0x70, 0x62, 0x78, 0x2e, 0x53, 0x65, 0x71, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x06, + 0x64, 0x65, 0x6c, 0x53, 0x65, 0x71, 0x12, 0x24, 0x0a, 0x0e, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, + 0x5f, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, + 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x22, 0x0a, 0x0d, + 0x61, 0x63, 0x74, 0x6f, 0x72, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x09, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0b, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x55, 0x73, 0x65, 0x72, 0x49, 0x64, + 0x12, 0x21, 0x0a, 0x03, 0x61, 0x63, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, + 0x70, 0x62, 0x78, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x03, + 0x61, 0x63, 0x73, 0x22, 0x86, 0x01, 0x0a, 0x04, 0x57, 0x68, 0x61, 0x74, 0x12, 0x06, 0x0a, 0x02, + 0x58, 0x33, 0x10, 0x00, 0x12, 0x06, 0x0a, 0x02, 0x4f, 0x4e, 0x10, 0x01, 0x12, 0x07, 0x0a, 0x03, + 0x4f, 0x46, 0x46, 0x10, 0x02, 0x12, 0x06, 0x0a, 0x02, 0x55, 0x41, 0x10, 0x03, 0x12, 0x07, 0x0a, + 0x03, 0x55, 0x50, 0x44, 0x10, 0x04, 0x12, 0x08, 0x0a, 0x04, 0x47, 0x4f, 0x4e, 0x45, 0x10, 0x05, + 0x12, 0x07, 0x0a, 0x03, 0x41, 0x43, 0x53, 0x10, 0x06, 0x12, 0x08, 0x0a, 0x04, 0x54, 0x45, 0x52, + 0x4d, 0x10, 0x07, 0x12, 0x07, 0x0a, 0x03, 0x4d, 0x53, 0x47, 0x10, 0x08, 0x12, 0x08, 0x0a, 0x04, + 0x52, 0x45, 0x41, 0x44, 0x10, 0x09, 0x12, 0x08, 0x0a, 0x04, 0x52, 0x45, 0x43, 0x56, 0x10, 0x0a, + 0x12, 0x07, 0x0a, 0x03, 0x44, 0x45, 0x4c, 0x10, 0x0b, 0x12, 0x08, 0x0a, 0x04, 0x54, 0x41, 0x47, + 0x53, 0x10, 0x0c, 0x12, 0x07, 0x0a, 0x03, 0x41, 0x55, 0x58, 0x10, 0x0d, 0x22, 0xb6, 0x02, 0x0a, + 0x0a, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x61, 0x12, 0x0e, 0x0a, 0x02, 0x69, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x74, + 0x6f, 0x70, 0x69, 0x63, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x70, 0x69, + 0x63, 0x12, 0x22, 0x0a, 0x04, 0x64, 0x65, 0x73, 0x63, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x0e, 0x2e, 0x70, 0x62, 0x78, 0x2e, 0x54, 0x6f, 0x70, 0x69, 0x63, 0x44, 0x65, 0x73, 0x63, 0x52, + 0x04, 0x64, 0x65, 0x73, 0x63, 0x12, 0x1f, 0x0a, 0x03, 0x73, 0x75, 0x62, 0x18, 0x04, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x70, 0x62, 0x78, 0x2e, 0x54, 0x6f, 0x70, 0x69, 0x63, 0x53, 0x75, + 0x62, 0x52, 0x03, 0x73, 0x75, 0x62, 0x12, 0x20, 0x0a, 0x03, 0x64, 0x65, 0x6c, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x62, 0x78, 0x2e, 0x44, 0x65, 0x6c, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x73, 0x52, 0x03, 0x64, 0x65, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x61, 0x67, 0x73, + 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x74, 0x61, 0x67, 0x73, 0x12, 0x23, 0x0a, 0x04, + 0x63, 0x72, 0x65, 0x64, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x70, 0x62, 0x78, + 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x43, 0x72, 0x65, 0x64, 0x52, 0x04, 0x63, 0x72, 0x65, + 0x64, 0x12, 0x2a, 0x0a, 0x03, 0x61, 0x75, 0x78, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, + 0x2e, 0x70, 0x62, 0x78, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x61, 0x2e, + 0x41, 0x75, 0x78, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x03, 0x61, 0x75, 0x78, 0x1a, 0x36, 0x0a, + 0x08, 0x41, 0x75, 0x78, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xd0, 0x01, 0x0a, 0x0a, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x12, 0x20, 0x0a, 0x0c, 0x66, 0x72, + 0x6f, 0x6d, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0a, 0x66, 0x72, 0x6f, 0x6d, 0x55, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x04, + 0x77, 0x68, 0x61, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0d, 0x2e, 0x70, 0x62, 0x78, + 0x2e, 0x49, 0x6e, 0x66, 0x6f, 0x4e, 0x6f, 0x74, 0x65, 0x52, 0x04, 0x77, 0x68, 0x61, 0x74, 0x12, + 0x15, 0x0a, 0x06, 0x73, 0x65, 0x71, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, + 0x05, 0x73, 0x65, 0x71, 0x49, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x72, 0x63, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x03, 0x73, 0x72, 0x63, 0x12, 0x24, 0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e, + 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0e, 0x2e, 0x70, 0x62, 0x78, 0x2e, 0x43, 0x61, + 0x6c, 0x6c, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x18, + 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x22, 0xf3, 0x01, 0x0a, 0x09, 0x53, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x4d, 0x73, 0x67, 0x12, 0x25, 0x0a, 0x04, 0x63, 0x74, 0x72, 0x6c, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x70, 0x62, 0x78, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x43, 0x74, 0x72, 0x6c, 0x48, 0x00, 0x52, 0x04, 0x63, 0x74, 0x72, 0x6c, 0x12, 0x25, 0x0a, + 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x70, 0x62, + 0x78, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x48, 0x00, 0x52, 0x04, + 0x64, 0x61, 0x74, 0x61, 0x12, 0x25, 0x0a, 0x04, 0x70, 0x72, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x70, 0x62, 0x78, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x50, + 0x72, 0x65, 0x73, 0x48, 0x00, 0x52, 0x04, 0x70, 0x72, 0x65, 0x73, 0x12, 0x25, 0x0a, 0x04, 0x6d, + 0x65, 0x74, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x70, 0x62, 0x78, 0x2e, + 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x61, 0x48, 0x00, 0x52, 0x04, 0x6d, 0x65, + 0x74, 0x61, 0x12, 0x25, 0x0a, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x0f, 0x2e, 0x70, 0x62, 0x78, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x49, 0x6e, 0x66, + 0x6f, 0x48, 0x00, 0x52, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x12, 0x18, 0x0a, 0x05, 0x74, 0x6f, 0x70, + 0x69, 0x63, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x42, 0x02, 0x18, 0x01, 0x52, 0x05, 0x74, 0x6f, + 0x70, 0x69, 0x63, 0x42, 0x09, 0x0a, 0x07, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x81, + 0x01, 0x0a, 0x0a, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x12, 0x25, 0x0a, + 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0d, 0x2e, + 0x70, 0x62, 0x78, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x43, 0x6f, 0x64, 0x65, 0x52, 0x06, 0x73, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x12, 0x26, 0x0a, 0x06, 0x73, 0x72, 0x76, 0x6d, 0x73, 0x67, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x62, 0x78, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x4d, 0x73, 0x67, 0x52, 0x06, 0x73, 0x72, 0x76, 0x6d, 0x73, 0x67, 0x12, 0x24, 0x0a, 0x05, + 0x63, 0x6c, 0x6d, 0x73, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x62, + 0x78, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x4d, 0x73, 0x67, 0x52, 0x05, 0x63, 0x6c, 0x6d, + 0x73, 0x67, 0x22, 0xe9, 0x01, 0x0a, 0x07, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1d, + 0x0a, 0x0a, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x09, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x17, 0x0a, + 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, + 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x2d, 0x0a, 0x0a, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x6c, + 0x65, 0x76, 0x65, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0e, 0x2e, 0x70, 0x62, 0x78, + 0x2e, 0x41, 0x75, 0x74, 0x68, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x52, 0x09, 0x61, 0x75, 0x74, 0x68, + 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x5f, + 0x61, 0x64, 0x64, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72, 0x65, 0x6d, 0x6f, + 0x74, 0x65, 0x41, 0x64, 0x64, 0x72, 0x12, 0x1d, 0x0a, 0x0a, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x61, + 0x67, 0x65, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x75, 0x73, 0x65, 0x72, + 0x41, 0x67, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, + 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, + 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x18, 0x07, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x22, 0x4f, + 0x0a, 0x09, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x12, 0x20, 0x0a, 0x03, 0x6d, + 0x73, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x62, 0x78, 0x2e, 0x43, + 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x4d, 0x73, 0x67, 0x52, 0x03, 0x6d, 0x73, 0x67, 0x12, 0x20, 0x0a, + 0x04, 0x73, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x70, 0x62, + 0x78, 0x2e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x04, 0x73, 0x65, 0x73, 0x73, 0x22, + 0x3c, 0x0a, 0x0b, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x17, + 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x22, 0x71, 0x0a, + 0x0b, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x46, 0x6f, 0x75, 0x6e, 0x64, 0x12, 0x25, 0x0a, 0x06, + 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0d, 0x2e, 0x70, + 0x62, 0x78, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x43, 0x6f, 0x64, 0x65, 0x52, 0x06, 0x73, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x12, 0x25, 0x0a, 0x06, 0x72, 0x65, 0x73, + 0x75, 0x6c, 0x74, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x70, 0x62, 0x78, 0x2e, + 0x54, 0x6f, 0x70, 0x69, 0x63, 0x53, 0x75, 0x62, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, + 0x22, 0x67, 0x0a, 0x0a, 0x54, 0x6f, 0x70, 0x69, 0x63, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x21, + 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x09, + 0x2e, 0x70, 0x62, 0x78, 0x2e, 0x43, 0x72, 0x75, 0x64, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x22, 0x0a, 0x04, 0x64, 0x65, 0x73, 0x63, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x62, 0x78, 0x2e, 0x54, 0x6f, 0x70, 0x69, 0x63, 0x44, + 0x65, 0x73, 0x63, 0x52, 0x04, 0x64, 0x65, 0x73, 0x63, 0x22, 0xac, 0x01, 0x0a, 0x0c, 0x41, 0x63, + 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x21, 0x0a, 0x06, 0x61, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x09, 0x2e, 0x70, 0x62, 0x78, + 0x2e, 0x43, 0x72, 0x75, 0x64, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x17, 0x0a, + 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, + 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x34, 0x0a, 0x0b, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, + 0x74, 0x5f, 0x61, 0x63, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x70, 0x62, + 0x78, 0x2e, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x41, 0x63, 0x73, 0x4d, 0x6f, 0x64, 0x65, + 0x52, 0x0a, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x41, 0x63, 0x73, 0x12, 0x16, 0x0a, 0x06, + 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x70, 0x75, + 0x62, 0x6c, 0x69, 0x63, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x61, 0x67, 0x73, 0x18, 0x08, 0x20, 0x03, + 0x28, 0x09, 0x52, 0x04, 0x74, 0x61, 0x67, 0x73, 0x22, 0xed, 0x01, 0x0a, 0x11, 0x53, 0x75, 0x62, + 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x21, + 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x09, + 0x2e, 0x70, 0x62, 0x78, 0x2e, 0x43, 0x72, 0x75, 0x64, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, + 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, + 0x12, 0x15, 0x0a, 0x06, 0x64, 0x65, 0x6c, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, + 0x52, 0x05, 0x64, 0x65, 0x6c, 0x49, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x72, 0x65, 0x61, 0x64, 0x5f, + 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x72, 0x65, 0x61, 0x64, 0x49, 0x64, + 0x12, 0x17, 0x0a, 0x07, 0x72, 0x65, 0x63, 0x76, 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, + 0x05, 0x52, 0x06, 0x72, 0x65, 0x63, 0x76, 0x49, 0x64, 0x12, 0x23, 0x0a, 0x04, 0x6d, 0x6f, 0x64, + 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x70, 0x62, 0x78, 0x2e, 0x41, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x12, 0x18, + 0x0a, 0x07, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x07, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x22, 0x54, 0x0a, 0x0c, 0x4d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x21, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x09, 0x2e, 0x70, 0x62, 0x78, 0x2e, 0x43, + 0x72, 0x75, 0x64, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x21, 0x0a, 0x03, 0x6d, + 0x73, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x70, 0x62, 0x78, 0x2e, 0x53, + 0x65, 0x72, 0x76, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x52, 0x03, 0x6d, 0x73, 0x67, 0x22, 0x36, + 0x0a, 0x04, 0x41, 0x75, 0x74, 0x68, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x65, 0x12, 0x16, + 0x0a, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, + 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x22, 0x63, 0x0a, 0x08, 0x46, 0x69, 0x6c, 0x65, 0x4d, 0x65, + 0x74, 0x61, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x6d, 0x69, 0x6d, 0x65, 0x5f, 0x74, + 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6d, 0x69, 0x6d, 0x65, 0x54, + 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x65, 0x74, 0x61, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x65, 0x74, 0x61, 0x67, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x22, 0x8d, 0x01, 0x0a, 0x09, + 0x46, 0x69, 0x6c, 0x65, 0x55, 0x70, 0x52, 0x65, 0x71, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1d, 0x0a, 0x04, 0x61, 0x75, 0x74, + 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x09, 0x2e, 0x70, 0x62, 0x78, 0x2e, 0x41, 0x75, + 0x74, 0x68, 0x52, 0x04, 0x61, 0x75, 0x74, 0x68, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x70, 0x69, + 0x63, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x12, 0x21, + 0x0a, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x70, + 0x62, 0x78, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x52, 0x04, 0x6d, 0x65, 0x74, + 0x61, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x22, 0x84, 0x01, 0x0a, 0x0a, + 0x46, 0x69, 0x6c, 0x65, 0x55, 0x70, 0x52, 0x65, 0x73, 0x70, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, + 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x12, + 0x0a, 0x04, 0x74, 0x65, 0x78, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x65, + 0x78, 0x74, 0x12, 0x21, 0x0a, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x0d, 0x2e, 0x70, 0x62, 0x78, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x52, + 0x04, 0x6d, 0x65, 0x74, 0x61, 0x12, 0x1b, 0x0a, 0x09, 0x72, 0x65, 0x64, 0x69, 0x72, 0x5f, 0x75, + 0x72, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x64, 0x69, 0x72, 0x55, + 0x72, 0x6c, 0x22, 0x6f, 0x0a, 0x0b, 0x46, 0x69, 0x6c, 0x65, 0x44, 0x6f, 0x77, 0x6e, 0x52, 0x65, + 0x71, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, + 0x64, 0x12, 0x1d, 0x0a, 0x04, 0x61, 0x75, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x09, 0x2e, 0x70, 0x62, 0x78, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x52, 0x04, 0x61, 0x75, 0x74, 0x68, + 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x69, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, + 0x72, 0x69, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x66, 0x5f, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, + 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x69, 0x66, 0x4d, 0x6f, 0x64, 0x69, 0x66, + 0x69, 0x65, 0x64, 0x22, 0xa0, 0x01, 0x0a, 0x0c, 0x46, 0x69, 0x6c, 0x65, 0x44, 0x6f, 0x77, 0x6e, + 0x52, 0x65, 0x73, 0x70, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x05, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x65, 0x78, 0x74, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x65, 0x78, 0x74, 0x12, 0x21, 0x0a, 0x04, + 0x6d, 0x65, 0x74, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x70, 0x62, 0x78, + 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x52, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x12, + 0x1b, 0x0a, 0x09, 0x72, 0x65, 0x64, 0x69, 0x72, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x64, 0x69, 0x72, 0x55, 0x72, 0x6c, 0x12, 0x18, 0x0a, 0x07, + 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, + 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2a, 0x33, 0x0a, 0x09, 0x41, 0x75, 0x74, 0x68, 0x4c, 0x65, + 0x76, 0x65, 0x6c, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x4f, 0x4e, 0x45, 0x10, 0x00, 0x12, 0x08, 0x0a, + 0x04, 0x41, 0x4e, 0x4f, 0x4e, 0x10, 0x0a, 0x12, 0x08, 0x0a, 0x04, 0x41, 0x55, 0x54, 0x48, 0x10, + 0x14, 0x12, 0x08, 0x0a, 0x04, 0x52, 0x4f, 0x4f, 0x54, 0x10, 0x1e, 0x2a, 0x38, 0x0a, 0x08, 0x49, + 0x6e, 0x66, 0x6f, 0x4e, 0x6f, 0x74, 0x65, 0x12, 0x06, 0x0a, 0x02, 0x58, 0x31, 0x10, 0x00, 0x12, + 0x08, 0x0a, 0x04, 0x52, 0x45, 0x41, 0x44, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x52, 0x45, 0x43, + 0x56, 0x10, 0x02, 0x12, 0x06, 0x0a, 0x02, 0x4b, 0x50, 0x10, 0x03, 0x12, 0x08, 0x0a, 0x04, 0x43, + 0x41, 0x4c, 0x4c, 0x10, 0x04, 0x2a, 0x6f, 0x0a, 0x09, 0x43, 0x61, 0x6c, 0x6c, 0x45, 0x76, 0x65, + 0x6e, 0x74, 0x12, 0x06, 0x0a, 0x02, 0x58, 0x32, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x41, 0x43, + 0x43, 0x45, 0x50, 0x54, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x41, 0x4e, 0x53, 0x57, 0x45, 0x52, + 0x10, 0x02, 0x12, 0x0b, 0x0a, 0x07, 0x48, 0x41, 0x4e, 0x47, 0x5f, 0x55, 0x50, 0x10, 0x03, 0x12, + 0x11, 0x0a, 0x0d, 0x49, 0x43, 0x45, 0x5f, 0x43, 0x41, 0x4e, 0x44, 0x49, 0x44, 0x41, 0x54, 0x45, + 0x10, 0x04, 0x12, 0x0a, 0x0a, 0x06, 0x49, 0x4e, 0x56, 0x49, 0x54, 0x45, 0x10, 0x05, 0x12, 0x09, + 0x0a, 0x05, 0x4f, 0x46, 0x46, 0x45, 0x52, 0x10, 0x06, 0x12, 0x0b, 0x0a, 0x07, 0x52, 0x49, 0x4e, + 0x47, 0x49, 0x4e, 0x47, 0x10, 0x07, 0x2a, 0x3c, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x43, 0x6f, + 0x64, 0x65, 0x12, 0x0c, 0x0a, 0x08, 0x43, 0x4f, 0x4e, 0x54, 0x49, 0x4e, 0x55, 0x45, 0x10, 0x00, + 0x12, 0x08, 0x0a, 0x04, 0x44, 0x52, 0x4f, 0x50, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x52, 0x45, + 0x53, 0x50, 0x4f, 0x4e, 0x44, 0x10, 0x02, 0x12, 0x0b, 0x0a, 0x07, 0x52, 0x45, 0x50, 0x4c, 0x41, + 0x43, 0x45, 0x10, 0x03, 0x2a, 0x2a, 0x0a, 0x04, 0x43, 0x72, 0x75, 0x64, 0x12, 0x0a, 0x0a, 0x06, + 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x55, 0x50, 0x44, 0x41, + 0x54, 0x45, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x02, + 0x32, 0xaf, 0x01, 0x0a, 0x04, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x33, 0x0a, 0x0b, 0x4d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x4c, 0x6f, 0x6f, 0x70, 0x12, 0x0e, 0x2e, 0x70, 0x62, 0x78, 0x2e, 0x43, + 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x4d, 0x73, 0x67, 0x1a, 0x0e, 0x2e, 0x70, 0x62, 0x78, 0x2e, 0x53, + 0x65, 0x72, 0x76, 0x65, 0x72, 0x4d, 0x73, 0x67, 0x22, 0x00, 0x28, 0x01, 0x30, 0x01, 0x12, 0x37, + 0x0a, 0x10, 0x4c, 0x61, 0x72, 0x67, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x63, 0x65, 0x69, + 0x76, 0x65, 0x12, 0x0e, 0x2e, 0x70, 0x62, 0x78, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x55, 0x70, 0x52, + 0x65, 0x71, 0x1a, 0x0f, 0x2e, 0x70, 0x62, 0x78, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x55, 0x70, 0x52, + 0x65, 0x73, 0x70, 0x22, 0x00, 0x28, 0x01, 0x12, 0x39, 0x0a, 0x0e, 0x4c, 0x61, 0x72, 0x67, 0x65, + 0x46, 0x69, 0x6c, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x12, 0x10, 0x2e, 0x70, 0x62, 0x78, 0x2e, + 0x46, 0x69, 0x6c, 0x65, 0x44, 0x6f, 0x77, 0x6e, 0x52, 0x65, 0x71, 0x1a, 0x11, 0x2e, 0x70, 0x62, + 0x78, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x44, 0x6f, 0x77, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, + 0x30, 0x01, 0x32, 0x9f, 0x02, 0x0a, 0x06, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x12, 0x2d, 0x0a, + 0x08, 0x46, 0x69, 0x72, 0x65, 0x48, 0x6f, 0x73, 0x65, 0x12, 0x0e, 0x2e, 0x70, 0x62, 0x78, 0x2e, + 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x0f, 0x2e, 0x70, 0x62, 0x78, 0x2e, + 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x2c, 0x0a, 0x04, + 0x46, 0x69, 0x6e, 0x64, 0x12, 0x10, 0x2e, 0x70, 0x62, 0x78, 0x2e, 0x53, 0x65, 0x61, 0x72, 0x63, + 0x68, 0x51, 0x75, 0x65, 0x72, 0x79, 0x1a, 0x10, 0x2e, 0x70, 0x62, 0x78, 0x2e, 0x53, 0x65, 0x61, + 0x72, 0x63, 0x68, 0x46, 0x6f, 0x75, 0x6e, 0x64, 0x22, 0x00, 0x12, 0x2b, 0x0a, 0x07, 0x41, 0x63, + 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x11, 0x2e, 0x70, 0x62, 0x78, 0x2e, 0x41, 0x63, 0x63, 0x6f, + 0x75, 0x6e, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x1a, 0x0b, 0x2e, 0x70, 0x62, 0x78, 0x2e, 0x55, + 0x6e, 0x75, 0x73, 0x65, 0x64, 0x22, 0x00, 0x12, 0x27, 0x0a, 0x05, 0x54, 0x6f, 0x70, 0x69, 0x63, + 0x12, 0x0f, 0x2e, 0x70, 0x62, 0x78, 0x2e, 0x54, 0x6f, 0x70, 0x69, 0x63, 0x45, 0x76, 0x65, 0x6e, + 0x74, 0x1a, 0x0b, 0x2e, 0x70, 0x62, 0x78, 0x2e, 0x55, 0x6e, 0x75, 0x73, 0x65, 0x64, 0x22, 0x00, + 0x12, 0x35, 0x0a, 0x0c, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x12, 0x16, 0x2e, 0x70, 0x62, 0x78, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x1a, 0x0b, 0x2e, 0x70, 0x62, 0x78, 0x2e, 0x55, + 0x6e, 0x75, 0x73, 0x65, 0x64, 0x22, 0x00, 0x12, 0x2b, 0x0a, 0x07, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x12, 0x11, 0x2e, 0x70, 0x62, 0x78, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x1a, 0x0b, 0x2e, 0x70, 0x62, 0x78, 0x2e, 0x55, 0x6e, 0x75, 0x73, + 0x65, 0x64, 0x22, 0x00, 0x42, 0x1c, 0x5a, 0x1a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, + 0x6f, 0x6d, 0x2f, 0x74, 0x69, 0x6e, 0x6f, 0x64, 0x65, 0x2f, 0x63, 0x68, 0x61, 0x74, 0x2f, 0x70, + 0x62, 0x78, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_model_proto_rawDescOnce sync.Once + file_model_proto_rawDescData = file_model_proto_rawDesc +) + +func file_model_proto_rawDescGZIP() []byte { + file_model_proto_rawDescOnce.Do(func() { + file_model_proto_rawDescData = protoimpl.X.CompressGZIP(file_model_proto_rawDescData) + }) + return file_model_proto_rawDescData +} + +var file_model_proto_enumTypes = make([]protoimpl.EnumInfo, 7) +var file_model_proto_msgTypes = make([]protoimpl.MessageInfo, 53) +var file_model_proto_goTypes = []interface{}{ + (AuthLevel)(0), // 0: pbx.AuthLevel + (InfoNote)(0), // 1: pbx.InfoNote + (CallEvent)(0), // 2: pbx.CallEvent + (RespCode)(0), // 3: pbx.RespCode + (Crud)(0), // 4: pbx.Crud + (ClientDel_What)(0), // 5: pbx.ClientDel.What + (ServerPres_What)(0), // 6: pbx.ServerPres.What + (*Unused)(nil), // 7: pbx.Unused + (*DefaultAcsMode)(nil), // 8: pbx.DefaultAcsMode + (*AccessMode)(nil), // 9: pbx.AccessMode + (*SetSub)(nil), // 10: pbx.SetSub + (*ClientCred)(nil), // 11: pbx.ClientCred + (*SetDesc)(nil), // 12: pbx.SetDesc + (*SeqRange)(nil), // 13: pbx.SeqRange + (*GetOpts)(nil), // 14: pbx.GetOpts + (*GetQuery)(nil), // 15: pbx.GetQuery + (*SetQuery)(nil), // 16: pbx.SetQuery + (*ClientHi)(nil), // 17: pbx.ClientHi + (*ClientAcc)(nil), // 18: pbx.ClientAcc + (*ClientLogin)(nil), // 19: pbx.ClientLogin + (*ClientSub)(nil), // 20: pbx.ClientSub + (*ClientLeave)(nil), // 21: pbx.ClientLeave + (*ClientPub)(nil), // 22: pbx.ClientPub + (*ClientGet)(nil), // 23: pbx.ClientGet + (*ClientSet)(nil), // 24: pbx.ClientSet + (*ClientDel)(nil), // 25: pbx.ClientDel + (*ClientNote)(nil), // 26: pbx.ClientNote + (*ClientExtra)(nil), // 27: pbx.ClientExtra + (*ClientMsg)(nil), // 28: pbx.ClientMsg + (*ServerCred)(nil), // 29: pbx.ServerCred + (*TopicDesc)(nil), // 30: pbx.TopicDesc + (*TopicSub)(nil), // 31: pbx.TopicSub + (*DelValues)(nil), // 32: pbx.DelValues + (*ServerCtrl)(nil), // 33: pbx.ServerCtrl + (*ServerData)(nil), // 34: pbx.ServerData + (*ServerPres)(nil), // 35: pbx.ServerPres + (*ServerMeta)(nil), // 36: pbx.ServerMeta + (*ServerInfo)(nil), // 37: pbx.ServerInfo + (*ServerMsg)(nil), // 38: pbx.ServerMsg + (*ServerResp)(nil), // 39: pbx.ServerResp + (*Session)(nil), // 40: pbx.Session + (*ClientReq)(nil), // 41: pbx.ClientReq + (*SearchQuery)(nil), // 42: pbx.SearchQuery + (*SearchFound)(nil), // 43: pbx.SearchFound + (*TopicEvent)(nil), // 44: pbx.TopicEvent + (*AccountEvent)(nil), // 45: pbx.AccountEvent + (*SubscriptionEvent)(nil), // 46: pbx.SubscriptionEvent + (*MessageEvent)(nil), // 47: pbx.MessageEvent + (*Auth)(nil), // 48: pbx.Auth + (*FileMeta)(nil), // 49: pbx.FileMeta + (*FileUpReq)(nil), // 50: pbx.FileUpReq + (*FileUpResp)(nil), // 51: pbx.FileUpResp + (*FileDownReq)(nil), // 52: pbx.FileDownReq + (*FileDownResp)(nil), // 53: pbx.FileDownResp + nil, // 54: pbx.ClientCred.ParamsEntry + nil, // 55: pbx.SetQuery.AuxEntry + nil, // 56: pbx.ClientPub.HeadEntry + nil, // 57: pbx.ServerCtrl.ParamsEntry + nil, // 58: pbx.ServerData.HeadEntry + nil, // 59: pbx.ServerMeta.AuxEntry +} +var file_model_proto_depIdxs = []int32{ + 54, // 0: pbx.ClientCred.params:type_name -> pbx.ClientCred.ParamsEntry + 8, // 1: pbx.SetDesc.default_acs:type_name -> pbx.DefaultAcsMode + 13, // 2: pbx.GetOpts.ranges:type_name -> pbx.SeqRange + 14, // 3: pbx.GetQuery.desc:type_name -> pbx.GetOpts + 14, // 4: pbx.GetQuery.sub:type_name -> pbx.GetOpts + 14, // 5: pbx.GetQuery.data:type_name -> pbx.GetOpts + 12, // 6: pbx.SetQuery.desc:type_name -> pbx.SetDesc + 10, // 7: pbx.SetQuery.sub:type_name -> pbx.SetSub + 11, // 8: pbx.SetQuery.cred:type_name -> pbx.ClientCred + 55, // 9: pbx.SetQuery.aux:type_name -> pbx.SetQuery.AuxEntry + 12, // 10: pbx.ClientAcc.desc:type_name -> pbx.SetDesc + 11, // 11: pbx.ClientAcc.cred:type_name -> pbx.ClientCred + 0, // 12: pbx.ClientAcc.auth_level:type_name -> pbx.AuthLevel + 11, // 13: pbx.ClientLogin.cred:type_name -> pbx.ClientCred + 16, // 14: pbx.ClientSub.set_query:type_name -> pbx.SetQuery + 15, // 15: pbx.ClientSub.get_query:type_name -> pbx.GetQuery + 56, // 16: pbx.ClientPub.head:type_name -> pbx.ClientPub.HeadEntry + 15, // 17: pbx.ClientGet.query:type_name -> pbx.GetQuery + 16, // 18: pbx.ClientSet.query:type_name -> pbx.SetQuery + 5, // 19: pbx.ClientDel.what:type_name -> pbx.ClientDel.What + 13, // 20: pbx.ClientDel.del_seq:type_name -> pbx.SeqRange + 11, // 21: pbx.ClientDel.cred:type_name -> pbx.ClientCred + 1, // 22: pbx.ClientNote.what:type_name -> pbx.InfoNote + 2, // 23: pbx.ClientNote.event:type_name -> pbx.CallEvent + 0, // 24: pbx.ClientExtra.auth_level:type_name -> pbx.AuthLevel + 17, // 25: pbx.ClientMsg.hi:type_name -> pbx.ClientHi + 18, // 26: pbx.ClientMsg.acc:type_name -> pbx.ClientAcc + 19, // 27: pbx.ClientMsg.login:type_name -> pbx.ClientLogin + 20, // 28: pbx.ClientMsg.sub:type_name -> pbx.ClientSub + 21, // 29: pbx.ClientMsg.leave:type_name -> pbx.ClientLeave + 22, // 30: pbx.ClientMsg.pub:type_name -> pbx.ClientPub + 23, // 31: pbx.ClientMsg.get:type_name -> pbx.ClientGet + 24, // 32: pbx.ClientMsg.set:type_name -> pbx.ClientSet + 25, // 33: pbx.ClientMsg.del:type_name -> pbx.ClientDel + 26, // 34: pbx.ClientMsg.note:type_name -> pbx.ClientNote + 27, // 35: pbx.ClientMsg.extra:type_name -> pbx.ClientExtra + 8, // 36: pbx.TopicDesc.defacs:type_name -> pbx.DefaultAcsMode + 9, // 37: pbx.TopicDesc.acs:type_name -> pbx.AccessMode + 9, // 38: pbx.TopicSub.acs:type_name -> pbx.AccessMode + 13, // 39: pbx.DelValues.del_seq:type_name -> pbx.SeqRange + 57, // 40: pbx.ServerCtrl.params:type_name -> pbx.ServerCtrl.ParamsEntry + 58, // 41: pbx.ServerData.head:type_name -> pbx.ServerData.HeadEntry + 6, // 42: pbx.ServerPres.what:type_name -> pbx.ServerPres.What + 13, // 43: pbx.ServerPres.del_seq:type_name -> pbx.SeqRange + 9, // 44: pbx.ServerPres.acs:type_name -> pbx.AccessMode + 30, // 45: pbx.ServerMeta.desc:type_name -> pbx.TopicDesc + 31, // 46: pbx.ServerMeta.sub:type_name -> pbx.TopicSub + 32, // 47: pbx.ServerMeta.del:type_name -> pbx.DelValues + 29, // 48: pbx.ServerMeta.cred:type_name -> pbx.ServerCred + 59, // 49: pbx.ServerMeta.aux:type_name -> pbx.ServerMeta.AuxEntry + 1, // 50: pbx.ServerInfo.what:type_name -> pbx.InfoNote + 2, // 51: pbx.ServerInfo.event:type_name -> pbx.CallEvent + 33, // 52: pbx.ServerMsg.ctrl:type_name -> pbx.ServerCtrl + 34, // 53: pbx.ServerMsg.data:type_name -> pbx.ServerData + 35, // 54: pbx.ServerMsg.pres:type_name -> pbx.ServerPres + 36, // 55: pbx.ServerMsg.meta:type_name -> pbx.ServerMeta + 37, // 56: pbx.ServerMsg.info:type_name -> pbx.ServerInfo + 3, // 57: pbx.ServerResp.status:type_name -> pbx.RespCode + 38, // 58: pbx.ServerResp.srvmsg:type_name -> pbx.ServerMsg + 28, // 59: pbx.ServerResp.clmsg:type_name -> pbx.ClientMsg + 0, // 60: pbx.Session.auth_level:type_name -> pbx.AuthLevel + 28, // 61: pbx.ClientReq.msg:type_name -> pbx.ClientMsg + 40, // 62: pbx.ClientReq.sess:type_name -> pbx.Session + 3, // 63: pbx.SearchFound.status:type_name -> pbx.RespCode + 31, // 64: pbx.SearchFound.result:type_name -> pbx.TopicSub + 4, // 65: pbx.TopicEvent.action:type_name -> pbx.Crud + 30, // 66: pbx.TopicEvent.desc:type_name -> pbx.TopicDesc + 4, // 67: pbx.AccountEvent.action:type_name -> pbx.Crud + 8, // 68: pbx.AccountEvent.default_acs:type_name -> pbx.DefaultAcsMode + 4, // 69: pbx.SubscriptionEvent.action:type_name -> pbx.Crud + 9, // 70: pbx.SubscriptionEvent.mode:type_name -> pbx.AccessMode + 4, // 71: pbx.MessageEvent.action:type_name -> pbx.Crud + 34, // 72: pbx.MessageEvent.msg:type_name -> pbx.ServerData + 48, // 73: pbx.FileUpReq.auth:type_name -> pbx.Auth + 49, // 74: pbx.FileUpReq.meta:type_name -> pbx.FileMeta + 49, // 75: pbx.FileUpResp.meta:type_name -> pbx.FileMeta + 48, // 76: pbx.FileDownReq.auth:type_name -> pbx.Auth + 49, // 77: pbx.FileDownResp.meta:type_name -> pbx.FileMeta + 28, // 78: pbx.Node.MessageLoop:input_type -> pbx.ClientMsg + 50, // 79: pbx.Node.LargeFileReceive:input_type -> pbx.FileUpReq + 52, // 80: pbx.Node.LargeFileServe:input_type -> pbx.FileDownReq + 41, // 81: pbx.Plugin.FireHose:input_type -> pbx.ClientReq + 42, // 82: pbx.Plugin.Find:input_type -> pbx.SearchQuery + 45, // 83: pbx.Plugin.Account:input_type -> pbx.AccountEvent + 44, // 84: pbx.Plugin.Topic:input_type -> pbx.TopicEvent + 46, // 85: pbx.Plugin.Subscription:input_type -> pbx.SubscriptionEvent + 47, // 86: pbx.Plugin.Message:input_type -> pbx.MessageEvent + 38, // 87: pbx.Node.MessageLoop:output_type -> pbx.ServerMsg + 51, // 88: pbx.Node.LargeFileReceive:output_type -> pbx.FileUpResp + 53, // 89: pbx.Node.LargeFileServe:output_type -> pbx.FileDownResp + 39, // 90: pbx.Plugin.FireHose:output_type -> pbx.ServerResp + 43, // 91: pbx.Plugin.Find:output_type -> pbx.SearchFound + 7, // 92: pbx.Plugin.Account:output_type -> pbx.Unused + 7, // 93: pbx.Plugin.Topic:output_type -> pbx.Unused + 7, // 94: pbx.Plugin.Subscription:output_type -> pbx.Unused + 7, // 95: pbx.Plugin.Message:output_type -> pbx.Unused + 87, // [87:96] is the sub-list for method output_type + 78, // [78:87] is the sub-list for method input_type + 78, // [78:78] is the sub-list for extension type_name + 78, // [78:78] is the sub-list for extension extendee + 0, // [0:78] is the sub-list for field type_name +} + +func init() { file_model_proto_init() } +func file_model_proto_init() { + if File_model_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_model_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Unused); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_model_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DefaultAcsMode); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_model_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AccessMode); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_model_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SetSub); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_model_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ClientCred); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_model_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SetDesc); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_model_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SeqRange); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_model_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetOpts); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_model_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetQuery); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_model_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SetQuery); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_model_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ClientHi); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_model_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ClientAcc); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_model_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ClientLogin); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_model_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ClientSub); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_model_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ClientLeave); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_model_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ClientPub); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_model_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ClientGet); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_model_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ClientSet); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_model_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ClientDel); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_model_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ClientNote); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_model_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ClientExtra); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_model_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ClientMsg); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_model_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ServerCred); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_model_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*TopicDesc); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_model_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*TopicSub); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_model_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DelValues); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_model_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ServerCtrl); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_model_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ServerData); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_model_proto_msgTypes[28].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ServerPres); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_model_proto_msgTypes[29].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ServerMeta); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_model_proto_msgTypes[30].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ServerInfo); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_model_proto_msgTypes[31].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ServerMsg); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_model_proto_msgTypes[32].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ServerResp); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_model_proto_msgTypes[33].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Session); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_model_proto_msgTypes[34].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ClientReq); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_model_proto_msgTypes[35].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SearchQuery); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_model_proto_msgTypes[36].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SearchFound); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_model_proto_msgTypes[37].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*TopicEvent); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_model_proto_msgTypes[38].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AccountEvent); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_model_proto_msgTypes[39].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SubscriptionEvent); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_model_proto_msgTypes[40].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*MessageEvent); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_model_proto_msgTypes[41].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Auth); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_model_proto_msgTypes[42].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*FileMeta); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_model_proto_msgTypes[43].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*FileUpReq); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_model_proto_msgTypes[44].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*FileUpResp); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_model_proto_msgTypes[45].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*FileDownReq); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_model_proto_msgTypes[46].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*FileDownResp); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + file_model_proto_msgTypes[21].OneofWrappers = []interface{}{ + (*ClientMsg_Hi)(nil), + (*ClientMsg_Acc)(nil), + (*ClientMsg_Login)(nil), + (*ClientMsg_Sub)(nil), + (*ClientMsg_Leave)(nil), + (*ClientMsg_Pub)(nil), + (*ClientMsg_Get)(nil), + (*ClientMsg_Set)(nil), + (*ClientMsg_Del)(nil), + (*ClientMsg_Note)(nil), + } + file_model_proto_msgTypes[31].OneofWrappers = []interface{}{ + (*ServerMsg_Ctrl)(nil), + (*ServerMsg_Data)(nil), + (*ServerMsg_Pres)(nil), + (*ServerMsg_Meta)(nil), + (*ServerMsg_Info)(nil), + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_model_proto_rawDesc, + NumEnums: 7, + NumMessages: 53, + NumExtensions: 0, + NumServices: 2, + }, + GoTypes: file_model_proto_goTypes, + DependencyIndexes: file_model_proto_depIdxs, + EnumInfos: file_model_proto_enumTypes, + MessageInfos: file_model_proto_msgTypes, + }.Build() + File_model_proto = out.File + file_model_proto_rawDesc = nil + file_model_proto_goTypes = nil + file_model_proto_depIdxs = nil +} diff --git a/pbx/model.proto b/pbx/model.proto index e69de29..6b9b196 100644 --- a/pbx/model.proto +++ b/pbx/model.proto @@ -0,0 +1,660 @@ +syntax = "proto3"; +package pbx; +option go_package = "github.com/tinode/chat/pbx"; + +// This is the methods that needs to be implemented by a gRPC client. +service Node { + // Client sends a stream of ClientMsg, server responds with a stream of ServerMsg + rpc MessageLoop(stream ClientMsg) returns (stream ServerMsg) {} + + // Large file upload: a request with a stream of chunks. + rpc LargeFileReceive(stream FileUpReq) returns (FileUpResp) {} + + // Large file file download: a response with a stream of chunks. + rpc LargeFileServe(FileDownReq) returns (stream FileDownResp) {} +} + +// Plugin interface. +service Plugin { + // This plugin method is called by Tinode server for every message received from the clients. The + // method returns a ServerResp message. ServerResp.status tells Tinode server what to do next. + // See possible values for ServerResp.status in RespCode below. + rpc FireHose(ClientReq) returns (ServerResp) {} + + // An alteranative user and topic discovery mechanism. + // A search request issued on a 'fnd' topic. This method is called to generate an alternative result set. + rpc Find(SearchQuery) returns (SearchFound) {} + + // The following methods are for the Tinode server to report individual events. + + // Account created, updated or deleted + rpc Account(AccountEvent) returns (Unused) {} + + // Topic created, updated [or deleted -- not supported yet] + rpc Topic(TopicEvent) returns (Unused) {} + + // Subscription created, updated or deleted + rpc Subscription(SubscriptionEvent) returns (Unused) {} + + // Message published or deleted + rpc Message(MessageEvent) returns (Unused) {} +} + +// Dummy placeholder message. +message Unused { +} + +// Common client/server messages + +// Authentication level +enum AuthLevel { + NONE = 0; + ANON = 10; + AUTH = 20; + ROOT = 30; +} + +// Client messages + +// Topic default access mode +message DefaultAcsMode { + string auth = 1; + string anon = 2; +} + +// Actual access mode +message AccessMode { + // Access mode requested by the user + string want = 1; + // Access mode granted to the user by the admin + string given = 2; +} + +// SetSub: payload in set.sub request to update current subscription or invite another user, {sub.what} == "sub" +message SetSub { + // User affected by this request. Default (empty): current user + string user_id = 1; + + // Access mode change, either Given or Want depending on context + string mode = 2; +} + +// Credentials such as email or phone number +message ClientCred { + // Credential type, i.e. `email` or `tel`. + string method = 1; + // Value to verify, i.e. `user@example.com` or `+18003287448` + string value = 2; + // Verification response + string response = 3; + // Request parameters, such as preferences or country code. + map params = 4; +} + +// SetDesc: C2S in set.what == "desc" and sub.init message +message SetDesc { + DefaultAcsMode default_acs = 1; + bytes public = 2; + bytes private = 3; + bytes trusted = 4; +} + +message SeqRange { + int32 low = 1; + int32 hi = 2; +} + +message GetOpts { + // Timestamp in milliseconds since epoch 01/01/1970 + int64 if_modified_since = 1; + // Limit search to this user ID + string user = 2; + // Limit search results to one topic; + string topic = 3; + // Load messages with seq id equal or greater than this + int32 since_id = 4; + // Load messages with seq id lower than this + int32 before_id = 5; + // Maximum number of results to return + int32 limit = 6; + // Load messages by id or ranges of ids + repeated SeqRange ranges = 7; +} + +message GetQuery { + string what = 1; + + // Parameters of "desc" request + GetOpts desc = 2; + // Parameters of "sub" request + GetOpts sub = 3; + // Parameters of "data" request + GetOpts data = 4; +} + +message SetQuery { + // Topic metadata, new topic & new subscriptions only + SetDesc desc = 1; + // Subscription parameters + SetSub sub = 2; + // Indexable tags + repeated string tags = 3; + // Credential being updated. + ClientCred cred = 4; + // Auxiliary data. + map aux = 5; +} + +// Client handshake +message ClientHi { + string id = 1; + string user_agent = 2; + string ver = 3; + string device_id = 4; + string lang = 5; + string platform = 6; + bool background = 7; + string tenant = 8; +} + +// User creation message {acc} +message ClientAcc { + string id = 1; + // User being created or updated + string user_id = 2; + // The initial authentication scheme the account can use + string scheme = 3; + // Shared secret + bytes secret = 4; + // Authenticate session with the newly created account + bool login = 5; + // Indexable tags for user discovery + repeated string tags = 6; + // User initialization data when creating a new user, otherwise ignored + SetDesc desc = 7; + // Credentials for verification. + repeated ClientCred cred = 8; + // Authentication token used for resetting a password. + bytes token = 9; + // Account state: normal ("ok"), suspended + string state = 10; + // AuthLevel + AuthLevel auth_level = 11; + // Temporary auth params for one-off actions like password reset. + string tmp_scheme = 12; + bytes tmp_secret = 13; +} + +// Login {login} message +message ClientLogin { + string id = 1; + // Authentication scheme + string scheme = 2; + // Shared secret + bytes secret = 3; + // Credentials for verification. + repeated ClientCred cred = 4; +} + +// Subscription request {sub} message +message ClientSub { + string id = 1; + string topic = 2; + + // mirrors {set} + SetQuery set_query = 3; + + // mirrors {get} + GetQuery get_query = 4; +} + +// Unsubscribe {leave} request message +message ClientLeave { + string id = 1; + string topic = 2; + bool unsub = 3; +} + +// ClientPub is client's request to publish data to topic subscribers {pub} +message ClientPub { + string id = 1; + string topic = 2; + bool no_echo = 3; + map head = 4; + bytes content = 5; +} + +// Query topic state {get} +message ClientGet { + string id = 1; + string topic = 2; + GetQuery query = 3; +} + +// Update topic state {set} +message ClientSet { + string id = 1; + string topic = 2; + SetQuery query = 3; +} + +// ClientDel delete messages or topic +message ClientDel { + string id = 1; + string topic = 2; + // What to delete, either "msg" to delete messages (default) or "topic" to delete the topic or "sub" + // to delete a subscription to topic. + enum What { + // Invalid value. The name must be globally unique. + X0 = 0; + MSG = 1; + TOPIC = 2; + SUB = 3; + USER = 4; + CRED = 5; + } + What what = 3; + // Delete messages by id or range of ids + repeated SeqRange del_seq = 4; + // User ID of the subscription to delete + string user_id = 5; + // Credential to delete. + ClientCred cred = 6; + // Request to hard-delete messages for all users, if such option is available. + bool hard = 7; +} + +enum InfoNote { + // Invalid value. The name must be globally unique. + X1 = 0; + READ = 1; + RECV = 2; + KP = 3; + CALL = 4; +} + +enum CallEvent { + // Invalid value. The name must be globally unique. + X2 = 0; + ACCEPT = 1; + ANSWER = 2; + HANG_UP = 3; + ICE_CANDIDATE = 4; + INVITE = 5; + OFFER = 6; + RINGING = 7; +} + +// ClientNote is a client-generated notification for topic subscribers +message ClientNote { + string topic = 1; + // what is being reported: "recv" - message received, "read" - message read, + // "kp" - typing notification, "call" - voice/video call + InfoNote what = 2; + // Server-issued message ID being reported + int32 seq_id = 3; + // Client's count of unread messages to report back to the server. Used in push notifications on iOS. + int32 unread = 4; + // Call event. + CallEvent event = 5; + // Arbitrary json payload (used in video calls). + bytes payload = 6; +} + +message ClientExtra { + repeated string attachments = 1; + // Root user may send messages on behalf of other users. + string on_behalf_of = 2; + AuthLevel auth_level = 3; +} + +message ClientMsg { + oneof Message { + ClientHi hi = 1; + ClientAcc acc = 2; + ClientLogin login = 3; + ClientSub sub = 4; + ClientLeave leave = 5; + ClientPub pub = 6; + ClientGet get = 7; + ClientSet set = 8; + ClientDel del = 9; + ClientNote note = 10; + } + // Additional message parameters. + ClientExtra extra = 13; +} + +// ************************ +// Server response messages + +// Credentials +message ServerCred { + // Credential type, i.e. `email` or `tel`. + string method = 1; + // Value to verify, i.e. `user@example.com` or `+18003287448` + string value = 2; + // Indicator that the credential is validated + bool done = 3; +} + +// Topic description, S2C in Meta message +message TopicDesc { + int64 created_at = 1; + int64 updated_at = 2; + int64 touched_at = 3; + DefaultAcsMode defacs = 4; + AccessMode acs = 5; + int32 seq_id = 6; + int32 read_id = 7; + int32 recv_id = 8; + int32 del_id = 9; + bytes public = 10; + bytes private = 11; + string state = 12; + int64 state_at = 13; + bytes trusted = 14; + bool is_chan = 17; // 17! + bool online = 18; + + // P2P only: other user's last online timestamp & user agent + int64 last_seen_time = 15; + string last_seen_user_agent = 16; +} + +// MsgTopicSub: topic subscription details, sent in Meta message +message TopicSub { + int64 updated_at = 1; + int64 deleted_at = 2; + + bool online = 3; + + AccessMode acs = 4; + int32 read_id = 5; + int32 recv_id = 6; + bytes public = 7; + bytes trusted = 16; // 16! + bytes private = 8; + + // Response to non-'me' topic + + // Uid of the subscribed user + string user_id = 9; + + // 'me' topic only + + // Topic name of this subscription + string topic = 10; + int64 touched_at = 11; + // ID of the last {data} message in a topic + int32 seq_id = 12; + // Messages are deleted up to this ID + int32 del_id = 13; + + // P2P topics only: + + // Other user's last online timestamp & user agent + int64 last_seen_time = 14; + string last_seen_user_agent = 15; +} + +message DelValues { + int32 del_id = 1; + repeated SeqRange del_seq = 2; +} + +// {ctrl} message +message ServerCtrl { + string id = 1; + string topic = 2; + int32 code = 3; + string text = 4; + map params = 5; +} + +// {data} message +message ServerData { + string topic = 1; + // ID of the user who originated the message as {pub}, could be empty if sent by the system + string from_user_id = 2; + // Timestamp when the message was sent. + int64 timestamp = 7; + // Timestamp when the message was deleted or 0. Milliseconds since the epoch 01/01/1970 + int64 deleted_at = 3; + int32 seq_id = 4; + map head = 5; + bytes content = 6; +} + +// {pres} message +message ServerPres { + string topic = 1; + string src = 2; + enum What { + // Invalid value. The name must be globally unique. + X3 = 0; + ON = 1; + OFF = 2; + UA = 3; + UPD = 4; + GONE = 5; + ACS = 6; + TERM = 7; + MSG = 8; + READ = 9; + RECV = 10; + DEL = 11; + TAGS = 12; + AUX = 13; + } + What what = 3; + string user_agent = 4; + int32 seq_id = 5; + int32 del_id = 6; + repeated SeqRange del_seq = 7; + string target_user_id = 8; + string actor_user_id = 9; + AccessMode acs = 10; +} + +// {meta} message +message ServerMeta { + string id = 1; + string topic = 2; + + TopicDesc desc = 3; + repeated TopicSub sub = 4; + DelValues del = 5; + repeated string tags = 6; + repeated ServerCred cred = 7; + map aux = 8; +} + +// {info} message: server-side copy of ClientNote with From and optional Src added. +message ServerInfo { + string topic = 1; + string from_user_id = 2; + InfoNote what = 3; + int32 seq_id = 4; + string src = 5; + CallEvent event = 6; + bytes payload = 7; +} + +// Cumulative message +message ServerMsg { + oneof Message { + ServerCtrl ctrl = 1; + ServerData data = 2; + ServerPres pres = 3; + ServerMeta meta = 4; + ServerInfo info = 5; + } + // DEPRECATED. Will be removed soon. + // When response is sent to Root, send internal topic name too. + string topic = 6 [deprecated = true]; +} + +// Plugin response codes +enum RespCode { + // Instruct Tinode server to continue with default processing of the client request. + CONTINUE = 0; + // Drop the request as if the client did not send it + DROP = 1; + // Send the the provided srvmsg response to the client. ServerResp must contain non-zero + // srvmsg. + RESPOND = 2; + // Replace client's original request with the provided clmsg request then continue with + // processing. ServerResp must contain non-zero clmsg. + REPLACE = 3; +} + +message ServerResp { + RespCode status = 1; + ServerMsg srvmsg = 2; + ClientMsg clmsg = 3; +} + +// Context message +message Session { + string session_id = 1; + string user_id = 2; + AuthLevel auth_level = 3; + string remote_addr = 4; + string user_agent = 5; + string device_id = 6; + string language = 7; +} + +message ClientReq { + ClientMsg msg = 1; + Session sess = 2; +} + +// Search + +message SearchQuery { + string user_id = 1; + string query = 2; +} + +message SearchFound { + RespCode status = 1; + // New search query If status == REPLACE, otherwise unset. + string query = 2; + // Search results. + repeated TopicSub result = 3; +} + +// CRUD event messages + +enum Crud { + CREATE = 0; + UPDATE = 1; + DELETE = 2; +} + +message TopicEvent { + Crud action = 1; + string name = 2; + TopicDesc desc = 3; +} + +message AccountEvent { + Crud action = 1; + string user_id = 2; + + DefaultAcsMode default_acs = 3; + bytes public = 4; + + // Indexable tags for user discovery + repeated string tags = 8; +} + +message SubscriptionEvent { + Crud action = 1; + string topic = 2; + string user_id = 3; + + int32 del_id = 4; + int32 read_id = 5; + int32 recv_id = 6; + + AccessMode mode = 7; + + bytes private = 8; +} + +message MessageEvent { + Crud action = 1; + ServerData msg = 2; +} + +// Large file handling. + +message Auth { + string scheme = 1; + string secret = 2; +} + +// File description. +message FileMeta { + string name = 1; + string mime_type = 2; + string etag = 3; + int64 size = 4; +} + +// File upload request. +message FileUpReq { + // Request ID. + string id = 1; + // Request authentication credentials. + Auth auth = 2; + // The topic this upload belongs to. + string topic = 3; + // Uploaded metadata. + FileMeta meta = 4; + // File bytes being uploaded. + bytes content = 5; +} + +// Response to file upload. +message FileUpResp { + // Response ID. + string id = 1; + // Response code. + int32 code = 2; + // Response text. + string text = 3; + FileMeta meta = 4; + // New upload location. + string redir_url = 5; +} + +// File download request. +message FileDownReq { + // Request ID + string id = 1; + // Request authentication credentials. + Auth auth = 2; + // File URI to download. + string uri = 3; + // ETag + string if_modified = 4; +} + +// Response to file download. +message FileDownResp { + // Response ID. + string id = 1; + // Response code. + int32 code = 2; + // Response text. + string text = 3; + FileMeta meta = 4; + // File location. + string redir_url = 5; + // File bytes. + bytes content = 6; +} diff --git a/pbx/model_grpc.pb.go b/pbx/model_grpc.pb.go index e69de29..e2b98f9 100644 --- a/pbx/model_grpc.pb.go +++ b/pbx/model_grpc.pb.go @@ -0,0 +1,560 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.2.0 +// - protoc v3.21.12 +// source: model.proto + +package pbx + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +// NodeClient is the client API for Node service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type NodeClient interface { + // Client sends a stream of ClientMsg, server responds with a stream of ServerMsg + MessageLoop(ctx context.Context, opts ...grpc.CallOption) (Node_MessageLoopClient, error) + // Large file upload: a request with a stream of chunks. + LargeFileReceive(ctx context.Context, opts ...grpc.CallOption) (Node_LargeFileReceiveClient, error) + // Large file file download: a response with a stream of chunks. + LargeFileServe(ctx context.Context, in *FileDownReq, opts ...grpc.CallOption) (Node_LargeFileServeClient, error) +} + +type nodeClient struct { + cc grpc.ClientConnInterface +} + +func NewNodeClient(cc grpc.ClientConnInterface) NodeClient { + return &nodeClient{cc} +} + +func (c *nodeClient) MessageLoop(ctx context.Context, opts ...grpc.CallOption) (Node_MessageLoopClient, error) { + stream, err := c.cc.NewStream(ctx, &Node_ServiceDesc.Streams[0], "/pbx.Node/MessageLoop", opts...) + if err != nil { + return nil, err + } + x := &nodeMessageLoopClient{stream} + return x, nil +} + +type Node_MessageLoopClient interface { + Send(*ClientMsg) error + Recv() (*ServerMsg, error) + grpc.ClientStream +} + +type nodeMessageLoopClient struct { + grpc.ClientStream +} + +func (x *nodeMessageLoopClient) Send(m *ClientMsg) error { + return x.ClientStream.SendMsg(m) +} + +func (x *nodeMessageLoopClient) Recv() (*ServerMsg, error) { + m := new(ServerMsg) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +func (c *nodeClient) LargeFileReceive(ctx context.Context, opts ...grpc.CallOption) (Node_LargeFileReceiveClient, error) { + stream, err := c.cc.NewStream(ctx, &Node_ServiceDesc.Streams[1], "/pbx.Node/LargeFileReceive", opts...) + if err != nil { + return nil, err + } + x := &nodeLargeFileReceiveClient{stream} + return x, nil +} + +type Node_LargeFileReceiveClient interface { + Send(*FileUpReq) error + CloseAndRecv() (*FileUpResp, error) + grpc.ClientStream +} + +type nodeLargeFileReceiveClient struct { + grpc.ClientStream +} + +func (x *nodeLargeFileReceiveClient) Send(m *FileUpReq) error { + return x.ClientStream.SendMsg(m) +} + +func (x *nodeLargeFileReceiveClient) CloseAndRecv() (*FileUpResp, error) { + if err := x.ClientStream.CloseSend(); err != nil { + return nil, err + } + m := new(FileUpResp) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +func (c *nodeClient) LargeFileServe(ctx context.Context, in *FileDownReq, opts ...grpc.CallOption) (Node_LargeFileServeClient, error) { + stream, err := c.cc.NewStream(ctx, &Node_ServiceDesc.Streams[2], "/pbx.Node/LargeFileServe", opts...) + if err != nil { + return nil, err + } + x := &nodeLargeFileServeClient{stream} + if err := x.ClientStream.SendMsg(in); err != nil { + return nil, err + } + if err := x.ClientStream.CloseSend(); err != nil { + return nil, err + } + return x, nil +} + +type Node_LargeFileServeClient interface { + Recv() (*FileDownResp, error) + grpc.ClientStream +} + +type nodeLargeFileServeClient struct { + grpc.ClientStream +} + +func (x *nodeLargeFileServeClient) Recv() (*FileDownResp, error) { + m := new(FileDownResp) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +// NodeServer is the server API for Node service. +// All implementations must embed UnimplementedNodeServer +// for forward compatibility +type NodeServer interface { + // Client sends a stream of ClientMsg, server responds with a stream of ServerMsg + MessageLoop(Node_MessageLoopServer) error + // Large file upload: a request with a stream of chunks. + LargeFileReceive(Node_LargeFileReceiveServer) error + // Large file file download: a response with a stream of chunks. + LargeFileServe(*FileDownReq, Node_LargeFileServeServer) error + mustEmbedUnimplementedNodeServer() +} + +// UnimplementedNodeServer must be embedded to have forward compatible implementations. +type UnimplementedNodeServer struct { +} + +func (UnimplementedNodeServer) MessageLoop(Node_MessageLoopServer) error { + return status.Errorf(codes.Unimplemented, "method MessageLoop not implemented") +} +func (UnimplementedNodeServer) LargeFileReceive(Node_LargeFileReceiveServer) error { + return status.Errorf(codes.Unimplemented, "method LargeFileReceive not implemented") +} +func (UnimplementedNodeServer) LargeFileServe(*FileDownReq, Node_LargeFileServeServer) error { + return status.Errorf(codes.Unimplemented, "method LargeFileServe not implemented") +} +func (UnimplementedNodeServer) mustEmbedUnimplementedNodeServer() {} + +// UnsafeNodeServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to NodeServer will +// result in compilation errors. +type UnsafeNodeServer interface { + mustEmbedUnimplementedNodeServer() +} + +func RegisterNodeServer(s grpc.ServiceRegistrar, srv NodeServer) { + s.RegisterService(&Node_ServiceDesc, srv) +} + +func _Node_MessageLoop_Handler(srv interface{}, stream grpc.ServerStream) error { + return srv.(NodeServer).MessageLoop(&nodeMessageLoopServer{stream}) +} + +type Node_MessageLoopServer interface { + Send(*ServerMsg) error + Recv() (*ClientMsg, error) + grpc.ServerStream +} + +type nodeMessageLoopServer struct { + grpc.ServerStream +} + +func (x *nodeMessageLoopServer) Send(m *ServerMsg) error { + return x.ServerStream.SendMsg(m) +} + +func (x *nodeMessageLoopServer) Recv() (*ClientMsg, error) { + m := new(ClientMsg) + if err := x.ServerStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +func _Node_LargeFileReceive_Handler(srv interface{}, stream grpc.ServerStream) error { + return srv.(NodeServer).LargeFileReceive(&nodeLargeFileReceiveServer{stream}) +} + +type Node_LargeFileReceiveServer interface { + SendAndClose(*FileUpResp) error + Recv() (*FileUpReq, error) + grpc.ServerStream +} + +type nodeLargeFileReceiveServer struct { + grpc.ServerStream +} + +func (x *nodeLargeFileReceiveServer) SendAndClose(m *FileUpResp) error { + return x.ServerStream.SendMsg(m) +} + +func (x *nodeLargeFileReceiveServer) Recv() (*FileUpReq, error) { + m := new(FileUpReq) + if err := x.ServerStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +func _Node_LargeFileServe_Handler(srv interface{}, stream grpc.ServerStream) error { + m := new(FileDownReq) + if err := stream.RecvMsg(m); err != nil { + return err + } + return srv.(NodeServer).LargeFileServe(m, &nodeLargeFileServeServer{stream}) +} + +type Node_LargeFileServeServer interface { + Send(*FileDownResp) error + grpc.ServerStream +} + +type nodeLargeFileServeServer struct { + grpc.ServerStream +} + +func (x *nodeLargeFileServeServer) Send(m *FileDownResp) error { + return x.ServerStream.SendMsg(m) +} + +// Node_ServiceDesc is the grpc.ServiceDesc for Node service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var Node_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "pbx.Node", + HandlerType: (*NodeServer)(nil), + Methods: []grpc.MethodDesc{}, + Streams: []grpc.StreamDesc{ + { + StreamName: "MessageLoop", + Handler: _Node_MessageLoop_Handler, + ServerStreams: true, + ClientStreams: true, + }, + { + StreamName: "LargeFileReceive", + Handler: _Node_LargeFileReceive_Handler, + ClientStreams: true, + }, + { + StreamName: "LargeFileServe", + Handler: _Node_LargeFileServe_Handler, + ServerStreams: true, + }, + }, + Metadata: "model.proto", +} + +// PluginClient is the client API for Plugin service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type PluginClient interface { + // This plugin method is called by Tinode server for every message received from the clients. The + // method returns a ServerResp message. ServerResp.status tells Tinode server what to do next. + // See possible values for ServerResp.status in RespCode below. + FireHose(ctx context.Context, in *ClientReq, opts ...grpc.CallOption) (*ServerResp, error) + // An alteranative user and topic discovery mechanism. + // A search request issued on a 'fnd' topic. This method is called to generate an alternative result set. + Find(ctx context.Context, in *SearchQuery, opts ...grpc.CallOption) (*SearchFound, error) + // Account created, updated or deleted + Account(ctx context.Context, in *AccountEvent, opts ...grpc.CallOption) (*Unused, error) + // Topic created, updated [or deleted -- not supported yet] + Topic(ctx context.Context, in *TopicEvent, opts ...grpc.CallOption) (*Unused, error) + // Subscription created, updated or deleted + Subscription(ctx context.Context, in *SubscriptionEvent, opts ...grpc.CallOption) (*Unused, error) + // Message published or deleted + Message(ctx context.Context, in *MessageEvent, opts ...grpc.CallOption) (*Unused, error) +} + +type pluginClient struct { + cc grpc.ClientConnInterface +} + +func NewPluginClient(cc grpc.ClientConnInterface) PluginClient { + return &pluginClient{cc} +} + +func (c *pluginClient) FireHose(ctx context.Context, in *ClientReq, opts ...grpc.CallOption) (*ServerResp, error) { + out := new(ServerResp) + err := c.cc.Invoke(ctx, "/pbx.Plugin/FireHose", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *pluginClient) Find(ctx context.Context, in *SearchQuery, opts ...grpc.CallOption) (*SearchFound, error) { + out := new(SearchFound) + err := c.cc.Invoke(ctx, "/pbx.Plugin/Find", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *pluginClient) Account(ctx context.Context, in *AccountEvent, opts ...grpc.CallOption) (*Unused, error) { + out := new(Unused) + err := c.cc.Invoke(ctx, "/pbx.Plugin/Account", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *pluginClient) Topic(ctx context.Context, in *TopicEvent, opts ...grpc.CallOption) (*Unused, error) { + out := new(Unused) + err := c.cc.Invoke(ctx, "/pbx.Plugin/Topic", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *pluginClient) Subscription(ctx context.Context, in *SubscriptionEvent, opts ...grpc.CallOption) (*Unused, error) { + out := new(Unused) + err := c.cc.Invoke(ctx, "/pbx.Plugin/Subscription", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *pluginClient) Message(ctx context.Context, in *MessageEvent, opts ...grpc.CallOption) (*Unused, error) { + out := new(Unused) + err := c.cc.Invoke(ctx, "/pbx.Plugin/Message", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// PluginServer is the server API for Plugin service. +// All implementations must embed UnimplementedPluginServer +// for forward compatibility +type PluginServer interface { + // This plugin method is called by Tinode server for every message received from the clients. The + // method returns a ServerResp message. ServerResp.status tells Tinode server what to do next. + // See possible values for ServerResp.status in RespCode below. + FireHose(context.Context, *ClientReq) (*ServerResp, error) + // An alteranative user and topic discovery mechanism. + // A search request issued on a 'fnd' topic. This method is called to generate an alternative result set. + Find(context.Context, *SearchQuery) (*SearchFound, error) + // Account created, updated or deleted + Account(context.Context, *AccountEvent) (*Unused, error) + // Topic created, updated [or deleted -- not supported yet] + Topic(context.Context, *TopicEvent) (*Unused, error) + // Subscription created, updated or deleted + Subscription(context.Context, *SubscriptionEvent) (*Unused, error) + // Message published or deleted + Message(context.Context, *MessageEvent) (*Unused, error) + mustEmbedUnimplementedPluginServer() +} + +// UnimplementedPluginServer must be embedded to have forward compatible implementations. +type UnimplementedPluginServer struct { +} + +func (UnimplementedPluginServer) FireHose(context.Context, *ClientReq) (*ServerResp, error) { + return nil, status.Errorf(codes.Unimplemented, "method FireHose not implemented") +} +func (UnimplementedPluginServer) Find(context.Context, *SearchQuery) (*SearchFound, error) { + return nil, status.Errorf(codes.Unimplemented, "method Find not implemented") +} +func (UnimplementedPluginServer) Account(context.Context, *AccountEvent) (*Unused, error) { + return nil, status.Errorf(codes.Unimplemented, "method Account not implemented") +} +func (UnimplementedPluginServer) Topic(context.Context, *TopicEvent) (*Unused, error) { + return nil, status.Errorf(codes.Unimplemented, "method Topic not implemented") +} +func (UnimplementedPluginServer) Subscription(context.Context, *SubscriptionEvent) (*Unused, error) { + return nil, status.Errorf(codes.Unimplemented, "method Subscription not implemented") +} +func (UnimplementedPluginServer) Message(context.Context, *MessageEvent) (*Unused, error) { + return nil, status.Errorf(codes.Unimplemented, "method Message not implemented") +} +func (UnimplementedPluginServer) mustEmbedUnimplementedPluginServer() {} + +// UnsafePluginServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to PluginServer will +// result in compilation errors. +type UnsafePluginServer interface { + mustEmbedUnimplementedPluginServer() +} + +func RegisterPluginServer(s grpc.ServiceRegistrar, srv PluginServer) { + s.RegisterService(&Plugin_ServiceDesc, srv) +} + +func _Plugin_FireHose_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ClientReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(PluginServer).FireHose(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pbx.Plugin/FireHose", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(PluginServer).FireHose(ctx, req.(*ClientReq)) + } + return interceptor(ctx, in, info, handler) +} + +func _Plugin_Find_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(SearchQuery) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(PluginServer).Find(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pbx.Plugin/Find", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(PluginServer).Find(ctx, req.(*SearchQuery)) + } + return interceptor(ctx, in, info, handler) +} + +func _Plugin_Account_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(AccountEvent) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(PluginServer).Account(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pbx.Plugin/Account", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(PluginServer).Account(ctx, req.(*AccountEvent)) + } + return interceptor(ctx, in, info, handler) +} + +func _Plugin_Topic_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(TopicEvent) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(PluginServer).Topic(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pbx.Plugin/Topic", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(PluginServer).Topic(ctx, req.(*TopicEvent)) + } + return interceptor(ctx, in, info, handler) +} + +func _Plugin_Subscription_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(SubscriptionEvent) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(PluginServer).Subscription(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pbx.Plugin/Subscription", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(PluginServer).Subscription(ctx, req.(*SubscriptionEvent)) + } + return interceptor(ctx, in, info, handler) +} + +func _Plugin_Message_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MessageEvent) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(PluginServer).Message(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pbx.Plugin/Message", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(PluginServer).Message(ctx, req.(*MessageEvent)) + } + return interceptor(ctx, in, info, handler) +} + +// Plugin_ServiceDesc is the grpc.ServiceDesc for Plugin service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var Plugin_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "pbx.Plugin", + HandlerType: (*PluginServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "FireHose", + Handler: _Plugin_FireHose_Handler, + }, + { + MethodName: "Find", + Handler: _Plugin_Find_Handler, + }, + { + MethodName: "Account", + Handler: _Plugin_Account_Handler, + }, + { + MethodName: "Topic", + Handler: _Plugin_Topic_Handler, + }, + { + MethodName: "Subscription", + Handler: _Plugin_Subscription_Handler, + }, + { + MethodName: "Message", + Handler: _Plugin_Message_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "model.proto", +} diff --git a/pbx/py-generate.sh b/pbx/py-generate.sh old mode 100644 new mode 100755 index e69de29..9bacb77 --- a/pbx/py-generate.sh +++ b/pbx/py-generate.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +# Generate python gRPC bindings for Tinode. A command line parameter v=XX will use specified python version, +# i.e. ./generate-python.sh v=3 will use python3. + +for line in $@; do + eval "$line" +done + +python="python${v}" + +# This generates python gRPC bindings for Tinode. +$python -m grpc_tools.protoc -I../pbx --python_out=../py_grpc/tinode_grpc --grpc_python_out=../py_grpc/tinode_grpc --pyi_out=../py_grpc/tinode_grpc ../pbx/model.proto +# Bindings are incompatible with Python packaging system. This is a fix. +$python py_fix.py diff --git a/pbx/py_fix.py b/pbx/py_fix.py index e69de29..2a370bb 100644 --- a/pbx/py_fix.py +++ b/pbx/py_fix.py @@ -0,0 +1,11 @@ +# grpc-tools generates python 2 file which does not work with +# python3 packaging system. This is a fix. + +model_pb2_grpc = "../py_grpc/tinode_grpc/model_pb2_grpc.py" + +with open(model_pb2_grpc, "r") as fh: + content = fh.read().replace("\nimport model_pb2 as model__pb2", + "\nfrom . import model_pb2 as model__pb2") + + with open(model_pb2_grpc,"w") as fh: + fh.write(content) diff --git a/py_grpc/.gitignore b/py_grpc/.gitignore index e69de29..4da280b 100644 --- a/py_grpc/.gitignore +++ b/py_grpc/.gitignore @@ -0,0 +1,9 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +/build/ +/dist/ +/tinode_grpc/GIT_VERSION +*.egg-info/ \ No newline at end of file diff --git a/py_grpc/LICENSE b/py_grpc/LICENSE index e69de29..3331e7b 100644 --- a/py_grpc/LICENSE +++ b/py_grpc/LICENSE @@ -0,0 +1,2 @@ +The code in this folder is licensed under Apache 2.0 +http://www.apache.org/licenses/LICENSE-2.0 diff --git a/py_grpc/README.md b/py_grpc/README.md index e69de29..c47c63b 100644 --- a/py_grpc/README.md +++ b/py_grpc/README.md @@ -0,0 +1,24 @@ +# Generated Protocol Buffer and gRPC files for [Tinode](https://github.com/tinode) + +Generated Python code for [gRPC](https://grpc.io/) client and plugins. + +gRPC clients must implement rpc service `Node`, plugins must implement `Plugin`. + +For a sample implementation of a command line client see [tn-cli](https://github.com/tinode/chat/tree/master/tn-cli/). +For a partial plugin implementation see [chatbot](https://github.com/tinode/chat/tree/master/chatbot). + +## Installing + +Install the package by executing +``` +pip install tinode_grpc +``` + + +## Generating files + +Don't modify included files directly. If you want to make changes, you have to install protobuffers tool chain and gRPC then generate the Python bindings from [`pbx/model.proto`](https://github.com/tinode/chat/tree/master/pbx/model.proto) (your path to `model.proto` may be different): +``` +python -m grpc_tools.protoc -I../pbx --python_out=. --pyi_out=. --grpc_python_out=. ../pbx/model.proto +``` +The generated `model_pb2_grpc.py` imports `model_pb2.py` as a module instead of a package which is incompatible with python3 packaging system. Use `../pbx/py_fix.py` to apply a fix. This is only needed if you want to repackage the generated files. diff --git a/py_grpc/pyproject.toml b/py_grpc/pyproject.toml index e69de29..640b832 100644 --- a/py_grpc/pyproject.toml +++ b/py_grpc/pyproject.toml @@ -0,0 +1,48 @@ +[build-system] +requires = ["setuptools>=45", "wheel"] +build-backend = "setuptools.build_meta" + +[project] +name = "tinode_grpc" +description = "Tinode gRPC bindings." +authors = [ + {name = "Tinode Authors", email = "info@tinode.co"}, +] +license = "Apache-2.0" +readme = "README.md" +keywords = ["chat", "messaging", "messenger", "im", "tinode"] +classifiers = [ + "Programming Language :: Python :: 2", + "Programming Language :: Python :: 2.7", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.5", + "Programming Language :: Python :: 3.6", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Operating System :: OS Independent", + "Topic :: Communications :: Chat", + "Intended Audience :: Developers", +] +dependencies = [ + "protobuf>=3.6.1", + "grpcio>=1.19.0", +] +dynamic = ["version"] + +[project.urls] +Homepage = "https://github.com/tinode/chat" +Repository = "https://github.com/tinode/chat" +Issues = "https://github.com/tinode/chat/issues" + +[tool.setuptools] +packages = ["tinode_grpc"] + +[tool.setuptools.package-data] +"*" = ["GIT_VERSION", "*.pyi"] + +# Alternative version handling if you want to keep reading from GIT_VERSION file +[tool.setuptools.dynamic] +version = {file = "tinode_grpc/GIT_VERSION"} diff --git a/py_grpc/tinode_grpc/__init__.py b/py_grpc/tinode_grpc/__init__.py index e69de29..9bb17e7 100644 --- a/py_grpc/tinode_grpc/__init__.py +++ b/py_grpc/tinode_grpc/__init__.py @@ -0,0 +1,2 @@ +from . import model_pb2 as pb +from . import model_pb2_grpc as pbx diff --git a/py_grpc/tinode_grpc/model_pb2.py b/py_grpc/tinode_grpc/model_pb2.py index e69de29..96d20f0 100644 --- a/py_grpc/tinode_grpc/model_pb2.py +++ b/py_grpc/tinode_grpc/model_pb2.py @@ -0,0 +1,162 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: model.proto +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import symbol_database as _symbol_database +from google.protobuf.internal import builder as _builder +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0bmodel.proto\x12\x03pbx\"\x08\n\x06Unused\",\n\x0e\x44\x65\x66\x61ultAcsMode\x12\x0c\n\x04\x61uth\x18\x01 \x01(\t\x12\x0c\n\x04\x61non\x18\x02 \x01(\t\")\n\nAccessMode\x12\x0c\n\x04want\x18\x01 \x01(\t\x12\r\n\x05given\x18\x02 \x01(\t\"\'\n\x06SetSub\x12\x0f\n\x07user_id\x18\x01 \x01(\t\x12\x0c\n\x04mode\x18\x02 \x01(\t\"\x99\x01\n\nClientCred\x12\x0e\n\x06method\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t\x12\x10\n\x08response\x18\x03 \x01(\t\x12+\n\x06params\x18\x04 \x03(\x0b\x32\x1b.pbx.ClientCred.ParamsEntry\x1a-\n\x0bParamsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\x0c:\x02\x38\x01\"e\n\x07SetDesc\x12(\n\x0b\x64\x65\x66\x61ult_acs\x18\x01 \x01(\x0b\x32\x13.pbx.DefaultAcsMode\x12\x0e\n\x06public\x18\x02 \x01(\x0c\x12\x0f\n\x07private\x18\x03 \x01(\x0c\x12\x0f\n\x07trusted\x18\x04 \x01(\x0c\"#\n\x08SeqRange\x12\x0b\n\x03low\x18\x01 \x01(\x05\x12\n\n\x02hi\x18\x02 \x01(\x05\"\x94\x01\n\x07GetOpts\x12\x19\n\x11if_modified_since\x18\x01 \x01(\x03\x12\x0c\n\x04user\x18\x02 \x01(\t\x12\r\n\x05topic\x18\x03 \x01(\t\x12\x10\n\x08since_id\x18\x04 \x01(\x05\x12\x11\n\tbefore_id\x18\x05 \x01(\x05\x12\r\n\x05limit\x18\x06 \x01(\x05\x12\x1d\n\x06ranges\x18\x07 \x03(\x0b\x32\r.pbx.SeqRange\"k\n\x08GetQuery\x12\x0c\n\x04what\x18\x01 \x01(\t\x12\x1a\n\x04\x64\x65sc\x18\x02 \x01(\x0b\x32\x0c.pbx.GetOpts\x12\x19\n\x03sub\x18\x03 \x01(\x0b\x32\x0c.pbx.GetOpts\x12\x1a\n\x04\x64\x61ta\x18\x04 \x01(\x0b\x32\x0c.pbx.GetOpts\"\xbe\x01\n\x08SetQuery\x12\x1a\n\x04\x64\x65sc\x18\x01 \x01(\x0b\x32\x0c.pbx.SetDesc\x12\x18\n\x03sub\x18\x02 \x01(\x0b\x32\x0b.pbx.SetSub\x12\x0c\n\x04tags\x18\x03 \x03(\t\x12\x1d\n\x04\x63red\x18\x04 \x01(\x0b\x32\x0f.pbx.ClientCred\x12#\n\x03\x61ux\x18\x05 \x03(\x0b\x32\x16.pbx.SetQuery.AuxEntry\x1a*\n\x08\x41uxEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\x0c:\x02\x38\x01\"\x8e\x01\n\x08\x43lientHi\x12\n\n\x02id\x18\x01 \x01(\t\x12\x12\n\nuser_agent\x18\x02 \x01(\t\x12\x0b\n\x03ver\x18\x03 \x01(\t\x12\x11\n\tdevice_id\x18\x04 \x01(\t\x12\x0c\n\x04lang\x18\x05 \x01(\t\x12\x10\n\x08platform\x18\x06 \x01(\t\x12\x12\n\nbackground\x18\x07 \x01(\x08\x12\x0e\n\x06tenant\x18\x08 \x01(\t\"\x8a\x02\n\tClientAcc\x12\n\n\x02id\x18\x01 \x01(\t\x12\x0f\n\x07user_id\x18\x02 \x01(\t\x12\x0e\n\x06scheme\x18\x03 \x01(\t\x12\x0e\n\x06secret\x18\x04 \x01(\x0c\x12\r\n\x05login\x18\x05 \x01(\x08\x12\x0c\n\x04tags\x18\x06 \x03(\t\x12\x1a\n\x04\x64\x65sc\x18\x07 \x01(\x0b\x32\x0c.pbx.SetDesc\x12\x1d\n\x04\x63red\x18\x08 \x03(\x0b\x32\x0f.pbx.ClientCred\x12\r\n\x05token\x18\t \x01(\x0c\x12\r\n\x05state\x18\n \x01(\t\x12\"\n\nauth_level\x18\x0b \x01(\x0e\x32\x0e.pbx.AuthLevel\x12\x12\n\ntmp_scheme\x18\x0c \x01(\t\x12\x12\n\ntmp_secret\x18\r \x01(\x0c\"X\n\x0b\x43lientLogin\x12\n\n\x02id\x18\x01 \x01(\t\x12\x0e\n\x06scheme\x18\x02 \x01(\t\x12\x0e\n\x06secret\x18\x03 \x01(\x0c\x12\x1d\n\x04\x63red\x18\x04 \x03(\x0b\x32\x0f.pbx.ClientCred\"j\n\tClientSub\x12\n\n\x02id\x18\x01 \x01(\t\x12\r\n\x05topic\x18\x02 \x01(\t\x12 \n\tset_query\x18\x03 \x01(\x0b\x32\r.pbx.SetQuery\x12 \n\tget_query\x18\x04 \x01(\x0b\x32\r.pbx.GetQuery\"7\n\x0b\x43lientLeave\x12\n\n\x02id\x18\x01 \x01(\t\x12\r\n\x05topic\x18\x02 \x01(\t\x12\r\n\x05unsub\x18\x03 \x01(\x08\"\x9d\x01\n\tClientPub\x12\n\n\x02id\x18\x01 \x01(\t\x12\r\n\x05topic\x18\x02 \x01(\t\x12\x0f\n\x07no_echo\x18\x03 \x01(\x08\x12&\n\x04head\x18\x04 \x03(\x0b\x32\x18.pbx.ClientPub.HeadEntry\x12\x0f\n\x07\x63ontent\x18\x05 \x01(\x0c\x1a+\n\tHeadEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\x0c:\x02\x38\x01\"D\n\tClientGet\x12\n\n\x02id\x18\x01 \x01(\t\x12\r\n\x05topic\x18\x02 \x01(\t\x12\x1c\n\x05query\x18\x03 \x01(\x0b\x32\r.pbx.GetQuery\"D\n\tClientSet\x12\n\n\x02id\x18\x01 \x01(\t\x12\r\n\x05topic\x18\x02 \x01(\t\x12\x1c\n\x05query\x18\x03 \x01(\x0b\x32\r.pbx.SetQuery\"\xe8\x01\n\tClientDel\x12\n\n\x02id\x18\x01 \x01(\t\x12\r\n\x05topic\x18\x02 \x01(\t\x12!\n\x04what\x18\x03 \x01(\x0e\x32\x13.pbx.ClientDel.What\x12\x1e\n\x07\x64\x65l_seq\x18\x04 \x03(\x0b\x32\r.pbx.SeqRange\x12\x0f\n\x07user_id\x18\x05 \x01(\t\x12\x1d\n\x04\x63red\x18\x06 \x01(\x0b\x32\x0f.pbx.ClientCred\x12\x0c\n\x04hard\x18\x07 \x01(\x08\"?\n\x04What\x12\x06\n\x02X0\x10\x00\x12\x07\n\x03MSG\x10\x01\x12\t\n\x05TOPIC\x10\x02\x12\x07\n\x03SUB\x10\x03\x12\x08\n\x04USER\x10\x04\x12\x08\n\x04\x43RED\x10\x05\"\x88\x01\n\nClientNote\x12\r\n\x05topic\x18\x01 \x01(\t\x12\x1b\n\x04what\x18\x02 \x01(\x0e\x32\r.pbx.InfoNote\x12\x0e\n\x06seq_id\x18\x03 \x01(\x05\x12\x0e\n\x06unread\x18\x04 \x01(\x05\x12\x1d\n\x05\x65vent\x18\x05 \x01(\x0e\x32\x0e.pbx.CallEvent\x12\x0f\n\x07payload\x18\x06 \x01(\x0c\"\\\n\x0b\x43lientExtra\x12\x13\n\x0b\x61ttachments\x18\x01 \x03(\t\x12\x14\n\x0con_behalf_of\x18\x02 \x01(\t\x12\"\n\nauth_level\x18\x03 \x01(\x0e\x32\x0e.pbx.AuthLevel\"\xf5\x02\n\tClientMsg\x12\x1b\n\x02hi\x18\x01 \x01(\x0b\x32\r.pbx.ClientHiH\x00\x12\x1d\n\x03\x61\x63\x63\x18\x02 \x01(\x0b\x32\x0e.pbx.ClientAccH\x00\x12!\n\x05login\x18\x03 \x01(\x0b\x32\x10.pbx.ClientLoginH\x00\x12\x1d\n\x03sub\x18\x04 \x01(\x0b\x32\x0e.pbx.ClientSubH\x00\x12!\n\x05leave\x18\x05 \x01(\x0b\x32\x10.pbx.ClientLeaveH\x00\x12\x1d\n\x03pub\x18\x06 \x01(\x0b\x32\x0e.pbx.ClientPubH\x00\x12\x1d\n\x03get\x18\x07 \x01(\x0b\x32\x0e.pbx.ClientGetH\x00\x12\x1d\n\x03set\x18\x08 \x01(\x0b\x32\x0e.pbx.ClientSetH\x00\x12\x1d\n\x03\x64\x65l\x18\t \x01(\x0b\x32\x0e.pbx.ClientDelH\x00\x12\x1f\n\x04note\x18\n \x01(\x0b\x32\x0f.pbx.ClientNoteH\x00\x12\x1f\n\x05\x65xtra\x18\r \x01(\x0b\x32\x10.pbx.ClientExtraB\t\n\x07Message\"9\n\nServerCred\x12\x0e\n\x06method\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t\x12\x0c\n\x04\x64one\x18\x03 \x01(\x08\"\xf6\x02\n\tTopicDesc\x12\x12\n\ncreated_at\x18\x01 \x01(\x03\x12\x12\n\nupdated_at\x18\x02 \x01(\x03\x12\x12\n\ntouched_at\x18\x03 \x01(\x03\x12#\n\x06\x64\x65\x66\x61\x63s\x18\x04 \x01(\x0b\x32\x13.pbx.DefaultAcsMode\x12\x1c\n\x03\x61\x63s\x18\x05 \x01(\x0b\x32\x0f.pbx.AccessMode\x12\x0e\n\x06seq_id\x18\x06 \x01(\x05\x12\x0f\n\x07read_id\x18\x07 \x01(\x05\x12\x0f\n\x07recv_id\x18\x08 \x01(\x05\x12\x0e\n\x06\x64\x65l_id\x18\t \x01(\x05\x12\x0e\n\x06public\x18\n \x01(\x0c\x12\x0f\n\x07private\x18\x0b \x01(\x0c\x12\r\n\x05state\x18\x0c \x01(\t\x12\x10\n\x08state_at\x18\r \x01(\x03\x12\x0f\n\x07trusted\x18\x0e \x01(\x0c\x12\x0f\n\x07is_chan\x18\x11 \x01(\x08\x12\x0e\n\x06online\x18\x12 \x01(\x08\x12\x16\n\x0elast_seen_time\x18\x0f \x01(\x03\x12\x1c\n\x14last_seen_user_agent\x18\x10 \x01(\t\"\xbe\x02\n\x08TopicSub\x12\x12\n\nupdated_at\x18\x01 \x01(\x03\x12\x12\n\ndeleted_at\x18\x02 \x01(\x03\x12\x0e\n\x06online\x18\x03 \x01(\x08\x12\x1c\n\x03\x61\x63s\x18\x04 \x01(\x0b\x32\x0f.pbx.AccessMode\x12\x0f\n\x07read_id\x18\x05 \x01(\x05\x12\x0f\n\x07recv_id\x18\x06 \x01(\x05\x12\x0e\n\x06public\x18\x07 \x01(\x0c\x12\x0f\n\x07trusted\x18\x10 \x01(\x0c\x12\x0f\n\x07private\x18\x08 \x01(\x0c\x12\x0f\n\x07user_id\x18\t \x01(\t\x12\r\n\x05topic\x18\n \x01(\t\x12\x12\n\ntouched_at\x18\x0b \x01(\x03\x12\x0e\n\x06seq_id\x18\x0c \x01(\x05\x12\x0e\n\x06\x64\x65l_id\x18\r \x01(\x05\x12\x16\n\x0elast_seen_time\x18\x0e \x01(\x03\x12\x1c\n\x14last_seen_user_agent\x18\x0f \x01(\t\";\n\tDelValues\x12\x0e\n\x06\x64\x65l_id\x18\x01 \x01(\x05\x12\x1e\n\x07\x64\x65l_seq\x18\x02 \x03(\x0b\x32\r.pbx.SeqRange\"\x9f\x01\n\nServerCtrl\x12\n\n\x02id\x18\x01 \x01(\t\x12\r\n\x05topic\x18\x02 \x01(\t\x12\x0c\n\x04\x63ode\x18\x03 \x01(\x05\x12\x0c\n\x04text\x18\x04 \x01(\t\x12+\n\x06params\x18\x05 \x03(\x0b\x32\x1b.pbx.ServerCtrl.ParamsEntry\x1a-\n\x0bParamsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\x0c:\x02\x38\x01\"\xcf\x01\n\nServerData\x12\r\n\x05topic\x18\x01 \x01(\t\x12\x14\n\x0c\x66rom_user_id\x18\x02 \x01(\t\x12\x11\n\ttimestamp\x18\x07 \x01(\x03\x12\x12\n\ndeleted_at\x18\x03 \x01(\x03\x12\x0e\n\x06seq_id\x18\x04 \x01(\x05\x12\'\n\x04head\x18\x05 \x03(\x0b\x32\x19.pbx.ServerData.HeadEntry\x12\x0f\n\x07\x63ontent\x18\x06 \x01(\x0c\x1a+\n\tHeadEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\x0c:\x02\x38\x01\"\xf6\x02\n\nServerPres\x12\r\n\x05topic\x18\x01 \x01(\t\x12\x0b\n\x03src\x18\x02 \x01(\t\x12\"\n\x04what\x18\x03 \x01(\x0e\x32\x14.pbx.ServerPres.What\x12\x12\n\nuser_agent\x18\x04 \x01(\t\x12\x0e\n\x06seq_id\x18\x05 \x01(\x05\x12\x0e\n\x06\x64\x65l_id\x18\x06 \x01(\x05\x12\x1e\n\x07\x64\x65l_seq\x18\x07 \x03(\x0b\x32\r.pbx.SeqRange\x12\x16\n\x0etarget_user_id\x18\x08 \x01(\t\x12\x15\n\ractor_user_id\x18\t \x01(\t\x12\x1c\n\x03\x61\x63s\x18\n \x01(\x0b\x32\x0f.pbx.AccessMode\"\x86\x01\n\x04What\x12\x06\n\x02X3\x10\x00\x12\x06\n\x02ON\x10\x01\x12\x07\n\x03OFF\x10\x02\x12\x06\n\x02UA\x10\x03\x12\x07\n\x03UPD\x10\x04\x12\x08\n\x04GONE\x10\x05\x12\x07\n\x03\x41\x43S\x10\x06\x12\x08\n\x04TERM\x10\x07\x12\x07\n\x03MSG\x10\x08\x12\x08\n\x04READ\x10\t\x12\x08\n\x04RECV\x10\n\x12\x07\n\x03\x44\x45L\x10\x0b\x12\x08\n\x04TAGS\x10\x0c\x12\x07\n\x03\x41UX\x10\r\"\xfe\x01\n\nServerMeta\x12\n\n\x02id\x18\x01 \x01(\t\x12\r\n\x05topic\x18\x02 \x01(\t\x12\x1c\n\x04\x64\x65sc\x18\x03 \x01(\x0b\x32\x0e.pbx.TopicDesc\x12\x1a\n\x03sub\x18\x04 \x03(\x0b\x32\r.pbx.TopicSub\x12\x1b\n\x03\x64\x65l\x18\x05 \x01(\x0b\x32\x0e.pbx.DelValues\x12\x0c\n\x04tags\x18\x06 \x03(\t\x12\x1d\n\x04\x63red\x18\x07 \x03(\x0b\x32\x0f.pbx.ServerCred\x12%\n\x03\x61ux\x18\x08 \x03(\x0b\x32\x18.pbx.ServerMeta.AuxEntry\x1a*\n\x08\x41uxEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\x0c:\x02\x38\x01\"\x9b\x01\n\nServerInfo\x12\r\n\x05topic\x18\x01 \x01(\t\x12\x14\n\x0c\x66rom_user_id\x18\x02 \x01(\t\x12\x1b\n\x04what\x18\x03 \x01(\x0e\x32\r.pbx.InfoNote\x12\x0e\n\x06seq_id\x18\x04 \x01(\x05\x12\x0b\n\x03src\x18\x05 \x01(\t\x12\x1d\n\x05\x65vent\x18\x06 \x01(\x0e\x32\x0e.pbx.CallEvent\x12\x0f\n\x07payload\x18\x07 \x01(\x0c\"\xce\x01\n\tServerMsg\x12\x1f\n\x04\x63trl\x18\x01 \x01(\x0b\x32\x0f.pbx.ServerCtrlH\x00\x12\x1f\n\x04\x64\x61ta\x18\x02 \x01(\x0b\x32\x0f.pbx.ServerDataH\x00\x12\x1f\n\x04pres\x18\x03 \x01(\x0b\x32\x0f.pbx.ServerPresH\x00\x12\x1f\n\x04meta\x18\x04 \x01(\x0b\x32\x0f.pbx.ServerMetaH\x00\x12\x1f\n\x04info\x18\x05 \x01(\x0b\x32\x0f.pbx.ServerInfoH\x00\x12\x11\n\x05topic\x18\x06 \x01(\tB\x02\x18\x01\x42\t\n\x07Message\"j\n\nServerResp\x12\x1d\n\x06status\x18\x01 \x01(\x0e\x32\r.pbx.RespCode\x12\x1e\n\x06srvmsg\x18\x02 \x01(\x0b\x32\x0e.pbx.ServerMsg\x12\x1d\n\x05\x63lmsg\x18\x03 \x01(\x0b\x32\x0e.pbx.ClientMsg\"\xa0\x01\n\x07Session\x12\x12\n\nsession_id\x18\x01 \x01(\t\x12\x0f\n\x07user_id\x18\x02 \x01(\t\x12\"\n\nauth_level\x18\x03 \x01(\x0e\x32\x0e.pbx.AuthLevel\x12\x13\n\x0bremote_addr\x18\x04 \x01(\t\x12\x12\n\nuser_agent\x18\x05 \x01(\t\x12\x11\n\tdevice_id\x18\x06 \x01(\t\x12\x10\n\x08language\x18\x07 \x01(\t\"D\n\tClientReq\x12\x1b\n\x03msg\x18\x01 \x01(\x0b\x32\x0e.pbx.ClientMsg\x12\x1a\n\x04sess\x18\x02 \x01(\x0b\x32\x0c.pbx.Session\"-\n\x0bSearchQuery\x12\x0f\n\x07user_id\x18\x01 \x01(\t\x12\r\n\x05query\x18\x02 \x01(\t\"Z\n\x0bSearchFound\x12\x1d\n\x06status\x18\x01 \x01(\x0e\x32\r.pbx.RespCode\x12\r\n\x05query\x18\x02 \x01(\t\x12\x1d\n\x06result\x18\x03 \x03(\x0b\x32\r.pbx.TopicSub\"S\n\nTopicEvent\x12\x19\n\x06\x61\x63tion\x18\x01 \x01(\x0e\x32\t.pbx.Crud\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x1c\n\x04\x64\x65sc\x18\x03 \x01(\x0b\x32\x0e.pbx.TopicDesc\"\x82\x01\n\x0c\x41\x63\x63ountEvent\x12\x19\n\x06\x61\x63tion\x18\x01 \x01(\x0e\x32\t.pbx.Crud\x12\x0f\n\x07user_id\x18\x02 \x01(\t\x12(\n\x0b\x64\x65\x66\x61ult_acs\x18\x03 \x01(\x0b\x32\x13.pbx.DefaultAcsMode\x12\x0e\n\x06public\x18\x04 \x01(\x0c\x12\x0c\n\x04tags\x18\x08 \x03(\t\"\xb0\x01\n\x11SubscriptionEvent\x12\x19\n\x06\x61\x63tion\x18\x01 \x01(\x0e\x32\t.pbx.Crud\x12\r\n\x05topic\x18\x02 \x01(\t\x12\x0f\n\x07user_id\x18\x03 \x01(\t\x12\x0e\n\x06\x64\x65l_id\x18\x04 \x01(\x05\x12\x0f\n\x07read_id\x18\x05 \x01(\x05\x12\x0f\n\x07recv_id\x18\x06 \x01(\x05\x12\x1d\n\x04mode\x18\x07 \x01(\x0b\x32\x0f.pbx.AccessMode\x12\x0f\n\x07private\x18\x08 \x01(\x0c\"G\n\x0cMessageEvent\x12\x19\n\x06\x61\x63tion\x18\x01 \x01(\x0e\x32\t.pbx.Crud\x12\x1c\n\x03msg\x18\x02 \x01(\x0b\x32\x0f.pbx.ServerData\"&\n\x04\x41uth\x12\x0e\n\x06scheme\x18\x01 \x01(\t\x12\x0e\n\x06secret\x18\x02 \x01(\t\"G\n\x08\x46ileMeta\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x11\n\tmime_type\x18\x02 \x01(\t\x12\x0c\n\x04\x65tag\x18\x03 \x01(\t\x12\x0c\n\x04size\x18\x04 \x01(\x03\"m\n\tFileUpReq\x12\n\n\x02id\x18\x01 \x01(\t\x12\x17\n\x04\x61uth\x18\x02 \x01(\x0b\x32\t.pbx.Auth\x12\r\n\x05topic\x18\x03 \x01(\t\x12\x1b\n\x04meta\x18\x04 \x01(\x0b\x32\r.pbx.FileMeta\x12\x0f\n\x07\x63ontent\x18\x05 \x01(\x0c\"d\n\nFileUpResp\x12\n\n\x02id\x18\x01 \x01(\t\x12\x0c\n\x04\x63ode\x18\x02 \x01(\x05\x12\x0c\n\x04text\x18\x03 \x01(\t\x12\x1b\n\x04meta\x18\x04 \x01(\x0b\x32\r.pbx.FileMeta\x12\x11\n\tredir_url\x18\x05 \x01(\t\"T\n\x0b\x46ileDownReq\x12\n\n\x02id\x18\x01 \x01(\t\x12\x17\n\x04\x61uth\x18\x02 \x01(\x0b\x32\t.pbx.Auth\x12\x0b\n\x03uri\x18\x03 \x01(\t\x12\x13\n\x0bif_modified\x18\x04 \x01(\t\"w\n\x0c\x46ileDownResp\x12\n\n\x02id\x18\x01 \x01(\t\x12\x0c\n\x04\x63ode\x18\x02 \x01(\x05\x12\x0c\n\x04text\x18\x03 \x01(\t\x12\x1b\n\x04meta\x18\x04 \x01(\x0b\x32\r.pbx.FileMeta\x12\x11\n\tredir_url\x18\x05 \x01(\t\x12\x0f\n\x07\x63ontent\x18\x06 \x01(\x0c*3\n\tAuthLevel\x12\x08\n\x04NONE\x10\x00\x12\x08\n\x04\x41NON\x10\n\x12\x08\n\x04\x41UTH\x10\x14\x12\x08\n\x04ROOT\x10\x1e*8\n\x08InfoNote\x12\x06\n\x02X1\x10\x00\x12\x08\n\x04READ\x10\x01\x12\x08\n\x04RECV\x10\x02\x12\x06\n\x02KP\x10\x03\x12\x08\n\x04\x43\x41LL\x10\x04*o\n\tCallEvent\x12\x06\n\x02X2\x10\x00\x12\n\n\x06\x41\x43\x43\x45PT\x10\x01\x12\n\n\x06\x41NSWER\x10\x02\x12\x0b\n\x07HANG_UP\x10\x03\x12\x11\n\rICE_CANDIDATE\x10\x04\x12\n\n\x06INVITE\x10\x05\x12\t\n\x05OFFER\x10\x06\x12\x0b\n\x07RINGING\x10\x07*<\n\x08RespCode\x12\x0c\n\x08\x43ONTINUE\x10\x00\x12\x08\n\x04\x44ROP\x10\x01\x12\x0b\n\x07RESPOND\x10\x02\x12\x0b\n\x07REPLACE\x10\x03**\n\x04\x43rud\x12\n\n\x06\x43REATE\x10\x00\x12\n\n\x06UPDATE\x10\x01\x12\n\n\x06\x44\x45LETE\x10\x02\x32\xaf\x01\n\x04Node\x12\x33\n\x0bMessageLoop\x12\x0e.pbx.ClientMsg\x1a\x0e.pbx.ServerMsg\"\x00(\x01\x30\x01\x12\x37\n\x10LargeFileReceive\x12\x0e.pbx.FileUpReq\x1a\x0f.pbx.FileUpResp\"\x00(\x01\x12\x39\n\x0eLargeFileServe\x12\x10.pbx.FileDownReq\x1a\x11.pbx.FileDownResp\"\x00\x30\x01\x32\x9f\x02\n\x06Plugin\x12-\n\x08\x46ireHose\x12\x0e.pbx.ClientReq\x1a\x0f.pbx.ServerResp\"\x00\x12,\n\x04\x46ind\x12\x10.pbx.SearchQuery\x1a\x10.pbx.SearchFound\"\x00\x12+\n\x07\x41\x63\x63ount\x12\x11.pbx.AccountEvent\x1a\x0b.pbx.Unused\"\x00\x12\'\n\x05Topic\x12\x0f.pbx.TopicEvent\x1a\x0b.pbx.Unused\"\x00\x12\x35\n\x0cSubscription\x12\x16.pbx.SubscriptionEvent\x1a\x0b.pbx.Unused\"\x00\x12+\n\x07Message\x12\x11.pbx.MessageEvent\x1a\x0b.pbx.Unused\"\x00\x42\x1cZ\x1agithub.com/tinode/chat/pbxb\x06proto3') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'model_pb2', _globals) +if _descriptor._USE_C_DESCRIPTORS == False: + DESCRIPTOR._options = None + DESCRIPTOR._serialized_options = b'Z\032github.com/tinode/chat/pbx' + _CLIENTCRED_PARAMSENTRY._options = None + _CLIENTCRED_PARAMSENTRY._serialized_options = b'8\001' + _SETQUERY_AUXENTRY._options = None + _SETQUERY_AUXENTRY._serialized_options = b'8\001' + _CLIENTPUB_HEADENTRY._options = None + _CLIENTPUB_HEADENTRY._serialized_options = b'8\001' + _SERVERCTRL_PARAMSENTRY._options = None + _SERVERCTRL_PARAMSENTRY._serialized_options = b'8\001' + _SERVERDATA_HEADENTRY._options = None + _SERVERDATA_HEADENTRY._serialized_options = b'8\001' + _SERVERMETA_AUXENTRY._options = None + _SERVERMETA_AUXENTRY._serialized_options = b'8\001' + _SERVERMSG.fields_by_name['topic']._options = None + _SERVERMSG.fields_by_name['topic']._serialized_options = b'\030\001' + _globals['_AUTHLEVEL']._serialized_start=6396 + _globals['_AUTHLEVEL']._serialized_end=6447 + _globals['_INFONOTE']._serialized_start=6449 + _globals['_INFONOTE']._serialized_end=6505 + _globals['_CALLEVENT']._serialized_start=6507 + _globals['_CALLEVENT']._serialized_end=6618 + _globals['_RESPCODE']._serialized_start=6620 + _globals['_RESPCODE']._serialized_end=6680 + _globals['_CRUD']._serialized_start=6682 + _globals['_CRUD']._serialized_end=6724 + _globals['_UNUSED']._serialized_start=20 + _globals['_UNUSED']._serialized_end=28 + _globals['_DEFAULTACSMODE']._serialized_start=30 + _globals['_DEFAULTACSMODE']._serialized_end=74 + _globals['_ACCESSMODE']._serialized_start=76 + _globals['_ACCESSMODE']._serialized_end=117 + _globals['_SETSUB']._serialized_start=119 + _globals['_SETSUB']._serialized_end=158 + _globals['_CLIENTCRED']._serialized_start=161 + _globals['_CLIENTCRED']._serialized_end=314 + _globals['_CLIENTCRED_PARAMSENTRY']._serialized_start=269 + _globals['_CLIENTCRED_PARAMSENTRY']._serialized_end=314 + _globals['_SETDESC']._serialized_start=316 + _globals['_SETDESC']._serialized_end=417 + _globals['_SEQRANGE']._serialized_start=419 + _globals['_SEQRANGE']._serialized_end=454 + _globals['_GETOPTS']._serialized_start=457 + _globals['_GETOPTS']._serialized_end=605 + _globals['_GETQUERY']._serialized_start=607 + _globals['_GETQUERY']._serialized_end=714 + _globals['_SETQUERY']._serialized_start=717 + _globals['_SETQUERY']._serialized_end=907 + _globals['_SETQUERY_AUXENTRY']._serialized_start=865 + _globals['_SETQUERY_AUXENTRY']._serialized_end=907 + _globals['_CLIENTHI']._serialized_start=910 + _globals['_CLIENTHI']._serialized_end=1052 + _globals['_CLIENTACC']._serialized_start=1055 + _globals['_CLIENTACC']._serialized_end=1321 + _globals['_CLIENTLOGIN']._serialized_start=1323 + _globals['_CLIENTLOGIN']._serialized_end=1411 + _globals['_CLIENTSUB']._serialized_start=1413 + _globals['_CLIENTSUB']._serialized_end=1519 + _globals['_CLIENTLEAVE']._serialized_start=1521 + _globals['_CLIENTLEAVE']._serialized_end=1576 + _globals['_CLIENTPUB']._serialized_start=1579 + _globals['_CLIENTPUB']._serialized_end=1736 + _globals['_CLIENTPUB_HEADENTRY']._serialized_start=1693 + _globals['_CLIENTPUB_HEADENTRY']._serialized_end=1736 + _globals['_CLIENTGET']._serialized_start=1738 + _globals['_CLIENTGET']._serialized_end=1806 + _globals['_CLIENTSET']._serialized_start=1808 + _globals['_CLIENTSET']._serialized_end=1876 + _globals['_CLIENTDEL']._serialized_start=1879 + _globals['_CLIENTDEL']._serialized_end=2111 + _globals['_CLIENTDEL_WHAT']._serialized_start=2048 + _globals['_CLIENTDEL_WHAT']._serialized_end=2111 + _globals['_CLIENTNOTE']._serialized_start=2114 + _globals['_CLIENTNOTE']._serialized_end=2250 + _globals['_CLIENTEXTRA']._serialized_start=2252 + _globals['_CLIENTEXTRA']._serialized_end=2344 + _globals['_CLIENTMSG']._serialized_start=2347 + _globals['_CLIENTMSG']._serialized_end=2720 + _globals['_SERVERCRED']._serialized_start=2722 + _globals['_SERVERCRED']._serialized_end=2779 + _globals['_TOPICDESC']._serialized_start=2782 + _globals['_TOPICDESC']._serialized_end=3156 + _globals['_TOPICSUB']._serialized_start=3159 + _globals['_TOPICSUB']._serialized_end=3477 + _globals['_DELVALUES']._serialized_start=3479 + _globals['_DELVALUES']._serialized_end=3538 + _globals['_SERVERCTRL']._serialized_start=3541 + _globals['_SERVERCTRL']._serialized_end=3700 + _globals['_SERVERCTRL_PARAMSENTRY']._serialized_start=269 + _globals['_SERVERCTRL_PARAMSENTRY']._serialized_end=314 + _globals['_SERVERDATA']._serialized_start=3703 + _globals['_SERVERDATA']._serialized_end=3910 + _globals['_SERVERDATA_HEADENTRY']._serialized_start=1693 + _globals['_SERVERDATA_HEADENTRY']._serialized_end=1736 + _globals['_SERVERPRES']._serialized_start=3913 + _globals['_SERVERPRES']._serialized_end=4287 + _globals['_SERVERPRES_WHAT']._serialized_start=4153 + _globals['_SERVERPRES_WHAT']._serialized_end=4287 + _globals['_SERVERMETA']._serialized_start=4290 + _globals['_SERVERMETA']._serialized_end=4544 + _globals['_SERVERMETA_AUXENTRY']._serialized_start=865 + _globals['_SERVERMETA_AUXENTRY']._serialized_end=907 + _globals['_SERVERINFO']._serialized_start=4547 + _globals['_SERVERINFO']._serialized_end=4702 + _globals['_SERVERMSG']._serialized_start=4705 + _globals['_SERVERMSG']._serialized_end=4911 + _globals['_SERVERRESP']._serialized_start=4913 + _globals['_SERVERRESP']._serialized_end=5019 + _globals['_SESSION']._serialized_start=5022 + _globals['_SESSION']._serialized_end=5182 + _globals['_CLIENTREQ']._serialized_start=5184 + _globals['_CLIENTREQ']._serialized_end=5252 + _globals['_SEARCHQUERY']._serialized_start=5254 + _globals['_SEARCHQUERY']._serialized_end=5299 + _globals['_SEARCHFOUND']._serialized_start=5301 + _globals['_SEARCHFOUND']._serialized_end=5391 + _globals['_TOPICEVENT']._serialized_start=5393 + _globals['_TOPICEVENT']._serialized_end=5476 + _globals['_ACCOUNTEVENT']._serialized_start=5479 + _globals['_ACCOUNTEVENT']._serialized_end=5609 + _globals['_SUBSCRIPTIONEVENT']._serialized_start=5612 + _globals['_SUBSCRIPTIONEVENT']._serialized_end=5788 + _globals['_MESSAGEEVENT']._serialized_start=5790 + _globals['_MESSAGEEVENT']._serialized_end=5861 + _globals['_AUTH']._serialized_start=5863 + _globals['_AUTH']._serialized_end=5901 + _globals['_FILEMETA']._serialized_start=5903 + _globals['_FILEMETA']._serialized_end=5974 + _globals['_FILEUPREQ']._serialized_start=5976 + _globals['_FILEUPREQ']._serialized_end=6085 + _globals['_FILEUPRESP']._serialized_start=6087 + _globals['_FILEUPRESP']._serialized_end=6187 + _globals['_FILEDOWNREQ']._serialized_start=6189 + _globals['_FILEDOWNREQ']._serialized_end=6273 + _globals['_FILEDOWNRESP']._serialized_start=6275 + _globals['_FILEDOWNRESP']._serialized_end=6394 + _globals['_NODE']._serialized_start=6727 + _globals['_NODE']._serialized_end=6902 + _globals['_PLUGIN']._serialized_start=6905 + _globals['_PLUGIN']._serialized_end=7192 +# @@protoc_insertion_point(module_scope) diff --git a/py_grpc/tinode_grpc/model_pb2.pyi b/py_grpc/tinode_grpc/model_pb2.pyi index e69de29..3040615 100644 --- a/py_grpc/tinode_grpc/model_pb2.pyi +++ b/py_grpc/tinode_grpc/model_pb2.pyi @@ -0,0 +1,832 @@ +from google.protobuf.internal import containers as _containers +from google.protobuf.internal import enum_type_wrapper as _enum_type_wrapper +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from typing import ClassVar as _ClassVar, Iterable as _Iterable, Mapping as _Mapping, Optional as _Optional, Union as _Union + +DESCRIPTOR: _descriptor.FileDescriptor + +class AuthLevel(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): + __slots__ = [] + NONE: _ClassVar[AuthLevel] + ANON: _ClassVar[AuthLevel] + AUTH: _ClassVar[AuthLevel] + ROOT: _ClassVar[AuthLevel] + +class InfoNote(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): + __slots__ = [] + X1: _ClassVar[InfoNote] + READ: _ClassVar[InfoNote] + RECV: _ClassVar[InfoNote] + KP: _ClassVar[InfoNote] + CALL: _ClassVar[InfoNote] + +class CallEvent(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): + __slots__ = [] + X2: _ClassVar[CallEvent] + ACCEPT: _ClassVar[CallEvent] + ANSWER: _ClassVar[CallEvent] + HANG_UP: _ClassVar[CallEvent] + ICE_CANDIDATE: _ClassVar[CallEvent] + INVITE: _ClassVar[CallEvent] + OFFER: _ClassVar[CallEvent] + RINGING: _ClassVar[CallEvent] + +class RespCode(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): + __slots__ = [] + CONTINUE: _ClassVar[RespCode] + DROP: _ClassVar[RespCode] + RESPOND: _ClassVar[RespCode] + REPLACE: _ClassVar[RespCode] + +class Crud(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): + __slots__ = [] + CREATE: _ClassVar[Crud] + UPDATE: _ClassVar[Crud] + DELETE: _ClassVar[Crud] +NONE: AuthLevel +ANON: AuthLevel +AUTH: AuthLevel +ROOT: AuthLevel +X1: InfoNote +READ: InfoNote +RECV: InfoNote +KP: InfoNote +CALL: InfoNote +X2: CallEvent +ACCEPT: CallEvent +ANSWER: CallEvent +HANG_UP: CallEvent +ICE_CANDIDATE: CallEvent +INVITE: CallEvent +OFFER: CallEvent +RINGING: CallEvent +CONTINUE: RespCode +DROP: RespCode +RESPOND: RespCode +REPLACE: RespCode +CREATE: Crud +UPDATE: Crud +DELETE: Crud + +class Unused(_message.Message): + __slots__ = [] + def __init__(self) -> None: ... + +class DefaultAcsMode(_message.Message): + __slots__ = ["auth", "anon"] + AUTH_FIELD_NUMBER: _ClassVar[int] + ANON_FIELD_NUMBER: _ClassVar[int] + auth: str + anon: str + def __init__(self, auth: _Optional[str] = ..., anon: _Optional[str] = ...) -> None: ... + +class AccessMode(_message.Message): + __slots__ = ["want", "given"] + WANT_FIELD_NUMBER: _ClassVar[int] + GIVEN_FIELD_NUMBER: _ClassVar[int] + want: str + given: str + def __init__(self, want: _Optional[str] = ..., given: _Optional[str] = ...) -> None: ... + +class SetSub(_message.Message): + __slots__ = ["user_id", "mode"] + USER_ID_FIELD_NUMBER: _ClassVar[int] + MODE_FIELD_NUMBER: _ClassVar[int] + user_id: str + mode: str + def __init__(self, user_id: _Optional[str] = ..., mode: _Optional[str] = ...) -> None: ... + +class ClientCred(_message.Message): + __slots__ = ["method", "value", "response", "params"] + class ParamsEntry(_message.Message): + __slots__ = ["key", "value"] + KEY_FIELD_NUMBER: _ClassVar[int] + VALUE_FIELD_NUMBER: _ClassVar[int] + key: str + value: bytes + def __init__(self, key: _Optional[str] = ..., value: _Optional[bytes] = ...) -> None: ... + METHOD_FIELD_NUMBER: _ClassVar[int] + VALUE_FIELD_NUMBER: _ClassVar[int] + RESPONSE_FIELD_NUMBER: _ClassVar[int] + PARAMS_FIELD_NUMBER: _ClassVar[int] + method: str + value: str + response: str + params: _containers.ScalarMap[str, bytes] + def __init__(self, method: _Optional[str] = ..., value: _Optional[str] = ..., response: _Optional[str] = ..., params: _Optional[_Mapping[str, bytes]] = ...) -> None: ... + +class SetDesc(_message.Message): + __slots__ = ["default_acs", "public", "private", "trusted"] + DEFAULT_ACS_FIELD_NUMBER: _ClassVar[int] + PUBLIC_FIELD_NUMBER: _ClassVar[int] + PRIVATE_FIELD_NUMBER: _ClassVar[int] + TRUSTED_FIELD_NUMBER: _ClassVar[int] + default_acs: DefaultAcsMode + public: bytes + private: bytes + trusted: bytes + def __init__(self, default_acs: _Optional[_Union[DefaultAcsMode, _Mapping]] = ..., public: _Optional[bytes] = ..., private: _Optional[bytes] = ..., trusted: _Optional[bytes] = ...) -> None: ... + +class SeqRange(_message.Message): + __slots__ = ["low", "hi"] + LOW_FIELD_NUMBER: _ClassVar[int] + HI_FIELD_NUMBER: _ClassVar[int] + low: int + hi: int + def __init__(self, low: _Optional[int] = ..., hi: _Optional[int] = ...) -> None: ... + +class GetOpts(_message.Message): + __slots__ = ["if_modified_since", "user", "topic", "since_id", "before_id", "limit", "ranges"] + IF_MODIFIED_SINCE_FIELD_NUMBER: _ClassVar[int] + USER_FIELD_NUMBER: _ClassVar[int] + TOPIC_FIELD_NUMBER: _ClassVar[int] + SINCE_ID_FIELD_NUMBER: _ClassVar[int] + BEFORE_ID_FIELD_NUMBER: _ClassVar[int] + LIMIT_FIELD_NUMBER: _ClassVar[int] + RANGES_FIELD_NUMBER: _ClassVar[int] + if_modified_since: int + user: str + topic: str + since_id: int + before_id: int + limit: int + ranges: _containers.RepeatedCompositeFieldContainer[SeqRange] + def __init__(self, if_modified_since: _Optional[int] = ..., user: _Optional[str] = ..., topic: _Optional[str] = ..., since_id: _Optional[int] = ..., before_id: _Optional[int] = ..., limit: _Optional[int] = ..., ranges: _Optional[_Iterable[_Union[SeqRange, _Mapping]]] = ...) -> None: ... + +class GetQuery(_message.Message): + __slots__ = ["what", "desc", "sub", "data"] + WHAT_FIELD_NUMBER: _ClassVar[int] + DESC_FIELD_NUMBER: _ClassVar[int] + SUB_FIELD_NUMBER: _ClassVar[int] + DATA_FIELD_NUMBER: _ClassVar[int] + what: str + desc: GetOpts + sub: GetOpts + data: GetOpts + def __init__(self, what: _Optional[str] = ..., desc: _Optional[_Union[GetOpts, _Mapping]] = ..., sub: _Optional[_Union[GetOpts, _Mapping]] = ..., data: _Optional[_Union[GetOpts, _Mapping]] = ...) -> None: ... + +class SetQuery(_message.Message): + __slots__ = ["desc", "sub", "tags", "cred", "aux"] + class AuxEntry(_message.Message): + __slots__ = ["key", "value"] + KEY_FIELD_NUMBER: _ClassVar[int] + VALUE_FIELD_NUMBER: _ClassVar[int] + key: str + value: bytes + def __init__(self, key: _Optional[str] = ..., value: _Optional[bytes] = ...) -> None: ... + DESC_FIELD_NUMBER: _ClassVar[int] + SUB_FIELD_NUMBER: _ClassVar[int] + TAGS_FIELD_NUMBER: _ClassVar[int] + CRED_FIELD_NUMBER: _ClassVar[int] + AUX_FIELD_NUMBER: _ClassVar[int] + desc: SetDesc + sub: SetSub + tags: _containers.RepeatedScalarFieldContainer[str] + cred: ClientCred + aux: _containers.ScalarMap[str, bytes] + def __init__(self, desc: _Optional[_Union[SetDesc, _Mapping]] = ..., sub: _Optional[_Union[SetSub, _Mapping]] = ..., tags: _Optional[_Iterable[str]] = ..., cred: _Optional[_Union[ClientCred, _Mapping]] = ..., aux: _Optional[_Mapping[str, bytes]] = ...) -> None: ... + +class ClientHi(_message.Message): + __slots__ = ["id", "user_agent", "ver", "device_id", "lang", "platform", "background", "tenant"] + ID_FIELD_NUMBER: _ClassVar[int] + USER_AGENT_FIELD_NUMBER: _ClassVar[int] + VER_FIELD_NUMBER: _ClassVar[int] + DEVICE_ID_FIELD_NUMBER: _ClassVar[int] + LANG_FIELD_NUMBER: _ClassVar[int] + PLATFORM_FIELD_NUMBER: _ClassVar[int] + BACKGROUND_FIELD_NUMBER: _ClassVar[int] + TENANT_FIELD_NUMBER: _ClassVar[int] + id: str + user_agent: str + ver: str + device_id: str + lang: str + platform: str + background: bool + tenant: str + def __init__(self, id: _Optional[str] = ..., user_agent: _Optional[str] = ..., ver: _Optional[str] = ..., device_id: _Optional[str] = ..., lang: _Optional[str] = ..., platform: _Optional[str] = ..., background: bool = ..., tenant: _Optional[str] = ...) -> None: ... + +class ClientAcc(_message.Message): + __slots__ = ["id", "user_id", "scheme", "secret", "login", "tags", "desc", "cred", "token", "state", "auth_level", "tmp_scheme", "tmp_secret"] + ID_FIELD_NUMBER: _ClassVar[int] + USER_ID_FIELD_NUMBER: _ClassVar[int] + SCHEME_FIELD_NUMBER: _ClassVar[int] + SECRET_FIELD_NUMBER: _ClassVar[int] + LOGIN_FIELD_NUMBER: _ClassVar[int] + TAGS_FIELD_NUMBER: _ClassVar[int] + DESC_FIELD_NUMBER: _ClassVar[int] + CRED_FIELD_NUMBER: _ClassVar[int] + TOKEN_FIELD_NUMBER: _ClassVar[int] + STATE_FIELD_NUMBER: _ClassVar[int] + AUTH_LEVEL_FIELD_NUMBER: _ClassVar[int] + TMP_SCHEME_FIELD_NUMBER: _ClassVar[int] + TMP_SECRET_FIELD_NUMBER: _ClassVar[int] + id: str + user_id: str + scheme: str + secret: bytes + login: bool + tags: _containers.RepeatedScalarFieldContainer[str] + desc: SetDesc + cred: _containers.RepeatedCompositeFieldContainer[ClientCred] + token: bytes + state: str + auth_level: AuthLevel + tmp_scheme: str + tmp_secret: bytes + def __init__(self, id: _Optional[str] = ..., user_id: _Optional[str] = ..., scheme: _Optional[str] = ..., secret: _Optional[bytes] = ..., login: bool = ..., tags: _Optional[_Iterable[str]] = ..., desc: _Optional[_Union[SetDesc, _Mapping]] = ..., cred: _Optional[_Iterable[_Union[ClientCred, _Mapping]]] = ..., token: _Optional[bytes] = ..., state: _Optional[str] = ..., auth_level: _Optional[_Union[AuthLevel, str]] = ..., tmp_scheme: _Optional[str] = ..., tmp_secret: _Optional[bytes] = ...) -> None: ... + +class ClientLogin(_message.Message): + __slots__ = ["id", "scheme", "secret", "cred"] + ID_FIELD_NUMBER: _ClassVar[int] + SCHEME_FIELD_NUMBER: _ClassVar[int] + SECRET_FIELD_NUMBER: _ClassVar[int] + CRED_FIELD_NUMBER: _ClassVar[int] + id: str + scheme: str + secret: bytes + cred: _containers.RepeatedCompositeFieldContainer[ClientCred] + def __init__(self, id: _Optional[str] = ..., scheme: _Optional[str] = ..., secret: _Optional[bytes] = ..., cred: _Optional[_Iterable[_Union[ClientCred, _Mapping]]] = ...) -> None: ... + +class ClientSub(_message.Message): + __slots__ = ["id", "topic", "set_query", "get_query"] + ID_FIELD_NUMBER: _ClassVar[int] + TOPIC_FIELD_NUMBER: _ClassVar[int] + SET_QUERY_FIELD_NUMBER: _ClassVar[int] + GET_QUERY_FIELD_NUMBER: _ClassVar[int] + id: str + topic: str + set_query: SetQuery + get_query: GetQuery + def __init__(self, id: _Optional[str] = ..., topic: _Optional[str] = ..., set_query: _Optional[_Union[SetQuery, _Mapping]] = ..., get_query: _Optional[_Union[GetQuery, _Mapping]] = ...) -> None: ... + +class ClientLeave(_message.Message): + __slots__ = ["id", "topic", "unsub"] + ID_FIELD_NUMBER: _ClassVar[int] + TOPIC_FIELD_NUMBER: _ClassVar[int] + UNSUB_FIELD_NUMBER: _ClassVar[int] + id: str + topic: str + unsub: bool + def __init__(self, id: _Optional[str] = ..., topic: _Optional[str] = ..., unsub: bool = ...) -> None: ... + +class ClientPub(_message.Message): + __slots__ = ["id", "topic", "no_echo", "head", "content"] + class HeadEntry(_message.Message): + __slots__ = ["key", "value"] + KEY_FIELD_NUMBER: _ClassVar[int] + VALUE_FIELD_NUMBER: _ClassVar[int] + key: str + value: bytes + def __init__(self, key: _Optional[str] = ..., value: _Optional[bytes] = ...) -> None: ... + ID_FIELD_NUMBER: _ClassVar[int] + TOPIC_FIELD_NUMBER: _ClassVar[int] + NO_ECHO_FIELD_NUMBER: _ClassVar[int] + HEAD_FIELD_NUMBER: _ClassVar[int] + CONTENT_FIELD_NUMBER: _ClassVar[int] + id: str + topic: str + no_echo: bool + head: _containers.ScalarMap[str, bytes] + content: bytes + def __init__(self, id: _Optional[str] = ..., topic: _Optional[str] = ..., no_echo: bool = ..., head: _Optional[_Mapping[str, bytes]] = ..., content: _Optional[bytes] = ...) -> None: ... + +class ClientGet(_message.Message): + __slots__ = ["id", "topic", "query"] + ID_FIELD_NUMBER: _ClassVar[int] + TOPIC_FIELD_NUMBER: _ClassVar[int] + QUERY_FIELD_NUMBER: _ClassVar[int] + id: str + topic: str + query: GetQuery + def __init__(self, id: _Optional[str] = ..., topic: _Optional[str] = ..., query: _Optional[_Union[GetQuery, _Mapping]] = ...) -> None: ... + +class ClientSet(_message.Message): + __slots__ = ["id", "topic", "query"] + ID_FIELD_NUMBER: _ClassVar[int] + TOPIC_FIELD_NUMBER: _ClassVar[int] + QUERY_FIELD_NUMBER: _ClassVar[int] + id: str + topic: str + query: SetQuery + def __init__(self, id: _Optional[str] = ..., topic: _Optional[str] = ..., query: _Optional[_Union[SetQuery, _Mapping]] = ...) -> None: ... + +class ClientDel(_message.Message): + __slots__ = ["id", "topic", "what", "del_seq", "user_id", "cred", "hard"] + class What(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): + __slots__ = [] + X0: _ClassVar[ClientDel.What] + MSG: _ClassVar[ClientDel.What] + TOPIC: _ClassVar[ClientDel.What] + SUB: _ClassVar[ClientDel.What] + USER: _ClassVar[ClientDel.What] + CRED: _ClassVar[ClientDel.What] + X0: ClientDel.What + MSG: ClientDel.What + TOPIC: ClientDel.What + SUB: ClientDel.What + USER: ClientDel.What + CRED: ClientDel.What + ID_FIELD_NUMBER: _ClassVar[int] + TOPIC_FIELD_NUMBER: _ClassVar[int] + WHAT_FIELD_NUMBER: _ClassVar[int] + DEL_SEQ_FIELD_NUMBER: _ClassVar[int] + USER_ID_FIELD_NUMBER: _ClassVar[int] + CRED_FIELD_NUMBER: _ClassVar[int] + HARD_FIELD_NUMBER: _ClassVar[int] + id: str + topic: str + what: ClientDel.What + del_seq: _containers.RepeatedCompositeFieldContainer[SeqRange] + user_id: str + cred: ClientCred + hard: bool + def __init__(self, id: _Optional[str] = ..., topic: _Optional[str] = ..., what: _Optional[_Union[ClientDel.What, str]] = ..., del_seq: _Optional[_Iterable[_Union[SeqRange, _Mapping]]] = ..., user_id: _Optional[str] = ..., cred: _Optional[_Union[ClientCred, _Mapping]] = ..., hard: bool = ...) -> None: ... + +class ClientNote(_message.Message): + __slots__ = ["topic", "what", "seq_id", "unread", "event", "payload"] + TOPIC_FIELD_NUMBER: _ClassVar[int] + WHAT_FIELD_NUMBER: _ClassVar[int] + SEQ_ID_FIELD_NUMBER: _ClassVar[int] + UNREAD_FIELD_NUMBER: _ClassVar[int] + EVENT_FIELD_NUMBER: _ClassVar[int] + PAYLOAD_FIELD_NUMBER: _ClassVar[int] + topic: str + what: InfoNote + seq_id: int + unread: int + event: CallEvent + payload: bytes + def __init__(self, topic: _Optional[str] = ..., what: _Optional[_Union[InfoNote, str]] = ..., seq_id: _Optional[int] = ..., unread: _Optional[int] = ..., event: _Optional[_Union[CallEvent, str]] = ..., payload: _Optional[bytes] = ...) -> None: ... + +class ClientExtra(_message.Message): + __slots__ = ["attachments", "on_behalf_of", "auth_level"] + ATTACHMENTS_FIELD_NUMBER: _ClassVar[int] + ON_BEHALF_OF_FIELD_NUMBER: _ClassVar[int] + AUTH_LEVEL_FIELD_NUMBER: _ClassVar[int] + attachments: _containers.RepeatedScalarFieldContainer[str] + on_behalf_of: str + auth_level: AuthLevel + def __init__(self, attachments: _Optional[_Iterable[str]] = ..., on_behalf_of: _Optional[str] = ..., auth_level: _Optional[_Union[AuthLevel, str]] = ...) -> None: ... + +class ClientMsg(_message.Message): + __slots__ = ["hi", "acc", "login", "sub", "leave", "pub", "get", "set", "note", "extra"] + HI_FIELD_NUMBER: _ClassVar[int] + ACC_FIELD_NUMBER: _ClassVar[int] + LOGIN_FIELD_NUMBER: _ClassVar[int] + SUB_FIELD_NUMBER: _ClassVar[int] + LEAVE_FIELD_NUMBER: _ClassVar[int] + PUB_FIELD_NUMBER: _ClassVar[int] + GET_FIELD_NUMBER: _ClassVar[int] + SET_FIELD_NUMBER: _ClassVar[int] + DEL_FIELD_NUMBER: _ClassVar[int] + NOTE_FIELD_NUMBER: _ClassVar[int] + EXTRA_FIELD_NUMBER: _ClassVar[int] + hi: ClientHi + acc: ClientAcc + login: ClientLogin + sub: ClientSub + leave: ClientLeave + pub: ClientPub + get: ClientGet + set: ClientSet + note: ClientNote + extra: ClientExtra + def __init__(self, hi: _Optional[_Union[ClientHi, _Mapping]] = ..., acc: _Optional[_Union[ClientAcc, _Mapping]] = ..., login: _Optional[_Union[ClientLogin, _Mapping]] = ..., sub: _Optional[_Union[ClientSub, _Mapping]] = ..., leave: _Optional[_Union[ClientLeave, _Mapping]] = ..., pub: _Optional[_Union[ClientPub, _Mapping]] = ..., get: _Optional[_Union[ClientGet, _Mapping]] = ..., set: _Optional[_Union[ClientSet, _Mapping]] = ..., note: _Optional[_Union[ClientNote, _Mapping]] = ..., extra: _Optional[_Union[ClientExtra, _Mapping]] = ..., **kwargs) -> None: ... + +class ServerCred(_message.Message): + __slots__ = ["method", "value", "done"] + METHOD_FIELD_NUMBER: _ClassVar[int] + VALUE_FIELD_NUMBER: _ClassVar[int] + DONE_FIELD_NUMBER: _ClassVar[int] + method: str + value: str + done: bool + def __init__(self, method: _Optional[str] = ..., value: _Optional[str] = ..., done: bool = ...) -> None: ... + +class TopicDesc(_message.Message): + __slots__ = ["created_at", "updated_at", "touched_at", "defacs", "acs", "seq_id", "read_id", "recv_id", "del_id", "public", "private", "state", "state_at", "trusted", "is_chan", "online", "last_seen_time", "last_seen_user_agent"] + CREATED_AT_FIELD_NUMBER: _ClassVar[int] + UPDATED_AT_FIELD_NUMBER: _ClassVar[int] + TOUCHED_AT_FIELD_NUMBER: _ClassVar[int] + DEFACS_FIELD_NUMBER: _ClassVar[int] + ACS_FIELD_NUMBER: _ClassVar[int] + SEQ_ID_FIELD_NUMBER: _ClassVar[int] + READ_ID_FIELD_NUMBER: _ClassVar[int] + RECV_ID_FIELD_NUMBER: _ClassVar[int] + DEL_ID_FIELD_NUMBER: _ClassVar[int] + PUBLIC_FIELD_NUMBER: _ClassVar[int] + PRIVATE_FIELD_NUMBER: _ClassVar[int] + STATE_FIELD_NUMBER: _ClassVar[int] + STATE_AT_FIELD_NUMBER: _ClassVar[int] + TRUSTED_FIELD_NUMBER: _ClassVar[int] + IS_CHAN_FIELD_NUMBER: _ClassVar[int] + ONLINE_FIELD_NUMBER: _ClassVar[int] + LAST_SEEN_TIME_FIELD_NUMBER: _ClassVar[int] + LAST_SEEN_USER_AGENT_FIELD_NUMBER: _ClassVar[int] + created_at: int + updated_at: int + touched_at: int + defacs: DefaultAcsMode + acs: AccessMode + seq_id: int + read_id: int + recv_id: int + del_id: int + public: bytes + private: bytes + state: str + state_at: int + trusted: bytes + is_chan: bool + online: bool + last_seen_time: int + last_seen_user_agent: str + def __init__(self, created_at: _Optional[int] = ..., updated_at: _Optional[int] = ..., touched_at: _Optional[int] = ..., defacs: _Optional[_Union[DefaultAcsMode, _Mapping]] = ..., acs: _Optional[_Union[AccessMode, _Mapping]] = ..., seq_id: _Optional[int] = ..., read_id: _Optional[int] = ..., recv_id: _Optional[int] = ..., del_id: _Optional[int] = ..., public: _Optional[bytes] = ..., private: _Optional[bytes] = ..., state: _Optional[str] = ..., state_at: _Optional[int] = ..., trusted: _Optional[bytes] = ..., is_chan: bool = ..., online: bool = ..., last_seen_time: _Optional[int] = ..., last_seen_user_agent: _Optional[str] = ...) -> None: ... + +class TopicSub(_message.Message): + __slots__ = ["updated_at", "deleted_at", "online", "acs", "read_id", "recv_id", "public", "trusted", "private", "user_id", "topic", "touched_at", "seq_id", "del_id", "last_seen_time", "last_seen_user_agent"] + UPDATED_AT_FIELD_NUMBER: _ClassVar[int] + DELETED_AT_FIELD_NUMBER: _ClassVar[int] + ONLINE_FIELD_NUMBER: _ClassVar[int] + ACS_FIELD_NUMBER: _ClassVar[int] + READ_ID_FIELD_NUMBER: _ClassVar[int] + RECV_ID_FIELD_NUMBER: _ClassVar[int] + PUBLIC_FIELD_NUMBER: _ClassVar[int] + TRUSTED_FIELD_NUMBER: _ClassVar[int] + PRIVATE_FIELD_NUMBER: _ClassVar[int] + USER_ID_FIELD_NUMBER: _ClassVar[int] + TOPIC_FIELD_NUMBER: _ClassVar[int] + TOUCHED_AT_FIELD_NUMBER: _ClassVar[int] + SEQ_ID_FIELD_NUMBER: _ClassVar[int] + DEL_ID_FIELD_NUMBER: _ClassVar[int] + LAST_SEEN_TIME_FIELD_NUMBER: _ClassVar[int] + LAST_SEEN_USER_AGENT_FIELD_NUMBER: _ClassVar[int] + updated_at: int + deleted_at: int + online: bool + acs: AccessMode + read_id: int + recv_id: int + public: bytes + trusted: bytes + private: bytes + user_id: str + topic: str + touched_at: int + seq_id: int + del_id: int + last_seen_time: int + last_seen_user_agent: str + def __init__(self, updated_at: _Optional[int] = ..., deleted_at: _Optional[int] = ..., online: bool = ..., acs: _Optional[_Union[AccessMode, _Mapping]] = ..., read_id: _Optional[int] = ..., recv_id: _Optional[int] = ..., public: _Optional[bytes] = ..., trusted: _Optional[bytes] = ..., private: _Optional[bytes] = ..., user_id: _Optional[str] = ..., topic: _Optional[str] = ..., touched_at: _Optional[int] = ..., seq_id: _Optional[int] = ..., del_id: _Optional[int] = ..., last_seen_time: _Optional[int] = ..., last_seen_user_agent: _Optional[str] = ...) -> None: ... + +class DelValues(_message.Message): + __slots__ = ["del_id", "del_seq"] + DEL_ID_FIELD_NUMBER: _ClassVar[int] + DEL_SEQ_FIELD_NUMBER: _ClassVar[int] + del_id: int + del_seq: _containers.RepeatedCompositeFieldContainer[SeqRange] + def __init__(self, del_id: _Optional[int] = ..., del_seq: _Optional[_Iterable[_Union[SeqRange, _Mapping]]] = ...) -> None: ... + +class ServerCtrl(_message.Message): + __slots__ = ["id", "topic", "code", "text", "params"] + class ParamsEntry(_message.Message): + __slots__ = ["key", "value"] + KEY_FIELD_NUMBER: _ClassVar[int] + VALUE_FIELD_NUMBER: _ClassVar[int] + key: str + value: bytes + def __init__(self, key: _Optional[str] = ..., value: _Optional[bytes] = ...) -> None: ... + ID_FIELD_NUMBER: _ClassVar[int] + TOPIC_FIELD_NUMBER: _ClassVar[int] + CODE_FIELD_NUMBER: _ClassVar[int] + TEXT_FIELD_NUMBER: _ClassVar[int] + PARAMS_FIELD_NUMBER: _ClassVar[int] + id: str + topic: str + code: int + text: str + params: _containers.ScalarMap[str, bytes] + def __init__(self, id: _Optional[str] = ..., topic: _Optional[str] = ..., code: _Optional[int] = ..., text: _Optional[str] = ..., params: _Optional[_Mapping[str, bytes]] = ...) -> None: ... + +class ServerData(_message.Message): + __slots__ = ["topic", "from_user_id", "timestamp", "deleted_at", "seq_id", "head", "content"] + class HeadEntry(_message.Message): + __slots__ = ["key", "value"] + KEY_FIELD_NUMBER: _ClassVar[int] + VALUE_FIELD_NUMBER: _ClassVar[int] + key: str + value: bytes + def __init__(self, key: _Optional[str] = ..., value: _Optional[bytes] = ...) -> None: ... + TOPIC_FIELD_NUMBER: _ClassVar[int] + FROM_USER_ID_FIELD_NUMBER: _ClassVar[int] + TIMESTAMP_FIELD_NUMBER: _ClassVar[int] + DELETED_AT_FIELD_NUMBER: _ClassVar[int] + SEQ_ID_FIELD_NUMBER: _ClassVar[int] + HEAD_FIELD_NUMBER: _ClassVar[int] + CONTENT_FIELD_NUMBER: _ClassVar[int] + topic: str + from_user_id: str + timestamp: int + deleted_at: int + seq_id: int + head: _containers.ScalarMap[str, bytes] + content: bytes + def __init__(self, topic: _Optional[str] = ..., from_user_id: _Optional[str] = ..., timestamp: _Optional[int] = ..., deleted_at: _Optional[int] = ..., seq_id: _Optional[int] = ..., head: _Optional[_Mapping[str, bytes]] = ..., content: _Optional[bytes] = ...) -> None: ... + +class ServerPres(_message.Message): + __slots__ = ["topic", "src", "what", "user_agent", "seq_id", "del_id", "del_seq", "target_user_id", "actor_user_id", "acs"] + class What(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): + __slots__ = [] + X3: _ClassVar[ServerPres.What] + ON: _ClassVar[ServerPres.What] + OFF: _ClassVar[ServerPres.What] + UA: _ClassVar[ServerPres.What] + UPD: _ClassVar[ServerPres.What] + GONE: _ClassVar[ServerPres.What] + ACS: _ClassVar[ServerPres.What] + TERM: _ClassVar[ServerPres.What] + MSG: _ClassVar[ServerPres.What] + READ: _ClassVar[ServerPres.What] + RECV: _ClassVar[ServerPres.What] + DEL: _ClassVar[ServerPres.What] + TAGS: _ClassVar[ServerPres.What] + AUX: _ClassVar[ServerPres.What] + X3: ServerPres.What + ON: ServerPres.What + OFF: ServerPres.What + UA: ServerPres.What + UPD: ServerPres.What + GONE: ServerPres.What + ACS: ServerPres.What + TERM: ServerPres.What + MSG: ServerPres.What + READ: ServerPres.What + RECV: ServerPres.What + DEL: ServerPres.What + TAGS: ServerPres.What + AUX: ServerPres.What + TOPIC_FIELD_NUMBER: _ClassVar[int] + SRC_FIELD_NUMBER: _ClassVar[int] + WHAT_FIELD_NUMBER: _ClassVar[int] + USER_AGENT_FIELD_NUMBER: _ClassVar[int] + SEQ_ID_FIELD_NUMBER: _ClassVar[int] + DEL_ID_FIELD_NUMBER: _ClassVar[int] + DEL_SEQ_FIELD_NUMBER: _ClassVar[int] + TARGET_USER_ID_FIELD_NUMBER: _ClassVar[int] + ACTOR_USER_ID_FIELD_NUMBER: _ClassVar[int] + ACS_FIELD_NUMBER: _ClassVar[int] + topic: str + src: str + what: ServerPres.What + user_agent: str + seq_id: int + del_id: int + del_seq: _containers.RepeatedCompositeFieldContainer[SeqRange] + target_user_id: str + actor_user_id: str + acs: AccessMode + def __init__(self, topic: _Optional[str] = ..., src: _Optional[str] = ..., what: _Optional[_Union[ServerPres.What, str]] = ..., user_agent: _Optional[str] = ..., seq_id: _Optional[int] = ..., del_id: _Optional[int] = ..., del_seq: _Optional[_Iterable[_Union[SeqRange, _Mapping]]] = ..., target_user_id: _Optional[str] = ..., actor_user_id: _Optional[str] = ..., acs: _Optional[_Union[AccessMode, _Mapping]] = ...) -> None: ... + +class ServerMeta(_message.Message): + __slots__ = ["id", "topic", "desc", "sub", "tags", "cred", "aux"] + class AuxEntry(_message.Message): + __slots__ = ["key", "value"] + KEY_FIELD_NUMBER: _ClassVar[int] + VALUE_FIELD_NUMBER: _ClassVar[int] + key: str + value: bytes + def __init__(self, key: _Optional[str] = ..., value: _Optional[bytes] = ...) -> None: ... + ID_FIELD_NUMBER: _ClassVar[int] + TOPIC_FIELD_NUMBER: _ClassVar[int] + DESC_FIELD_NUMBER: _ClassVar[int] + SUB_FIELD_NUMBER: _ClassVar[int] + DEL_FIELD_NUMBER: _ClassVar[int] + TAGS_FIELD_NUMBER: _ClassVar[int] + CRED_FIELD_NUMBER: _ClassVar[int] + AUX_FIELD_NUMBER: _ClassVar[int] + id: str + topic: str + desc: TopicDesc + sub: _containers.RepeatedCompositeFieldContainer[TopicSub] + tags: _containers.RepeatedScalarFieldContainer[str] + cred: _containers.RepeatedCompositeFieldContainer[ServerCred] + aux: _containers.ScalarMap[str, bytes] + def __init__(self, id: _Optional[str] = ..., topic: _Optional[str] = ..., desc: _Optional[_Union[TopicDesc, _Mapping]] = ..., sub: _Optional[_Iterable[_Union[TopicSub, _Mapping]]] = ..., tags: _Optional[_Iterable[str]] = ..., cred: _Optional[_Iterable[_Union[ServerCred, _Mapping]]] = ..., aux: _Optional[_Mapping[str, bytes]] = ..., **kwargs) -> None: ... + +class ServerInfo(_message.Message): + __slots__ = ["topic", "from_user_id", "what", "seq_id", "src", "event", "payload"] + TOPIC_FIELD_NUMBER: _ClassVar[int] + FROM_USER_ID_FIELD_NUMBER: _ClassVar[int] + WHAT_FIELD_NUMBER: _ClassVar[int] + SEQ_ID_FIELD_NUMBER: _ClassVar[int] + SRC_FIELD_NUMBER: _ClassVar[int] + EVENT_FIELD_NUMBER: _ClassVar[int] + PAYLOAD_FIELD_NUMBER: _ClassVar[int] + topic: str + from_user_id: str + what: InfoNote + seq_id: int + src: str + event: CallEvent + payload: bytes + def __init__(self, topic: _Optional[str] = ..., from_user_id: _Optional[str] = ..., what: _Optional[_Union[InfoNote, str]] = ..., seq_id: _Optional[int] = ..., src: _Optional[str] = ..., event: _Optional[_Union[CallEvent, str]] = ..., payload: _Optional[bytes] = ...) -> None: ... + +class ServerMsg(_message.Message): + __slots__ = ["ctrl", "data", "pres", "meta", "info", "topic"] + CTRL_FIELD_NUMBER: _ClassVar[int] + DATA_FIELD_NUMBER: _ClassVar[int] + PRES_FIELD_NUMBER: _ClassVar[int] + META_FIELD_NUMBER: _ClassVar[int] + INFO_FIELD_NUMBER: _ClassVar[int] + TOPIC_FIELD_NUMBER: _ClassVar[int] + ctrl: ServerCtrl + data: ServerData + pres: ServerPres + meta: ServerMeta + info: ServerInfo + topic: str + def __init__(self, ctrl: _Optional[_Union[ServerCtrl, _Mapping]] = ..., data: _Optional[_Union[ServerData, _Mapping]] = ..., pres: _Optional[_Union[ServerPres, _Mapping]] = ..., meta: _Optional[_Union[ServerMeta, _Mapping]] = ..., info: _Optional[_Union[ServerInfo, _Mapping]] = ..., topic: _Optional[str] = ...) -> None: ... + +class ServerResp(_message.Message): + __slots__ = ["status", "srvmsg", "clmsg"] + STATUS_FIELD_NUMBER: _ClassVar[int] + SRVMSG_FIELD_NUMBER: _ClassVar[int] + CLMSG_FIELD_NUMBER: _ClassVar[int] + status: RespCode + srvmsg: ServerMsg + clmsg: ClientMsg + def __init__(self, status: _Optional[_Union[RespCode, str]] = ..., srvmsg: _Optional[_Union[ServerMsg, _Mapping]] = ..., clmsg: _Optional[_Union[ClientMsg, _Mapping]] = ...) -> None: ... + +class Session(_message.Message): + __slots__ = ["session_id", "user_id", "auth_level", "remote_addr", "user_agent", "device_id", "language"] + SESSION_ID_FIELD_NUMBER: _ClassVar[int] + USER_ID_FIELD_NUMBER: _ClassVar[int] + AUTH_LEVEL_FIELD_NUMBER: _ClassVar[int] + REMOTE_ADDR_FIELD_NUMBER: _ClassVar[int] + USER_AGENT_FIELD_NUMBER: _ClassVar[int] + DEVICE_ID_FIELD_NUMBER: _ClassVar[int] + LANGUAGE_FIELD_NUMBER: _ClassVar[int] + session_id: str + user_id: str + auth_level: AuthLevel + remote_addr: str + user_agent: str + device_id: str + language: str + def __init__(self, session_id: _Optional[str] = ..., user_id: _Optional[str] = ..., auth_level: _Optional[_Union[AuthLevel, str]] = ..., remote_addr: _Optional[str] = ..., user_agent: _Optional[str] = ..., device_id: _Optional[str] = ..., language: _Optional[str] = ...) -> None: ... + +class ClientReq(_message.Message): + __slots__ = ["msg", "sess"] + MSG_FIELD_NUMBER: _ClassVar[int] + SESS_FIELD_NUMBER: _ClassVar[int] + msg: ClientMsg + sess: Session + def __init__(self, msg: _Optional[_Union[ClientMsg, _Mapping]] = ..., sess: _Optional[_Union[Session, _Mapping]] = ...) -> None: ... + +class SearchQuery(_message.Message): + __slots__ = ["user_id", "query"] + USER_ID_FIELD_NUMBER: _ClassVar[int] + QUERY_FIELD_NUMBER: _ClassVar[int] + user_id: str + query: str + def __init__(self, user_id: _Optional[str] = ..., query: _Optional[str] = ...) -> None: ... + +class SearchFound(_message.Message): + __slots__ = ["status", "query", "result"] + STATUS_FIELD_NUMBER: _ClassVar[int] + QUERY_FIELD_NUMBER: _ClassVar[int] + RESULT_FIELD_NUMBER: _ClassVar[int] + status: RespCode + query: str + result: _containers.RepeatedCompositeFieldContainer[TopicSub] + def __init__(self, status: _Optional[_Union[RespCode, str]] = ..., query: _Optional[str] = ..., result: _Optional[_Iterable[_Union[TopicSub, _Mapping]]] = ...) -> None: ... + +class TopicEvent(_message.Message): + __slots__ = ["action", "name", "desc"] + ACTION_FIELD_NUMBER: _ClassVar[int] + NAME_FIELD_NUMBER: _ClassVar[int] + DESC_FIELD_NUMBER: _ClassVar[int] + action: Crud + name: str + desc: TopicDesc + def __init__(self, action: _Optional[_Union[Crud, str]] = ..., name: _Optional[str] = ..., desc: _Optional[_Union[TopicDesc, _Mapping]] = ...) -> None: ... + +class AccountEvent(_message.Message): + __slots__ = ["action", "user_id", "default_acs", "public", "tags"] + ACTION_FIELD_NUMBER: _ClassVar[int] + USER_ID_FIELD_NUMBER: _ClassVar[int] + DEFAULT_ACS_FIELD_NUMBER: _ClassVar[int] + PUBLIC_FIELD_NUMBER: _ClassVar[int] + TAGS_FIELD_NUMBER: _ClassVar[int] + action: Crud + user_id: str + default_acs: DefaultAcsMode + public: bytes + tags: _containers.RepeatedScalarFieldContainer[str] + def __init__(self, action: _Optional[_Union[Crud, str]] = ..., user_id: _Optional[str] = ..., default_acs: _Optional[_Union[DefaultAcsMode, _Mapping]] = ..., public: _Optional[bytes] = ..., tags: _Optional[_Iterable[str]] = ...) -> None: ... + +class SubscriptionEvent(_message.Message): + __slots__ = ["action", "topic", "user_id", "del_id", "read_id", "recv_id", "mode", "private"] + ACTION_FIELD_NUMBER: _ClassVar[int] + TOPIC_FIELD_NUMBER: _ClassVar[int] + USER_ID_FIELD_NUMBER: _ClassVar[int] + DEL_ID_FIELD_NUMBER: _ClassVar[int] + READ_ID_FIELD_NUMBER: _ClassVar[int] + RECV_ID_FIELD_NUMBER: _ClassVar[int] + MODE_FIELD_NUMBER: _ClassVar[int] + PRIVATE_FIELD_NUMBER: _ClassVar[int] + action: Crud + topic: str + user_id: str + del_id: int + read_id: int + recv_id: int + mode: AccessMode + private: bytes + def __init__(self, action: _Optional[_Union[Crud, str]] = ..., topic: _Optional[str] = ..., user_id: _Optional[str] = ..., del_id: _Optional[int] = ..., read_id: _Optional[int] = ..., recv_id: _Optional[int] = ..., mode: _Optional[_Union[AccessMode, _Mapping]] = ..., private: _Optional[bytes] = ...) -> None: ... + +class MessageEvent(_message.Message): + __slots__ = ["action", "msg"] + ACTION_FIELD_NUMBER: _ClassVar[int] + MSG_FIELD_NUMBER: _ClassVar[int] + action: Crud + msg: ServerData + def __init__(self, action: _Optional[_Union[Crud, str]] = ..., msg: _Optional[_Union[ServerData, _Mapping]] = ...) -> None: ... + +class Auth(_message.Message): + __slots__ = ["scheme", "secret"] + SCHEME_FIELD_NUMBER: _ClassVar[int] + SECRET_FIELD_NUMBER: _ClassVar[int] + scheme: str + secret: str + def __init__(self, scheme: _Optional[str] = ..., secret: _Optional[str] = ...) -> None: ... + +class FileMeta(_message.Message): + __slots__ = ["name", "mime_type", "etag", "size"] + NAME_FIELD_NUMBER: _ClassVar[int] + MIME_TYPE_FIELD_NUMBER: _ClassVar[int] + ETAG_FIELD_NUMBER: _ClassVar[int] + SIZE_FIELD_NUMBER: _ClassVar[int] + name: str + mime_type: str + etag: str + size: int + def __init__(self, name: _Optional[str] = ..., mime_type: _Optional[str] = ..., etag: _Optional[str] = ..., size: _Optional[int] = ...) -> None: ... + +class FileUpReq(_message.Message): + __slots__ = ["id", "auth", "topic", "meta", "content"] + ID_FIELD_NUMBER: _ClassVar[int] + AUTH_FIELD_NUMBER: _ClassVar[int] + TOPIC_FIELD_NUMBER: _ClassVar[int] + META_FIELD_NUMBER: _ClassVar[int] + CONTENT_FIELD_NUMBER: _ClassVar[int] + id: str + auth: Auth + topic: str + meta: FileMeta + content: bytes + def __init__(self, id: _Optional[str] = ..., auth: _Optional[_Union[Auth, _Mapping]] = ..., topic: _Optional[str] = ..., meta: _Optional[_Union[FileMeta, _Mapping]] = ..., content: _Optional[bytes] = ...) -> None: ... + +class FileUpResp(_message.Message): + __slots__ = ["id", "code", "text", "meta", "redir_url"] + ID_FIELD_NUMBER: _ClassVar[int] + CODE_FIELD_NUMBER: _ClassVar[int] + TEXT_FIELD_NUMBER: _ClassVar[int] + META_FIELD_NUMBER: _ClassVar[int] + REDIR_URL_FIELD_NUMBER: _ClassVar[int] + id: str + code: int + text: str + meta: FileMeta + redir_url: str + def __init__(self, id: _Optional[str] = ..., code: _Optional[int] = ..., text: _Optional[str] = ..., meta: _Optional[_Union[FileMeta, _Mapping]] = ..., redir_url: _Optional[str] = ...) -> None: ... + +class FileDownReq(_message.Message): + __slots__ = ["id", "auth", "uri", "if_modified"] + ID_FIELD_NUMBER: _ClassVar[int] + AUTH_FIELD_NUMBER: _ClassVar[int] + URI_FIELD_NUMBER: _ClassVar[int] + IF_MODIFIED_FIELD_NUMBER: _ClassVar[int] + id: str + auth: Auth + uri: str + if_modified: str + def __init__(self, id: _Optional[str] = ..., auth: _Optional[_Union[Auth, _Mapping]] = ..., uri: _Optional[str] = ..., if_modified: _Optional[str] = ...) -> None: ... + +class FileDownResp(_message.Message): + __slots__ = ["id", "code", "text", "meta", "redir_url", "content"] + ID_FIELD_NUMBER: _ClassVar[int] + CODE_FIELD_NUMBER: _ClassVar[int] + TEXT_FIELD_NUMBER: _ClassVar[int] + META_FIELD_NUMBER: _ClassVar[int] + REDIR_URL_FIELD_NUMBER: _ClassVar[int] + CONTENT_FIELD_NUMBER: _ClassVar[int] + id: str + code: int + text: str + meta: FileMeta + redir_url: str + content: bytes + def __init__(self, id: _Optional[str] = ..., code: _Optional[int] = ..., text: _Optional[str] = ..., meta: _Optional[_Union[FileMeta, _Mapping]] = ..., redir_url: _Optional[str] = ..., content: _Optional[bytes] = ...) -> None: ... diff --git a/py_grpc/tinode_grpc/model_pb2_grpc.py b/py_grpc/tinode_grpc/model_pb2_grpc.py index e69de29..73976a8 100644 --- a/py_grpc/tinode_grpc/model_pb2_grpc.py +++ b/py_grpc/tinode_grpc/model_pb2_grpc.py @@ -0,0 +1,378 @@ +# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! +"""Client and server classes corresponding to protobuf-defined services.""" +import grpc + +from . import model_pb2 as model__pb2 + + +class NodeStub(object): + """This is the methods that needs to be implemented by a gRPC client. + """ + + def __init__(self, channel): + """Constructor. + + Args: + channel: A grpc.Channel. + """ + self.MessageLoop = channel.stream_stream( + '/pbx.Node/MessageLoop', + request_serializer=model__pb2.ClientMsg.SerializeToString, + response_deserializer=model__pb2.ServerMsg.FromString, + ) + self.LargeFileReceive = channel.stream_unary( + '/pbx.Node/LargeFileReceive', + request_serializer=model__pb2.FileUpReq.SerializeToString, + response_deserializer=model__pb2.FileUpResp.FromString, + ) + self.LargeFileServe = channel.unary_stream( + '/pbx.Node/LargeFileServe', + request_serializer=model__pb2.FileDownReq.SerializeToString, + response_deserializer=model__pb2.FileDownResp.FromString, + ) + + +class NodeServicer(object): + """This is the methods that needs to be implemented by a gRPC client. + """ + + def MessageLoop(self, request_iterator, context): + """Client sends a stream of ClientMsg, server responds with a stream of ServerMsg + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def LargeFileReceive(self, request_iterator, context): + """Large file upload: a request with a stream of chunks. + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def LargeFileServe(self, request, context): + """Large file file download: a response with a stream of chunks. + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + +def add_NodeServicer_to_server(servicer, server): + rpc_method_handlers = { + 'MessageLoop': grpc.stream_stream_rpc_method_handler( + servicer.MessageLoop, + request_deserializer=model__pb2.ClientMsg.FromString, + response_serializer=model__pb2.ServerMsg.SerializeToString, + ), + 'LargeFileReceive': grpc.stream_unary_rpc_method_handler( + servicer.LargeFileReceive, + request_deserializer=model__pb2.FileUpReq.FromString, + response_serializer=model__pb2.FileUpResp.SerializeToString, + ), + 'LargeFileServe': grpc.unary_stream_rpc_method_handler( + servicer.LargeFileServe, + request_deserializer=model__pb2.FileDownReq.FromString, + response_serializer=model__pb2.FileDownResp.SerializeToString, + ), + } + generic_handler = grpc.method_handlers_generic_handler( + 'pbx.Node', rpc_method_handlers) + server.add_generic_rpc_handlers((generic_handler,)) + + + # This class is part of an EXPERIMENTAL API. +class Node(object): + """This is the methods that needs to be implemented by a gRPC client. + """ + + @staticmethod + def MessageLoop(request_iterator, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.stream_stream(request_iterator, target, '/pbx.Node/MessageLoop', + model__pb2.ClientMsg.SerializeToString, + model__pb2.ServerMsg.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def LargeFileReceive(request_iterator, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.stream_unary(request_iterator, target, '/pbx.Node/LargeFileReceive', + model__pb2.FileUpReq.SerializeToString, + model__pb2.FileUpResp.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def LargeFileServe(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_stream(request, target, '/pbx.Node/LargeFileServe', + model__pb2.FileDownReq.SerializeToString, + model__pb2.FileDownResp.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + +class PluginStub(object): + """Plugin interface. + """ + + def __init__(self, channel): + """Constructor. + + Args: + channel: A grpc.Channel. + """ + self.FireHose = channel.unary_unary( + '/pbx.Plugin/FireHose', + request_serializer=model__pb2.ClientReq.SerializeToString, + response_deserializer=model__pb2.ServerResp.FromString, + ) + self.Find = channel.unary_unary( + '/pbx.Plugin/Find', + request_serializer=model__pb2.SearchQuery.SerializeToString, + response_deserializer=model__pb2.SearchFound.FromString, + ) + self.Account = channel.unary_unary( + '/pbx.Plugin/Account', + request_serializer=model__pb2.AccountEvent.SerializeToString, + response_deserializer=model__pb2.Unused.FromString, + ) + self.Topic = channel.unary_unary( + '/pbx.Plugin/Topic', + request_serializer=model__pb2.TopicEvent.SerializeToString, + response_deserializer=model__pb2.Unused.FromString, + ) + self.Subscription = channel.unary_unary( + '/pbx.Plugin/Subscription', + request_serializer=model__pb2.SubscriptionEvent.SerializeToString, + response_deserializer=model__pb2.Unused.FromString, + ) + self.Message = channel.unary_unary( + '/pbx.Plugin/Message', + request_serializer=model__pb2.MessageEvent.SerializeToString, + response_deserializer=model__pb2.Unused.FromString, + ) + + +class PluginServicer(object): + """Plugin interface. + """ + + def FireHose(self, request, context): + """This plugin method is called by Tinode server for every message received from the clients. The + method returns a ServerResp message. ServerResp.status tells Tinode server what to do next. + See possible values for ServerResp.status in RespCode below. + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def Find(self, request, context): + """An alteranative user and topic discovery mechanism. + A search request issued on a 'fnd' topic. This method is called to generate an alternative result set. + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def Account(self, request, context): + """The following methods are for the Tinode server to report individual events. + + Account created, updated or deleted + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def Topic(self, request, context): + """Topic created, updated [or deleted -- not supported yet] + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def Subscription(self, request, context): + """Subscription created, updated or deleted + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def Message(self, request, context): + """Message published or deleted + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + +def add_PluginServicer_to_server(servicer, server): + rpc_method_handlers = { + 'FireHose': grpc.unary_unary_rpc_method_handler( + servicer.FireHose, + request_deserializer=model__pb2.ClientReq.FromString, + response_serializer=model__pb2.ServerResp.SerializeToString, + ), + 'Find': grpc.unary_unary_rpc_method_handler( + servicer.Find, + request_deserializer=model__pb2.SearchQuery.FromString, + response_serializer=model__pb2.SearchFound.SerializeToString, + ), + 'Account': grpc.unary_unary_rpc_method_handler( + servicer.Account, + request_deserializer=model__pb2.AccountEvent.FromString, + response_serializer=model__pb2.Unused.SerializeToString, + ), + 'Topic': grpc.unary_unary_rpc_method_handler( + servicer.Topic, + request_deserializer=model__pb2.TopicEvent.FromString, + response_serializer=model__pb2.Unused.SerializeToString, + ), + 'Subscription': grpc.unary_unary_rpc_method_handler( + servicer.Subscription, + request_deserializer=model__pb2.SubscriptionEvent.FromString, + response_serializer=model__pb2.Unused.SerializeToString, + ), + 'Message': grpc.unary_unary_rpc_method_handler( + servicer.Message, + request_deserializer=model__pb2.MessageEvent.FromString, + response_serializer=model__pb2.Unused.SerializeToString, + ), + } + generic_handler = grpc.method_handlers_generic_handler( + 'pbx.Plugin', rpc_method_handlers) + server.add_generic_rpc_handlers((generic_handler,)) + + + # This class is part of an EXPERIMENTAL API. +class Plugin(object): + """Plugin interface. + """ + + @staticmethod + def FireHose(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/pbx.Plugin/FireHose', + model__pb2.ClientReq.SerializeToString, + model__pb2.ServerResp.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def Find(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/pbx.Plugin/Find', + model__pb2.SearchQuery.SerializeToString, + model__pb2.SearchFound.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def Account(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/pbx.Plugin/Account', + model__pb2.AccountEvent.SerializeToString, + model__pb2.Unused.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def Topic(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/pbx.Plugin/Topic', + model__pb2.TopicEvent.SerializeToString, + model__pb2.Unused.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def Subscription(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/pbx.Plugin/Subscription', + model__pb2.SubscriptionEvent.SerializeToString, + model__pb2.Unused.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def Message(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/pbx.Plugin/Message', + model__pb2.MessageEvent.SerializeToString, + model__pb2.Unused.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata)