commit 6696cd31521b1d94d0a8346f72f0fb16cf996a2a Author: sbouaram Date: Fri Oct 20 13:41:39 2023 +0200 first commit diff --git a/config.go b/config.go new file mode 100644 index 0000000..3d9e3c3 --- /dev/null +++ b/config.go @@ -0,0 +1,16 @@ +package main + +import ( + "github.com/spf13/viper" + "strings" +) + +func ReadConfig() (*viper.Viper, error) { + v := viper.New() + v.SetConfigName("config") + v.AddConfigPath(".") + v.SetEnvKeyReplacer(strings.NewReplacer(".", "_")) + v.AutomaticEnv() + err := v.ReadInConfig() + return v, err +} diff --git a/config.yaml b/config.yaml new file mode 100644 index 0000000..b3cbca7 --- /dev/null +++ b/config.yaml @@ -0,0 +1,36 @@ +name: COOPGO Solidarity Service + +dev_env: true + +storage: + db: + type: psql + psql: + host: localhost + dbname: coopgo_platform + user: postgres + password: postgres + sslmode: disable + port: 5432 + schema: solidarity_service + tables: + drivers: drivers + passengers: passengers + bookings: bookings + +services: + grpc: + enable: true + port: 8089 + solidarity-api: + enable: true + address: 0.0.0.0:9999 + +routing: + type: valhalla + valhalla: + base_url: https://valhalla.coopgo.io/ + + + + diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..1a80b25 --- /dev/null +++ b/go.mod @@ -0,0 +1,44 @@ +module solidarity-service + +go 1.20 + +require ( + git.coopgo.io/coopgo-platform/routing-service v0.0.0-20230403183358-4d30329f06be + github.com/golang/protobuf v1.5.3 + github.com/google/uuid v1.3.1 + github.com/lib/pq v1.10.9 + github.com/paulmach/orb v0.10.0 + github.com/rs/zerolog v1.31.0 + github.com/spf13/viper v1.17.0 + google.golang.org/grpc v1.58.3 + google.golang.org/protobuf v1.31.0 +) + +require ( + github.com/fsnotify/fsnotify v1.6.0 // indirect + github.com/gorilla/mux v1.8.0 // indirect + github.com/hashicorp/hcl v1.0.0 // indirect + github.com/magiconair/properties v1.8.7 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.19 // indirect + github.com/mitchellh/mapstructure v1.5.0 // indirect + github.com/pelletier/go-toml/v2 v2.1.0 // indirect + github.com/sagikazarmark/locafero v0.3.0 // indirect + github.com/sagikazarmark/slog-shim v0.1.0 // indirect + github.com/sourcegraph/conc v0.3.0 // indirect + github.com/spf13/afero v1.10.0 // indirect + github.com/spf13/cast v1.5.1 // indirect + github.com/spf13/pflag v1.0.5 // indirect + github.com/subosito/gotenv v1.6.0 // indirect + github.com/twpayne/go-polyline v1.1.1 // indirect + go.mongodb.org/mongo-driver v1.11.4 // indirect + go.uber.org/atomic v1.9.0 // indirect + go.uber.org/multierr v1.9.0 // indirect + golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect + golang.org/x/net v0.15.0 // indirect + golang.org/x/sys v0.12.0 // indirect + golang.org/x/text v0.13.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20230920204549-e6e6cdab5c13 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..3fd5f27 --- /dev/null +++ b/go.sum @@ -0,0 +1,552 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= +cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.44.3/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= +cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= +cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= +cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= +cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= +cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= +cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= +cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= +cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= +cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= +cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= +cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= +cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= +cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= +cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= +cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= +cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= +cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= +cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= +cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= +cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= +cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= +cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= +cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= +cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= +cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= +cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= +cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= +cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +git.coopgo.io/coopgo-platform/routing-service v0.0.0-20230403183358-4d30329f06be h1:VIzWX8NftKzQX1clunLaMf79Ut1dygcCc/ZLV/iWOaY= +git.coopgo.io/coopgo-platform/routing-service v0.0.0-20230403183358-4d30329f06be/go.mod h1:Nh7o15LlV0OuO9zxvJIs9FlelpeAaLYkXtFdgIkFrgg= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +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/dvyukov/go-fuzz v0.0.0-20200318091601-be3528f3a813/go.mod h1:11Gm+ccJnvAhCNLlf5+cS9KjtbaD5I5zaZpFMsTHWTw= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= +github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= +github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= +github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= +github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= +github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= +github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +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/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= +github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= +github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= +github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= +github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= +github.com/paulmach/orb v0.10.0 h1:guVYVqzxHE/CQ1KpfGO077TR0ATHSNjp4s6XGLn3W9s= +github.com/paulmach/orb v0.10.0/go.mod h1:5mULz1xQfs3bmQm63QEJA6lNGujuRafwA5S/EnuLaLU= +github.com/paulmach/protoscan v0.2.1/go.mod h1:SpcSwydNLrxUGSDvXvO0P7g7AuhJ7lcKfDlhJCDw2gY= +github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4= +github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= +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/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= +github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= +github.com/rs/zerolog v1.31.0 h1:FcTR3NnLWW+NnTwwhFWiJSZr4ECLpqCm6QsEnyvbV4A= +github.com/rs/zerolog v1.31.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= +github.com/sagikazarmark/locafero v0.3.0 h1:zT7VEGWC2DTflmccN/5T1etyKvxSxpHsjb9cJvm4SvQ= +github.com/sagikazarmark/locafero v0.3.0/go.mod h1:w+v7UsPNFwzF1cHuOajOOzoq4U7v/ig1mpRjqV+Bu1U= +github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= +github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= +github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= +github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= +github.com/spf13/afero v1.10.0 h1:EaGW2JJh15aKOejeuJ+wpFSHnbd7GE6Wvp3TsNhb6LY= +github.com/spf13/afero v1.10.0/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ= +github.com/spf13/cast v1.5.1 h1:R+kOtfhWQE6TVQzY+4D7wJLBgkdVasCEFxSUBYBYIlA= +github.com/spf13/cast v1.5.1/go.mod h1:b9PdjNptOpzXr7Rq1q9gJML/2cdGQAo69NKzQ10KN48= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/viper v1.17.0 h1:I5txKw7MJasPL/BrfkbA0Jyo/oELqVmux4pR/UxOMfI= +github.com/spf13/viper v1.17.0/go.mod h1:BmMMMLQXSbcHK6KAOiFLz0l5JHrU89OdIRHvsk0+yVI= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.3.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/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= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +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.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= +github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= +github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4= +github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= +github.com/twpayne/go-polyline v1.1.1 h1:/tSF1BR7rN4HWj4XKqvRUNrCiYVMCvywxTFVofvDV0w= +github.com/twpayne/go-polyline v1.1.1/go.mod h1:ybd9IWWivW/rlXPXuuckeKUyF3yrIim+iqA7kSl4NFY= +github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= +github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g= +github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8= +github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= +github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +go.mongodb.org/mongo-driver v1.11.4 h1:4ayjakA013OdpGyL2K3ZqylTac/rMjrJOMZ1EHizXas= +go.mongodb.org/mongo-driver v1.11.4/go.mod h1:PTSz5yu21bkT/wXpkS7WR5f0ddqw5quethTUn9WM+2g= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= +go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= +go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI= +go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= +golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= +golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= +golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= +golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= +golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g= +golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k= +golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= +golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8= +golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/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-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o= +golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= +golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +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= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= +google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= +google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= +google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= +google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= +google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= +google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= +google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= +google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230920204549-e6e6cdab5c13 h1:N3bU/SQDCDyD6R528GJ/PwW9KjYcJA3dgyH+MovAkIM= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230920204549-e6e6cdab5c13/go.mod h1:KSqppvjFjtoCI+KGd4PELB0qLNxdJHRGqRI09mB6pQA= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= +google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= +google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= +google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.58.3 h1:BjnpXut1btbtgN/6sp+brB2Kbm2LjNXnidYujAVbSoQ= +google.golang.org/grpc v1.58.3/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +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.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= +google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= +gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/yaml.v2 v2.2.2/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.0-20210107192922-496545a6307b/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= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= diff --git a/handler/handler.go b/handler/handler.go new file mode 100644 index 0000000..e54a7c8 --- /dev/null +++ b/handler/handler.go @@ -0,0 +1,21 @@ +package handler + +import ( + "git.coopgo.io/coopgo-platform/routing-service" + "github.com/spf13/viper" + "solidarity-service/storage" +) + +type SolidarityServiceHandler struct { + Config *viper.Viper + Routing routing.RoutingService + Storage storage.Storage +} + +func NewSolidarityServiceHandler(cfg *viper.Viper, routing routing.RoutingService, storage storage.Storage) (*SolidarityServiceHandler, error) { + return &SolidarityServiceHandler{ + Config: cfg, + Routing: routing, + Storage: storage, + }, nil +} diff --git a/handler/haversine_distance.go b/handler/haversine_distance.go new file mode 100644 index 0000000..adeeedd --- /dev/null +++ b/handler/haversine_distance.go @@ -0,0 +1,14 @@ +package handler + +import ( + "github.com/paulmach/orb" + "github.com/paulmach/orb/geojson" + "solidarity-service/servers/utils" +) + +func (handler *SolidarityServiceHandler) CalculateDistanceBetweenFeatures(feature1, feature2 *geojson.Feature) int64 { + coords1 := feature1.Geometry.(orb.Point) + coords2 := feature2.Geometry.(orb.Point) + distance := utils.Haversine(coords1[1], coords1[0], coords2[1], coords2[0]) + return int64(distance) +} diff --git a/handler/routing.go b/handler/routing.go new file mode 100644 index 0000000..2aa1a36 --- /dev/null +++ b/handler/routing.go @@ -0,0 +1,23 @@ +package handler + +import ( + "github.com/paulmach/orb" + "time" +) + +type RoutingService interface { + Route(locations []orb.Point) (route *Route, err error) +} +type Route struct { + Summary RouteSummary + Legs []RouteLeg +} + +type RouteSummary struct { + Polyline string +} +type RouteLeg struct { + Distance float64 + Duration time.Duration + Polyline string +} diff --git a/handler/services.go b/handler/services.go new file mode 100644 index 0000000..9b46fd5 --- /dev/null +++ b/handler/services.go @@ -0,0 +1,98 @@ +package handler + +import ( + "context" + "github.com/paulmach/orb/geojson" + "solidarity-service/internal" +) + +func (s *SolidarityServiceHandler) GetPassenger(ctx context.Context, id string) (passenger internal.Passenger, err error) { + passenger, err = s.Storage.GetPassenger(id) + if err != nil { + return internal.Passenger{}, err + } + return passenger, nil +} + +func (s *SolidarityServiceHandler) GetDriver(ctx context.Context, id string) (driver internal.Driver, err error) { + driver, err = s.Storage.GetDriver(id) + if err != nil { + return internal.Driver{}, err + } + return driver, nil +} + +func (s *SolidarityServiceHandler) SetDriverAvailabilities(ctx context.Context, driver internal.Driver) (err error) { + driver.Driver.Operator = "internal-grpc" + err = s.Storage.CreateDriver(driver) + if err != nil { + return err + } + return nil +} + +func (s *SolidarityServiceHandler) SetPassengerTrip(ctx context.Context, passenger internal.Passenger) (err error) { + passenger.Passenger.Operator = "internal-grpc" + err = s.Storage.CreatePassenger(passenger) + if err != nil { + return err + } + return nil +} + +func (s *SolidarityServiceHandler) CreateBooking(ctx context.Context, bookingRequest internal.BookingRequest) (passenger internal.Passenger, driver internal.Driver, err error) { + bookingRequest.Operator = "internal-grpc" + err = s.Storage.CreateBooking(bookingRequest) + if err != nil { + return internal.Passenger{}, internal.Driver{}, err + } + passenger, err = s.Storage.GetPassenger(bookingRequest.Passenger_id) + if err != nil { + return internal.Passenger{}, internal.Driver{}, err + } + driver, err = s.Storage.GetDriver(bookingRequest.Driver_id) + if err != nil { + return internal.Passenger{}, internal.Driver{}, err + } + return passenger, driver, nil +} + +func (s *SolidarityServiceHandler) UpdateBooking(ctx context.Context, bookingId string, status internal.BookingStatus) (err error) { + err = s.Storage.UpdateBookingStatus(bookingId, status) + if err != nil { + return err + } + return nil +} + +func (s *SolidarityServiceHandler) GetBooking(ctx context.Context, bookingId string) (booking internal.Booking, passenger internal.Passenger, driver internal.Driver, err error) { + booking, err = s.Storage.GetBooking(bookingId) + if err != nil { + return internal.Booking{}, internal.Passenger{}, internal.Driver{}, err + } + passenger, err = s.Storage.GetPassenger(booking.Passenger.ID) + if err != nil { + return internal.Booking{}, internal.Passenger{}, internal.Driver{}, err + } + driver, err = s.Storage.GetDriver(booking.Driver.ID) + if err != nil { + return internal.Booking{}, internal.Passenger{}, internal.Driver{}, err + } + return booking, passenger, driver, nil +} + +func (s *SolidarityServiceHandler) GetBookingsByStatus(ctx context.Context, status string, filterType string, id string) (bookings []internal.Booking, err error) { + bookings, err = s.Storage.FilterUserBookingsByStatus(filterType, internal.BookingStatus(status), id) + if err != nil { + return nil, err + } + return bookings, nil +} + +func (s *SolidarityServiceHandler) GetDriverJourneys(ctx context.Context, departure_route *geojson.Feature, departure_date int64) (drivers []internal.Driver, err error) { + drivers, err = s.Storage.DriverJourneys(departure_route, departure_date) + if err != nil { + return nil, err + } + return drivers, nil +} diff --git a/handler/trip_duration.go b/handler/trip_duration.go new file mode 100644 index 0000000..e461ffc --- /dev/null +++ b/handler/trip_duration.go @@ -0,0 +1,52 @@ +package handler + +import ( + "encoding/json" + "errors" + "fmt" + "github.com/paulmach/orb/geojson" + "net/http" +) + +func (handler *SolidarityServiceHandler) CalculateDurationBetweenFeatures(feature1, feature2 *geojson.Feature) (int64, error) { + coords1 := feature1.Point() + coords2 := feature2.Point() + routing_base_url := handler.Config.GetString("routing.valhalla.base_url") + url := fmt.Sprintf("%sroute?json=%s", routing_base_url, createJSONROUTERequest(coords1.X(), coords1.Y(), coords2.X(), coords2.Y())) + response, err := http.Get(url) + if err != nil { + return 0, errors.New("routing service error") + } + var result map[string]interface{} + decoder := json.NewDecoder(response.Body) + if err := decoder.Decode(&result); err != nil { + return 0, errors.New("routing response decoding error") + } + trip, ok := result["trip"].(map[string]interface{}) + if !ok { + return 0, errors.New("routing response decoding error") + } + summary, ok := trip["summary"].(map[string]interface{}) + if !ok { + return 0, errors.New("routing response decoding error") + } + duration, ok := summary["time"].(float64) + if !ok { + return 0, errors.New("routing response decoding error") + } + + return int64(duration), nil +} + +func createJSONROUTERequest(lat1, lon1, lat2, lon2 float64) string { + request := map[string]interface{}{ + "locations": []map[string]float64{ + {"lat": lat1, "lon": lon1}, + {"lat": lat2, "lon": lon2}, + }, + "costing": "auto", + } + + jsonRequest, _ := json.Marshal(request) + return string(jsonRequest) +} diff --git a/internal/models.go b/internal/models.go new file mode 100644 index 0000000..7b800a0 --- /dev/null +++ b/internal/models.go @@ -0,0 +1,95 @@ +package internal + +import ( + "github.com/paulmach/orb/geojson" +) + +const ( + Punctual AvailabilitiesType = "PUNCTUAL" + Regular AvailabilitiesType = "REGULAR" + BookingStatusINITIATED BookingStatus = "INITIATED" + BookingStatusWAITINGPASSENGERCONFIRMATION BookingStatus = "WAITING_PASSENGER_CONFIRMATION" + BookingStatusWAITINGDRIVERCONFIRMATION BookingStatus = "WAITING_DRIVER_CONFIRMATION" + BookingStatusCONFIRMED BookingStatus = "CONFIRMED" + BookingStatusCANCELLED BookingStatus = "CANCELLED" + BookingStatusCOMPLETEDPENDINGVALIDATION BookingStatus = "COMPLETED_PENDING_VALIDATION" + BookingStatusVALIDATED BookingStatus = "VALIDATED" +) + +type Passenger struct { + Passenger_departure_address *geojson.Feature + Passenger_destination_address *geojson.Feature + Passenger_pickup_date int64 + Passenger User + Preferences Preferences +} + +type Driver struct { + Driver_departure_address *geojson.Feature + Radius int32 + Driver User + Preferences Preferences + AvailabilitiesType AvailabilitiesType + RegularAvailabilities []RegularAvailabilities `json:"availabilities,omitempty"` + PunctualAvailabilities []PunctualAvailabilities `json:"availabilities,omitempty"` + Car Car `json:"car,omitempty"` +} + +type Car struct { + Model string `json:"model,omitempty"` + Brand string `json:"brand,omitempty"` +} + +type AvailabilitiesType string +type BookingStatus string + +type User struct { + ID string `json:"id"` + Operator string `json:"operator"` + Alias string `json:"alias"` + FirstName string `json:"first_name,omitempty"` + LastName string `json:"last_name,omitempty"` + Grade int64 `json:"grade,omitempty"` + Picture string `json:"picture,omitempty"` + Gender string `json:"gender,omitempty"` + VerifiedIdentity bool `json:"verified_identity,omitempty"` +} + +type Preferences struct { + Smoking bool `json:"smoking,omitempty"` + Animals bool `json:"animals,omitempty"` + Music bool `json:"music,omitempty"` + Is_talker bool `json:"is_talker,omitempty"` + Luggage_size int64 `json:"luggage_size,omitempty"` +} + +type BookingRequest struct { + ID string `json:"id"` + Passenger_id string `json:"passenger_id"` + Driver_id string `json:"driver_id"` + Status BookingStatus `json:"booking_status"` + Details map[string]any `json:"booking_details"` + Operator string `json:"operator"` +} + +type Booking struct { + ID string `json:"id"` + Passenger User `json:"passenger"` + Driver User `json:"driver"` + PassengerPickupAddress *geojson.Feature + PassengerDropAddress *geojson.Feature + Status BookingStatus `json:"booking_status"` + Details map[string]any `json:"booking_details"` +} + +type RegularAvailabilities struct { + DayOfWeek string `json:"dayOfWeek"` + StartTime string `json:"startTime"` + EndTime string `json:"endTime"` +} + +type PunctualAvailabilities struct { + Date int64 `json:"date"` + StartTime string `json:"startTime"` + EndTime string `json:"endTime"` +} diff --git a/interoperability/solidarity-api/oas.yaml b/interoperability/solidarity-api/oas.yaml new file mode 100644 index 0000000..90fe3cb --- /dev/null +++ b/interoperability/solidarity-api/oas.yaml @@ -0,0 +1,1227 @@ +openapi: 3.0.0 +info: + title: Solidarity Mobility API + version: 1.0.0 +servers: + # Added by API Auto Mocking Plugin + - description: SwaggerHub API Auto Mocking + url: https://virtserver.swaggerhub.com/salimbouaram12/SOLIDARITYCOOPGO/1.0.0 + - url: / +paths: + /passenger: + post: + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/PassengerTripRequest' + required: true + responses: + "201": + description: Trip Request Created + "400": + content: + application/json: + schema: + $ref: '#/components/schemas/_passenger_post_400_response' + description: Bad Request. See error message. + "401": + description: Unauthorized. You must authenticate. + "429": + description: Too Many Requests. Please slow down. + headers: + Retry-After: + explode: false + schema: + type: integer + style: simple + "500": + description: Internal Server Error. Please try again later. + summary: Create a Passenger Trip Request + tags: + - Passenger Trip Request + /driver_journeys: + get: + description: Route used to retrieve a collection of punctual planned outward + driver journeys matching the provided criteria. + operationId: getDriverJourneys + parameters: + - description: Latitude of searched departure point. + explode: true + in: query + name: departureLat + required: true + schema: + type: number + style: form + - description: Longitude of searched departure point. + explode: true + in: query + name: departureLng + required: true + schema: + type: number + style: form + - description: Departure datetime using a UNIX UTC timestamp in seconds. + explode: true + in: query + name: departureDate + required: true + schema: + type: integer + style: form + - description: The operator's FQDN. + explode: true + in: query + name: operator + required: true + schema: + type: string + style: form + responses: + "200": + content: + application/json: + schema: + items: + oneOf: + - $ref: '#/components/schemas/PunctualDriverJourney' + - $ref: '#/components/schemas/RegularDriverJourney' + title: DriverJourneys + type: array + description: Ok. Request processed successfully. + "400": + content: + application/json: + schema: + $ref: '#/components/schemas/_passenger_post_400_response' + description: Bad Request. See error message. + "401": + description: Unauthorized. You must authenticate. + "429": + description: Too Many Requests. Please slow down. + headers: + Retry-After: + explode: false + schema: + type: integer + style: simple + "500": + description: Internal Server Error. Please try again later. + summary: Search for matching punctual planned outward driver journeys. + tags: + - Search + /driver_regular_availabilities: + post: + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/DriverRegularAvailabilitiesRequest' + required: true + responses: + "201": + description: Regular driver availabilities set successfully. + "400": + content: + application/json: + schema: + $ref: '#/components/schemas/_passenger_post_400_response' + description: Bad Request. See error message. + "429": + description: Too Many Requests. Please slow down. + headers: + Retry-After: + explode: false + schema: + type: integer + style: simple + "500": + description: Internal Server Error. Please try again later. + summary: Set Regular Driver Availabilities + tags: + - Driver Availability and Schedule + /driver_punctual_availabilities: + post: + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/DriverPunctualAvailabilitiesRequest' + required: true + responses: + "201": + description: Punctual driver availabilities set successfully. + "400": + content: + application/json: + schema: + $ref: '#/components/schemas/_passenger_post_400_response' + description: Bad Request. See error message. + "429": + description: Too Many Requests. Please slow down. + headers: + Retry-After: + explode: false + schema: + type: integer + style: simple + "500": + description: Internal Server Error. Please try again later. + summary: Set Punctual Driver Availabilities + tags: + - Driver Availability and Schedule + /messages: + post: + description: Route used to allow a user to connect back to the owner of a retrieved + journey through a texte message. + operationId: postConnections + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/postConnections_request' + responses: + "201": + description: Successful operation. + "404": + description: The targeted journey or user no more exists. + "400": + content: + application/json: + schema: + $ref: '#/components/schemas/_passenger_post_400_response' + description: Bad Request. See error message. + "401": + description: Unauthorized. You must authenticate. + "429": + description: Too Many Requests. Please slow down. + headers: + Retry-After: + explode: false + schema: + type: integer + style: simple + "500": + description: Internal Server Error. Please try again later. + summary: Send a message to the owner of a retrieved journey. + tags: + - Interact + /bookings: + get: + description: "Route used to filter and retrieve bookings based on the specified\ + \ status, type, and ID." + operationId: filterBookingsByStatus + parameters: + - description: The operator's FQDN. + explode: true + in: query + name: operator + required: true + schema: + type: string + style: form + - description: The status of the bookings to filter. + explode: true + in: query + name: status + required: true + schema: + enum: + - WAITING_DRIVER_CONFIRMATION + - WAITING_PASSENGER_CONFIRMATION + - CONFIRMED + - CANCELLED + - COMPLETED_PENDING_VALIDATION + - VALIDATED + type: string + style: form + - explode: true + in: query + name: filterType + required: true + schema: + enum: + - driver + - passenger + type: string + style: form + - description: The ID (UUID) used. + explode: true + in: query + name: Id + required: true + schema: + format: uuid + type: string + style: form + responses: + "200": + content: + application/json: + schema: + items: + $ref: '#/components/schemas/Booking' + type: array + description: "Successful operation. Bookings matching the specified status,\ + \ type, and ID." + "400": + content: + application/json: + schema: + $ref: '#/components/schemas/_passenger_post_400_response' + description: Bad Request. See error message. + "401": + description: Unauthorized. You must authenticate. + "429": + description: Too Many Requests. Please slow down. + headers: + Retry-After: + explode: false + schema: + type: integer + style: simple + "500": + description: Internal Server Error. Please try again later. + "404": + content: + application/json: + schema: + $ref: '#/components/schemas/_passenger_post_400_response' + description: "No bookings found for the specified status, type, and ID." + summary: "Filter and retrieve bookings by status, type, and ID." + tags: + - Bookings Filter + post: + description: "Route used to synchronize a Booking request initiated by a platform\ + \ to the second platform involved in the shared punctual outward journey.\ + \ While posting a new Booking, its status must always be set first as `status=WAITING_CONFIRMATION`." + operationId: postBookings + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/BookingRequest' + responses: + "201": + content: + application/json: + schema: + $ref: '#/components/schemas/Booking' + description: Successful operation. A new Booking has been created. + "400": + content: + application/json: + schema: + $ref: '#/components/schemas/_passenger_post_400_response' + description: Bad Request. See error message. + "401": + description: Unauthorized. You must authenticate. + "429": + description: Too Many Requests. Please slow down. + headers: + Retry-After: + explode: false + schema: + type: integer + style: simple + "500": + description: Internal Server Error. Please try again later. + summary: Create a punctual outward Booking request. + tags: + - Interact + /bookings/{bookingId}: + get: + description: "Route used to retrieve the details of an existing Booking request.\ + \ Can only be used by the operator having created the Booking request. This\ + \ route is provided to check if the Booking object state is similar between\ + \ two operators, but its usage should be required to handle the full use case\ + \ of a booking." + operationId: getBookings + parameters: + - description: The operator's FQDN. + explode: true + in: query + name: operator + required: true + schema: + type: string + style: form + - explode: false + in: path + name: bookingId + required: true + schema: + $ref: '#/components/schemas/bookingId' + style: simple + responses: + "200": + content: + application/json: + schema: + $ref: '#/components/schemas/Booking' + description: Successful operation. + "400": + content: + application/json: + schema: + $ref: '#/components/schemas/_passenger_post_400_response' + description: Bad Request. See error message. + "401": + description: Unauthorized. You must authenticate. + "429": + description: Too Many Requests. Please slow down. + headers: + Retry-After: + explode: false + schema: + type: integer + style: simple + "500": + description: Internal Server Error. Please try again later. + "404": + content: + application/json: + schema: + $ref: '#/components/schemas/getBookings_404_response' + description: "This Booking object no more exists. Error code can be among\ + \ `missing_journey, missing_booking, missing_user` ." + summary: Retrieves an existing Booking request. + tags: + - Interact + patch: + description: "Route used to update the status of an existing Booking request.\ + \ Should be used usually just to confirm, cancel, etc. an existing Booking." + operationId: patchBookings + parameters: + - description: The operator's FQDN. + explode: true + in: query + name: operator + required: true + schema: + type: string + style: form + - explode: false + in: path + name: bookingId + required: true + schema: + $ref: '#/components/schemas/bookingId' + style: simple + - description: New status of the Booking. + explode: true + in: query + name: status + required: true + schema: + $ref: '#/components/schemas/bookingStatus' + style: form + - description: Free text content of a message. The message can contain explanations + on the status change. + explode: true + in: query + name: message + required: false + schema: + maxLength: 500 + type: string + style: form + responses: + "200": + description: Successful operation. + "400": + content: + application/json: + schema: + $ref: '#/components/schemas/_passenger_post_400_response' + description: Bad Request. See error message. + "401": + description: Unauthorized. You must authenticate. + "429": + description: Too Many Requests. Please slow down. + headers: + Retry-After: + explode: false + schema: + type: integer + style: simple + "500": + description: Internal Server Error. Please try again later. + "404": + content: + application/json: + schema: + $ref: '#/components/schemas/getBookings_404_response' + description: "The targeted journey, booking or user no more exists. Error\ + \ code can be among `missing_journey, missing_booking, missing_user`\ + \ ." + "409": + content: + application/json: + schema: + $ref: '#/components/schemas/getBookings_404_response' + description: Conflict. This booking has already the new status requested. + Error code is `status_already_set`. + summary: Updates status of an existing Booking request. + tags: + - Interact +components: + parameters: + departureLat: + description: Latitude of searched departure point. + explode: true + in: query + name: departureLat + required: true + schema: + type: number + style: form + departureLng: + description: Longitude of searched departure point. + explode: true + in: query + name: departureLng + required: true + schema: + type: number + style: form + arrivalLat: + description: Latitude of searched arrival point. + explode: true + in: query + name: arrivalLat + required: true + schema: + type: number + style: form + arrivalLng: + description: Longitude of searched arrival point. + explode: true + in: query + name: arrivalLng + required: true + schema: + type: number + style: form + departureDate: + description: Departure datetime using a UNIX UTC timestamp in seconds. + explode: true + in: query + name: departureDate + required: true + schema: + type: integer + style: form + departureTimeOfDay: + description: "Departure time of day represented as [RFC3339 partial-time](https://datatracker.ietf.org/doc/html/rfc3339#section-5.6)." + example: 07:30:00 + explode: true + in: query + name: departureTimeOfDay + required: true + schema: + format: partial-time + type: string + style: form + timeDelta: + description: Time margin in seconds. The retrieved journeys must match the given + time parameters within a +`timeDelta` / -`timeDelta` interval . + explode: true + in: query + name: timeDelta + required: false + schema: + default: 900 + type: integer + style: form + minDepartureDate: + description: Minimum date of departure for the returned journeys. Datetime using + a UNIX UTC timestamp in seconds. + explode: true + in: query + name: minDepartureDate + required: false + schema: + type: integer + style: form + maxDepartureDate: + description: Maximum date of departure for the returned journeys. Datetime using + a UNIX UTC timestamp in seconds. + explode: true + in: query + name: maxDepartureDate + required: false + schema: + type: integer + style: form + departureRadius: + description: Search radius in kilometers around the departure point. + explode: true + in: query + name: departureRadius + required: false + schema: + default: 1.0 + type: number + style: form + arrivalRadius: + description: Search radius in kilometers around the arrival point. + explode: true + in: query + name: arrivalRadius + required: false + schema: + default: 1.0 + type: number + style: form + count: + description: "Maximum number of returned results. If missing, all matching results\ + \ are returned." + explode: true + in: query + name: count + required: false + schema: + type: integer + style: form + responses: + BadRequest: + content: + application/json: + schema: + $ref: '#/components/schemas/_passenger_post_400_response' + description: Bad Request. See error message. + Unauthorized: + description: Unauthorized. You must authenticate. + TooManyRequests: + description: Too Many Requests. Please slow down. + headers: + Retry-After: + explode: false + schema: + type: integer + style: simple + InternalServerError: + description: Internal Server Error. Please try again later. + schemas: + PunctualDriverJourney: + allOf: + - $ref: '#/components/schemas/DriverTrip' + - $ref: '#/components/schemas/JourneySchedule' + - properties: + price: + $ref: '#/components/schemas/Price' + driver_departure_Address: + type: string + + punctual_availabilities: + $ref: '#/components/schemas/PunctualAvailabilitySlot' + + + type: object + RegularDriverJourney: + allOf: + - $ref: '#/components/schemas/DriverTrip' + - $ref: '#/components/schemas/JourneySchedule' + - properties: + price: + $ref: '#/components/schemas/Price' + driver_departure_Address: + type: string + regular_availabilities: + $ref: '#/components/schemas/RegularAvailabilitySlot' + + + + type: object + Price: + example: + amount: 9.301444 + currency: currency + type: FREE + properties: + amount: + description: "Carpooling passenger cost estimate. In the case of integrated\ + \ booking by API, amount expected by the carpooling operator." + format: float + type: number + currency: + description: ISO 4217 code representing the currency of the price. + type: string + type: object + Car: + example: + model: model + brand: brand + properties: + model: + description: Model of the car. + type: string + brand: + description: Brand of the car. + type: string + type: object + User: + example: + firstName: firstName + lastName: lastName + gender: F + grade: 1 + alias: alias + id: id + verifiedIdentity: true + operator: operator + picture: picture + properties: + id: + description: User's identifier. It MUST be unique for a given `operator`. + type: string + operator: + description: The operator identifier. MUST be a Fully Qualified Domain Name + (example carpool.mycity.com) owned by the operator or a Partially Qualified + Domain Name (example operator.org) owned and exclusively operated by the + operator. Operators SHOULD always send the same value. + type: string + alias: + description: User's alias. + type: string + firstName: + description: User's first name. + type: string + lastName: + description: User's last name. + type: string + grade: + description: User's grade from 1 to 5. + maximum: 5 + minimum: 1 + type: integer + picture: + description: User's profile picture absolute URL. + type: string + gender: + description: User's gender. 'O' stands for 'Other'. + enum: + - F + - M + - O + type: string + verifiedIdentity: + description: "true if the identity of this user has been verified by the\ + \ operator or a third party; and the firstName, lastName, birthdate have\ + \ been confirmed as identitical to an official identity proof document.\ + \ Can be left empty if the information is not available." + type: boolean + required: + - alias + - id + - operator + type: object + DriverTrip: + allOf: + - properties: + user: + $ref: '#/components/schemas/User' + car: + $ref: '#/components/schemas/Car' + required: + - user + type: object + type: object + PassengerTripRequest: + example: + departure_address: departure_address + preferences: + music: true + luggageSize: 3 + smoking: true + animals: true + isTalker: true + destination_address: destination_address + departure_longitude: 5.637376656633329 + destination_latitude: 6.027456183070403 + departure_date: 2 + destination_longitude: 1.4658129805029452 + user: + firstName: firstName + lastName: lastName + gender: F + grade: 1 + alias: alias + id: id + verifiedIdentity: true + operator: operator + picture: picture + departure_latitude: 5.962133916683182 + properties: + user: + $ref: '#/components/schemas/User' + destination_address: + type: string + destination_latitude: + format: double + type: number + destination_longitude: + format: double + type: number + departure_address: + type: string + departure_latitude: + format: double + type: number + departure_longitude: + format: double + type: number + departure_date: + description: Departure datetime using a UNIX UTC timestamp in seconds. + type: integer + preferences: + $ref: '#/components/schemas/Preferences' + required: + - departure_address + - departure_date + - departure_latitude + - departure_longitude + - destination_address + - destination_latitude + - destination_longitude + - user + type: object + Preferences: + example: + music: true + luggageSize: 3 + smoking: true + animals: true + isTalker: true + properties: + smoking: + description: "If driver journey, specifies if the driver allows smoking\ + \ in the car." + type: boolean + animals: + description: "If driver journey, specifies if the driver allows animals\ + \ in the car." + type: boolean + music: + description: "If driver journey, specifies if the driver enjoys music in\ + \ the car." + type: boolean + isTalker: + description: "If driver journey, specifies if the driver enjoys talking\ + \ with passengers." + type: boolean + luggageSize: + description: |- + If driver journey, specifies the size of allowed luggages. + From very small (1) to very big (5). + maximum: 5 + minimum: 1 + type: integer + type: object + bookingId: + description: "Booking id is common between both operators, and must be created\ + \ as a [UUID](https://datatracker.ietf.org/doc/html/rfc4122) by whoever initiates\ + \ the booking. Usage of a [4 UUID](https://datatracker.ietf.org/doc/html/rfc4122#section-4.4)\ + \ generation algorithm is advised." + format: uuid + type: string + passengerId: + format: uuid + type: string + driverId: + format: uuid + type: string + JourneySchedule: + properties: + driver_departure_Date: + description: Driver pickup datetime as a UNIX UTC timestamp in seconds. + format: long + type: number + required: + - driver_departure_Date + type: object + BookingRequest: + example: + driverId: 046b6c7f-0b8a-43b9-b35d-6489e6daee91 + passengerId: 046b6c7f-0b8a-43b9-b35d-6489e6daee91 + id: 046b6c7f-0b8a-43b9-b35d-6489e6daee91 + operator: operator + status: null + properties: + id: + description: "Booking id is common between both operators, and must be created\ + \ as a [UUID](https://datatracker.ietf.org/doc/html/rfc4122) by whoever\ + \ initiates the booking. Usage of a [4 UUID](https://datatracker.ietf.org/doc/html/rfc4122#section-4.4)\ + \ generation algorithm is advised." + format: uuid + type: string + passengerId: + format: uuid + type: string + driverId: + format: uuid + type: string + status: + $ref: '#/components/schemas/bookingStatus' + operator: + type: string + required: + - driverId + - id + - operator + - passengerId + - status + type: object + Booking: + example: + passengerDropLng: 5.637376656633329 + distance: 7 + passengerDropLat: 5.962133916683182 + passengerPickupDate: 0.8008281904610115 + passengerDropAddress: passengerDropAddress + passengerPickupAddress: passengerPickupAddress + passengerPickupLng: 1.4658129805029452 + duration: 2 + driver: + firstName: firstName + lastName: lastName + gender: F + grade: 1 + alias: alias + id: id + verifiedIdentity: true + operator: operator + picture: picture + passenger: + firstName: firstName + lastName: lastName + gender: F + grade: 1 + alias: alias + id: id + verifiedIdentity: true + operator: operator + picture: picture + car: + model: model + brand: brand + passengerPickupLat: 6.027456183070403 + price: + amount: 9.301444 + currency: currency + type: FREE + id: 046b6c7f-0b8a-43b9-b35d-6489e6daee91 + status: null + properties: + id: + description: "Booking id is common between both operators, and must be created\ + \ as a [UUID](https://datatracker.ietf.org/doc/html/rfc4122) by whoever\ + \ initiates the booking. Usage of a [4 UUID](https://datatracker.ietf.org/doc/html/rfc4122#section-4.4)\ + \ generation algorithm is advised." + format: uuid + type: string + driver: + $ref: '#/components/schemas/User' + passenger: + $ref: '#/components/schemas/User' + passengerPickupDate: + description: Passenger pickup datetime as a UNIX UTC timestamp in seconds. + format: long + type: number + passengerPickupLat: + description: Latitude of the passenger pick-up point. + format: double + type: number + passengerPickupLng: + description: Longitude of the passenger pick-up point. + format: double + type: number + passengerDropLat: + description: Latitude of the passenger drop-off point. + format: double + type: number + passengerDropLng: + description: Longitude of the passenger drop-off point. + format: double + type: number + passengerPickupAddress: + description: String representing the pickup-up address. + type: string + passengerDropAddress: + description: String representing the drop-off address. + type: string + status: + $ref: '#/components/schemas/bookingStatus' + duration: + description: Carpooling duration in seconds. + type: integer + distance: + description: | + Carpooling distance in meters. + type: integer + price: + $ref: '#/components/schemas/Price' + car: + $ref: '#/components/schemas/Car' + required: + - driver + - id + - passenger + - passengerDropLat + - passengerDropLng + - passengerPickupDate + - passengerPickupLat + - passengerPickupLng + - price + - status + type: object + bookingStatus: + default: WAITING_DRIVER_CONFIRMATION + description: Status of the booking. + enum: + - WAITING_DRIVER_CONFIRMATION + - WAITING_PASSENGER_CONFIRMATION + - CONFIRMED + - CANCELLED + - COMPLETED_PENDING_VALIDATION + - VALIDATED + type: string + DriverRegularAvailabilitiesRequest: + example: + preferences: + music: true + luggageSize: 3 + smoking: true + animals: true + isTalker: true + address: address + car: + model: model + brand: brand + availabilities: + - dayOfWeek: MON + startTime: startTime + endTime: endTime + - dayOfWeek: MON + startTime: startTime + endTime: endTime + latitude: 0.8008281904610115 + radius: 1 + user: + firstName: firstName + lastName: lastName + gender: F + grade: 1 + alias: alias + id: id + verifiedIdentity: true + operator: operator + picture: picture + longitude: 6.027456183070403 + properties: + address: + description: The address or location description. + type: string + latitude: + description: The latitude coordinate of the location. + format: double + type: number + longitude: + description: The longitude coordinate of the location. + format: double + type: number + radius: + description: The radius around the location. + format: int32 + type: integer + availabilities: + items: + $ref: '#/components/schemas/RegularAvailabilitySlot' + type: array + user: + $ref: '#/components/schemas/User' + preferences: + $ref: '#/components/schemas/Preferences' + car: + $ref: '#/components/schemas/Car' + required: + - address + - availabilities + - latitude + - longitude + - radius + - user + type: object + DriverPunctualAvailabilitiesRequest: + example: + preferences: + music: true + luggageSize: 3 + smoking: true + animals: true + isTalker: true + address: address + car: + model: model + brand: brand + availabilities: + - date: 5 + startTime: startTime + endTime: endTime + - date: 5 + startTime: startTime + endTime: endTime + latitude: 0.8008281904610115 + radius: 1 + user: + firstName: firstName + lastName: lastName + gender: F + grade: 1 + alias: alias + id: id + verifiedIdentity: true + operator: operator + picture: picture + longitude: 6.027456183070403 + properties: + address: + description: The address or location description. + type: string + latitude: + description: The latitude coordinate of the location. + format: double + type: number + longitude: + description: The longitude coordinate of the location. + format: double + type: number + radius: + description: The radius around the location. + format: int32 + type: integer + availabilities: + items: + $ref: '#/components/schemas/PunctualAvailabilitySlot' + type: array + user: + $ref: '#/components/schemas/User' + preferences: + $ref: '#/components/schemas/Preferences' + car: + $ref: '#/components/schemas/Car' + required: + - address + - availabilities + - latitude + - longitude + - radius + - user + type: object + RegularAvailabilitySlot: + example: + dayOfWeek: MON + startTime: startTime + endTime: endTime + properties: + dayOfWeek: + description: Day of the week for regular scheduling. + enum: + - MON + - TUE + - WED + - THU + - FRI + - SAT + - SUN + type: string + startTime: + description: Start time for regular scheduling (RFC3339 partial-time). + format: partial-time + type: string + endTime: + description: End time for regular scheduling (RFC3339 partial-time). + format: partial-time + type: string + required: + - dayOfWeek + - endTime + - startTime + type: object + PunctualAvailabilitySlot: + example: + date: 5 + startTime: startTime + endTime: endTime + properties: + date: + description: UNIX UTC timestamp in seconds. + type: integer + startTime: + description: Start time for punctual scheduling (RFC3339 partial-time). + format: partial-time + type: string + endTime: + description: End time for punctual scheduling (RFC3339 partial-time). + format: partial-time + type: string + required: + - date + - endTime + - startTime + type: object + _passenger_post_400_response: + properties: + error: + type: string + type: object + postConnections_request: + properties: + from: + $ref: '#/components/schemas/User' + to: + $ref: '#/components/schemas/User' + message: + description: "Free text content of a message. The message can contain all\ + \ the details (phone number, email, etc.) allowing the recipient to call\ + \ back the sender in order to carpool with him/her." + maxLength: 500 + type: string + recipientCarpoolerType: + default: DRIVER + description: Defines if the recipient of this message is either the driver + or the passenger. + enum: + - DRIVER + - PASSENGER + type: string + driverJourneyId: + description: ID of the Driver's journey to which the message is related + (if any). Unique given the `Driver`'s `operator` property. + maxLength: 255 + minLength: 1 + type: string + passengerJourneyId: + description: ID of the Passenger's journey to which the message is related + (if any). Unique given the `Passenger`'s `operator` property. + maxLength: 255 + minLength: 1 + type: string + bookingId: + allOf: + - $ref: '#/components/schemas/bookingId' + description: ID of the booking to which the message is related (if any) + required: + - from + - message + - recipientCarpoolerType + - to + type: object + getBookings_404_response: + properties: + error: + description: Explain why the request couldn't be processed. + type: string + type: object diff --git a/interoperability/solidarity-api/server/.openapi-generator-ignore b/interoperability/solidarity-api/server/.openapi-generator-ignore new file mode 100644 index 0000000..7484ee5 --- /dev/null +++ b/interoperability/solidarity-api/server/.openapi-generator-ignore @@ -0,0 +1,23 @@ +# OpenAPI Generator Ignore +# Generated by openapi-generator https://github.com/openapitools/openapi-generator + +# Use this file to prevent files from being overwritten by the generator. +# The patterns follow closely to .gitignore or .dockerignore. + +# As an example, the C# client generator defines ApiClient.cs. +# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line: +#ApiClient.cs + +# You can match any string of characters against a directory, file or extension with a single asterisk (*): +#foo/*/qux +# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux + +# You can recursively match patterns against a directory, file or extension with a double asterisk (**): +#foo/**/qux +# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux + +# You can also negate patterns with an exclamation (!). +# For example, you can ignore all files in a docs folder with the file extension .md: +#docs/*.md +# Then explicitly reverse the ignore rule for a single file: +#!docs/README.md diff --git a/interoperability/solidarity-api/server/.openapi-generator/FILES b/interoperability/solidarity-api/server/.openapi-generator/FILES new file mode 100644 index 0000000..207a723 --- /dev/null +++ b/interoperability/solidarity-api/server/.openapi-generator/FILES @@ -0,0 +1,40 @@ +.openapi-generator-ignore +Dockerfile +README.md +api/openapi.yaml +go.mod +go/api.go +go/api_bookings_filter.go +go/api_bookings_filter_service.go +go/api_driver_availability_and_schedule.go +go/api_driver_availability_and_schedule_service.go +go/api_interact.go +go/api_interact_service.go +go/api_passenger_trip_request.go +go/api_passenger_trip_request_service.go +go/api_search.go +go/api_search_service.go +go/error.go +go/helpers.go +go/impl.go +go/logger.go +go/model__passenger_post_400_response.go +go/model_booking.go +go/model_booking_request.go +go/model_booking_status.go +go/model_car.go +go/model_driver_journey.go +go/model_driver_punctual_availabilities_request.go +go/model_driver_regular_availabilities_request.go +go/model_driver_trip.go +go/model_get_bookings_404_response.go +go/model_journey_schedule.go +go/model_passenger_trip_request.go +go/model_post_connections_request.go +go/model_preferences.go +go/model_price.go +go/model_punctual_availability_slot.go +go/model_regular_availability_slot.go +go/model_user.go +go/routers.go +main.go diff --git a/interoperability/solidarity-api/server/.openapi-generator/VERSION b/interoperability/solidarity-api/server/.openapi-generator/VERSION new file mode 100644 index 0000000..73a86b1 --- /dev/null +++ b/interoperability/solidarity-api/server/.openapi-generator/VERSION @@ -0,0 +1 @@ +7.0.1 \ No newline at end of file diff --git a/interoperability/solidarity-api/server/api/openapi.yaml b/interoperability/solidarity-api/server/api/openapi.yaml new file mode 100644 index 0000000..6e477c8 --- /dev/null +++ b/interoperability/solidarity-api/server/api/openapi.yaml @@ -0,0 +1,1238 @@ +openapi: 3.0.0 +info: + title: Solidarity Mobility API + version: 1.0.0 +servers: +- url: / +paths: + /passenger: + post: + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/PassengerTripRequest' + required: true + responses: + "201": + description: Trip Request Created + "400": + content: + application/json: + schema: + $ref: '#/components/schemas/_passenger_post_400_response' + description: Bad Request. See error message. + "401": + description: Unauthorized. You must authenticate. + "429": + description: Too Many Requests. Please slow down. + headers: + Retry-After: + explode: false + schema: + type: integer + style: simple + "500": + description: Internal Server Error. Please try again later. + summary: Create a Passenger Trip Request + tags: + - Passenger Trip Request + /driver_journeys: + get: + description: Route used to retrieve a collection of punctual planned outward + driver journeys matching the provided criteria. + operationId: getDriverJourneys + parameters: + - description: Latitude of searched departure point. + explode: true + in: query + name: departureLat + required: true + schema: + type: number + style: form + - description: Longitude of searched departure point. + explode: true + in: query + name: departureLng + required: true + schema: + type: number + style: form + - description: Latitude of searched arrival point. + explode: true + in: query + name: arrivalLat + required: true + schema: + type: number + style: form + - description: Longitude of searched arrival point. + explode: true + in: query + name: arrivalLng + required: true + schema: + type: number + style: form + - description: Departure datetime using a UNIX UTC timestamp in seconds. + explode: true + in: query + name: departureDate + required: true + schema: + type: integer + style: form + - description: The operator's FQDN. + explode: true + in: query + name: operator + required: true + schema: + type: string + style: form + responses: + "200": + content: + application/json: + schema: + items: + $ref: '#/components/schemas/DriverJourney' + title: DriverJourneys + type: array + description: Ok. Request processed successfully. + "400": + content: + application/json: + schema: + $ref: '#/components/schemas/_passenger_post_400_response' + description: Bad Request. See error message. + "401": + description: Unauthorized. You must authenticate. + "429": + description: Too Many Requests. Please slow down. + headers: + Retry-After: + explode: false + schema: + type: integer + style: simple + "500": + description: Internal Server Error. Please try again later. + summary: Search for matching punctual planned outward driver journeys. + tags: + - Search + /driver_regular_availabilities: + post: + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/DriverRegularAvailabilitiesRequest' + required: true + responses: + "201": + description: Regular driver availabilities set successfully. + "400": + content: + application/json: + schema: + $ref: '#/components/schemas/_passenger_post_400_response' + description: Bad Request. See error message. + "429": + description: Too Many Requests. Please slow down. + headers: + Retry-After: + explode: false + schema: + type: integer + style: simple + "500": + description: Internal Server Error. Please try again later. + summary: Set Regular Driver Availabilities + tags: + - Driver Availability and Schedule + /driver_punctual_availabilities: + post: + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/DriverPunctualAvailabilitiesRequest' + required: true + responses: + "201": + description: Punctual driver availabilities set successfully. + "400": + content: + application/json: + schema: + $ref: '#/components/schemas/_passenger_post_400_response' + description: Bad Request. See error message. + "429": + description: Too Many Requests. Please slow down. + headers: + Retry-After: + explode: false + schema: + type: integer + style: simple + "500": + description: Internal Server Error. Please try again later. + summary: Set Punctual Driver Availabilities + tags: + - Driver Availability and Schedule + /messages: + post: + description: Route used to allow a user to connect back to the owner of a retrieved + journey through a texte message. + operationId: postConnections + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/postConnections_request' + responses: + "201": + description: Successful operation. + "404": + description: The targeted journey or user no more exists. + "400": + content: + application/json: + schema: + $ref: '#/components/schemas/_passenger_post_400_response' + description: Bad Request. See error message. + "401": + description: Unauthorized. You must authenticate. + "429": + description: Too Many Requests. Please slow down. + headers: + Retry-After: + explode: false + schema: + type: integer + style: simple + "500": + description: Internal Server Error. Please try again later. + summary: Send a message to the owner of a retrieved journey. + tags: + - Interact + /bookings: + get: + description: "Route used to filter and retrieve bookings based on the specified\ + \ status, type, and ID." + operationId: filterBookingsByStatus + parameters: + - description: The operator's FQDN. + explode: true + in: query + name: operator + required: true + schema: + type: string + style: form + - description: The status of the bookings to filter. + explode: true + in: query + name: status + required: true + schema: + enum: + - WAITING_DRIVER_CONFIRMATION + - WAITING_PASSENGER_CONFIRMATION + - CONFIRMED + - CANCELLED + - COMPLETED_PENDING_VALIDATION + - VALIDATED + type: string + style: form + - explode: true + in: query + name: filterType + required: true + schema: + enum: + - driver + - passenger + type: string + style: form + - description: The ID (UUID) used. + explode: true + in: query + name: Id + required: true + schema: + format: uuid + type: string + style: form + responses: + "200": + content: + application/json: + schema: + items: + $ref: '#/components/schemas/Booking' + type: array + description: "Successful operation. Bookings matching the specified status,\ + \ type, and ID." + "400": + content: + application/json: + schema: + $ref: '#/components/schemas/_passenger_post_400_response' + description: Bad Request. See error message. + "401": + description: Unauthorized. You must authenticate. + "429": + description: Too Many Requests. Please slow down. + headers: + Retry-After: + explode: false + schema: + type: integer + style: simple + "500": + description: Internal Server Error. Please try again later. + "404": + content: + application/json: + schema: + $ref: '#/components/schemas/_passenger_post_400_response' + description: "No bookings found for the specified status, type, and ID." + summary: "Filter and retrieve bookings by status, type, and ID." + tags: + - Bookings Filter + post: + description: "Route used to synchronize a Booking request initiated by a platform\ + \ to the second platform involved in the shared punctual outward journey.\ + \ While posting a new Booking, its status must always be set first as `status=WAITING_CONFIRMATION`." + operationId: postBookings + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/BookingRequest' + responses: + "201": + content: + application/json: + schema: + $ref: '#/components/schemas/Booking' + description: Successful operation. A new Booking has been created. + "400": + content: + application/json: + schema: + $ref: '#/components/schemas/_passenger_post_400_response' + description: Bad Request. See error message. + "401": + description: Unauthorized. You must authenticate. + "429": + description: Too Many Requests. Please slow down. + headers: + Retry-After: + explode: false + schema: + type: integer + style: simple + "500": + description: Internal Server Error. Please try again later. + summary: Create a punctual outward Booking request. + tags: + - Interact + /bookings/{bookingId}: + get: + description: "Route used to retrieve the details of an existing Booking request.\ + \ Can only be used by the operator having created the Booking request. This\ + \ route is provided to check if the Booking object state is similar between\ + \ two operators, but its usage should be required to handle the full use case\ + \ of a booking." + operationId: getBookings + parameters: + - description: The operator's FQDN. + explode: true + in: query + name: operator + required: true + schema: + type: string + style: form + - explode: false + in: path + name: bookingId + required: true + schema: + $ref: '#/components/schemas/bookingId' + style: simple + responses: + "200": + content: + application/json: + schema: + $ref: '#/components/schemas/Booking' + description: Successful operation. + "400": + content: + application/json: + schema: + $ref: '#/components/schemas/_passenger_post_400_response' + description: Bad Request. See error message. + "401": + description: Unauthorized. You must authenticate. + "429": + description: Too Many Requests. Please slow down. + headers: + Retry-After: + explode: false + schema: + type: integer + style: simple + "500": + description: Internal Server Error. Please try again later. + "404": + content: + application/json: + schema: + $ref: '#/components/schemas/getBookings_404_response' + description: "This Booking object no more exists. Error code can be among\ + \ `missing_journey, missing_booking, missing_user` ." + summary: Retrieves an existing Booking request. + tags: + - Interact + patch: + description: "Route used to update the status of an existing Booking request.\ + \ Should be used usually just to confirm, cancel, etc. an existing Booking." + operationId: patchBookings + parameters: + - description: The operator's FQDN. + explode: true + in: query + name: operator + required: true + schema: + type: string + style: form + - explode: false + in: path + name: bookingId + required: true + schema: + $ref: '#/components/schemas/bookingId' + style: simple + - description: New status of the Booking. + explode: true + in: query + name: status + required: true + schema: + $ref: '#/components/schemas/bookingStatus' + style: form + - description: Free text content of a message. The message can contain explanations + on the status change. + explode: true + in: query + name: message + required: false + schema: + maxLength: 500 + type: string + style: form + responses: + "200": + description: Successful operation. + "400": + content: + application/json: + schema: + $ref: '#/components/schemas/_passenger_post_400_response' + description: Bad Request. See error message. + "401": + description: Unauthorized. You must authenticate. + "429": + description: Too Many Requests. Please slow down. + headers: + Retry-After: + explode: false + schema: + type: integer + style: simple + "500": + description: Internal Server Error. Please try again later. + "404": + content: + application/json: + schema: + $ref: '#/components/schemas/getBookings_404_response' + description: "The targeted journey, booking or user no more exists. Error\ + \ code can be among `missing_journey, missing_booking, missing_user`\ + \ ." + "409": + content: + application/json: + schema: + $ref: '#/components/schemas/getBookings_404_response' + description: Conflict. This booking has already the new status requested. + Error code is `status_already_set`. + summary: Updates status of an existing Booking request. + tags: + - Interact +components: + parameters: + departureLat: + description: Latitude of searched departure point. + explode: true + in: query + name: departureLat + required: true + schema: + type: number + style: form + departureLng: + description: Longitude of searched departure point. + explode: true + in: query + name: departureLng + required: true + schema: + type: number + style: form + arrivalLat: + description: Latitude of searched arrival point. + explode: true + in: query + name: arrivalLat + required: true + schema: + type: number + style: form + arrivalLng: + description: Longitude of searched arrival point. + explode: true + in: query + name: arrivalLng + required: true + schema: + type: number + style: form + departureDate: + description: Departure datetime using a UNIX UTC timestamp in seconds. + explode: true + in: query + name: departureDate + required: true + schema: + type: integer + style: form + departureTimeOfDay: + description: "Departure time of day represented as [RFC3339 partial-time](https://datatracker.ietf.org/doc/html/rfc3339#section-5.6)." + example: 07:30:00 + explode: true + in: query + name: departureTimeOfDay + required: true + schema: + format: partial-time + type: string + style: form + timeDelta: + description: Time margin in seconds. The retrieved journeys must match the given + time parameters within a +`timeDelta` / -`timeDelta` interval . + explode: true + in: query + name: timeDelta + required: false + schema: + default: 900 + type: integer + style: form + minDepartureDate: + description: Minimum date of departure for the returned journeys. Datetime using + a UNIX UTC timestamp in seconds. + explode: true + in: query + name: minDepartureDate + required: false + schema: + type: integer + style: form + maxDepartureDate: + description: Maximum date of departure for the returned journeys. Datetime using + a UNIX UTC timestamp in seconds. + explode: true + in: query + name: maxDepartureDate + required: false + schema: + type: integer + style: form + departureRadius: + description: Search radius in kilometers around the departure point. + explode: true + in: query + name: departureRadius + required: false + schema: + default: 1.0 + type: number + style: form + arrivalRadius: + description: Search radius in kilometers around the arrival point. + explode: true + in: query + name: arrivalRadius + required: false + schema: + default: 1.0 + type: number + style: form + count: + description: "Maximum number of returned results. If missing, all matching results\ + \ are returned." + explode: true + in: query + name: count + required: false + schema: + type: integer + style: form + responses: + BadRequest: + content: + application/json: + schema: + $ref: '#/components/schemas/_passenger_post_400_response' + description: Bad Request. See error message. + Unauthorized: + description: Unauthorized. You must authenticate. + TooManyRequests: + description: Too Many Requests. Please slow down. + headers: + Retry-After: + explode: false + schema: + type: integer + style: simple + InternalServerError: + description: Internal Server Error. Please try again later. + schemas: + DriverJourney: + allOf: + - $ref: '#/components/schemas/DriverTrip' + - $ref: '#/components/schemas/JourneySchedule' + - properties: + price: + $ref: '#/components/schemas/Price' + type: object + type: object + Price: + example: + amount: 9.301444 + currency: currency + type: FREE + properties: + type: + description: |- + Either « FREE », « PAYING » or « UNKNOWN ». « UNKNOWN » is given + when it should be « PAYING » but we cannot set the price yet. + enum: + - FREE + - PAYING + - UNKNOWN + type: string + amount: + description: "Carpooling passenger cost estimate. In the case of integrated\ + \ booking by API, amount expected by the carpooling operator." + format: float + type: number + currency: + description: ISO 4217 code representing the currency of the price. + type: string + type: object + Car: + example: + model: model + brand: brand + properties: + model: + description: Model of the car. + type: string + brand: + description: Brand of the car. + type: string + type: object + User: + example: + firstName: firstName + lastName: lastName + gender: F + grade: 1 + alias: alias + id: id + verifiedIdentity: true + operator: operator + picture: picture + properties: + id: + description: User's identifier. It MUST be unique for a given `operator`. + type: string + operator: + description: The operator identifier. MUST be a Fully Qualified Domain Name + (example carpool.mycity.com) owned by the operator or a Partially Qualified + Domain Name (example operator.org) owned and exclusively operated by the + operator. Operators SHOULD always send the same value. + type: string + alias: + description: User's alias. + type: string + firstName: + description: User's first name. + type: string + lastName: + description: User's last name. + type: string + grade: + description: User's grade from 1 to 5. + maximum: 5 + minimum: 1 + type: integer + picture: + description: User's profile picture absolute URL. + type: string + gender: + description: User's gender. 'O' stands for 'Other'. + enum: + - F + - M + - O + type: string + verifiedIdentity: + description: "true if the identity of this user has been verified by the\ + \ operator or a third party; and the firstName, lastName, birthdate have\ + \ been confirmed as identitical to an official identity proof document.\ + \ Can be left empty if the information is not available." + type: boolean + required: + - alias + - id + - operator + type: object + DriverTrip: + allOf: + - properties: + user: + $ref: '#/components/schemas/User' + car: + $ref: '#/components/schemas/Car' + required: + - user + type: object + type: object + PassengerTripRequest: + example: + departure_address: departure_address + preferences: + music: true + luggageSize: 3 + smoking: true + animals: true + isTalker: true + destination_address: destination_address + departure_longitude: 5.637376656633329 + destination_latitude: 6.027456183070403 + departure_date: 2 + destination_longitude: 1.4658129805029452 + user: + firstName: firstName + lastName: lastName + gender: F + grade: 1 + alias: alias + id: id + verifiedIdentity: true + operator: operator + picture: picture + departure_latitude: 5.962133916683182 + properties: + user: + $ref: '#/components/schemas/User' + destination_address: + type: string + destination_latitude: + format: double + type: number + destination_longitude: + format: double + type: number + departure_address: + type: string + departure_latitude: + format: double + type: number + departure_longitude: + format: double + type: number + departure_date: + description: Departure datetime using a UNIX UTC timestamp in seconds. + type: integer + preferences: + $ref: '#/components/schemas/Preferences' + required: + - departure_address + - departure_date + - departure_latitude + - departure_longitude + - destination_address + - destination_latitude + - destination_longitude + - user + type: object + Preferences: + example: + music: true + luggageSize: 3 + smoking: true + animals: true + isTalker: true + properties: + smoking: + description: "If driver journey, specifies if the driver allows smoking\ + \ in the car." + type: boolean + animals: + description: "If driver journey, specifies if the driver allows animals\ + \ in the car." + type: boolean + music: + description: "If driver journey, specifies if the driver enjoys music in\ + \ the car." + type: boolean + isTalker: + description: "If driver journey, specifies if the driver enjoys talking\ + \ with passengers." + type: boolean + luggageSize: + description: |- + If driver journey, specifies the size of allowed luggages. + From very small (1) to very big (5). + maximum: 5 + minimum: 1 + type: integer + type: object + bookingId: + description: "Booking id is common between both operators, and must be created\ + \ as a [UUID](https://datatracker.ietf.org/doc/html/rfc4122) by whoever initiates\ + \ the booking. Usage of a [4 UUID](https://datatracker.ietf.org/doc/html/rfc4122#section-4.4)\ + \ generation algorithm is advised." + format: uuid + type: string + passengerId: + format: uuid + type: string + driverId: + format: uuid + type: string + JourneySchedule: + properties: + passengerPickupDate: + description: Passenger pickup datetime as a UNIX UTC timestamp in seconds. + format: long + type: number + driverDepartureDate: + description: Driver departure datetime as a UNIX UTC timestamp in seconds. + format: long + type: number + type: + description: Type of journey. A dynamic journey is happening in real time. + enum: + - PLANNED + - DYNAMIC + - LINE + type: string + required: + - passengerPickupDate + - type + type: object + BookingRequest: + example: + driverId: 046b6c7f-0b8a-43b9-b35d-6489e6daee91 + passengerId: 046b6c7f-0b8a-43b9-b35d-6489e6daee91 + id: 046b6c7f-0b8a-43b9-b35d-6489e6daee91 + operator: operator + status: null + properties: + id: + description: "Booking id is common between both operators, and must be created\ + \ as a [UUID](https://datatracker.ietf.org/doc/html/rfc4122) by whoever\ + \ initiates the booking. Usage of a [4 UUID](https://datatracker.ietf.org/doc/html/rfc4122#section-4.4)\ + \ generation algorithm is advised." + format: uuid + type: string + passengerId: + format: uuid + type: string + driverId: + format: uuid + type: string + status: + $ref: '#/components/schemas/bookingStatus' + operator: + type: string + required: + - driverId + - id + - operator + - passengerId + - status + type: object + Booking: + example: + passengerDropLng: 5.637376656633329 + distance: 7 + passengerDropLat: 5.962133916683182 + passengerPickupDate: 0.8008281904610115 + passengerDropAddress: passengerDropAddress + passengerPickupAddress: passengerPickupAddress + passengerPickupLng: 1.4658129805029452 + duration: 2 + driver: + firstName: firstName + lastName: lastName + gender: F + grade: 1 + alias: alias + id: id + verifiedIdentity: true + operator: operator + picture: picture + passenger: + firstName: firstName + lastName: lastName + gender: F + grade: 1 + alias: alias + id: id + verifiedIdentity: true + operator: operator + picture: picture + car: + model: model + brand: brand + passengerPickupLat: 6.027456183070403 + price: + amount: 9.301444 + currency: currency + type: FREE + id: 046b6c7f-0b8a-43b9-b35d-6489e6daee91 + status: null + properties: + id: + description: "Booking id is common between both operators, and must be created\ + \ as a [UUID](https://datatracker.ietf.org/doc/html/rfc4122) by whoever\ + \ initiates the booking. Usage of a [4 UUID](https://datatracker.ietf.org/doc/html/rfc4122#section-4.4)\ + \ generation algorithm is advised." + format: uuid + type: string + driver: + $ref: '#/components/schemas/User' + passenger: + $ref: '#/components/schemas/User' + passengerPickupDate: + description: Passenger pickup datetime as a UNIX UTC timestamp in seconds. + format: long + type: number + passengerPickupLat: + description: Latitude of the passenger pick-up point. + format: double + type: number + passengerPickupLng: + description: Longitude of the passenger pick-up point. + format: double + type: number + passengerDropLat: + description: Latitude of the passenger drop-off point. + format: double + type: number + passengerDropLng: + description: Longitude of the passenger drop-off point. + format: double + type: number + passengerPickupAddress: + description: String representing the pickup-up address. + type: string + passengerDropAddress: + description: String representing the drop-off address. + type: string + status: + $ref: '#/components/schemas/bookingStatus' + duration: + description: Carpooling duration in seconds. + type: integer + distance: + description: | + Carpooling distance in meters. + type: integer + price: + $ref: '#/components/schemas/Price' + car: + $ref: '#/components/schemas/Car' + required: + - driver + - id + - passenger + - passengerDropLat + - passengerDropLng + - passengerPickupDate + - passengerPickupLat + - passengerPickupLng + - price + - status + type: object + bookingStatus: + default: WAITING_DRIVER_CONFIRMATION + description: Status of the booking. + enum: + - WAITING_DRIVER_CONFIRMATION + - WAITING_PASSENGER_CONFIRMATION + - CONFIRMED + - CANCELLED + - COMPLETED_PENDING_VALIDATION + - VALIDATED + type: string + DriverRegularAvailabilitiesRequest: + example: + preferences: + music: true + luggageSize: 3 + smoking: true + animals: true + isTalker: true + address: address + car: + model: model + brand: brand + availabilities: + - dayOfWeek: MON + startTime: startTime + endTime: endTime + - dayOfWeek: MON + startTime: startTime + endTime: endTime + latitude: 0.8008281904610115 + radius: 1 + user: + firstName: firstName + lastName: lastName + gender: F + grade: 1 + alias: alias + id: id + verifiedIdentity: true + operator: operator + picture: picture + longitude: 6.027456183070403 + properties: + address: + description: The address or location description. + type: string + latitude: + description: The latitude coordinate of the location. + format: double + type: number + longitude: + description: The longitude coordinate of the location. + format: double + type: number + radius: + description: The radius around the location. + format: int32 + type: integer + availabilities: + items: + $ref: '#/components/schemas/RegularAvailabilitySlot' + type: array + user: + $ref: '#/components/schemas/User' + preferences: + $ref: '#/components/schemas/Preferences' + car: + $ref: '#/components/schemas/Car' + required: + - address + - availabilities + - latitude + - longitude + - radius + - user + type: object + DriverPunctualAvailabilitiesRequest: + example: + preferences: + music: true + luggageSize: 3 + smoking: true + animals: true + isTalker: true + address: address + car: + model: model + brand: brand + availabilities: + - date: 5 + startTime: startTime + endTime: endTime + - date: 5 + startTime: startTime + endTime: endTime + latitude: 0.8008281904610115 + radius: 1 + user: + firstName: firstName + lastName: lastName + gender: F + grade: 1 + alias: alias + id: id + verifiedIdentity: true + operator: operator + picture: picture + longitude: 6.027456183070403 + properties: + address: + description: The address or location description. + type: string + latitude: + description: The latitude coordinate of the location. + format: double + type: number + longitude: + description: The longitude coordinate of the location. + format: double + type: number + radius: + description: The radius around the location. + format: int32 + type: integer + availabilities: + items: + $ref: '#/components/schemas/PunctualAvailabilitySlot' + type: array + user: + $ref: '#/components/schemas/User' + preferences: + $ref: '#/components/schemas/Preferences' + car: + $ref: '#/components/schemas/Car' + required: + - address + - availabilities + - latitude + - longitude + - radius + - user + type: object + RegularAvailabilitySlot: + example: + dayOfWeek: MON + startTime: startTime + endTime: endTime + properties: + dayOfWeek: + description: Day of the week for regular scheduling. + enum: + - MON + - TUE + - WED + - THU + - FRI + - SAT + - SUN + type: string + startTime: + description: Start time for regular scheduling (RFC3339 partial-time). + format: partial-time + type: string + endTime: + description: End time for regular scheduling (RFC3339 partial-time). + format: partial-time + type: string + required: + - dayOfWeek + - endTime + - startTime + type: object + PunctualAvailabilitySlot: + example: + date: 5 + startTime: startTime + endTime: endTime + properties: + date: + description: UNIX UTC timestamp in seconds. + type: integer + startTime: + description: Start time for punctual scheduling (RFC3339 partial-time). + format: partial-time + type: string + endTime: + description: End time for punctual scheduling (RFC3339 partial-time). + format: partial-time + type: string + required: + - date + - endTime + - startTime + type: object + _passenger_post_400_response: + properties: + error: + type: string + type: object + postConnections_request: + properties: + from: + $ref: '#/components/schemas/User' + to: + $ref: '#/components/schemas/User' + message: + description: "Free text content of a message. The message can contain all\ + \ the details (phone number, email, etc.) allowing the recipient to call\ + \ back the sender in order to carpool with him/her." + maxLength: 500 + type: string + recipientCarpoolerType: + default: DRIVER + description: Defines if the recipient of this message is either the driver + or the passenger. + enum: + - DRIVER + - PASSENGER + type: string + driverJourneyId: + description: ID of the Driver's journey to which the message is related + (if any). Unique given the `Driver`'s `operator` property. + maxLength: 255 + minLength: 1 + type: string + passengerJourneyId: + description: ID of the Passenger's journey to which the message is related + (if any). Unique given the `Passenger`'s `operator` property. + maxLength: 255 + minLength: 1 + type: string + bookingId: + allOf: + - $ref: '#/components/schemas/bookingId' + description: ID of the booking to which the message is related (if any) + required: + - from + - message + - recipientCarpoolerType + - to + type: object + getBookings_404_response: + properties: + error: + description: Explain why the request couldn't be processed. + type: string + type: object diff --git a/interoperability/solidarity-api/server/openapi/api.go b/interoperability/solidarity-api/server/openapi/api.go new file mode 100644 index 0000000..9c37653 --- /dev/null +++ b/interoperability/solidarity-api/server/openapi/api.go @@ -0,0 +1,98 @@ +/* + * Solidarity Mobility API + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * API version: 1.0.0 + * Generated by: OpenAPI Generator (https://openapi-generator.tech) + */ + +package openapi + +import ( + "context" + "net/http" +) + +// BookingsFilterAPIRouter defines the required methods for binding the api requests to a responses for the BookingsFilterAPI +// The BookingsFilterAPIRouter implementation should parse necessary information from the http request, +// pass the data to a BookingsFilterAPIServicer to perform the required actions, then write the service results to the http response. +type BookingsFilterAPIRouter interface { + FilterBookingsByStatus(http.ResponseWriter, *http.Request) +} + +// DriverAvailabilityAndScheduleAPIRouter defines the required methods for binding the api requests to a responses for the DriverAvailabilityAndScheduleAPI +// The DriverAvailabilityAndScheduleAPIRouter implementation should parse necessary information from the http request, +// pass the data to a DriverAvailabilityAndScheduleAPIServicer to perform the required actions, then write the service results to the http response. +type DriverAvailabilityAndScheduleAPIRouter interface { + DriverPunctualAvailabilitiesPost(http.ResponseWriter, *http.Request) + DriverRegularAvailabilitiesPost(http.ResponseWriter, *http.Request) +} + +// InteractAPIRouter defines the required methods for binding the api requests to a responses for the InteractAPI +// The InteractAPIRouter implementation should parse necessary information from the http request, +// pass the data to a InteractAPIServicer to perform the required actions, then write the service results to the http response. +type InteractAPIRouter interface { + GetBookings(http.ResponseWriter, *http.Request) + PatchBookings(http.ResponseWriter, *http.Request) + PostBookings(http.ResponseWriter, *http.Request) + PostConnections(http.ResponseWriter, *http.Request) +} + +// PassengerTripRequestAPIRouter defines the required methods for binding the api requests to a responses for the PassengerTripRequestAPI +// The PassengerTripRequestAPIRouter implementation should parse necessary information from the http request, +// pass the data to a PassengerTripRequestAPIServicer to perform the required actions, then write the service results to the http response. +type PassengerTripRequestAPIRouter interface { + PassengerPost(http.ResponseWriter, *http.Request) +} + +// SearchAPIRouter defines the required methods for binding the api requests to a responses for the SearchAPI +// The SearchAPIRouter implementation should parse necessary information from the http request, +// pass the data to a SearchAPIServicer to perform the required actions, then write the service results to the http response. +type SearchAPIRouter interface { + GetDriverJourneys(http.ResponseWriter, *http.Request) +} + +// BookingsFilterAPIServicer defines the api actions for the BookingsFilterAPI service +// This interface intended to stay up to date with the openapi yaml used to generate it, +// while the service implementation can be ignored with the .openapi-generator-ignore file +// and updated with the logic required for the API. +type BookingsFilterAPIServicer interface { + FilterBookingsByStatus(context.Context, string, string, string, string) (ImplResponse, error) +} + +// DriverAvailabilityAndScheduleAPIServicer defines the api actions for the DriverAvailabilityAndScheduleAPI service +// This interface intended to stay up to date with the openapi yaml used to generate it, +// while the service implementation can be ignored with the .openapi-generator-ignore file +// and updated with the logic required for the API. +type DriverAvailabilityAndScheduleAPIServicer interface { + DriverPunctualAvailabilitiesPost(context.Context, DriverPunctualAvailabilitiesRequest) (ImplResponse, error) + DriverRegularAvailabilitiesPost(context.Context, DriverRegularAvailabilitiesRequest) (ImplResponse, error) +} + +// InteractAPIServicer defines the api actions for the InteractAPI service +// This interface intended to stay up to date with the openapi yaml used to generate it, +// while the service implementation can be ignored with the .openapi-generator-ignore file +// and updated with the logic required for the API. +type InteractAPIServicer interface { + GetBookings(context.Context, string, string) (ImplResponse, error) + PatchBookings(context.Context, string, string, BookingStatus, string) (ImplResponse, error) + PostBookings(context.Context, BookingRequest) (ImplResponse, error) + PostConnections(context.Context, PostConnectionsRequest) (ImplResponse, error) +} + +// PassengerTripRequestAPIServicer defines the api actions for the PassengerTripRequestAPI service +// This interface intended to stay up to date with the openapi yaml used to generate it, +// while the service implementation can be ignored with the .openapi-generator-ignore file +// and updated with the logic required for the API. +type PassengerTripRequestAPIServicer interface { + PassengerPost(context.Context, PassengerTripRequest) (ImplResponse, error) +} + +// SearchAPIServicer defines the api actions for the SearchAPI service +// This interface intended to stay up to date with the openapi yaml used to generate it, +// while the service implementation can be ignored with the .openapi-generator-ignore file +// and updated with the logic required for the API. +type SearchAPIServicer interface { + GetDriverJourneys(context.Context, float32, float32, int32, string) (ImplResponse, error) +} diff --git a/interoperability/solidarity-api/server/openapi/api_bookings_filter.go b/interoperability/solidarity-api/server/openapi/api_bookings_filter.go new file mode 100644 index 0000000..3576e65 --- /dev/null +++ b/interoperability/solidarity-api/server/openapi/api_bookings_filter.go @@ -0,0 +1,82 @@ +/* + * Solidarity Mobility API + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * API version: 1.0.0 + * Generated by: OpenAPI Generator (https://openapi-generator.tech) + */ + +package openapi + +import ( + "net/http" + "strings" +) + +// BookingsFilterAPIController binds http requests to an api service and writes the service results to the http response +type BookingsFilterAPIController struct { + service BookingsFilterAPIServicer + errorHandler ErrorHandler +} + +// BookingsFilterAPIOption for how the controller is set up. +type BookingsFilterAPIOption func(*BookingsFilterAPIController) + +// WithBookingsFilterAPIErrorHandler inject ErrorHandler into controller +func WithBookingsFilterAPIErrorHandler(h ErrorHandler) BookingsFilterAPIOption { + return func(c *BookingsFilterAPIController) { + c.errorHandler = h + } +} + +// NewBookingsFilterAPIController creates a default api controller +func NewBookingsFilterAPIController(s BookingsFilterAPIServicer, opts ...BookingsFilterAPIOption) Router { + controller := &BookingsFilterAPIController{ + service: s, + errorHandler: DefaultErrorHandler, + } + + for _, opt := range opts { + opt(controller) + } + + return controller +} + +// Routes returns all the api routes for the BookingsFilterAPIController +func (c *BookingsFilterAPIController) Routes() Routes { + return Routes{ + "FilterBookingsByStatus": Route{ + strings.ToUpper("Get"), + "/bookings", + c.FilterBookingsByStatus, + }, + } +} + +// FilterBookingsByStatus - Filter and retrieve bookings by status, type, and ID. +func (c *BookingsFilterAPIController) FilterBookingsByStatus(w http.ResponseWriter, r *http.Request) { + authenticated := CheckOperatorAuthorization(r, AuthorizedOperators) + if !authenticated { + response := ImplResponse{ + Code: 401, + Body: "Unauthorized request. Check your operator / API Key.", + } + EncodeJSONResponse(response.Body, &response.Code, w) + return + } + query := r.URL.Query() + operatorParam := query.Get("operator") + statusParam := query.Get("status") + filterTypeParam := query.Get("filterType") + idParam := query.Get("Id") + result, err := c.service.FilterBookingsByStatus(r.Context(), operatorParam, statusParam, filterTypeParam, idParam) + // If an error occurred, encode the error with the status code + if err != nil { + c.errorHandler(w, r, err, &result) + return + } + // If no error, encode the body and the result code + EncodeJSONResponse(result.Body, &result.Code, w) +} diff --git a/interoperability/solidarity-api/server/openapi/api_bookings_filter_service.go b/interoperability/solidarity-api/server/openapi/api_bookings_filter_service.go new file mode 100644 index 0000000..42fd44f --- /dev/null +++ b/interoperability/solidarity-api/server/openapi/api_bookings_filter_service.go @@ -0,0 +1,111 @@ +/* + * Solidarity Mobility API + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * API version: 1.0.0 + * Generated by: OpenAPI Generator (https://openapi-generator.tech) + */ + +package openapi + +import ( + "context" + "fmt" + "github.com/spf13/viper" + "net/http" + "solidarity-service/handler" + "solidarity-service/internal" + "solidarity-service/storage" + "strings" +) + +// BookingsFilterAPIService is a service that implements the logic for the BookingsFilterAPIServicer +// This service should implement the business logic for every endpoint for the BookingsFilterAPI API. +// Include any external packages or services that will be required by this service. +type BookingsFilterAPIService struct { + config *viper.Viper + handler *handler.SolidarityServiceHandler + storage storage.Storage +} + +// NewBookingsFilterAPIService creates a default api service +func NewBookingsFilterAPIService(config *viper.Viper, handler *handler.SolidarityServiceHandler, storage storage.Storage) BookingsFilterAPIServicer { + return &BookingsFilterAPIService{ + config: config, + handler: handler, + storage: storage, + } +} + +// FilterBookingsByStatus - Filter and retrieve bookings by status, type, and ID. +func (s *BookingsFilterAPIService) FilterBookingsByStatus(ctx context.Context, operator string, status string, filterType string, id string) (ImplResponse, error) { + bookings, err := s.storage.FilterUserBookingsByStatus(filterType, internal.BookingStatus(status), id) + if err != nil { + fmt.Println(err) + if strings.Contains(err.Error(), " no rows in result set") { + return Response(http.StatusBadRequest, "ID not found in the database"), nil + } else { + return Response(http.StatusInternalServerError, nil), nil + } + } + responses := []Booking{} + for _, v := range bookings { + passenger, err := s.storage.GetPassenger(v.Passenger.ID) + if err != nil { + return Response(http.StatusInternalServerError, nil), nil + } + driver, err := s.storage.GetDriver(v.Driver.ID) + if err != nil { + return Response(http.StatusInternalServerError, nil), nil + } + duration, err := s.handler.CalculateDurationBetweenFeatures(passenger.Passenger_departure_address, passenger.Passenger_destination_address) + if err != nil { + duration = 0 + } + responses = append(responses, Booking{ + Id: v.ID, + Status: BookingStatus(v.Status), + Driver: User{ + Id: v.Driver.ID, + Operator: driver.Driver.Operator, + Alias: driver.Driver.Alias, + FirstName: driver.Driver.FirstName, + LastName: driver.Driver.LastName, + Grade: int32(driver.Driver.Grade), + Picture: driver.Driver.Picture, + Gender: driver.Driver.Gender, + VerifiedIdentity: driver.Driver.VerifiedIdentity, + }, + Passenger: User{ + Id: v.Passenger.ID, + Operator: passenger.Passenger.Operator, + Alias: passenger.Passenger.Alias, + FirstName: passenger.Passenger.FirstName, + LastName: passenger.Passenger.LastName, + Grade: int32(passenger.Passenger.Grade), + Picture: passenger.Passenger.Picture, + Gender: passenger.Passenger.Gender, + VerifiedIdentity: passenger.Passenger.VerifiedIdentity, + }, + PassengerPickupDate: int32(passenger.Passenger_pickup_date), + PassengerPickupLat: passenger.Passenger_departure_address.Point().X(), + PassengerPickupLng: passenger.Passenger_departure_address.Point().Y(), + PassengerPickupAddress: passenger.Passenger_departure_address.Properties.MustString("name"), + PassengerDropLat: passenger.Passenger_destination_address.Point().X(), + PassengerDropLng: passenger.Passenger_destination_address.Point().Y(), + PassengerDropAddress: passenger.Passenger_destination_address.Properties.MustString("name"), + Duration: int32(duration), + Distance: int32(s.handler.CalculateDistanceBetweenFeatures(passenger.Passenger_departure_address, passenger.Passenger_destination_address)), + Car: Car{ + Model: driver.Car.Model, + Brand: driver.Car.Brand, + }, + Price: Price{ + Type: "FREE", + }, + }) + } + + return Response(200, responses), nil +} diff --git a/interoperability/solidarity-api/server/openapi/api_driver_availability_and_schedule.go b/interoperability/solidarity-api/server/openapi/api_driver_availability_and_schedule.go new file mode 100644 index 0000000..02216f6 --- /dev/null +++ b/interoperability/solidarity-api/server/openapi/api_driver_availability_and_schedule.go @@ -0,0 +1,134 @@ +/* + * Solidarity Mobility API + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * API version: 1.0.0 + * Generated by: OpenAPI Generator (https://openapi-generator.tech) + */ + +package openapi + +import ( + "encoding/json" + "net/http" + "strings" +) + +// DriverAvailabilityAndScheduleAPIController binds http requests to an api service and writes the service results to the http response +type DriverAvailabilityAndScheduleAPIController struct { + service DriverAvailabilityAndScheduleAPIServicer + errorHandler ErrorHandler +} + +// DriverAvailabilityAndScheduleAPIOption for how the controller is set up. +type DriverAvailabilityAndScheduleAPIOption func(*DriverAvailabilityAndScheduleAPIController) + +// WithDriverAvailabilityAndScheduleAPIErrorHandler inject ErrorHandler into controller +func WithDriverAvailabilityAndScheduleAPIErrorHandler(h ErrorHandler) DriverAvailabilityAndScheduleAPIOption { + return func(c *DriverAvailabilityAndScheduleAPIController) { + c.errorHandler = h + } +} + +// NewDriverAvailabilityAndScheduleAPIController creates a default api controller +func NewDriverAvailabilityAndScheduleAPIController(s DriverAvailabilityAndScheduleAPIServicer, opts ...DriverAvailabilityAndScheduleAPIOption) Router { + controller := &DriverAvailabilityAndScheduleAPIController{ + service: s, + errorHandler: DefaultErrorHandler, + } + + for _, opt := range opts { + opt(controller) + } + + return controller +} + +// Routes returns all the api routes for the DriverAvailabilityAndScheduleAPIController +func (c *DriverAvailabilityAndScheduleAPIController) Routes() Routes { + return Routes{ + "DriverPunctualAvailabilitiesPost": Route{ + strings.ToUpper("Post"), + "/driver_punctual_availabilities", + c.DriverPunctualAvailabilitiesPost, + }, + "DriverRegularAvailabilitiesPost": Route{ + strings.ToUpper("Post"), + "/driver_regular_availabilities", + c.DriverRegularAvailabilitiesPost, + }, + } +} + +// DriverPunctualAvailabilitiesPost - Set Punctual Driver Availabilities +func (c *DriverAvailabilityAndScheduleAPIController) DriverPunctualAvailabilitiesPost(w http.ResponseWriter, r *http.Request) { + authenticated := CheckOperatorAuthorization(r, AuthorizedOperators) + if !authenticated { + response := ImplResponse{ + Code: 401, + Body: "Unauthorized request. Check your operator / API Key.", + } + EncodeJSONResponse(response.Body, &response.Code, w) + return + } + driverPunctualAvailabilitiesRequestParam := DriverPunctualAvailabilitiesRequest{} + d := json.NewDecoder(r.Body) + d.DisallowUnknownFields() + if err := d.Decode(&driverPunctualAvailabilitiesRequestParam); err != nil { + c.errorHandler(w, r, &ParsingError{Err: err}, nil) + return + } + if err := AssertDriverPunctualAvailabilitiesRequestRequired(driverPunctualAvailabilitiesRequestParam); err != nil { + c.errorHandler(w, r, err, nil) + return + } + if err := AssertDriverPunctualAvailabilitiesRequestConstraints(driverPunctualAvailabilitiesRequestParam); err != nil { + c.errorHandler(w, r, err, nil) + return + } + result, err := c.service.DriverPunctualAvailabilitiesPost(r.Context(), driverPunctualAvailabilitiesRequestParam) + // If an error occurred, encode the error with the status code + if err != nil { + c.errorHandler(w, r, err, &result) + return + } + // If no error, encode the body and the result code + EncodeJSONResponse(result.Body, &result.Code, w) +} + +// DriverRegularAvailabilitiesPost - Set Regular Driver Availabilities +func (c *DriverAvailabilityAndScheduleAPIController) DriverRegularAvailabilitiesPost(w http.ResponseWriter, r *http.Request) { + authenticated := CheckOperatorAuthorization(r, AuthorizedOperators) + if !authenticated { + response := ImplResponse{ + Code: 401, + Body: "Unauthorized request. Check your operator / API Key.", + } + EncodeJSONResponse(response.Body, &response.Code, w) + return + } + driverRegularAvailabilitiesRequestParam := DriverRegularAvailabilitiesRequest{} + d := json.NewDecoder(r.Body) + d.DisallowUnknownFields() + if err := d.Decode(&driverRegularAvailabilitiesRequestParam); err != nil { + c.errorHandler(w, r, &ParsingError{Err: err}, nil) + return + } + if err := AssertDriverRegularAvailabilitiesRequestRequired(driverRegularAvailabilitiesRequestParam); err != nil { + c.errorHandler(w, r, err, nil) + return + } + if err := AssertDriverRegularAvailabilitiesRequestConstraints(driverRegularAvailabilitiesRequestParam); err != nil { + c.errorHandler(w, r, err, nil) + return + } + result, err := c.service.DriverRegularAvailabilitiesPost(r.Context(), driverRegularAvailabilitiesRequestParam) + // If an error occurred, encode the error with the status code + if err != nil { + c.errorHandler(w, r, err, &result) + return + } + // If no error, encode the body and the result code + EncodeJSONResponse(result.Body, &result.Code, w) +} diff --git a/interoperability/solidarity-api/server/openapi/api_driver_availability_and_schedule_service.go b/interoperability/solidarity-api/server/openapi/api_driver_availability_and_schedule_service.go new file mode 100644 index 0000000..5ae7270 --- /dev/null +++ b/interoperability/solidarity-api/server/openapi/api_driver_availability_and_schedule_service.go @@ -0,0 +1,127 @@ +/* + * Solidarity Mobility API + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * API version: 1.0.0 + * Generated by: OpenAPI Generator (https://openapi-generator.tech) + */ + +package openapi + +import ( + "context" + "errors" + "github.com/paulmach/orb" + "github.com/paulmach/orb/geojson" + "github.com/spf13/viper" + "net/http" + "solidarity-service/handler" + "solidarity-service/internal" + "solidarity-service/storage" +) + +// DriverAvailabilityAndScheduleAPIService is a service that implements the logic for the DriverAvailabilityAndScheduleAPIServicer +// This service should implement the business logic for every endpoint for the DriverAvailabilityAndScheduleAPI API. +// Include any external packages or services that will be required by this service. +type DriverAvailabilityAndScheduleAPIService struct { + config *viper.Viper + handler *handler.SolidarityServiceHandler + storage storage.Storage +} + +// NewDriverAvailabilityAndScheduleAPIService creates a default api service +func NewDriverAvailabilityAndScheduleAPIService(config *viper.Viper, handler *handler.SolidarityServiceHandler, storage storage.Storage) DriverAvailabilityAndScheduleAPIServicer { + return &DriverAvailabilityAndScheduleAPIService{ + config: config, + handler: handler, + storage: storage, + } +} + +// DriverPunctualAvailabilitiesPost - Set Punctual Driver Availabilities +func (s *DriverAvailabilityAndScheduleAPIService) DriverPunctualAvailabilitiesPost(ctx context.Context, driverPunctualAvailabilitiesRequest DriverPunctualAvailabilitiesRequest) (ImplResponse, error) { + driver := internal.Driver{} + driver.Driver.ID = driverPunctualAvailabilitiesRequest.User.Id + driver.Driver.Operator = driverPunctualAvailabilitiesRequest.User.Operator + driver.Driver.Alias = driverPunctualAvailabilitiesRequest.User.Alias + driver.Driver.Grade = int64(driverPunctualAvailabilitiesRequest.User.Grade) + driver.Driver.Picture = driverPunctualAvailabilitiesRequest.User.Picture + driver.Driver.LastName = driverPunctualAvailabilitiesRequest.User.LastName + driver.Driver.FirstName = driverPunctualAvailabilitiesRequest.User.FirstName + driver.Driver.VerifiedIdentity = driverPunctualAvailabilitiesRequest.User.VerifiedIdentity + driver.Driver.Gender = driverPunctualAvailabilitiesRequest.User.Gender + driver.Preferences.Music = driverPunctualAvailabilitiesRequest.Preferences.Music + driver.Preferences.Is_talker = driverPunctualAvailabilitiesRequest.Preferences.IsTalker + driver.Preferences.Luggage_size = int64(driverPunctualAvailabilitiesRequest.Preferences.LuggageSize) + driver.Preferences.Smoking = driverPunctualAvailabilitiesRequest.Preferences.Smoking + driver.Preferences.Animals = driverPunctualAvailabilitiesRequest.Preferences.Animals + + driver.Driver_departure_address = &geojson.Feature{ + Type: "Feature", + Geometry: orb.Geometry(orb.Point{driverPunctualAvailabilitiesRequest.Latitude, driverPunctualAvailabilitiesRequest.Longitude}), + Properties: geojson.Properties{ + "name": driverPunctualAvailabilitiesRequest.Address, + }, + } + driver.Radius = driverPunctualAvailabilitiesRequest.Radius + driver.AvailabilitiesType = internal.Punctual + for _, v := range driverPunctualAvailabilitiesRequest.Availabilities { + driver.PunctualAvailabilities = append(driver.PunctualAvailabilities, internal.PunctualAvailabilities{ + Date: int64(v.Date), + StartTime: v.StartTime, + EndTime: v.EndTime, + }) + } + driver.Car.Brand = driverPunctualAvailabilitiesRequest.Car.Brand + driver.Car.Model = driverPunctualAvailabilitiesRequest.Car.Model + err := s.storage.CreateDriver(driver) + if err != nil { + return Response(http.StatusInternalServerError, nil), errors.New("DriverPunctualAvailabilitiesPost internal server error") + } else { + return Response(201, "Punctual driver availabilities set successfully"), nil + } +} + +// DriverRegularAvailabilitiesPost - Set Regular Driver Availabilities +func (s *DriverAvailabilityAndScheduleAPIService) DriverRegularAvailabilitiesPost(ctx context.Context, driverRegularAvailabilitiesRequest DriverRegularAvailabilitiesRequest) (ImplResponse, error) { + driver := internal.Driver{} + driver.Driver.ID = driverRegularAvailabilitiesRequest.User.Id + driver.Driver.Operator = driverRegularAvailabilitiesRequest.User.Operator + driver.Driver.Alias = driverRegularAvailabilitiesRequest.User.Alias + driver.Driver.Grade = int64(driverRegularAvailabilitiesRequest.User.Grade) + driver.Driver.Picture = driverRegularAvailabilitiesRequest.User.Picture + driver.Driver.LastName = driverRegularAvailabilitiesRequest.User.LastName + driver.Driver.FirstName = driverRegularAvailabilitiesRequest.User.FirstName + driver.Driver.VerifiedIdentity = driverRegularAvailabilitiesRequest.User.VerifiedIdentity + driver.Driver.Gender = driverRegularAvailabilitiesRequest.User.Gender + driver.Driver_departure_address = &geojson.Feature{ + Type: "Feature", + Geometry: orb.Geometry(orb.Point{driverRegularAvailabilitiesRequest.Latitude, driverRegularAvailabilitiesRequest.Longitude}), + Properties: geojson.Properties{ + "name": driverRegularAvailabilitiesRequest.Address, + }, + } + driver.Preferences.Music = driverRegularAvailabilitiesRequest.Preferences.Music + driver.Preferences.Is_talker = driverRegularAvailabilitiesRequest.Preferences.IsTalker + driver.Preferences.Luggage_size = int64(driverRegularAvailabilitiesRequest.Preferences.LuggageSize) + driver.Preferences.Smoking = driverRegularAvailabilitiesRequest.Preferences.Smoking + driver.Preferences.Animals = driverRegularAvailabilitiesRequest.Preferences.Animals + driver.Radius = driverRegularAvailabilitiesRequest.Radius + driver.AvailabilitiesType = internal.Regular + for _, v := range driverRegularAvailabilitiesRequest.Availabilities { + driver.RegularAvailabilities = append(driver.RegularAvailabilities, internal.RegularAvailabilities{ + DayOfWeek: v.DayOfWeek, + StartTime: v.StartTime, + EndTime: v.EndTime, + }) + } + driver.Car.Brand = driverRegularAvailabilitiesRequest.Car.Brand + driver.Car.Model = driverRegularAvailabilitiesRequest.Car.Model + err := s.storage.CreateDriver(driver) + if err != nil { + return Response(http.StatusInternalServerError, nil), errors.New("DriverPunctualAvailabilitiesPost internal server error") + } else { + return Response(201, "Regular driver availabilities set successfully"), nil + } +} diff --git a/interoperability/solidarity-api/server/openapi/api_interact.go b/interoperability/solidarity-api/server/openapi/api_interact.go new file mode 100644 index 0000000..21fb0e4 --- /dev/null +++ b/interoperability/solidarity-api/server/openapi/api_interact.go @@ -0,0 +1,190 @@ +/* + * Solidarity Mobility API + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * API version: 1.0.0 + * Generated by: OpenAPI Generator (https://openapi-generator.tech) + */ + +package openapi + +import ( + "encoding/json" + "errors" + "github.com/gorilla/mux" + "io" + "net/http" + "strings" +) + +// InteractAPIController binds http requests to an api service and writes the service results to the http response +type InteractAPIController struct { + service InteractAPIServicer + errorHandler ErrorHandler +} + +// InteractAPIOption for how the controller is set up. +type InteractAPIOption func(*InteractAPIController) + +// WithInteractAPIErrorHandler inject ErrorHandler into controller +func WithInteractAPIErrorHandler(h ErrorHandler) InteractAPIOption { + return func(c *InteractAPIController) { + c.errorHandler = h + } +} + +// NewInteractAPIController creates a default api controller +func NewInteractAPIController(s InteractAPIServicer, opts ...InteractAPIOption) Router { + controller := &InteractAPIController{ + service: s, + errorHandler: DefaultErrorHandler, + } + + for _, opt := range opts { + opt(controller) + } + + return controller +} + +// Routes returns all the api routes for the InteractAPIController +func (c *InteractAPIController) Routes() Routes { + return Routes{ + "GetBookings": Route{ + strings.ToUpper("Get"), + "/bookings/{bookingId}", + c.GetBookings, + }, + "PatchBookings": Route{ + strings.ToUpper("Patch"), + "/bookings/{bookingId}", + c.PatchBookings, + }, + "PostBookings": Route{ + strings.ToUpper("Post"), + "/bookings", + c.PostBookings, + }, + "PostConnections": Route{ + strings.ToUpper("Post"), + "/messages", + c.PostConnections, + }, + } +} + +// GetBookings - Retrieves an existing Booking request. +func (c *InteractAPIController) GetBookings(w http.ResponseWriter, r *http.Request) { + authenticated := CheckOperatorAuthorization(r, AuthorizedOperators) + if !authenticated { + response := ImplResponse{ + Code: 401, + Body: "Unauthorized request. Check your operator / API Key.", + } + EncodeJSONResponse(response.Body, &response.Code, w) + return + } + params := mux.Vars(r) + query := r.URL.Query() + operatorParam := query.Get("operator") + bookingIdParam := params["bookingId"] + result, err := c.service.GetBookings(r.Context(), operatorParam, bookingIdParam) + // If an error occurred, encode the error with the status code + if err != nil { + c.errorHandler(w, r, err, &result) + return + } + // If no error, encode the body and the result code + EncodeJSONResponse(result.Body, &result.Code, w) +} + +// PatchBookings - Updates status of an existing Booking request. +func (c *InteractAPIController) PatchBookings(w http.ResponseWriter, r *http.Request) { + authenticated := CheckOperatorAuthorization(r, AuthorizedOperators) + if !authenticated { + response := ImplResponse{ + Code: 401, + Body: "Unauthorized request. Check your operator / API Key.", + } + EncodeJSONResponse(response.Body, &response.Code, w) + return + } + params := mux.Vars(r) + query := r.URL.Query() + operatorParam := query.Get("operator") + bookingIdParam := params["bookingId"] + statusParam := query.Get("status") + messageParam := query.Get("message") + result, err := c.service.PatchBookings(r.Context(), operatorParam, bookingIdParam, BookingStatus(statusParam), messageParam) + // If an error occurred, encode the error with the status code + if err != nil { + c.errorHandler(w, r, err, &result) + return + } + // If no error, encode the body and the result code + EncodeJSONResponse(result.Body, &result.Code, w) +} + +// PostBookings - Create a punctual outward Booking request. +func (c *InteractAPIController) PostBookings(w http.ResponseWriter, r *http.Request) { + authenticated := CheckOperatorAuthorization(r, AuthorizedOperators) + if !authenticated { + response := ImplResponse{ + Code: 401, + Body: "Unauthorized request. Check your operator / API Key.", + } + EncodeJSONResponse(response.Body, &response.Code, w) + return + } + bookingRequestParam := BookingRequest{} + d := json.NewDecoder(r.Body) + d.DisallowUnknownFields() + if err := d.Decode(&bookingRequestParam); err != nil && !errors.Is(err, io.EOF) { + c.errorHandler(w, r, &ParsingError{Err: err}, nil) + return + } + if err := AssertBookingRequestRequired(bookingRequestParam); err != nil { + c.errorHandler(w, r, err, nil) + return + } + if err := AssertBookingRequestConstraints(bookingRequestParam); err != nil { + c.errorHandler(w, r, err, nil) + return + } + result, err := c.service.PostBookings(r.Context(), bookingRequestParam) + // If an error occurred, encode the error with the status code + if err != nil { + c.errorHandler(w, r, err, &result) + return + } + // If no error, encode the body and the result code + EncodeJSONResponse(result.Body, &result.Code, w) +} + +// PostConnections - Send a message to the owner of a retrieved journey. +func (c *InteractAPIController) PostConnections(w http.ResponseWriter, r *http.Request) { + postConnectionsRequestParam := PostConnectionsRequest{} + d := json.NewDecoder(r.Body) + d.DisallowUnknownFields() + if err := d.Decode(&postConnectionsRequestParam); err != nil && !errors.Is(err, io.EOF) { + c.errorHandler(w, r, &ParsingError{Err: err}, nil) + return + } + if err := AssertPostConnectionsRequestRequired(postConnectionsRequestParam); err != nil { + c.errorHandler(w, r, err, nil) + return + } + if err := AssertPostConnectionsRequestConstraints(postConnectionsRequestParam); err != nil { + c.errorHandler(w, r, err, nil) + return + } + result, err := c.service.PostConnections(r.Context(), postConnectionsRequestParam) + // If an error occurred, encode the error with the status code + if err != nil { + c.errorHandler(w, r, err, &result) + return + } + // If no error, encode the body and the result code + EncodeJSONResponse(result.Body, &result.Code, w) +} diff --git a/interoperability/solidarity-api/server/openapi/api_interact_service.go b/interoperability/solidarity-api/server/openapi/api_interact_service.go new file mode 100644 index 0000000..55dcac2 --- /dev/null +++ b/interoperability/solidarity-api/server/openapi/api_interact_service.go @@ -0,0 +1,196 @@ +/* + * Solidarity Mobility API + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * API version: 1.0.0 + * Generated by: OpenAPI Generator (https://openapi-generator.tech) +*/ + +package openapi + +import ( + "context" + "errors" + "fmt" + "github.com/spf13/viper" + "net/http" + "solidarity-service/handler" + "solidarity-service/internal" + "solidarity-service/storage" + "strings" +) + +// InteractAPIService is a service that implements the logic for the InteractAPIServicer +// This service should implement the business logic for every endpoint for the InteractAPI API. +// Include any external packages or services that will be required by this service. +type InteractAPIService struct { + config *viper.Viper + handler *handler.SolidarityServiceHandler + storage storage.Storage +} + +// NewInteractAPIService creates a default api service +func NewInteractAPIService(config *viper.Viper, handler *handler.SolidarityServiceHandler, storage storage.Storage) InteractAPIServicer { + return &InteractAPIService{ + config: config, + handler: handler, + storage: storage, + } +} + +// GetBookings - Retrieves an existing Booking request. +func (s *InteractAPIService) GetBookings(ctx context.Context, operator string, bookingId string) (ImplResponse, error) { + booking, err := s.storage.GetBooking(bookingId) + if err != nil { + if strings.Contains(err.Error(), " no rows in result set") { + return Response(http.StatusBadRequest, "ID not found in the database"), nil + } else { + return Response(http.StatusInternalServerError, nil), errors.New("DriverPunctualAvailabilitiesPost internal server error") + } + } + passenger, err := s.storage.GetPassenger(booking.Passenger.ID) + if err != nil { + return Response(http.StatusInternalServerError, nil), nil + } + driver, err := s.storage.GetDriver(booking.Driver.ID) + if err != nil { + return Response(http.StatusInternalServerError, nil), nil + } + duration, err := s.handler.CalculateDurationBetweenFeatures(passenger.Passenger_departure_address, passenger.Passenger_destination_address) + if err != nil { + duration = 0 + } + response := Booking{ + Id: booking.ID, + Driver: User{ + Id: driver.Driver.ID, + Operator: driver.Driver.Operator, + Alias: driver.Driver.Alias, + FirstName: driver.Driver.FirstName, + LastName: driver.Driver.LastName, + Grade: int32(driver.Driver.Grade), + Picture: driver.Driver.Picture, + Gender: driver.Driver.Gender, + VerifiedIdentity: driver.Driver.VerifiedIdentity, + }, + Passenger: User{ + Id: passenger.Passenger.ID, + Operator: passenger.Passenger.Operator, + Alias: passenger.Passenger.Alias, + FirstName: passenger.Passenger.FirstName, + LastName: passenger.Passenger.LastName, + Grade: int32(passenger.Passenger.Grade), + Picture: passenger.Passenger.Picture, + Gender: passenger.Passenger.Gender, + VerifiedIdentity: passenger.Passenger.VerifiedIdentity, + }, + PassengerPickupDate: int32(passenger.Passenger_pickup_date), + PassengerPickupLat: passenger.Passenger_departure_address.Point().X(), + PassengerPickupLng: passenger.Passenger_departure_address.Point().Y(), + PassengerPickupAddress: passenger.Passenger_departure_address.Properties.MustString("name"), + PassengerDropLat: passenger.Passenger_destination_address.Point().X(), + PassengerDropLng: passenger.Passenger_destination_address.Point().Y(), + PassengerDropAddress: passenger.Passenger_destination_address.Properties.MustString("name"), + Status: BookingStatus(booking.Status), + Duration: int32(duration), + Distance: int32(s.handler.CalculateDistanceBetweenFeatures(passenger.Passenger_departure_address, passenger.Passenger_destination_address)), + Car: Car{ + Model: driver.Car.Model, + Brand: driver.Car.Brand, + }, + Price: Price{ + Type: "FREE", + }, + } + fmt.Println(response) + return Response(200, response), nil + +} + +// PatchBookings - Updates status of an existing Booking request. +func (s *InteractAPIService) PatchBookings(ctx context.Context, operator string, bookingId string, status BookingStatus, message string) (ImplResponse, error) { + err := s.storage.UpdateBookingStatus(bookingId, internal.BookingStatus(status)) + fmt.Println(err) + if err != nil { + if strings.Contains(err.Error(), " no rows in result set") { + return Response(http.StatusBadRequest, "ID not found in the database"), nil + } + return Response(http.StatusInternalServerError, nil), nil + } + return Response(200, "Successful operation"), nil +} + +// PostBookings - Create a punctual outward Booking request. +func (s *InteractAPIService) PostBookings(ctx context.Context, bookingRequest BookingRequest) (ImplResponse, error) { + booking := internal.BookingRequest{} + booking.ID = bookingRequest.Id + booking.Status = internal.BookingStatus(bookingRequest.Status) + booking.Driver_id = bookingRequest.DriverId + booking.Passenger_id = bookingRequest.PassengerId + booking.Operator = bookingRequest.Operator + err := s.storage.CreateBooking(booking) + if err != nil { + return Response(http.StatusInternalServerError, nil), errors.New("PostBookings internal server error") + } + passenger, err := s.storage.GetPassenger(booking.Passenger_id) + if err != nil { + return Response(http.StatusInternalServerError, nil), errors.New("PostBookings internal server error") + } + driver, err := s.storage.GetDriver(booking.Driver_id) + if err != nil { + return Response(http.StatusInternalServerError, nil), errors.New("PostBookings internal server error") + } + duration, err := s.handler.CalculateDurationBetweenFeatures(passenger.Passenger_departure_address, passenger.Passenger_destination_address) + if err != nil { + duration = 0 + } + response := Booking{ + Id: bookingRequest.Id, + Driver: User{ + Id: driver.Driver.ID, + Operator: driver.Driver.Operator, + Alias: driver.Driver.Alias, + FirstName: driver.Driver.FirstName, + LastName: driver.Driver.LastName, + Grade: int32(driver.Driver.Grade), + Picture: driver.Driver.Picture, + Gender: driver.Driver.Gender, + VerifiedIdentity: driver.Driver.VerifiedIdentity, + }, + Passenger: User{ + Id: passenger.Passenger.ID, + Operator: passenger.Passenger.Operator, + Alias: passenger.Passenger.Alias, + FirstName: passenger.Passenger.FirstName, + LastName: passenger.Passenger.LastName, + Grade: int32(passenger.Passenger.Grade), + Picture: passenger.Passenger.Picture, + Gender: passenger.Passenger.Gender, + VerifiedIdentity: passenger.Passenger.VerifiedIdentity, + }, + PassengerPickupDate: int32(passenger.Passenger_pickup_date), + PassengerPickupLat: passenger.Passenger_departure_address.Point().X(), + PassengerPickupLng: passenger.Passenger_departure_address.Point().Y(), + PassengerPickupAddress: passenger.Passenger_departure_address.Properties.MustString("name"), + PassengerDropLat: passenger.Passenger_destination_address.Point().X(), + PassengerDropLng: passenger.Passenger_destination_address.Point().Y(), + PassengerDropAddress: passenger.Passenger_destination_address.Properties.MustString("name"), + Status: bookingRequest.Status, + Duration: int32(duration), + Distance: int32(s.handler.CalculateDistanceBetweenFeatures(passenger.Passenger_departure_address, passenger.Passenger_destination_address)), + Car: Car{ + Model: driver.Car.Model, + Brand: driver.Car.Brand, + }, + Price: Price{ + Type: "FREE", + }, + } + return Response(201, response), nil +} + +// PostConnections - Send a message to the owner of a retrieved journey. +func (s *InteractAPIService) PostConnections(ctx context.Context, postConnectionsRequest PostConnectionsRequest) (ImplResponse, error) { + return Response(http.StatusNotImplemented, nil), errors.New("PostConnections method not implemented") +} diff --git a/interoperability/solidarity-api/server/openapi/api_passenger_trip_request.go b/interoperability/solidarity-api/server/openapi/api_passenger_trip_request.go new file mode 100644 index 0000000..0b09467 --- /dev/null +++ b/interoperability/solidarity-api/server/openapi/api_passenger_trip_request.go @@ -0,0 +1,93 @@ +/* + * Solidarity Mobility API + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * API version: 1.0.0 + * Generated by: OpenAPI Generator (https://openapi-generator.tech) + */ + +package openapi + +import ( + "encoding/json" + "net/http" + "strings" +) + +// PassengerTripRequestAPIController binds http requests to an api service and writes the service results to the http response +type PassengerTripRequestAPIController struct { + service PassengerTripRequestAPIServicer + errorHandler ErrorHandler +} + +// PassengerTripRequestAPIOption for how the controller is set up. +type PassengerTripRequestAPIOption func(*PassengerTripRequestAPIController) + +// WithPassengerTripRequestAPIErrorHandler inject ErrorHandler into controller +func WithPassengerTripRequestAPIErrorHandler(h ErrorHandler) PassengerTripRequestAPIOption { + return func(c *PassengerTripRequestAPIController) { + c.errorHandler = h + } +} + +// NewPassengerTripRequestAPIController creates a default api controller +func NewPassengerTripRequestAPIController(s PassengerTripRequestAPIServicer, opts ...PassengerTripRequestAPIOption) Router { + controller := &PassengerTripRequestAPIController{ + service: s, + errorHandler: DefaultErrorHandler, + } + + for _, opt := range opts { + opt(controller) + } + + return controller +} + +// Routes returns all the api routes for the PassengerTripRequestAPIController +func (c *PassengerTripRequestAPIController) Routes() Routes { + return Routes{ + "PassengerPost": Route{ + strings.ToUpper("Post"), + "/passenger", + c.PassengerPost, + }, + } +} + +// PassengerPost - Create a Passenger Trip Request +func (c *PassengerTripRequestAPIController) PassengerPost(w http.ResponseWriter, r *http.Request) { + authenticated := CheckOperatorAuthorization(r, AuthorizedOperators) + if !authenticated { + response := ImplResponse{ + Code: 401, + Body: "Unauthorized request. Check your operator / API Key.", + } + EncodeJSONResponse(response.Body, &response.Code, w) + return + } + passengerTripRequestParam := PassengerTripRequest{} + d := json.NewDecoder(r.Body) + d.DisallowUnknownFields() + if err := d.Decode(&passengerTripRequestParam); err != nil { + c.errorHandler(w, r, &ParsingError{Err: err}, nil) + return + } + if err := AssertPassengerTripRequestRequired(passengerTripRequestParam); err != nil { + c.errorHandler(w, r, err, nil) + return + } + if err := AssertPassengerTripRequestConstraints(passengerTripRequestParam); err != nil { + c.errorHandler(w, r, err, nil) + return + } + result, err := c.service.PassengerPost(r.Context(), passengerTripRequestParam) + // If an error occurred, encode the error with the status code + if err != nil { + c.errorHandler(w, r, err, &result) + return + } + // If no error, encode the body and the result code + EncodeJSONResponse(result.Body, &result.Code, w) +} diff --git a/interoperability/solidarity-api/server/openapi/api_passenger_trip_request_service.go b/interoperability/solidarity-api/server/openapi/api_passenger_trip_request_service.go new file mode 100644 index 0000000..becc610 --- /dev/null +++ b/interoperability/solidarity-api/server/openapi/api_passenger_trip_request_service.go @@ -0,0 +1,80 @@ +/* + * Solidarity Mobility API + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * API version: 1.0.0 + * Generated by: OpenAPI Generator (https://openapi-generator.tech) + */ + +package openapi + +import ( + "context" + "errors" + "github.com/paulmach/orb" + "github.com/paulmach/orb/geojson" + "github.com/spf13/viper" + "net/http" + "solidarity-service/handler" + "solidarity-service/internal" + "solidarity-service/storage" +) + +// PassengerTripRequestAPIService is a service that implements the logic for the PassengerTripRequestAPIServicer +// This service should implement the business logic for every endpoint for the PassengerTripRequestAPI API. +// Include any external packages or services that will be required by this service. +type PassengerTripRequestAPIService struct { + config *viper.Viper + handler *handler.SolidarityServiceHandler + storage storage.Storage +} + +// NewPassengerTripRequestAPIService creates a default api service +func NewPassengerTripRequestAPIService(config *viper.Viper, handler *handler.SolidarityServiceHandler, storage storage.Storage) PassengerTripRequestAPIServicer { + return &PassengerTripRequestAPIService{ + config: config, + handler: handler, + storage: storage, + } +} + +// PassengerPost - Create a Passenger Trip Request +func (s *PassengerTripRequestAPIService) PassengerPost(ctx context.Context, passengerTripRequest PassengerTripRequest) (ImplResponse, error) { + passenger := internal.Passenger{} + passenger.Passenger_departure_address = &geojson.Feature{ + Type: "Feature", + Geometry: orb.Geometry(orb.Point{passengerTripRequest.DepartureLatitude, passengerTripRequest.DepartureLongitude}), + Properties: geojson.Properties{ + "name": passengerTripRequest.DepartureAddress, + }, + } + passenger.Passenger_destination_address = &geojson.Feature{ + Type: "Feature", + Geometry: orb.Geometry(orb.Point{passengerTripRequest.DestinationLatitude, passengerTripRequest.DestinationLongitude}), + Properties: geojson.Properties{ + "name": passengerTripRequest.DestinationAddress, + }, + } + passenger.Passenger_pickup_date = int64(passengerTripRequest.DepartureDate) + passenger.Passenger.ID = passengerTripRequest.User.Id + passenger.Passenger.Operator = passengerTripRequest.User.Operator + passenger.Passenger.Alias = passengerTripRequest.User.Alias + passenger.Passenger.FirstName = passengerTripRequest.User.FirstName + passenger.Passenger.LastName = passengerTripRequest.User.LastName + passenger.Passenger.Picture = passengerTripRequest.User.Picture + passenger.Passenger.Grade = int64(passengerTripRequest.User.Grade) + passenger.Passenger.Gender = passengerTripRequest.User.Gender + passenger.Passenger.VerifiedIdentity = passengerTripRequest.User.VerifiedIdentity + passenger.Preferences.Animals = passengerTripRequest.Preferences.Animals + passenger.Preferences.Luggage_size = int64(passengerTripRequest.Preferences.LuggageSize) + passenger.Preferences.Smoking = passengerTripRequest.Preferences.Smoking + passenger.Preferences.Is_talker = passengerTripRequest.Preferences.IsTalker + passenger.Preferences.Music = passengerTripRequest.Preferences.Music + err := s.storage.CreatePassenger(passenger) + if err != nil { + return Response(http.StatusInternalServerError, nil), errors.New("DriverPunctualAvailabilitiesPost internal server error") + } else { + return Response(201, "Trip request created"), nil + } +} diff --git a/interoperability/solidarity-api/server/openapi/api_search.go b/interoperability/solidarity-api/server/openapi/api_search.go new file mode 100644 index 0000000..f148f91 --- /dev/null +++ b/interoperability/solidarity-api/server/openapi/api_search.go @@ -0,0 +1,103 @@ +/* + * Solidarity Mobility API + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * API version: 1.0.0 + * Generated by: OpenAPI Generator (https://openapi-generator.tech) + */ + +package openapi + +import ( + "net/http" + "strings" +) + +// SearchAPIController binds http requests to an api service and writes the service results to the http response +type SearchAPIController struct { + service SearchAPIServicer + errorHandler ErrorHandler +} + +// SearchAPIOption for how the controller is set up. +type SearchAPIOption func(*SearchAPIController) + +// WithSearchAPIErrorHandler inject ErrorHandler into controller +func WithSearchAPIErrorHandler(h ErrorHandler) SearchAPIOption { + return func(c *SearchAPIController) { + c.errorHandler = h + } +} + +// NewSearchAPIController creates a default api controller +func NewSearchAPIController(s SearchAPIServicer, opts ...SearchAPIOption) Router { + controller := &SearchAPIController{ + service: s, + errorHandler: DefaultErrorHandler, + } + + for _, opt := range opts { + opt(controller) + } + + return controller +} + +// Routes returns all the api routes for the SearchAPIController +func (c *SearchAPIController) Routes() Routes { + return Routes{ + "GetDriverJourneys": Route{ + strings.ToUpper("Get"), + "/driver_journeys", + c.GetDriverJourneys, + }, + } +} + +// GetDriverJourneys - Search for matching punctual planned outward driver journeys. +func (c *SearchAPIController) GetDriverJourneys(w http.ResponseWriter, r *http.Request) { + authenticated := CheckOperatorAuthorization(r, AuthorizedOperators) + if !authenticated { + response := ImplResponse{ + Code: 401, + Body: "Unauthorized request. Check your operator / API Key.", + } + EncodeJSONResponse(response.Body, &response.Code, w) + return + } + query := r.URL.Query() + departureLatParam, err := parseNumericParameter[float32]( + query.Get("departureLat"), + WithRequire[float32](parseFloat32), + ) + if err != nil { + c.errorHandler(w, r, &ParsingError{Err: err}, nil) + return + } + departureLngParam, err := parseNumericParameter[float32]( + query.Get("departureLng"), + WithRequire[float32](parseFloat32), + ) + if err != nil { + c.errorHandler(w, r, &ParsingError{Err: err}, nil) + return + } + departureDateParam, err := parseNumericParameter[int32]( + query.Get("departureDate"), + WithRequire[int32](parseInt32), + ) + if err != nil { + c.errorHandler(w, r, &ParsingError{Err: err}, nil) + return + } + operatorParam := query.Get("operator") + result, err := c.service.GetDriverJourneys(r.Context(), departureLatParam, departureLngParam, departureDateParam, operatorParam) + // If an error occurred, encode the error with the status code + if err != nil { + c.errorHandler(w, r, err, &result) + return + } + // If no error, encode the body and the result code + EncodeJSONResponse(result.Body, &result.Code, w) +} diff --git a/interoperability/solidarity-api/server/openapi/api_search_service.go b/interoperability/solidarity-api/server/openapi/api_search_service.go new file mode 100644 index 0000000..75c8178 --- /dev/null +++ b/interoperability/solidarity-api/server/openapi/api_search_service.go @@ -0,0 +1,105 @@ +/* + * Solidarity Mobility API + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * API version: 1.0.0 + * Generated by: OpenAPI Generator (https://openapi-generator.tech) + */ + +package openapi + +import ( + "context" + "github.com/paulmach/orb" + "github.com/paulmach/orb/geojson" + "github.com/spf13/viper" + "net/http" + "solidarity-service/handler" + "solidarity-service/internal" + "solidarity-service/storage" + "strings" +) + +// SearchAPIService is a service that implements the logic for the SearchAPIServicer +// This service should implement the business logic for every endpoint for the SearchAPI API. +// Include any external packages or services that will be required by this service. +type SearchAPIService struct { + config *viper.Viper + handler *handler.SolidarityServiceHandler + storage storage.Storage +} + +// NewSearchAPIService creates a default api service +func NewSearchAPIService(config *viper.Viper, handler *handler.SolidarityServiceHandler, storage storage.Storage) SearchAPIServicer { + return &SearchAPIService{ + config: config, + handler: handler, + storage: storage, + } +} + +// GetDriverJourneys - Search for matching punctual planned outward driver journeys. +func (s *SearchAPIService) GetDriverJourneys(ctx context.Context, departureLat float32, departureLng float32, departureDate int32, operator string) (ImplResponse, error) { + drivers, err := s.storage.DriverJourneys(&geojson.Feature{ + Type: "Feature", + Geometry: orb.Geometry(orb.Point{float64(departureLat), float64(departureLng)}), + }, int64(departureDate)) + if err != nil { + if strings.Contains(err.Error(), " no rows in result set") { + return Response(http.StatusBadRequest, "ID not found in the database"), nil + } else { + return Response(http.StatusInternalServerError, nil), nil + } + } + response := []DriverJourney{} + for _, v := range drivers { + temp := DriverJourney{} + if v.AvailabilitiesType == internal.Regular && v.RegularAvailabilities != nil { + for _, v := range v.RegularAvailabilities { + temp.RegularAvailabilitySlot = append(temp.RegularAvailabilitySlot, RegularAvailabilitySlot{ + DayOfWeek: v.DayOfWeek, + StartTime: v.StartTime, + EndTime: v.EndTime, + }) + } + } else if v.AvailabilitiesType == internal.Punctual && v.PunctualAvailabilities != nil { + for _, v := range v.PunctualAvailabilities { + temp.PunctualAvailabilitySlot = append(temp.PunctualAvailabilitySlot, PunctualAvailabilitySlot{ + Date: int32(v.Date), + StartTime: v.StartTime, + EndTime: v.EndTime, + }) + } + } + tamp := DriverJourney{ + User: User{ + Id: v.Driver.ID, + Operator: v.Driver.Operator, + Alias: v.Driver.Alias, + FirstName: v.Driver.FirstName, + LastName: v.Driver.LastName, + Grade: int32(v.Driver.Grade), + Picture: v.Driver.Picture, + Gender: v.Driver.Gender, + VerifiedIdentity: v.Driver.VerifiedIdentity, + }, + Car: Car{ + Model: v.Car.Model, + Brand: v.Car.Brand, + }, + DriverDepartureDate: int64(departureDate), + Price: Price{ + Type: "FREE", + }, + DriverDepartureAddress: v.Driver_departure_address.Properties.MustString("name"), + } + temp.DriverDepartureAddress = tamp.DriverDepartureAddress + temp.Car = tamp.Car + temp.User = tamp.User + temp.DriverDepartureDate = tamp.DriverDepartureDate + temp.Price = tamp.Price + response = append(response, temp) + } + return Response(200, response), nil +} diff --git a/interoperability/solidarity-api/server/openapi/error.go b/interoperability/solidarity-api/server/openapi/error.go new file mode 100644 index 0000000..d242a86 --- /dev/null +++ b/interoperability/solidarity-api/server/openapi/error.go @@ -0,0 +1,62 @@ +/* + * Solidarity Mobility API + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * API version: 1.0.0 + * Generated by: OpenAPI Generator (https://openapi-generator.tech) + */ + +package openapi + +import ( + "errors" + "fmt" + "net/http" +) + +var ( + // ErrTypeAssertionError is thrown when type an interface does not match the asserted type + ErrTypeAssertionError = errors.New("unable to assert type") +) + +// ParsingError indicates that an error has occurred when parsing request parameters +type ParsingError struct { + Err error +} + +func (e *ParsingError) Unwrap() error { + return e.Err +} + +func (e *ParsingError) Error() string { + return e.Err.Error() +} + +// RequiredError indicates that an error has occurred when parsing request parameters +type RequiredError struct { + Field string +} + +func (e *RequiredError) Error() string { + return fmt.Sprintf("required field '%s' is zero value.", e.Field) +} + +// ErrorHandler defines the required method for handling error. You may implement it and inject this into a controller if +// you would like errors to be handled differently from the DefaultErrorHandler +type ErrorHandler func(w http.ResponseWriter, r *http.Request, err error, result *ImplResponse) + +// DefaultErrorHandler defines the default logic on how to handle errors from the controller. Any errors from parsing +// request params will return a StatusBadRequest. Otherwise, the error code originating from the servicer will be used. +func DefaultErrorHandler(w http.ResponseWriter, r *http.Request, err error, result *ImplResponse) { + if _, ok := err.(*ParsingError); ok { + // Handle parsing errors + EncodeJSONResponse(err.Error(), func(i int) *int { return &i }(http.StatusBadRequest), w) + } else if _, ok := err.(*RequiredError); ok { + // Handle missing required errors + EncodeJSONResponse(err.Error(), func(i int) *int { return &i }(http.StatusUnprocessableEntity), w) + } else { + // Handle all other errors + EncodeJSONResponse(err.Error(), &result.Code, w) + } +} diff --git a/interoperability/solidarity-api/server/openapi/helpers.go b/interoperability/solidarity-api/server/openapi/helpers.go new file mode 100644 index 0000000..3f4fdb5 --- /dev/null +++ b/interoperability/solidarity-api/server/openapi/helpers.go @@ -0,0 +1,60 @@ +/* + * Solidarity Mobility API + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * API version: 1.0.0 + * Generated by: OpenAPI Generator (https://openapi-generator.tech) + */ + +package openapi + +import ( + "reflect" +) + +// Response return a ImplResponse struct filled +func Response(code int, body interface{}) ImplResponse { + return ImplResponse { + Code: code, + Body: body, + } +} + +// IsZeroValue checks if the val is the zero-ed value. +func IsZeroValue(val interface{}) bool { + return val == nil || reflect.DeepEqual(val, reflect.Zero(reflect.TypeOf(val)).Interface()) +} + +// AssertRecurseInterfaceRequired recursively checks each struct in a slice against the callback. +// This method traverse nested slices in a preorder fashion. +func AssertRecurseInterfaceRequired[T any](obj interface{}, callback func(T) error) error { + return AssertRecurseValueRequired(reflect.ValueOf(obj), callback) +} + +// AssertRecurseValueRequired checks each struct in the nested slice against the callback. +// This method traverse nested slices in a preorder fashion. ErrTypeAssertionError is thrown if +// the underlying struct does not match type T. +func AssertRecurseValueRequired[T any](value reflect.Value, callback func(T) error) error { + switch value.Kind() { + // If it is a struct we check using callback + case reflect.Struct: + obj, ok := value.Interface().(T) + if !ok { + return ErrTypeAssertionError + } + + if err := callback(obj); err != nil { + return err + } + + // If it is a slice we continue recursion + case reflect.Slice: + for i := 0; i < value.Len(); i += 1 { + if err := AssertRecurseValueRequired(value.Index(i), callback); err != nil { + return err + } + } + } + return nil +} diff --git a/interoperability/solidarity-api/server/openapi/impl.go b/interoperability/solidarity-api/server/openapi/impl.go new file mode 100644 index 0000000..7bca802 --- /dev/null +++ b/interoperability/solidarity-api/server/openapi/impl.go @@ -0,0 +1,16 @@ +/* + * Solidarity Mobility API + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * API version: 1.0.0 + * Generated by: OpenAPI Generator (https://openapi-generator.tech) + */ + +package openapi + +// ImplResponse defines an implementation response with error code and the associated body +type ImplResponse struct { + Code int + Body interface{} +} diff --git a/interoperability/solidarity-api/server/openapi/logger.go b/interoperability/solidarity-api/server/openapi/logger.go new file mode 100644 index 0000000..045c03b --- /dev/null +++ b/interoperability/solidarity-api/server/openapi/logger.go @@ -0,0 +1,32 @@ +/* + * Solidarity Mobility API + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * API version: 1.0.0 + * Generated by: OpenAPI Generator (https://openapi-generator.tech) + */ + +package openapi + +import ( + "log" + "net/http" + "time" +) + +func Logger(inner http.Handler, name string) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + start := time.Now() + + inner.ServeHTTP(w, r) + + log.Printf( + "%s %s %s %s", + r.Method, + r.RequestURI, + name, + time.Since(start), + ) + }) +} diff --git a/interoperability/solidarity-api/server/openapi/model__passenger_post_400_response.go b/interoperability/solidarity-api/server/openapi/model__passenger_post_400_response.go new file mode 100644 index 0000000..6c640ba --- /dev/null +++ b/interoperability/solidarity-api/server/openapi/model__passenger_post_400_response.go @@ -0,0 +1,28 @@ +/* + * Solidarity Mobility API + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * API version: 1.0.0 + * Generated by: OpenAPI Generator (https://openapi-generator.tech) + */ + +package openapi + + + + +type PassengerPost400Response struct { + + Error string `json:"error,omitempty"` +} + +// AssertPassengerPost400ResponseRequired checks if the required fields are not zero-ed +func AssertPassengerPost400ResponseRequired(obj PassengerPost400Response) error { + return nil +} + +// AssertPassengerPost400ResponseConstraints checks if the values respects the defined constraints +func AssertPassengerPost400ResponseConstraints(obj PassengerPost400Response) error { + return nil +} diff --git a/interoperability/solidarity-api/server/openapi/model_booking.go b/interoperability/solidarity-api/server/openapi/model_booking.go new file mode 100644 index 0000000..01c976e --- /dev/null +++ b/interoperability/solidarity-api/server/openapi/model_booking.go @@ -0,0 +1,93 @@ +/* + * Solidarity Mobility API + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * API version: 1.0.0 + * Generated by: OpenAPI Generator (https://openapi-generator.tech) + */ + +package openapi + +type Booking struct { + + // Booking id is common between both operators, and must be created as a [UUID](https://datatracker.ietf.org/doc/html/rfc4122) by whoever initiates the booking. Usage of a [4 UUID](https://datatracker.ietf.org/doc/html/rfc4122#section-4.4) generation algorithm is advised. + Id string `json:"id"` + + Driver User `json:"driver"` + + Passenger User `json:"passenger"` + + // Passenger pickup datetime as a UNIX UTC timestamp in seconds. + PassengerPickupDate int32 `json:"passengerPickupDate"` + + // Latitude of the passenger pick-up point. + PassengerPickupLat float64 `json:"passengerPickupLat"` + + // Longitude of the passenger pick-up point. + PassengerPickupLng float64 `json:"passengerPickupLng"` + + // Latitude of the passenger drop-off point. + PassengerDropLat float64 `json:"passengerDropLat"` + + // Longitude of the passenger drop-off point. + PassengerDropLng float64 `json:"passengerDropLng"` + + // String representing the pickup-up address. + PassengerPickupAddress string `json:"passengerPickupAddress,omitempty"` + + // String representing the drop-off address. + PassengerDropAddress string `json:"passengerDropAddress,omitempty"` + + Status BookingStatus `json:"status"` + + // Carpooling duration in seconds. + Duration int32 `json:"duration,omitempty"` + + // Carpooling distance in meters. + Distance int32 `json:"distance,omitempty"` + + Price Price `json:"price"` + + Car Car `json:"car,omitempty"` +} + +// AssertBookingRequired checks if the required fields are not zero-ed +func AssertBookingRequired(obj Booking) error { + elements := map[string]interface{}{ + "id": obj.Id, + "driver": obj.Driver, + "passenger": obj.Passenger, + "passengerPickupDate": obj.PassengerPickupDate, + "passengerPickupLat": obj.PassengerPickupLat, + "passengerPickupLng": obj.PassengerPickupLng, + "passengerDropLat": obj.PassengerDropLat, + "passengerDropLng": obj.PassengerDropLng, + "status": obj.Status, + "price": obj.Price, + } + for name, el := range elements { + if isZero := IsZeroValue(el); isZero { + return &RequiredError{Field: name} + } + } + + if err := AssertUserRequired(obj.Driver); err != nil { + return err + } + if err := AssertUserRequired(obj.Passenger); err != nil { + return err + } + if err := AssertPriceRequired(obj.Price); err != nil { + return err + } + if err := AssertCarRequired(obj.Car); err != nil { + return err + } + return nil +} + +// AssertBookingConstraints checks if the values respects the defined constraints +func AssertBookingConstraints(obj Booking) error { + return nil +} diff --git a/interoperability/solidarity-api/server/openapi/model_booking_request.go b/interoperability/solidarity-api/server/openapi/model_booking_request.go new file mode 100644 index 0000000..476deed --- /dev/null +++ b/interoperability/solidarity-api/server/openapi/model_booking_request.go @@ -0,0 +1,50 @@ +/* + * Solidarity Mobility API + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * API version: 1.0.0 + * Generated by: OpenAPI Generator (https://openapi-generator.tech) + */ + +package openapi + + + + +type BookingRequest struct { + + // Booking id is common between both operators, and must be created as a [UUID](https://datatracker.ietf.org/doc/html/rfc4122) by whoever initiates the booking. Usage of a [4 UUID](https://datatracker.ietf.org/doc/html/rfc4122#section-4.4) generation algorithm is advised. + Id string `json:"id"` + + PassengerId string `json:"passengerId"` + + DriverId string `json:"driverId"` + + Status BookingStatus `json:"status"` + + Operator string `json:"operator"` +} + +// AssertBookingRequestRequired checks if the required fields are not zero-ed +func AssertBookingRequestRequired(obj BookingRequest) error { + elements := map[string]interface{}{ + "id": obj.Id, + "passengerId": obj.PassengerId, + "driverId": obj.DriverId, + "status": obj.Status, + "operator": obj.Operator, + } + for name, el := range elements { + if isZero := IsZeroValue(el); isZero { + return &RequiredError{Field: name} + } + } + + return nil +} + +// AssertBookingRequestConstraints checks if the values respects the defined constraints +func AssertBookingRequestConstraints(obj BookingRequest) error { + return nil +} diff --git a/interoperability/solidarity-api/server/openapi/model_booking_status.go b/interoperability/solidarity-api/server/openapi/model_booking_status.go new file mode 100644 index 0000000..b62b9ff --- /dev/null +++ b/interoperability/solidarity-api/server/openapi/model_booking_status.go @@ -0,0 +1,35 @@ +/* + * Solidarity Mobility API + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * API version: 1.0.0 + * Generated by: OpenAPI Generator (https://openapi-generator.tech) + */ + +package openapi + + + +// BookingStatus : Status of the booking. +type BookingStatus string + +// List of BookingStatus +const ( + WAITING_DRIVER_CONFIRMATION BookingStatus = "WAITING_DRIVER_CONFIRMATION" + WAITING_PASSENGER_CONFIRMATION BookingStatus = "WAITING_PASSENGER_CONFIRMATION" + CONFIRMED BookingStatus = "CONFIRMED" + CANCELLED BookingStatus = "CANCELLED" + COMPLETED_PENDING_VALIDATION BookingStatus = "COMPLETED_PENDING_VALIDATION" + VALIDATED BookingStatus = "VALIDATED" +) + +// AssertBookingStatusRequired checks if the required fields are not zero-ed +func AssertBookingStatusRequired(obj BookingStatus) error { + return nil +} + +// AssertBookingStatusConstraints checks if the values respects the defined constraints +func AssertBookingStatusConstraints(obj BookingStatus) error { + return nil +} diff --git a/interoperability/solidarity-api/server/openapi/model_car.go b/interoperability/solidarity-api/server/openapi/model_car.go new file mode 100644 index 0000000..234bcce --- /dev/null +++ b/interoperability/solidarity-api/server/openapi/model_car.go @@ -0,0 +1,32 @@ +/* + * Solidarity Mobility API + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * API version: 1.0.0 + * Generated by: OpenAPI Generator (https://openapi-generator.tech) + */ + +package openapi + + + + +type Car struct { + + // Model of the car. + Model string `json:"model,omitempty"` + + // Brand of the car. + Brand string `json:"brand,omitempty"` +} + +// AssertCarRequired checks if the required fields are not zero-ed +func AssertCarRequired(obj Car) error { + return nil +} + +// AssertCarConstraints checks if the values respects the defined constraints +func AssertCarConstraints(obj Car) error { + return nil +} diff --git a/interoperability/solidarity-api/server/openapi/model_driver_journey.go b/interoperability/solidarity-api/server/openapi/model_driver_journey.go new file mode 100644 index 0000000..f85dd69 --- /dev/null +++ b/interoperability/solidarity-api/server/openapi/model_driver_journey.go @@ -0,0 +1,51 @@ +/* + * Solidarity Mobility API + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * API version: 1.0.0 + * Generated by: OpenAPI Generator (https://openapi-generator.tech) + */ + +package openapi + +type DriverJourney struct { + User User `json:"user"` + + Car Car `json:"car,omitempty"` + RegularAvailabilitySlot []RegularAvailabilitySlot `json:"regular_availabilities,omitempty"` + PunctualAvailabilitySlot []PunctualAvailabilitySlot `json:"punctual_availabilities,omitempty"` + // Driver departure datetime as a UNIX UTC timestamp in seconds. + DriverDepartureDate int64 `json:"driver_departure_Date"` + DriverDepartureAddress string `json:"driver_departure_Address,omitempty"` + Price Price `json:"price,omitempty"` +} + +// AssertDriverJourneyRequired checks if the required fields are not zero-ed +func AssertDriverJourneyRequired(obj DriverJourney) error { + elements := map[string]interface{}{ + "user": obj.User, + "driverDepartureDate": obj.DriverDepartureDate, + } + for name, el := range elements { + if isZero := IsZeroValue(el); isZero { + return &RequiredError{Field: name} + } + } + + if err := AssertUserRequired(obj.User); err != nil { + return err + } + if err := AssertCarRequired(obj.Car); err != nil { + return err + } + if err := AssertPriceRequired(obj.Price); err != nil { + return err + } + return nil +} + +// AssertDriverJourneyConstraints checks if the values respects the defined constraints +func AssertDriverJourneyConstraints(obj DriverJourney) error { + return nil +} diff --git a/interoperability/solidarity-api/server/openapi/model_driver_punctual_availabilities_request.go b/interoperability/solidarity-api/server/openapi/model_driver_punctual_availabilities_request.go new file mode 100644 index 0000000..d8da4c2 --- /dev/null +++ b/interoperability/solidarity-api/server/openapi/model_driver_punctual_availabilities_request.go @@ -0,0 +1,74 @@ +/* + * Solidarity Mobility API + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * API version: 1.0.0 + * Generated by: OpenAPI Generator (https://openapi-generator.tech) + */ + +package openapi + + + + +type DriverPunctualAvailabilitiesRequest struct { + + // The address or location description. + Address string `json:"address"` + + // The latitude coordinate of the location. + Latitude float64 `json:"latitude"` + + // The longitude coordinate of the location. + Longitude float64 `json:"longitude"` + + // The radius around the location. + Radius int32 `json:"radius"` + + Availabilities []PunctualAvailabilitySlot `json:"availabilities"` + + User User `json:"user"` + + Preferences Preferences `json:"preferences,omitempty"` + + Car Car `json:"car,omitempty"` +} + +// AssertDriverPunctualAvailabilitiesRequestRequired checks if the required fields are not zero-ed +func AssertDriverPunctualAvailabilitiesRequestRequired(obj DriverPunctualAvailabilitiesRequest) error { + elements := map[string]interface{}{ + "address": obj.Address, + "latitude": obj.Latitude, + "longitude": obj.Longitude, + "radius": obj.Radius, + "availabilities": obj.Availabilities, + "user": obj.User, + } + for name, el := range elements { + if isZero := IsZeroValue(el); isZero { + return &RequiredError{Field: name} + } + } + + for _, el := range obj.Availabilities { + if err := AssertPunctualAvailabilitySlotRequired(el); err != nil { + return err + } + } + if err := AssertUserRequired(obj.User); err != nil { + return err + } + if err := AssertPreferencesRequired(obj.Preferences); err != nil { + return err + } + if err := AssertCarRequired(obj.Car); err != nil { + return err + } + return nil +} + +// AssertDriverPunctualAvailabilitiesRequestConstraints checks if the values respects the defined constraints +func AssertDriverPunctualAvailabilitiesRequestConstraints(obj DriverPunctualAvailabilitiesRequest) error { + return nil +} diff --git a/interoperability/solidarity-api/server/openapi/model_driver_regular_availabilities_request.go b/interoperability/solidarity-api/server/openapi/model_driver_regular_availabilities_request.go new file mode 100644 index 0000000..2b911a9 --- /dev/null +++ b/interoperability/solidarity-api/server/openapi/model_driver_regular_availabilities_request.go @@ -0,0 +1,74 @@ +/* + * Solidarity Mobility API + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * API version: 1.0.0 + * Generated by: OpenAPI Generator (https://openapi-generator.tech) + */ + +package openapi + + + + +type DriverRegularAvailabilitiesRequest struct { + + // The address or location description. + Address string `json:"address"` + + // The latitude coordinate of the location. + Latitude float64 `json:"latitude"` + + // The longitude coordinate of the location. + Longitude float64 `json:"longitude"` + + // The radius around the location. + Radius int32 `json:"radius"` + + Availabilities []RegularAvailabilitySlot `json:"availabilities"` + + User User `json:"user"` + + Preferences Preferences `json:"preferences,omitempty"` + + Car Car `json:"car,omitempty"` +} + +// AssertDriverRegularAvailabilitiesRequestRequired checks if the required fields are not zero-ed +func AssertDriverRegularAvailabilitiesRequestRequired(obj DriverRegularAvailabilitiesRequest) error { + elements := map[string]interface{}{ + "address": obj.Address, + "latitude": obj.Latitude, + "longitude": obj.Longitude, + "radius": obj.Radius, + "availabilities": obj.Availabilities, + "user": obj.User, + } + for name, el := range elements { + if isZero := IsZeroValue(el); isZero { + return &RequiredError{Field: name} + } + } + + for _, el := range obj.Availabilities { + if err := AssertRegularAvailabilitySlotRequired(el); err != nil { + return err + } + } + if err := AssertUserRequired(obj.User); err != nil { + return err + } + if err := AssertPreferencesRequired(obj.Preferences); err != nil { + return err + } + if err := AssertCarRequired(obj.Car); err != nil { + return err + } + return nil +} + +// AssertDriverRegularAvailabilitiesRequestConstraints checks if the values respects the defined constraints +func AssertDriverRegularAvailabilitiesRequestConstraints(obj DriverRegularAvailabilitiesRequest) error { + return nil +} diff --git a/interoperability/solidarity-api/server/openapi/model_driver_trip.go b/interoperability/solidarity-api/server/openapi/model_driver_trip.go new file mode 100644 index 0000000..343f55b --- /dev/null +++ b/interoperability/solidarity-api/server/openapi/model_driver_trip.go @@ -0,0 +1,45 @@ +/* + * Solidarity Mobility API + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * API version: 1.0.0 + * Generated by: OpenAPI Generator (https://openapi-generator.tech) + */ + +package openapi + + + + +type DriverTrip struct { + + User User `json:"user"` + + Car Car `json:"car,omitempty"` +} + +// AssertDriverTripRequired checks if the required fields are not zero-ed +func AssertDriverTripRequired(obj DriverTrip) error { + elements := map[string]interface{}{ + "user": obj.User, + } + for name, el := range elements { + if isZero := IsZeroValue(el); isZero { + return &RequiredError{Field: name} + } + } + + if err := AssertUserRequired(obj.User); err != nil { + return err + } + if err := AssertCarRequired(obj.Car); err != nil { + return err + } + return nil +} + +// AssertDriverTripConstraints checks if the values respects the defined constraints +func AssertDriverTripConstraints(obj DriverTrip) error { + return nil +} diff --git a/interoperability/solidarity-api/server/openapi/model_get_bookings_404_response.go b/interoperability/solidarity-api/server/openapi/model_get_bookings_404_response.go new file mode 100644 index 0000000..e445470 --- /dev/null +++ b/interoperability/solidarity-api/server/openapi/model_get_bookings_404_response.go @@ -0,0 +1,29 @@ +/* + * Solidarity Mobility API + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * API version: 1.0.0 + * Generated by: OpenAPI Generator (https://openapi-generator.tech) + */ + +package openapi + + + + +type GetBookings404Response struct { + + // Explain why the request couldn't be processed. + Error string `json:"error,omitempty"` +} + +// AssertGetBookings404ResponseRequired checks if the required fields are not zero-ed +func AssertGetBookings404ResponseRequired(obj GetBookings404Response) error { + return nil +} + +// AssertGetBookings404ResponseConstraints checks if the values respects the defined constraints +func AssertGetBookings404ResponseConstraints(obj GetBookings404Response) error { + return nil +} diff --git a/interoperability/solidarity-api/server/openapi/model_journey_schedule.go b/interoperability/solidarity-api/server/openapi/model_journey_schedule.go new file mode 100644 index 0000000..d414147 --- /dev/null +++ b/interoperability/solidarity-api/server/openapi/model_journey_schedule.go @@ -0,0 +1,45 @@ +/* + * Solidarity Mobility API + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * API version: 1.0.0 + * Generated by: OpenAPI Generator (https://openapi-generator.tech) + */ + +package openapi + + + + +type JourneySchedule struct { + + // Passenger pickup datetime as a UNIX UTC timestamp in seconds. + PassengerPickupDate float32 `json:"passengerPickupDate"` + + // Driver departure datetime as a UNIX UTC timestamp in seconds. + DriverDepartureDate float32 `json:"driverDepartureDate,omitempty"` + + // Type of journey. A dynamic journey is happening in real time. + Type string `json:"type"` +} + +// AssertJourneyScheduleRequired checks if the required fields are not zero-ed +func AssertJourneyScheduleRequired(obj JourneySchedule) error { + elements := map[string]interface{}{ + "passengerPickupDate": obj.PassengerPickupDate, + "type": obj.Type, + } + for name, el := range elements { + if isZero := IsZeroValue(el); isZero { + return &RequiredError{Field: name} + } + } + + return nil +} + +// AssertJourneyScheduleConstraints checks if the values respects the defined constraints +func AssertJourneyScheduleConstraints(obj JourneySchedule) error { + return nil +} diff --git a/interoperability/solidarity-api/server/openapi/model_passenger_trip_request.go b/interoperability/solidarity-api/server/openapi/model_passenger_trip_request.go new file mode 100644 index 0000000..7f73798 --- /dev/null +++ b/interoperability/solidarity-api/server/openapi/model_passenger_trip_request.go @@ -0,0 +1,67 @@ +/* + * Solidarity Mobility API + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * API version: 1.0.0 + * Generated by: OpenAPI Generator (https://openapi-generator.tech) + */ + +package openapi + + + + +type PassengerTripRequest struct { + + User User `json:"user"` + + DestinationAddress string `json:"destination_address"` + + DestinationLatitude float64 `json:"destination_latitude"` + + DestinationLongitude float64 `json:"destination_longitude"` + + DepartureAddress string `json:"departure_address"` + + DepartureLatitude float64 `json:"departure_latitude"` + + DepartureLongitude float64 `json:"departure_longitude"` + + // Departure datetime using a UNIX UTC timestamp in seconds. + DepartureDate int32 `json:"departure_date"` + + Preferences Preferences `json:"preferences,omitempty"` +} + +// AssertPassengerTripRequestRequired checks if the required fields are not zero-ed +func AssertPassengerTripRequestRequired(obj PassengerTripRequest) error { + elements := map[string]interface{}{ + "user": obj.User, + "destination_address": obj.DestinationAddress, + "destination_latitude": obj.DestinationLatitude, + "destination_longitude": obj.DestinationLongitude, + "departure_address": obj.DepartureAddress, + "departure_latitude": obj.DepartureLatitude, + "departure_longitude": obj.DepartureLongitude, + "departure_date": obj.DepartureDate, + } + for name, el := range elements { + if isZero := IsZeroValue(el); isZero { + return &RequiredError{Field: name} + } + } + + if err := AssertUserRequired(obj.User); err != nil { + return err + } + if err := AssertPreferencesRequired(obj.Preferences); err != nil { + return err + } + return nil +} + +// AssertPassengerTripRequestConstraints checks if the values respects the defined constraints +func AssertPassengerTripRequestConstraints(obj PassengerTripRequest) error { + return nil +} diff --git a/interoperability/solidarity-api/server/openapi/model_post_connections_request.go b/interoperability/solidarity-api/server/openapi/model_post_connections_request.go new file mode 100644 index 0000000..89bb684 --- /dev/null +++ b/interoperability/solidarity-api/server/openapi/model_post_connections_request.go @@ -0,0 +1,63 @@ +/* + * Solidarity Mobility API + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * API version: 1.0.0 + * Generated by: OpenAPI Generator (https://openapi-generator.tech) + */ + +package openapi + + + + +type PostConnectionsRequest struct { + + From User `json:"from"` + + To User `json:"to"` + + // Free text content of a message. The message can contain all the details (phone number, email, etc.) allowing the recipient to call back the sender in order to carpool with him/her. + Message string `json:"message"` + + // Defines if the recipient of this message is either the driver or the passenger. + RecipientCarpoolerType string `json:"recipientCarpoolerType"` + + // ID of the Driver's journey to which the message is related (if any). Unique given the `Driver`'s `operator` property. + DriverJourneyId string `json:"driverJourneyId,omitempty"` + + // ID of the Passenger's journey to which the message is related (if any). Unique given the `Passenger`'s `operator` property. + PassengerJourneyId string `json:"passengerJourneyId,omitempty"` + + // Booking id is common between both operators, and must be created as a [UUID](https://datatracker.ietf.org/doc/html/rfc4122) by whoever initiates the booking. Usage of a [4 UUID](https://datatracker.ietf.org/doc/html/rfc4122#section-4.4) generation algorithm is advised. + BookingId string `json:"bookingId,omitempty"` +} + +// AssertPostConnectionsRequestRequired checks if the required fields are not zero-ed +func AssertPostConnectionsRequestRequired(obj PostConnectionsRequest) error { + elements := map[string]interface{}{ + "from": obj.From, + "to": obj.To, + "message": obj.Message, + "recipientCarpoolerType": obj.RecipientCarpoolerType, + } + for name, el := range elements { + if isZero := IsZeroValue(el); isZero { + return &RequiredError{Field: name} + } + } + + if err := AssertUserRequired(obj.From); err != nil { + return err + } + if err := AssertUserRequired(obj.To); err != nil { + return err + } + return nil +} + +// AssertPostConnectionsRequestConstraints checks if the values respects the defined constraints +func AssertPostConnectionsRequestConstraints(obj PostConnectionsRequest) error { + return nil +} diff --git a/interoperability/solidarity-api/server/openapi/model_preferences.go b/interoperability/solidarity-api/server/openapi/model_preferences.go new file mode 100644 index 0000000..2b96b64 --- /dev/null +++ b/interoperability/solidarity-api/server/openapi/model_preferences.go @@ -0,0 +1,51 @@ +/* + * Solidarity Mobility API + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * API version: 1.0.0 + * Generated by: OpenAPI Generator (https://openapi-generator.tech) + */ + +package openapi + + +import ( + "errors" +) + + + +type Preferences struct { + + // If driver journey, specifies if the driver allows smoking in the car. + Smoking bool `json:"smoking,omitempty"` + + // If driver journey, specifies if the driver allows animals in the car. + Animals bool `json:"animals,omitempty"` + + // If driver journey, specifies if the driver enjoys music in the car. + Music bool `json:"music,omitempty"` + + // If driver journey, specifies if the driver enjoys talking with passengers. + IsTalker bool `json:"isTalker,omitempty"` + + // If driver journey, specifies the size of allowed luggages. From very small (1) to very big (5). + LuggageSize int32 `json:"luggageSize,omitempty"` +} + +// AssertPreferencesRequired checks if the required fields are not zero-ed +func AssertPreferencesRequired(obj Preferences) error { + return nil +} + +// AssertPreferencesConstraints checks if the values respects the defined constraints +func AssertPreferencesConstraints(obj Preferences) error { + if obj.LuggageSize < 1 { + return &ParsingError{Err: errors.New(errMsgMinValueConstraint)} + } + if obj.LuggageSize > 5 { + return &ParsingError{Err: errors.New(errMsgMaxValueConstraint)} + } + return nil +} diff --git a/interoperability/solidarity-api/server/openapi/model_price.go b/interoperability/solidarity-api/server/openapi/model_price.go new file mode 100644 index 0000000..43ece8c --- /dev/null +++ b/interoperability/solidarity-api/server/openapi/model_price.go @@ -0,0 +1,35 @@ +/* + * Solidarity Mobility API + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * API version: 1.0.0 + * Generated by: OpenAPI Generator (https://openapi-generator.tech) + */ + +package openapi + + + + +type Price struct { + + // Either « FREE », « PAYING » or « UNKNOWN ». « UNKNOWN » is given when it should be « PAYING » but we cannot set the price yet. + Type string `json:"type,omitempty"` + + // Carpooling passenger cost estimate. In the case of integrated booking by API, amount expected by the carpooling operator. + Amount float32 `json:"amount,omitempty"` + + // ISO 4217 code representing the currency of the price. + Currency string `json:"currency,omitempty"` +} + +// AssertPriceRequired checks if the required fields are not zero-ed +func AssertPriceRequired(obj Price) error { + return nil +} + +// AssertPriceConstraints checks if the values respects the defined constraints +func AssertPriceConstraints(obj Price) error { + return nil +} diff --git a/interoperability/solidarity-api/server/openapi/model_punctual_availability_slot.go b/interoperability/solidarity-api/server/openapi/model_punctual_availability_slot.go new file mode 100644 index 0000000..5e748ec --- /dev/null +++ b/interoperability/solidarity-api/server/openapi/model_punctual_availability_slot.go @@ -0,0 +1,46 @@ +/* + * Solidarity Mobility API + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * API version: 1.0.0 + * Generated by: OpenAPI Generator (https://openapi-generator.tech) + */ + +package openapi + + + + +type PunctualAvailabilitySlot struct { + + // UNIX UTC timestamp in seconds. + Date int32 `json:"date"` + + // Start time for punctual scheduling (RFC3339 partial-time). + StartTime string `json:"startTime"` + + // End time for punctual scheduling (RFC3339 partial-time). + EndTime string `json:"endTime"` +} + +// AssertPunctualAvailabilitySlotRequired checks if the required fields are not zero-ed +func AssertPunctualAvailabilitySlotRequired(obj PunctualAvailabilitySlot) error { + elements := map[string]interface{}{ + "date": obj.Date, + "startTime": obj.StartTime, + "endTime": obj.EndTime, + } + for name, el := range elements { + if isZero := IsZeroValue(el); isZero { + return &RequiredError{Field: name} + } + } + + return nil +} + +// AssertPunctualAvailabilitySlotConstraints checks if the values respects the defined constraints +func AssertPunctualAvailabilitySlotConstraints(obj PunctualAvailabilitySlot) error { + return nil +} diff --git a/interoperability/solidarity-api/server/openapi/model_regular_availability_slot.go b/interoperability/solidarity-api/server/openapi/model_regular_availability_slot.go new file mode 100644 index 0000000..2310cdb --- /dev/null +++ b/interoperability/solidarity-api/server/openapi/model_regular_availability_slot.go @@ -0,0 +1,46 @@ +/* + * Solidarity Mobility API + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * API version: 1.0.0 + * Generated by: OpenAPI Generator (https://openapi-generator.tech) + */ + +package openapi + + + + +type RegularAvailabilitySlot struct { + + // Day of the week for regular scheduling. + DayOfWeek string `json:"dayOfWeek"` + + // Start time for regular scheduling (RFC3339 partial-time). + StartTime string `json:"startTime"` + + // End time for regular scheduling (RFC3339 partial-time). + EndTime string `json:"endTime"` +} + +// AssertRegularAvailabilitySlotRequired checks if the required fields are not zero-ed +func AssertRegularAvailabilitySlotRequired(obj RegularAvailabilitySlot) error { + elements := map[string]interface{}{ + "dayOfWeek": obj.DayOfWeek, + "startTime": obj.StartTime, + "endTime": obj.EndTime, + } + for name, el := range elements { + if isZero := IsZeroValue(el); isZero { + return &RequiredError{Field: name} + } + } + + return nil +} + +// AssertRegularAvailabilitySlotConstraints checks if the values respects the defined constraints +func AssertRegularAvailabilitySlotConstraints(obj RegularAvailabilitySlot) error { + return nil +} diff --git a/interoperability/solidarity-api/server/openapi/model_user.go b/interoperability/solidarity-api/server/openapi/model_user.go new file mode 100644 index 0000000..d5c6c63 --- /dev/null +++ b/interoperability/solidarity-api/server/openapi/model_user.go @@ -0,0 +1,74 @@ +/* + * Solidarity Mobility API + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * API version: 1.0.0 + * Generated by: OpenAPI Generator (https://openapi-generator.tech) + */ + +package openapi + + +import ( + "errors" +) + + + +type User struct { + + // User's identifier. It MUST be unique for a given `operator`. + Id string `json:"id"` + + // The operator identifier. MUST be a Fully Qualified Domain Name (example carpool.mycity.com) owned by the operator or a Partially Qualified Domain Name (example operator.org) owned and exclusively operated by the operator. Operators SHOULD always send the same value. + Operator string `json:"operator"` + + // User's alias. + Alias string `json:"alias"` + + // User's first name. + FirstName string `json:"firstName,omitempty"` + + // User's last name. + LastName string `json:"lastName,omitempty"` + + // User's grade from 1 to 5. + Grade int32 `json:"grade,omitempty"` + + // User's profile picture absolute URL. + Picture string `json:"picture,omitempty"` + + // User's gender. 'O' stands for 'Other'. + Gender string `json:"gender,omitempty"` + + // true if the identity of this user has been verified by the operator or a third party; and the firstName, lastName, birthdate have been confirmed as identitical to an official identity proof document. Can be left empty if the information is not available. + VerifiedIdentity bool `json:"verifiedIdentity,omitempty"` +} + +// AssertUserRequired checks if the required fields are not zero-ed +func AssertUserRequired(obj User) error { + elements := map[string]interface{}{ + "id": obj.Id, + "operator": obj.Operator, + "alias": obj.Alias, + } + for name, el := range elements { + if isZero := IsZeroValue(el); isZero { + return &RequiredError{Field: name} + } + } + + return nil +} + +// AssertUserConstraints checks if the values respects the defined constraints +func AssertUserConstraints(obj User) error { + if obj.Grade < 1 { + return &ParsingError{Err: errors.New(errMsgMinValueConstraint)} + } + if obj.Grade > 5 { + return &ParsingError{Err: errors.New(errMsgMaxValueConstraint)} + } + return nil +} diff --git a/interoperability/solidarity-api/server/openapi/operators_authorization.go b/interoperability/solidarity-api/server/openapi/operators_authorization.go new file mode 100644 index 0000000..759e135 --- /dev/null +++ b/interoperability/solidarity-api/server/openapi/operators_authorization.go @@ -0,0 +1,68 @@ +package openapi + +import ( + "bytes" + "encoding/json" + "io/ioutil" + "net/http" + "strings" +) + +func CheckOperatorAuthorization(r *http.Request, authorizedOperators map[string]string) bool { + authorizationHeader := r.Header.Get("Authorization") + if authorizationHeader == "" { + return false + } + parts := strings.Split(authorizationHeader, " ") + if len(parts) != 2 { + return false + } + if parts[0] != "Bearer" { + return false + } + apiKey := parts[1] + operatorName, authorized := authorizedOperators[apiKey] + var operator string + var found bool + + if r.Body != nil { + body, err := ioutil.ReadAll(r.Body) + if err == nil { + var payload map[string]interface{} + if json.Unmarshal(body, &payload) == nil { + // Check for "operator" in the top-level body + if op, ok := payload["operator"].(string); ok { + operator = op + found = true + } else { + // Check for "user" struct in the body + if user, ok := payload["user"].(map[string]interface{}); ok { + if op, ok := user["operator"].(string); ok { + operator = op + found = true + } + } + } + } + } + r.Body = ioutil.NopCloser(bytes.NewReader(body)) + } + + // If operator is not found in the request body, check the request parameters. + if !found { + operatorFromParams := r.URL.Query().Get("operator") + if operatorFromParams != "" { + operator = operatorFromParams + found = true + } + } + + if found && operator == operatorName && authorized { + return true + } + return false +} + +var AuthorizedOperators = map[string]string{ + "$2y$10$TJuDZDu.mqy5dDKGMSfxSO5f6pz/36XVrAyQ1CXJd63ccjRlX7lmK": "test.com", +} diff --git a/interoperability/solidarity-api/server/openapi/routers.go b/interoperability/solidarity-api/server/openapi/routers.go new file mode 100644 index 0000000..ab4eed2 --- /dev/null +++ b/interoperability/solidarity-api/server/openapi/routers.go @@ -0,0 +1,297 @@ +/* + * Solidarity Mobility API + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * API version: 1.0.0 + * Generated by: OpenAPI Generator (https://openapi-generator.tech) + */ + +package openapi + +import ( + "encoding/json" + "errors" + "github.com/gorilla/mux" + "io/ioutil" + "mime/multipart" + "net/http" + "os" + "strconv" + "strings" +) + +// A Route defines the parameters for an api endpoint +type Route struct { + Method string + Pattern string + HandlerFunc http.HandlerFunc +} + +// Routes is a map of defined api endpoints +type Routes map[string]Route + +// Router defines the required methods for retrieving api routes +type Router interface { + Routes() Routes +} + +const errMsgRequiredMissing = "required parameter is missing" +const errMsgMinValueConstraint = "provided parameter is not respecting minimum value constraint" +const errMsgMaxValueConstraint = "provided parameter is not respecting maximum value constraint" + +// NewRouter creates a new router for any number of api routers +func NewRouter(routers ...Router) *mux.Router { + router := mux.NewRouter().StrictSlash(true) + for _, api := range routers { + for name, route := range api.Routes() { + var handler http.Handler + handler = route.HandlerFunc + handler = Logger(handler, name) + + router. + Methods(route.Method). + Path(route.Pattern). + Name(name). + Handler(handler) + } + } + + return router +} + +// EncodeJSONResponse uses the json encoder to write an interface to the http response with an optional status code +func EncodeJSONResponse(i interface{}, status *int, w http.ResponseWriter) error { + w.Header().Set("Content-Type", "application/json; charset=UTF-8") + if status != nil { + w.WriteHeader(*status) + } else { + w.WriteHeader(http.StatusOK) + } + + if i != nil { + return json.NewEncoder(w).Encode(i) + } + + return nil +} + +// ReadFormFileToTempFile reads file data from a request form and writes it to a temporary file +func ReadFormFileToTempFile(r *http.Request, key string) (*os.File, error) { + _, fileHeader, err := r.FormFile(key) + if err != nil { + return nil, err + } + + return readFileHeaderToTempFile(fileHeader) +} + +// ReadFormFilesToTempFiles reads files array data from a request form and writes it to a temporary files +func ReadFormFilesToTempFiles(r *http.Request, key string) ([]*os.File, error) { + if err := r.ParseMultipartForm(32 << 20); err != nil { + return nil, err + } + + files := make([]*os.File, 0, len(r.MultipartForm.File[key])) + + for _, fileHeader := range r.MultipartForm.File[key] { + file, err := readFileHeaderToTempFile(fileHeader) + if err != nil { + return nil, err + } + + files = append(files, file) + } + + return files, nil +} + +// readFileHeaderToTempFile reads multipart.FileHeader and writes it to a temporary file +func readFileHeaderToTempFile(fileHeader *multipart.FileHeader) (*os.File, error) { + formFile, err := fileHeader.Open() + if err != nil { + return nil, err + } + + defer formFile.Close() + + fileBytes, err := ioutil.ReadAll(formFile) + if err != nil { + return nil, err + } + + file, err := ioutil.TempFile("", fileHeader.Filename) + if err != nil { + return nil, err + } + + defer file.Close() + + file.Write(fileBytes) + + return file, nil +} + +type Number interface { + ~int32 | ~int64 | ~float32 | ~float64 +} + +type ParseString[T Number | string | bool] func(v string) (T, error) + +// parseFloat64 parses a string parameter to an float64. +func parseFloat64(param string) (float64, error) { + if param == "" { + return 0, nil + } + + return strconv.ParseFloat(param, 64) +} + +// parseFloat32 parses a string parameter to an float32. +func parseFloat32(param string) (float32, error) { + if param == "" { + return 0, nil + } + + v, err := strconv.ParseFloat(param, 32) + return float32(v), err +} + +// parseInt64 parses a string parameter to an int64. +func parseInt64(param string) (int64, error) { + if param == "" { + return 0, nil + } + + return strconv.ParseInt(param, 10, 64) +} + +// parseInt32 parses a string parameter to an int32. +func parseInt32(param string) (int32, error) { + if param == "" { + return 0, nil + } + + val, err := strconv.ParseInt(param, 10, 32) + return int32(val), err +} + +// parseBool parses a string parameter to an bool. +func parseBool(param string) (bool, error) { + if param == "" { + return false, nil + } + + return strconv.ParseBool(param) +} + +type Operation[T Number | string | bool] func(actual string) (T, bool, error) + +func WithRequire[T Number | string | bool](parse ParseString[T]) Operation[T] { + var empty T + return func(actual string) (T, bool, error) { + if actual == "" { + return empty, false, errors.New(errMsgRequiredMissing) + } + + v, err := parse(actual) + return v, false, err + } +} + +func WithDefaultOrParse[T Number | string | bool](def T, parse ParseString[T]) Operation[T] { + return func(actual string) (T, bool, error) { + if actual == "" { + return def, true, nil + } + + v, err := parse(actual) + return v, false, err + } +} + +func WithParse[T Number | string | bool](parse ParseString[T]) Operation[T] { + return func(actual string) (T, bool, error) { + v, err := parse(actual) + return v, false, err + } +} + +type Constraint[T Number | string | bool] func(actual T) error + +func WithMinimum[T Number](expected T) Constraint[T] { + return func(actual T) error { + if actual < expected { + return errors.New(errMsgMinValueConstraint) + } + + return nil + } +} + +func WithMaximum[T Number](expected T) Constraint[T] { + return func(actual T) error { + if actual > expected { + return errors.New(errMsgMaxValueConstraint) + } + + return nil + } +} + +// parseNumericParameter parses a numeric parameter to its respective type. +func parseNumericParameter[T Number](param string, fn Operation[T], checks ...Constraint[T]) (T, error) { + v, ok, err := fn(param) + if err != nil { + return 0, err + } + + if !ok { + for _, check := range checks { + if err := check(v); err != nil { + return 0, err + } + } + } + + return v, nil +} + +// parseBoolParameter parses a string parameter to a bool +func parseBoolParameter(param string, fn Operation[bool]) (bool, error) { + v, _, err := fn(param) + return v, err +} + +// parseNumericArrayParameter parses a string parameter containing array of values to its respective type. +func parseNumericArrayParameter[T Number](param, delim string, required bool, fn Operation[T], checks ...Constraint[T]) ([]T, error) { + if param == "" { + if required { + return nil, errors.New(errMsgRequiredMissing) + } + + return nil, nil + } + + str := strings.Split(param, delim) + values := make([]T, len(str)) + + for i, s := range str { + v, ok, err := fn(s) + if err != nil { + return nil, err + } + + if !ok { + for _, check := range checks { + if err := check(v); err != nil { + return nil, err + } + } + } + + values[i] = v + } + + return values, nil +} diff --git a/interoperability/solidarity-api/server/solidarity_api.go b/interoperability/solidarity-api/server/solidarity_api.go new file mode 100644 index 0000000..ae1a6d7 --- /dev/null +++ b/interoperability/solidarity-api/server/solidarity_api.go @@ -0,0 +1,40 @@ +/* + * Solidarity Mobility API + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * API version: 1.0.0 + * Generated by: OpenAPI Generator (https://openapi-generator.tech) + */ + +package Solidarity_api + +import ( + "github.com/spf13/viper" + "log" + "net/http" + "solidarity-service/handler" + "solidarity-service/interoperability/solidarity-api/server/openapi" + "solidarity-service/storage" +) + +func Run(cfg *viper.Viper, handler *handler.SolidarityServiceHandler, storage storage.Storage) { + BookingsFilterAPIService := openapi.NewBookingsFilterAPIService(cfg, handler, storage) + BookingsFilterAPIController := openapi.NewBookingsFilterAPIController(BookingsFilterAPIService) + + DriverAvailabilityAndScheduleAPIService := openapi.NewDriverAvailabilityAndScheduleAPIService(cfg, handler, storage) + DriverAvailabilityAndScheduleAPIController := openapi.NewDriverAvailabilityAndScheduleAPIController(DriverAvailabilityAndScheduleAPIService) + + InteractAPIService := openapi.NewInteractAPIService(cfg, handler, storage) + InteractAPIController := openapi.NewInteractAPIController(InteractAPIService) + + PassengerTripRequestAPIService := openapi.NewPassengerTripRequestAPIService(cfg, handler, storage) + PassengerTripRequestAPIController := openapi.NewPassengerTripRequestAPIController(PassengerTripRequestAPIService) + + SearchAPIService := openapi.NewSearchAPIService(cfg, handler, storage) + SearchAPIController := openapi.NewSearchAPIController(SearchAPIService) + + router := openapi.NewRouter(BookingsFilterAPIController, DriverAvailabilityAndScheduleAPIController, InteractAPIController, PassengerTripRequestAPIController, SearchAPIController) + + log.Fatal(http.ListenAndServe(":9999", router)) +} diff --git a/main.go b/main.go new file mode 100644 index 0000000..42cff29 --- /dev/null +++ b/main.go @@ -0,0 +1,60 @@ +package main + +import ( + routing "git.coopgo.io/coopgo-platform/routing-service" + "github.com/rs/zerolog" + "github.com/rs/zerolog/log" + SolidarityServiceHandler "solidarity-service/handler" + api "solidarity-service/interoperability/solidarity-api/server" + grpcserver "solidarity-service/servers/grpc/server" + "solidarity-service/storage" +) + +func main() { + zerolog.TimeFieldFormat = zerolog.TimeFormatUnix + + cfg, err := ReadConfig() + if err != nil { + panic(err) + } + + var ( + service_name = cfg.GetString("name") + grpc_enable = cfg.GetBool("services.grpc.enable") + solidarity_api_enable = cfg.GetBool("services.solidarity-api.enable") + routing_service_type = cfg.GetString("routing.type") + valhalla_base_url = cfg.GetString("routing.valhalla.base_url") + ) + + log.Info().Msg("Running " + service_name) + storageService, err := storage.NewStorage(cfg) + if err != nil { + log.Fatal().Err(err).Msg("Could not initiate the storage service") + return + } + routing, err := routing.NewRoutingService(routing_service_type, valhalla_base_url) + if err != nil { + log.Fatal().Err(err).Msg("Could not initiate the routing service") + return + } + handler, err := SolidarityServiceHandler.NewSolidarityServiceHandler(cfg, routing, storageService) + if err != nil { + log.Fatal().Err(err).Msg("Could not initiate the solidarity service handler") + return + } + + failed := make(chan error) + if grpc_enable { + log.Info().Msg("Running gRPC server") + go grpcserver.Run(failed, cfg, handler) + } + + if solidarity_api_enable { + log.Info().Msg("Running OCSS REST API") + go api.Run(cfg, handler, storageService) + } + + err = <-failed + + log.Fatal().Err(err).Msg("Terminating") +} diff --git a/servers/grpc/proto/solidarity-api-types.pb.go b/servers/grpc/proto/solidarity-api-types.pb.go new file mode 100644 index 0000000..a139ca8 --- /dev/null +++ b/servers/grpc/proto/solidarity-api-types.pb.go @@ -0,0 +1,1689 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.30.0 +// protoc v3.12.4 +// source: solidarity-api-types.proto + +package proto + +import ( + timestamp "github.com/golang/protobuf/ptypes/timestamp" + 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) +) + +type DayOfWeek int32 + +const ( + DayOfWeek_MON DayOfWeek = 0 + DayOfWeek_TUE DayOfWeek = 1 + DayOfWeek_WED DayOfWeek = 3 + DayOfWeek_THU DayOfWeek = 4 + DayOfWeek_FRI DayOfWeek = 5 + DayOfWeek_SAT DayOfWeek = 6 + DayOfWeek_SUN DayOfWeek = 7 +) + +// Enum value maps for DayOfWeek. +var ( + DayOfWeek_name = map[int32]string{ + 0: "MON", + 1: "TUE", + 3: "WED", + 4: "THU", + 5: "FRI", + 6: "SAT", + 7: "SUN", + } + DayOfWeek_value = map[string]int32{ + "MON": 0, + "TUE": 1, + "WED": 3, + "THU": 4, + "FRI": 5, + "SAT": 6, + "SUN": 7, + } +) + +func (x DayOfWeek) Enum() *DayOfWeek { + p := new(DayOfWeek) + *p = x + return p +} + +func (x DayOfWeek) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (DayOfWeek) Descriptor() protoreflect.EnumDescriptor { + return file_solidarity_api_types_proto_enumTypes[0].Descriptor() +} + +func (DayOfWeek) Type() protoreflect.EnumType { + return &file_solidarity_api_types_proto_enumTypes[0] +} + +func (x DayOfWeek) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use DayOfWeek.Descriptor instead. +func (DayOfWeek) EnumDescriptor() ([]byte, []int) { + return file_solidarity_api_types_proto_rawDescGZIP(), []int{0} +} + +type PriceType int32 + +const ( + PriceType_FREE PriceType = 0 + PriceType_PAYING PriceType = 1 + PriceType_UNKNOWN PriceType = 2 +) + +// Enum value maps for PriceType. +var ( + PriceType_name = map[int32]string{ + 0: "FREE", + 1: "PAYING", + 2: "UNKNOWN", + } + PriceType_value = map[string]int32{ + "FREE": 0, + "PAYING": 1, + "UNKNOWN": 2, + } +) + +func (x PriceType) Enum() *PriceType { + p := new(PriceType) + *p = x + return p +} + +func (x PriceType) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (PriceType) Descriptor() protoreflect.EnumDescriptor { + return file_solidarity_api_types_proto_enumTypes[1].Descriptor() +} + +func (PriceType) Type() protoreflect.EnumType { + return &file_solidarity_api_types_proto_enumTypes[1] +} + +func (x PriceType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use PriceType.Descriptor instead. +func (PriceType) EnumDescriptor() ([]byte, []int) { + return file_solidarity_api_types_proto_rawDescGZIP(), []int{1} +} + +type BookingStatus int32 + +const ( + BookingStatus_INITIATED BookingStatus = 0 + BookingStatus_WAITING_DRIVER_CONFIRMATION BookingStatus = 1 + BookingStatus_WAITING_PASSENGER_CONFIRMATION BookingStatus = 2 + BookingStatus_CONFIRMED BookingStatus = 3 + BookingStatus_CANCELLED BookingStatus = 4 + BookingStatus_COMPLETED_PENDING_VALIDATION BookingStatus = 5 + BookingStatus_VALIDATED BookingStatus = 6 +) + +// Enum value maps for BookingStatus. +var ( + BookingStatus_name = map[int32]string{ + 0: "INITIATED", + 1: "WAITING_DRIVER_CONFIRMATION", + 2: "WAITING_PASSENGER_CONFIRMATION", + 3: "CONFIRMED", + 4: "CANCELLED", + 5: "COMPLETED_PENDING_VALIDATION", + 6: "VALIDATED", + } + BookingStatus_value = map[string]int32{ + "INITIATED": 0, + "WAITING_DRIVER_CONFIRMATION": 1, + "WAITING_PASSENGER_CONFIRMATION": 2, + "CONFIRMED": 3, + "CANCELLED": 4, + "COMPLETED_PENDING_VALIDATION": 5, + "VALIDATED": 6, + } +) + +func (x BookingStatus) Enum() *BookingStatus { + p := new(BookingStatus) + *p = x + return p +} + +func (x BookingStatus) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (BookingStatus) Descriptor() protoreflect.EnumDescriptor { + return file_solidarity_api_types_proto_enumTypes[2].Descriptor() +} + +func (BookingStatus) Type() protoreflect.EnumType { + return &file_solidarity_api_types_proto_enumTypes[2] +} + +func (x BookingStatus) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use BookingStatus.Descriptor instead. +func (BookingStatus) EnumDescriptor() ([]byte, []int) { + return file_solidarity_api_types_proto_rawDescGZIP(), []int{2} +} + +type UserType int32 + +const ( + UserType_driver UserType = 0 + UserType_passenger UserType = 1 +) + +// Enum value maps for UserType. +var ( + UserType_name = map[int32]string{ + 0: "driver", + 1: "passenger", + } + UserType_value = map[string]int32{ + "driver": 0, + "passenger": 1, + } +) + +func (x UserType) Enum() *UserType { + p := new(UserType) + *p = x + return p +} + +func (x UserType) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (UserType) Descriptor() protoreflect.EnumDescriptor { + return file_solidarity_api_types_proto_enumTypes[3].Descriptor() +} + +func (UserType) Type() protoreflect.EnumType { + return &file_solidarity_api_types_proto_enumTypes[3] +} + +func (x UserType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use UserType.Descriptor instead. +func (UserType) EnumDescriptor() ([]byte, []int) { + return file_solidarity_api_types_proto_rawDescGZIP(), []int{3} +} + +type Feature struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Lat float64 `protobuf:"fixed64,1,opt,name=lat,proto3" json:"lat,omitempty"` + Long float64 `protobuf:"fixed64,2,opt,name=long,proto3" json:"long,omitempty"` + Address string `protobuf:"bytes,3,opt,name=address,proto3" json:"address,omitempty"` +} + +func (x *Feature) Reset() { + *x = Feature{} + if protoimpl.UnsafeEnabled { + mi := &file_solidarity_api_types_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Feature) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Feature) ProtoMessage() {} + +func (x *Feature) ProtoReflect() protoreflect.Message { + mi := &file_solidarity_api_types_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 Feature.ProtoReflect.Descriptor instead. +func (*Feature) Descriptor() ([]byte, []int) { + return file_solidarity_api_types_proto_rawDescGZIP(), []int{0} +} + +func (x *Feature) GetLat() float64 { + if x != nil { + return x.Lat + } + return 0 +} + +func (x *Feature) GetLong() float64 { + if x != nil { + return x.Long + } + return 0 +} + +func (x *Feature) GetAddress() string { + if x != nil { + return x.Address + } + return "" +} + +type DriverJourney struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + User *User `protobuf:"bytes,1,opt,name=user,proto3" json:"user,omitempty"` + Car *Car `protobuf:"bytes,2,opt,name=car,proto3,oneof" json:"car,omitempty"` + DriverDeparture_Date *timestamp.Timestamp `protobuf:"bytes,3,opt,name=driver_departure_Date,json=driverDepartureDate,proto3" json:"driver_departure_Date,omitempty"` + Price *Price `protobuf:"bytes,4,opt,name=price,proto3,oneof" json:"price,omitempty"` + DriverDeparture_Address string `protobuf:"bytes,5,opt,name=driver_departure_Address,json=driverDepartureAddress,proto3" json:"driver_departure_Address,omitempty"` + // Types that are assignable to Availabilities: + // + // *DriverJourney_RepeatedPunctualAvailabilities + // *DriverJourney_RepeatedRegularAvailabilities + Availabilities isDriverJourney_Availabilities `protobuf_oneof:"availabilities"` +} + +func (x *DriverJourney) Reset() { + *x = DriverJourney{} + if protoimpl.UnsafeEnabled { + mi := &file_solidarity_api_types_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DriverJourney) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DriverJourney) ProtoMessage() {} + +func (x *DriverJourney) ProtoReflect() protoreflect.Message { + mi := &file_solidarity_api_types_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 DriverJourney.ProtoReflect.Descriptor instead. +func (*DriverJourney) Descriptor() ([]byte, []int) { + return file_solidarity_api_types_proto_rawDescGZIP(), []int{1} +} + +func (x *DriverJourney) GetUser() *User { + if x != nil { + return x.User + } + return nil +} + +func (x *DriverJourney) GetCar() *Car { + if x != nil { + return x.Car + } + return nil +} + +func (x *DriverJourney) GetDriverDeparture_Date() *timestamp.Timestamp { + if x != nil { + return x.DriverDeparture_Date + } + return nil +} + +func (x *DriverJourney) GetPrice() *Price { + if x != nil { + return x.Price + } + return nil +} + +func (x *DriverJourney) GetDriverDeparture_Address() string { + if x != nil { + return x.DriverDeparture_Address + } + return "" +} + +func (m *DriverJourney) GetAvailabilities() isDriverJourney_Availabilities { + if m != nil { + return m.Availabilities + } + return nil +} + +func (x *DriverJourney) GetRepeatedPunctualAvailabilities() *RepeatedPunctualAvailabilitySlot { + if x, ok := x.GetAvailabilities().(*DriverJourney_RepeatedPunctualAvailabilities); ok { + return x.RepeatedPunctualAvailabilities + } + return nil +} + +func (x *DriverJourney) GetRepeatedRegularAvailabilities() *RepeatedRegularAvailabilitySlot { + if x, ok := x.GetAvailabilities().(*DriverJourney_RepeatedRegularAvailabilities); ok { + return x.RepeatedRegularAvailabilities + } + return nil +} + +type isDriverJourney_Availabilities interface { + isDriverJourney_Availabilities() +} + +type DriverJourney_RepeatedPunctualAvailabilities struct { + RepeatedPunctualAvailabilities *RepeatedPunctualAvailabilitySlot `protobuf:"bytes,6,opt,name=repeated_punctual_availabilities,json=repeatedPunctualAvailabilities,proto3,oneof"` +} + +type DriverJourney_RepeatedRegularAvailabilities struct { + RepeatedRegularAvailabilities *RepeatedRegularAvailabilitySlot `protobuf:"bytes,7,opt,name=repeated_regular_availabilities,json=repeatedRegularAvailabilities,proto3,oneof"` +} + +func (*DriverJourney_RepeatedPunctualAvailabilities) isDriverJourney_Availabilities() {} + +func (*DriverJourney_RepeatedRegularAvailabilities) isDriverJourney_Availabilities() {} + +type RepeatedPunctualAvailabilitySlot struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + PunctualAvailabilities []*PunctualAvailabilitySlot `protobuf:"bytes,1,rep,name=punctual_availabilities,json=punctualAvailabilities,proto3" json:"punctual_availabilities,omitempty"` +} + +func (x *RepeatedPunctualAvailabilitySlot) Reset() { + *x = RepeatedPunctualAvailabilitySlot{} + if protoimpl.UnsafeEnabled { + mi := &file_solidarity_api_types_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RepeatedPunctualAvailabilitySlot) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RepeatedPunctualAvailabilitySlot) ProtoMessage() {} + +func (x *RepeatedPunctualAvailabilitySlot) ProtoReflect() protoreflect.Message { + mi := &file_solidarity_api_types_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 RepeatedPunctualAvailabilitySlot.ProtoReflect.Descriptor instead. +func (*RepeatedPunctualAvailabilitySlot) Descriptor() ([]byte, []int) { + return file_solidarity_api_types_proto_rawDescGZIP(), []int{2} +} + +func (x *RepeatedPunctualAvailabilitySlot) GetPunctualAvailabilities() []*PunctualAvailabilitySlot { + if x != nil { + return x.PunctualAvailabilities + } + return nil +} + +type RepeatedRegularAvailabilitySlot struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + RegularAvailabilities []*RegularAvailabilitySlot `protobuf:"bytes,1,rep,name=regular_availabilities,json=regularAvailabilities,proto3" json:"regular_availabilities,omitempty"` +} + +func (x *RepeatedRegularAvailabilitySlot) Reset() { + *x = RepeatedRegularAvailabilitySlot{} + if protoimpl.UnsafeEnabled { + mi := &file_solidarity_api_types_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RepeatedRegularAvailabilitySlot) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RepeatedRegularAvailabilitySlot) ProtoMessage() {} + +func (x *RepeatedRegularAvailabilitySlot) ProtoReflect() protoreflect.Message { + mi := &file_solidarity_api_types_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 RepeatedRegularAvailabilitySlot.ProtoReflect.Descriptor instead. +func (*RepeatedRegularAvailabilitySlot) Descriptor() ([]byte, []int) { + return file_solidarity_api_types_proto_rawDescGZIP(), []int{3} +} + +func (x *RepeatedRegularAvailabilitySlot) GetRegularAvailabilities() []*RegularAvailabilitySlot { + if x != nil { + return x.RegularAvailabilities + } + return nil +} + +type DriverRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + DriverAddress *Feature `protobuf:"bytes,1,opt,name=driver_address,json=driverAddress,proto3" json:"driver_address,omitempty"` + DriverRadius int32 `protobuf:"varint,2,opt,name=driver_radius,json=driverRadius,proto3" json:"driver_radius,omitempty"` + Driver *User `protobuf:"bytes,3,opt,name=driver,proto3" json:"driver,omitempty"` + Preferences *Preferences `protobuf:"bytes,4,opt,name=preferences,proto3,oneof" json:"preferences,omitempty"` + Car *Car `protobuf:"bytes,5,opt,name=car,proto3,oneof" json:"car,omitempty"` +} + +func (x *DriverRequest) Reset() { + *x = DriverRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_solidarity_api_types_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DriverRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DriverRequest) ProtoMessage() {} + +func (x *DriverRequest) ProtoReflect() protoreflect.Message { + mi := &file_solidarity_api_types_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 DriverRequest.ProtoReflect.Descriptor instead. +func (*DriverRequest) Descriptor() ([]byte, []int) { + return file_solidarity_api_types_proto_rawDescGZIP(), []int{4} +} + +func (x *DriverRequest) GetDriverAddress() *Feature { + if x != nil { + return x.DriverAddress + } + return nil +} + +func (x *DriverRequest) GetDriverRadius() int32 { + if x != nil { + return x.DriverRadius + } + return 0 +} + +func (x *DriverRequest) GetDriver() *User { + if x != nil { + return x.Driver + } + return nil +} + +func (x *DriverRequest) GetPreferences() *Preferences { + if x != nil { + return x.Preferences + } + return nil +} + +func (x *DriverRequest) GetCar() *Car { + if x != nil { + return x.Car + } + return nil +} + +type PunctualAvailabilitySlot struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Date *timestamp.Timestamp `protobuf:"bytes,1,opt,name=date,proto3" json:"date,omitempty"` + StartTime string `protobuf:"bytes,2,opt,name=startTime,proto3" json:"startTime,omitempty"` + EndTime string `protobuf:"bytes,3,opt,name=endTime,proto3" json:"endTime,omitempty"` +} + +func (x *PunctualAvailabilitySlot) Reset() { + *x = PunctualAvailabilitySlot{} + if protoimpl.UnsafeEnabled { + mi := &file_solidarity_api_types_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PunctualAvailabilitySlot) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PunctualAvailabilitySlot) ProtoMessage() {} + +func (x *PunctualAvailabilitySlot) ProtoReflect() protoreflect.Message { + mi := &file_solidarity_api_types_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 PunctualAvailabilitySlot.ProtoReflect.Descriptor instead. +func (*PunctualAvailabilitySlot) Descriptor() ([]byte, []int) { + return file_solidarity_api_types_proto_rawDescGZIP(), []int{5} +} + +func (x *PunctualAvailabilitySlot) GetDate() *timestamp.Timestamp { + if x != nil { + return x.Date + } + return nil +} + +func (x *PunctualAvailabilitySlot) GetStartTime() string { + if x != nil { + return x.StartTime + } + return "" +} + +func (x *PunctualAvailabilitySlot) GetEndTime() string { + if x != nil { + return x.EndTime + } + return "" +} + +type RegularAvailabilitySlot struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + DayOfWeek DayOfWeek `protobuf:"varint,1,opt,name=dayOfWeek,proto3,enum=DayOfWeek" json:"dayOfWeek,omitempty"` + StartTime string `protobuf:"bytes,2,opt,name=startTime,proto3" json:"startTime,omitempty"` + EndTime string `protobuf:"bytes,3,opt,name=endTime,proto3" json:"endTime,omitempty"` +} + +func (x *RegularAvailabilitySlot) Reset() { + *x = RegularAvailabilitySlot{} + if protoimpl.UnsafeEnabled { + mi := &file_solidarity_api_types_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RegularAvailabilitySlot) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RegularAvailabilitySlot) ProtoMessage() {} + +func (x *RegularAvailabilitySlot) ProtoReflect() protoreflect.Message { + mi := &file_solidarity_api_types_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 RegularAvailabilitySlot.ProtoReflect.Descriptor instead. +func (*RegularAvailabilitySlot) Descriptor() ([]byte, []int) { + return file_solidarity_api_types_proto_rawDescGZIP(), []int{6} +} + +func (x *RegularAvailabilitySlot) GetDayOfWeek() DayOfWeek { + if x != nil { + return x.DayOfWeek + } + return DayOfWeek_MON +} + +func (x *RegularAvailabilitySlot) GetStartTime() string { + if x != nil { + return x.StartTime + } + return "" +} + +func (x *RegularAvailabilitySlot) GetEndTime() string { + if x != nil { + return x.EndTime + } + return "" +} + +type BookingRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + PassengerId string `protobuf:"bytes,2,opt,name=passengerId,proto3" json:"passengerId,omitempty"` + DriverId string `protobuf:"bytes,3,opt,name=driverId,proto3" json:"driverId,omitempty"` + Status BookingStatus `protobuf:"varint,4,opt,name=status,proto3,enum=BookingStatus" json:"status,omitempty"` +} + +func (x *BookingRequest) Reset() { + *x = BookingRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_solidarity_api_types_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *BookingRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BookingRequest) ProtoMessage() {} + +func (x *BookingRequest) ProtoReflect() protoreflect.Message { + mi := &file_solidarity_api_types_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 BookingRequest.ProtoReflect.Descriptor instead. +func (*BookingRequest) Descriptor() ([]byte, []int) { + return file_solidarity_api_types_proto_rawDescGZIP(), []int{7} +} + +func (x *BookingRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *BookingRequest) GetPassengerId() string { + if x != nil { + return x.PassengerId + } + return "" +} + +func (x *BookingRequest) GetDriverId() string { + if x != nil { + return x.DriverId + } + return "" +} + +func (x *BookingRequest) GetStatus() BookingStatus { + if x != nil { + return x.Status + } + return BookingStatus_INITIATED +} + +type Booking struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Driver *User `protobuf:"bytes,2,opt,name=driver,proto3" json:"driver,omitempty"` + Passenger *User `protobuf:"bytes,3,opt,name=passenger,proto3" json:"passenger,omitempty"` + PassengerPickupDate *timestamp.Timestamp `protobuf:"bytes,4,opt,name=passengerPickupDate,proto3" json:"passengerPickupDate,omitempty"` + PassengerDepartureRoute *Feature `protobuf:"bytes,5,opt,name=passenger_departure_route,json=passengerDepartureRoute,proto3" json:"passenger_departure_route,omitempty"` + PassengerDestinationRoute *Feature `protobuf:"bytes,6,opt,name=passenger_destination_route,json=passengerDestinationRoute,proto3" json:"passenger_destination_route,omitempty"` + Status BookingStatus `protobuf:"varint,7,opt,name=status,proto3,enum=BookingStatus" json:"status,omitempty"` + Duration *int64 `protobuf:"varint,8,opt,name=duration,proto3,oneof" json:"duration,omitempty"` + Distance *int64 `protobuf:"varint,9,opt,name=distance,proto3,oneof" json:"distance,omitempty"` + Price *Price `protobuf:"bytes,10,opt,name=price,proto3" json:"price,omitempty"` + Car *Car `protobuf:"bytes,11,opt,name=car,proto3,oneof" json:"car,omitempty"` +} + +func (x *Booking) Reset() { + *x = Booking{} + if protoimpl.UnsafeEnabled { + mi := &file_solidarity_api_types_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Booking) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Booking) ProtoMessage() {} + +func (x *Booking) ProtoReflect() protoreflect.Message { + mi := &file_solidarity_api_types_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 Booking.ProtoReflect.Descriptor instead. +func (*Booking) Descriptor() ([]byte, []int) { + return file_solidarity_api_types_proto_rawDescGZIP(), []int{8} +} + +func (x *Booking) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *Booking) GetDriver() *User { + if x != nil { + return x.Driver + } + return nil +} + +func (x *Booking) GetPassenger() *User { + if x != nil { + return x.Passenger + } + return nil +} + +func (x *Booking) GetPassengerPickupDate() *timestamp.Timestamp { + if x != nil { + return x.PassengerPickupDate + } + return nil +} + +func (x *Booking) GetPassengerDepartureRoute() *Feature { + if x != nil { + return x.PassengerDepartureRoute + } + return nil +} + +func (x *Booking) GetPassengerDestinationRoute() *Feature { + if x != nil { + return x.PassengerDestinationRoute + } + return nil +} + +func (x *Booking) GetStatus() BookingStatus { + if x != nil { + return x.Status + } + return BookingStatus_INITIATED +} + +func (x *Booking) GetDuration() int64 { + if x != nil && x.Duration != nil { + return *x.Duration + } + return 0 +} + +func (x *Booking) GetDistance() int64 { + if x != nil && x.Distance != nil { + return *x.Distance + } + return 0 +} + +func (x *Booking) GetPrice() *Price { + if x != nil { + return x.Price + } + return nil +} + +func (x *Booking) GetCar() *Car { + if x != nil { + return x.Car + } + return nil +} + +type Car struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Model *string `protobuf:"bytes,1,opt,name=model,proto3,oneof" json:"model,omitempty"` + Brand *string `protobuf:"bytes,2,opt,name=brand,proto3,oneof" json:"brand,omitempty"` +} + +func (x *Car) Reset() { + *x = Car{} + if protoimpl.UnsafeEnabled { + mi := &file_solidarity_api_types_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Car) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Car) ProtoMessage() {} + +func (x *Car) ProtoReflect() protoreflect.Message { + mi := &file_solidarity_api_types_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 Car.ProtoReflect.Descriptor instead. +func (*Car) Descriptor() ([]byte, []int) { + return file_solidarity_api_types_proto_rawDescGZIP(), []int{9} +} + +func (x *Car) GetModel() string { + if x != nil && x.Model != nil { + return *x.Model + } + return "" +} + +func (x *Car) GetBrand() string { + if x != nil && x.Brand != nil { + return *x.Brand + } + return "" +} + +type Preferences struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Smoking *bool `protobuf:"varint,1,opt,name=smoking,proto3,oneof" json:"smoking,omitempty"` + Animals *bool `protobuf:"varint,2,opt,name=animals,proto3,oneof" json:"animals,omitempty"` + Music *bool `protobuf:"varint,3,opt,name=music,proto3,oneof" json:"music,omitempty"` + IsTalker *bool `protobuf:"varint,4,opt,name=is_talker,json=isTalker,proto3,oneof" json:"is_talker,omitempty"` + LuggageSize *int64 `protobuf:"varint,5,opt,name=luggage_size,json=luggageSize,proto3,oneof" json:"luggage_size,omitempty"` +} + +func (x *Preferences) Reset() { + *x = Preferences{} + if protoimpl.UnsafeEnabled { + mi := &file_solidarity_api_types_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Preferences) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Preferences) ProtoMessage() {} + +func (x *Preferences) ProtoReflect() protoreflect.Message { + mi := &file_solidarity_api_types_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 Preferences.ProtoReflect.Descriptor instead. +func (*Preferences) Descriptor() ([]byte, []int) { + return file_solidarity_api_types_proto_rawDescGZIP(), []int{10} +} + +func (x *Preferences) GetSmoking() bool { + if x != nil && x.Smoking != nil { + return *x.Smoking + } + return false +} + +func (x *Preferences) GetAnimals() bool { + if x != nil && x.Animals != nil { + return *x.Animals + } + return false +} + +func (x *Preferences) GetMusic() bool { + if x != nil && x.Music != nil { + return *x.Music + } + return false +} + +func (x *Preferences) GetIsTalker() bool { + if x != nil && x.IsTalker != nil { + return *x.IsTalker + } + return false +} + +func (x *Preferences) GetLuggageSize() int64 { + if x != nil && x.LuggageSize != nil { + return *x.LuggageSize + } + return 0 +} + +type Price struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Type *PriceType `protobuf:"varint,1,opt,name=type,proto3,enum=PriceType,oneof" json:"type,omitempty"` + Amount *float64 `protobuf:"fixed64,2,opt,name=amount,proto3,oneof" json:"amount,omitempty"` + Currency *string `protobuf:"bytes,3,opt,name=currency,proto3,oneof" json:"currency,omitempty"` +} + +func (x *Price) Reset() { + *x = Price{} + if protoimpl.UnsafeEnabled { + mi := &file_solidarity_api_types_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Price) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Price) ProtoMessage() {} + +func (x *Price) ProtoReflect() protoreflect.Message { + mi := &file_solidarity_api_types_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 Price.ProtoReflect.Descriptor instead. +func (*Price) Descriptor() ([]byte, []int) { + return file_solidarity_api_types_proto_rawDescGZIP(), []int{11} +} + +func (x *Price) GetType() PriceType { + if x != nil && x.Type != nil { + return *x.Type + } + return PriceType_FREE +} + +func (x *Price) GetAmount() float64 { + if x != nil && x.Amount != nil { + return *x.Amount + } + return 0 +} + +func (x *Price) GetCurrency() string { + if x != nil && x.Currency != nil { + return *x.Currency + } + return "" +} + +type User struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Alias string `protobuf:"bytes,2,opt,name=alias,proto3" json:"alias,omitempty"` + FirstName *string `protobuf:"bytes,3,opt,name=first_name,json=firstName,proto3,oneof" json:"first_name,omitempty"` + LastName *string `protobuf:"bytes,4,opt,name=last_name,json=lastName,proto3,oneof" json:"last_name,omitempty"` + Grade *int64 `protobuf:"varint,5,opt,name=grade,proto3,oneof" json:"grade,omitempty"` + Picture *string `protobuf:"bytes,6,opt,name=picture,proto3,oneof" json:"picture,omitempty"` + Gender *string `protobuf:"bytes,7,opt,name=gender,proto3,oneof" json:"gender,omitempty"` + VerifiedIdentity *bool `protobuf:"varint,8,opt,name=verified_identity,json=verifiedIdentity,proto3,oneof" json:"verified_identity,omitempty"` +} + +func (x *User) Reset() { + *x = User{} + if protoimpl.UnsafeEnabled { + mi := &file_solidarity_api_types_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *User) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*User) ProtoMessage() {} + +func (x *User) ProtoReflect() protoreflect.Message { + mi := &file_solidarity_api_types_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 User.ProtoReflect.Descriptor instead. +func (*User) Descriptor() ([]byte, []int) { + return file_solidarity_api_types_proto_rawDescGZIP(), []int{12} +} + +func (x *User) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *User) GetAlias() string { + if x != nil { + return x.Alias + } + return "" +} + +func (x *User) GetFirstName() string { + if x != nil && x.FirstName != nil { + return *x.FirstName + } + return "" +} + +func (x *User) GetLastName() string { + if x != nil && x.LastName != nil { + return *x.LastName + } + return "" +} + +func (x *User) GetGrade() int64 { + if x != nil && x.Grade != nil { + return *x.Grade + } + return 0 +} + +func (x *User) GetPicture() string { + if x != nil && x.Picture != nil { + return *x.Picture + } + return "" +} + +func (x *User) GetGender() string { + if x != nil && x.Gender != nil { + return *x.Gender + } + return "" +} + +func (x *User) GetVerifiedIdentity() bool { + if x != nil && x.VerifiedIdentity != nil { + return *x.VerifiedIdentity + } + return false +} + +var File_solidarity_api_types_proto protoreflect.FileDescriptor + +var file_solidarity_api_types_proto_rawDesc = []byte{ + 0x0a, 0x1a, 0x73, 0x6f, 0x6c, 0x69, 0x64, 0x61, 0x72, 0x69, 0x74, 0x79, 0x2d, 0x61, 0x70, 0x69, + 0x2d, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, + 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x49, 0x0a, + 0x07, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6c, 0x61, 0x74, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x01, 0x52, 0x03, 0x6c, 0x61, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x6f, + 0x6e, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x01, 0x52, 0x04, 0x6c, 0x6f, 0x6e, 0x67, 0x12, 0x18, + 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x22, 0xf3, 0x03, 0x0a, 0x0d, 0x44, 0x72, 0x69, + 0x76, 0x65, 0x72, 0x4a, 0x6f, 0x75, 0x72, 0x6e, 0x65, 0x79, 0x12, 0x19, 0x0a, 0x04, 0x75, 0x73, + 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x05, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, + 0x04, 0x75, 0x73, 0x65, 0x72, 0x12, 0x1b, 0x0a, 0x03, 0x63, 0x61, 0x72, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x04, 0x2e, 0x43, 0x61, 0x72, 0x48, 0x01, 0x52, 0x03, 0x63, 0x61, 0x72, 0x88, + 0x01, 0x01, 0x12, 0x4e, 0x0a, 0x15, 0x64, 0x72, 0x69, 0x76, 0x65, 0x72, 0x5f, 0x64, 0x65, 0x70, + 0x61, 0x72, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x44, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x13, 0x64, + 0x72, 0x69, 0x76, 0x65, 0x72, 0x44, 0x65, 0x70, 0x61, 0x72, 0x74, 0x75, 0x72, 0x65, 0x44, 0x61, + 0x74, 0x65, 0x12, 0x21, 0x0a, 0x05, 0x70, 0x72, 0x69, 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x06, 0x2e, 0x50, 0x72, 0x69, 0x63, 0x65, 0x48, 0x02, 0x52, 0x05, 0x70, 0x72, 0x69, + 0x63, 0x65, 0x88, 0x01, 0x01, 0x12, 0x38, 0x0a, 0x18, 0x64, 0x72, 0x69, 0x76, 0x65, 0x72, 0x5f, + 0x64, 0x65, 0x70, 0x61, 0x72, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, + 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x16, 0x64, 0x72, 0x69, 0x76, 0x65, 0x72, 0x44, + 0x65, 0x70, 0x61, 0x72, 0x74, 0x75, 0x72, 0x65, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, + 0x6d, 0x0a, 0x20, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x70, 0x75, 0x6e, 0x63, + 0x74, 0x75, 0x61, 0x6c, 0x5f, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, + 0x69, 0x65, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x52, 0x65, 0x70, 0x65, + 0x61, 0x74, 0x65, 0x64, 0x50, 0x75, 0x6e, 0x63, 0x74, 0x75, 0x61, 0x6c, 0x41, 0x76, 0x61, 0x69, + 0x6c, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x53, 0x6c, 0x6f, 0x74, 0x48, 0x00, 0x52, 0x1e, + 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x50, 0x75, 0x6e, 0x63, 0x74, 0x75, 0x61, 0x6c, + 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x12, 0x6a, + 0x0a, 0x1f, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x72, 0x65, 0x67, 0x75, 0x6c, + 0x61, 0x72, 0x5f, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, + 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x52, 0x65, 0x70, 0x65, 0x61, 0x74, + 0x65, 0x64, 0x52, 0x65, 0x67, 0x75, 0x6c, 0x61, 0x72, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, + 0x69, 0x6c, 0x69, 0x74, 0x79, 0x53, 0x6c, 0x6f, 0x74, 0x48, 0x00, 0x52, 0x1d, 0x72, 0x65, 0x70, + 0x65, 0x61, 0x74, 0x65, 0x64, 0x52, 0x65, 0x67, 0x75, 0x6c, 0x61, 0x72, 0x41, 0x76, 0x61, 0x69, + 0x6c, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x42, 0x10, 0x0a, 0x0e, 0x61, 0x76, + 0x61, 0x69, 0x6c, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x42, 0x06, 0x0a, 0x04, + 0x5f, 0x63, 0x61, 0x72, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x70, 0x72, 0x69, 0x63, 0x65, 0x22, 0x76, + 0x0a, 0x20, 0x52, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x50, 0x75, 0x6e, 0x63, 0x74, 0x75, + 0x61, 0x6c, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x53, 0x6c, + 0x6f, 0x74, 0x12, 0x52, 0x0a, 0x17, 0x70, 0x75, 0x6e, 0x63, 0x74, 0x75, 0x61, 0x6c, 0x5f, 0x61, + 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x50, 0x75, 0x6e, 0x63, 0x74, 0x75, 0x61, 0x6c, 0x41, 0x76, + 0x61, 0x69, 0x6c, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x53, 0x6c, 0x6f, 0x74, 0x52, 0x16, + 0x70, 0x75, 0x6e, 0x63, 0x74, 0x75, 0x61, 0x6c, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x69, + 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x22, 0x72, 0x0a, 0x1f, 0x52, 0x65, 0x70, 0x65, 0x61, 0x74, + 0x65, 0x64, 0x52, 0x65, 0x67, 0x75, 0x6c, 0x61, 0x72, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, + 0x69, 0x6c, 0x69, 0x74, 0x79, 0x53, 0x6c, 0x6f, 0x74, 0x12, 0x4f, 0x0a, 0x16, 0x72, 0x65, 0x67, + 0x75, 0x6c, 0x61, 0x72, 0x5f, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, + 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x52, 0x65, 0x67, 0x75, + 0x6c, 0x61, 0x72, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x53, + 0x6c, 0x6f, 0x74, 0x52, 0x15, 0x72, 0x65, 0x67, 0x75, 0x6c, 0x61, 0x72, 0x41, 0x76, 0x61, 0x69, + 0x6c, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x22, 0xee, 0x01, 0x0a, 0x0d, 0x44, + 0x72, 0x69, 0x76, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2f, 0x0a, 0x0e, + 0x64, 0x72, 0x69, 0x76, 0x65, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x08, 0x2e, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x0d, + 0x64, 0x72, 0x69, 0x76, 0x65, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x23, 0x0a, + 0x0d, 0x64, 0x72, 0x69, 0x76, 0x65, 0x72, 0x5f, 0x72, 0x61, 0x64, 0x69, 0x75, 0x73, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x64, 0x72, 0x69, 0x76, 0x65, 0x72, 0x52, 0x61, 0x64, 0x69, + 0x75, 0x73, 0x12, 0x1d, 0x0a, 0x06, 0x64, 0x72, 0x69, 0x76, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x05, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x06, 0x64, 0x72, 0x69, 0x76, 0x65, + 0x72, 0x12, 0x33, 0x0a, 0x0b, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, + 0x6e, 0x63, 0x65, 0x73, 0x48, 0x00, 0x52, 0x0b, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, + 0x63, 0x65, 0x73, 0x88, 0x01, 0x01, 0x12, 0x1b, 0x0a, 0x03, 0x63, 0x61, 0x72, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x04, 0x2e, 0x43, 0x61, 0x72, 0x48, 0x01, 0x52, 0x03, 0x63, 0x61, 0x72, + 0x88, 0x01, 0x01, 0x42, 0x0e, 0x0a, 0x0c, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, + 0x63, 0x65, 0x73, 0x42, 0x06, 0x0a, 0x04, 0x5f, 0x63, 0x61, 0x72, 0x22, 0x82, 0x01, 0x0a, 0x18, + 0x50, 0x75, 0x6e, 0x63, 0x74, 0x75, 0x61, 0x6c, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x69, + 0x6c, 0x69, 0x74, 0x79, 0x53, 0x6c, 0x6f, 0x74, 0x12, 0x2e, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, + 0x6d, 0x70, 0x52, 0x04, 0x64, 0x61, 0x74, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x74, 0x61, 0x72, + 0x74, 0x54, 0x69, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x74, 0x61, + 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x64, 0x54, 0x69, 0x6d, + 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x65, 0x6e, 0x64, 0x54, 0x69, 0x6d, 0x65, + 0x22, 0x7b, 0x0a, 0x17, 0x52, 0x65, 0x67, 0x75, 0x6c, 0x61, 0x72, 0x41, 0x76, 0x61, 0x69, 0x6c, + 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x53, 0x6c, 0x6f, 0x74, 0x12, 0x28, 0x0a, 0x09, 0x64, + 0x61, 0x79, 0x4f, 0x66, 0x57, 0x65, 0x65, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0a, + 0x2e, 0x44, 0x61, 0x79, 0x4f, 0x66, 0x57, 0x65, 0x65, 0x6b, 0x52, 0x09, 0x64, 0x61, 0x79, 0x4f, + 0x66, 0x57, 0x65, 0x65, 0x6b, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, + 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, + 0x69, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x65, 0x6e, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x22, 0x86, 0x01, + 0x0a, 0x0e, 0x42, 0x6f, 0x6f, 0x6b, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, + 0x12, 0x20, 0x0a, 0x0b, 0x70, 0x61, 0x73, 0x73, 0x65, 0x6e, 0x67, 0x65, 0x72, 0x49, 0x64, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x70, 0x61, 0x73, 0x73, 0x65, 0x6e, 0x67, 0x65, 0x72, + 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x72, 0x69, 0x76, 0x65, 0x72, 0x49, 0x64, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x64, 0x72, 0x69, 0x76, 0x65, 0x72, 0x49, 0x64, 0x12, 0x26, + 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0e, + 0x2e, 0x42, 0x6f, 0x6f, 0x6b, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, + 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x82, 0x04, 0x0a, 0x07, 0x42, 0x6f, 0x6f, 0x6b, 0x69, + 0x6e, 0x67, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, + 0x69, 0x64, 0x12, 0x1d, 0x0a, 0x06, 0x64, 0x72, 0x69, 0x76, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x05, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x06, 0x64, 0x72, 0x69, 0x76, 0x65, + 0x72, 0x12, 0x23, 0x0a, 0x09, 0x70, 0x61, 0x73, 0x73, 0x65, 0x6e, 0x67, 0x65, 0x72, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x05, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x09, 0x70, 0x61, 0x73, + 0x73, 0x65, 0x6e, 0x67, 0x65, 0x72, 0x12, 0x4c, 0x0a, 0x13, 0x70, 0x61, 0x73, 0x73, 0x65, 0x6e, + 0x67, 0x65, 0x72, 0x50, 0x69, 0x63, 0x6b, 0x75, 0x70, 0x44, 0x61, 0x74, 0x65, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, + 0x13, 0x70, 0x61, 0x73, 0x73, 0x65, 0x6e, 0x67, 0x65, 0x72, 0x50, 0x69, 0x63, 0x6b, 0x75, 0x70, + 0x44, 0x61, 0x74, 0x65, 0x12, 0x44, 0x0a, 0x19, 0x70, 0x61, 0x73, 0x73, 0x65, 0x6e, 0x67, 0x65, + 0x72, 0x5f, 0x64, 0x65, 0x70, 0x61, 0x72, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x72, 0x6f, 0x75, 0x74, + 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x08, 0x2e, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, + 0x65, 0x52, 0x17, 0x70, 0x61, 0x73, 0x73, 0x65, 0x6e, 0x67, 0x65, 0x72, 0x44, 0x65, 0x70, 0x61, + 0x72, 0x74, 0x75, 0x72, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x12, 0x48, 0x0a, 0x1b, 0x70, 0x61, + 0x73, 0x73, 0x65, 0x6e, 0x67, 0x65, 0x72, 0x5f, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x08, 0x2e, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x19, 0x70, 0x61, 0x73, 0x73, 0x65, + 0x6e, 0x67, 0x65, 0x72, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, + 0x6f, 0x75, 0x74, 0x65, 0x12, 0x26, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x07, + 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0e, 0x2e, 0x42, 0x6f, 0x6f, 0x6b, 0x69, 0x6e, 0x67, 0x53, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1f, 0x0a, 0x08, + 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x03, 0x48, 0x00, + 0x52, 0x08, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x88, 0x01, 0x01, 0x12, 0x1f, 0x0a, + 0x08, 0x64, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x03, 0x48, + 0x01, 0x52, 0x08, 0x64, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x88, 0x01, 0x01, 0x12, 0x1c, + 0x0a, 0x05, 0x70, 0x72, 0x69, 0x63, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x06, 0x2e, + 0x50, 0x72, 0x69, 0x63, 0x65, 0x52, 0x05, 0x70, 0x72, 0x69, 0x63, 0x65, 0x12, 0x1b, 0x0a, 0x03, + 0x63, 0x61, 0x72, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x04, 0x2e, 0x43, 0x61, 0x72, 0x48, + 0x02, 0x52, 0x03, 0x63, 0x61, 0x72, 0x88, 0x01, 0x01, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x64, 0x75, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x64, 0x69, 0x73, 0x74, 0x61, + 0x6e, 0x63, 0x65, 0x42, 0x06, 0x0a, 0x04, 0x5f, 0x63, 0x61, 0x72, 0x22, 0x4f, 0x0a, 0x03, 0x43, + 0x61, 0x72, 0x12, 0x19, 0x0a, 0x05, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x48, 0x00, 0x52, 0x05, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x88, 0x01, 0x01, 0x12, 0x19, 0x0a, + 0x05, 0x62, 0x72, 0x61, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x01, 0x52, 0x05, + 0x62, 0x72, 0x61, 0x6e, 0x64, 0x88, 0x01, 0x01, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x6d, 0x6f, 0x64, + 0x65, 0x6c, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x62, 0x72, 0x61, 0x6e, 0x64, 0x22, 0xf1, 0x01, 0x0a, + 0x0b, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x1d, 0x0a, 0x07, + 0x73, 0x6d, 0x6f, 0x6b, 0x69, 0x6e, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, + 0x07, 0x73, 0x6d, 0x6f, 0x6b, 0x69, 0x6e, 0x67, 0x88, 0x01, 0x01, 0x12, 0x1d, 0x0a, 0x07, 0x61, + 0x6e, 0x69, 0x6d, 0x61, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x48, 0x01, 0x52, 0x07, + 0x61, 0x6e, 0x69, 0x6d, 0x61, 0x6c, 0x73, 0x88, 0x01, 0x01, 0x12, 0x19, 0x0a, 0x05, 0x6d, 0x75, + 0x73, 0x69, 0x63, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x48, 0x02, 0x52, 0x05, 0x6d, 0x75, 0x73, + 0x69, 0x63, 0x88, 0x01, 0x01, 0x12, 0x20, 0x0a, 0x09, 0x69, 0x73, 0x5f, 0x74, 0x61, 0x6c, 0x6b, + 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x48, 0x03, 0x52, 0x08, 0x69, 0x73, 0x54, 0x61, + 0x6c, 0x6b, 0x65, 0x72, 0x88, 0x01, 0x01, 0x12, 0x26, 0x0a, 0x0c, 0x6c, 0x75, 0x67, 0x67, 0x61, + 0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x48, 0x04, 0x52, + 0x0b, 0x6c, 0x75, 0x67, 0x67, 0x61, 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x88, 0x01, 0x01, 0x42, + 0x0a, 0x0a, 0x08, 0x5f, 0x73, 0x6d, 0x6f, 0x6b, 0x69, 0x6e, 0x67, 0x42, 0x0a, 0x0a, 0x08, 0x5f, + 0x61, 0x6e, 0x69, 0x6d, 0x61, 0x6c, 0x73, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x6d, 0x75, 0x73, 0x69, + 0x63, 0x42, 0x0c, 0x0a, 0x0a, 0x5f, 0x69, 0x73, 0x5f, 0x74, 0x61, 0x6c, 0x6b, 0x65, 0x72, 0x42, + 0x0f, 0x0a, 0x0d, 0x5f, 0x6c, 0x75, 0x67, 0x67, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, + 0x22, 0x8b, 0x01, 0x0a, 0x05, 0x50, 0x72, 0x69, 0x63, 0x65, 0x12, 0x23, 0x0a, 0x04, 0x74, 0x79, + 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0a, 0x2e, 0x50, 0x72, 0x69, 0x63, 0x65, + 0x54, 0x79, 0x70, 0x65, 0x48, 0x00, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x88, 0x01, 0x01, 0x12, + 0x1b, 0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x01, 0x48, + 0x01, 0x52, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x88, 0x01, 0x01, 0x12, 0x1f, 0x0a, 0x08, + 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x48, 0x02, + 0x52, 0x08, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x88, 0x01, 0x01, 0x42, 0x07, 0x0a, + 0x05, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x61, 0x6d, 0x6f, 0x75, 0x6e, + 0x74, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x22, 0xcf, + 0x02, 0x0a, 0x04, 0x55, 0x73, 0x65, 0x72, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x6c, 0x69, 0x61, 0x73, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x12, 0x22, 0x0a, + 0x0a, 0x66, 0x69, 0x72, 0x73, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x48, 0x00, 0x52, 0x09, 0x66, 0x69, 0x72, 0x73, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x88, 0x01, + 0x01, 0x12, 0x20, 0x0a, 0x09, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x09, 0x48, 0x01, 0x52, 0x08, 0x6c, 0x61, 0x73, 0x74, 0x4e, 0x61, 0x6d, 0x65, + 0x88, 0x01, 0x01, 0x12, 0x19, 0x0a, 0x05, 0x67, 0x72, 0x61, 0x64, 0x65, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x03, 0x48, 0x02, 0x52, 0x05, 0x67, 0x72, 0x61, 0x64, 0x65, 0x88, 0x01, 0x01, 0x12, 0x1d, + 0x0a, 0x07, 0x70, 0x69, 0x63, 0x74, 0x75, 0x72, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x48, + 0x03, 0x52, 0x07, 0x70, 0x69, 0x63, 0x74, 0x75, 0x72, 0x65, 0x88, 0x01, 0x01, 0x12, 0x1b, 0x0a, + 0x06, 0x67, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x48, 0x04, 0x52, + 0x06, 0x67, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x88, 0x01, 0x01, 0x12, 0x30, 0x0a, 0x11, 0x76, 0x65, + 0x72, 0x69, 0x66, 0x69, 0x65, 0x64, 0x5f, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x18, + 0x08, 0x20, 0x01, 0x28, 0x08, 0x48, 0x05, 0x52, 0x10, 0x76, 0x65, 0x72, 0x69, 0x66, 0x69, 0x65, + 0x64, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x88, 0x01, 0x01, 0x42, 0x0d, 0x0a, 0x0b, + 0x5f, 0x66, 0x69, 0x72, 0x73, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x42, 0x0c, 0x0a, 0x0a, 0x5f, + 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x67, 0x72, + 0x61, 0x64, 0x65, 0x42, 0x0a, 0x0a, 0x08, 0x5f, 0x70, 0x69, 0x63, 0x74, 0x75, 0x72, 0x65, 0x42, + 0x09, 0x0a, 0x07, 0x5f, 0x67, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x42, 0x14, 0x0a, 0x12, 0x5f, 0x76, + 0x65, 0x72, 0x69, 0x66, 0x69, 0x65, 0x64, 0x5f, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, + 0x2a, 0x4a, 0x0a, 0x09, 0x44, 0x61, 0x79, 0x4f, 0x66, 0x57, 0x65, 0x65, 0x6b, 0x12, 0x07, 0x0a, + 0x03, 0x4d, 0x4f, 0x4e, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x54, 0x55, 0x45, 0x10, 0x01, 0x12, + 0x07, 0x0a, 0x03, 0x57, 0x45, 0x44, 0x10, 0x03, 0x12, 0x07, 0x0a, 0x03, 0x54, 0x48, 0x55, 0x10, + 0x04, 0x12, 0x07, 0x0a, 0x03, 0x46, 0x52, 0x49, 0x10, 0x05, 0x12, 0x07, 0x0a, 0x03, 0x53, 0x41, + 0x54, 0x10, 0x06, 0x12, 0x07, 0x0a, 0x03, 0x53, 0x55, 0x4e, 0x10, 0x07, 0x2a, 0x2e, 0x0a, 0x09, + 0x50, 0x72, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x08, 0x0a, 0x04, 0x46, 0x52, 0x45, + 0x45, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x50, 0x41, 0x59, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, + 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x02, 0x2a, 0xb2, 0x01, 0x0a, + 0x0d, 0x42, 0x6f, 0x6f, 0x6b, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x0d, + 0x0a, 0x09, 0x49, 0x4e, 0x49, 0x54, 0x49, 0x41, 0x54, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1f, 0x0a, + 0x1b, 0x57, 0x41, 0x49, 0x54, 0x49, 0x4e, 0x47, 0x5f, 0x44, 0x52, 0x49, 0x56, 0x45, 0x52, 0x5f, + 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x52, 0x4d, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x01, 0x12, 0x22, + 0x0a, 0x1e, 0x57, 0x41, 0x49, 0x54, 0x49, 0x4e, 0x47, 0x5f, 0x50, 0x41, 0x53, 0x53, 0x45, 0x4e, + 0x47, 0x45, 0x52, 0x5f, 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x52, 0x4d, 0x41, 0x54, 0x49, 0x4f, 0x4e, + 0x10, 0x02, 0x12, 0x0d, 0x0a, 0x09, 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x52, 0x4d, 0x45, 0x44, 0x10, + 0x03, 0x12, 0x0d, 0x0a, 0x09, 0x43, 0x41, 0x4e, 0x43, 0x45, 0x4c, 0x4c, 0x45, 0x44, 0x10, 0x04, + 0x12, 0x20, 0x0a, 0x1c, 0x43, 0x4f, 0x4d, 0x50, 0x4c, 0x45, 0x54, 0x45, 0x44, 0x5f, 0x50, 0x45, + 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x5f, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x41, 0x54, 0x49, 0x4f, 0x4e, + 0x10, 0x05, 0x12, 0x0d, 0x0a, 0x09, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x41, 0x54, 0x45, 0x44, 0x10, + 0x06, 0x2a, 0x25, 0x0a, 0x08, 0x55, 0x73, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0a, 0x0a, + 0x06, 0x64, 0x72, 0x69, 0x76, 0x65, 0x72, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x70, 0x61, 0x73, + 0x73, 0x65, 0x6e, 0x67, 0x65, 0x72, 0x10, 0x01, 0x42, 0x45, 0x5a, 0x43, 0x67, 0x69, 0x74, 0x2e, + 0x63, 0x6f, 0x6f, 0x70, 0x67, 0x6f, 0x2e, 0x69, 0x6f, 0x2f, 0x63, 0x6f, 0x6f, 0x70, 0x67, 0x6f, + 0x2d, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x2f, 0x73, 0x6f, 0x6c, 0x69, 0x64, 0x61, + 0x72, 0x69, 0x74, 0x79, 0x2d, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2f, 0x73, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x73, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_solidarity_api_types_proto_rawDescOnce sync.Once + file_solidarity_api_types_proto_rawDescData = file_solidarity_api_types_proto_rawDesc +) + +func file_solidarity_api_types_proto_rawDescGZIP() []byte { + file_solidarity_api_types_proto_rawDescOnce.Do(func() { + file_solidarity_api_types_proto_rawDescData = protoimpl.X.CompressGZIP(file_solidarity_api_types_proto_rawDescData) + }) + return file_solidarity_api_types_proto_rawDescData +} + +var file_solidarity_api_types_proto_enumTypes = make([]protoimpl.EnumInfo, 4) +var file_solidarity_api_types_proto_msgTypes = make([]protoimpl.MessageInfo, 13) +var file_solidarity_api_types_proto_goTypes = []interface{}{ + (DayOfWeek)(0), // 0: DayOfWeek + (PriceType)(0), // 1: PriceType + (BookingStatus)(0), // 2: BookingStatus + (UserType)(0), // 3: UserType + (*Feature)(nil), // 4: Feature + (*DriverJourney)(nil), // 5: DriverJourney + (*RepeatedPunctualAvailabilitySlot)(nil), // 6: RepeatedPunctualAvailabilitySlot + (*RepeatedRegularAvailabilitySlot)(nil), // 7: RepeatedRegularAvailabilitySlot + (*DriverRequest)(nil), // 8: DriverRequest + (*PunctualAvailabilitySlot)(nil), // 9: PunctualAvailabilitySlot + (*RegularAvailabilitySlot)(nil), // 10: RegularAvailabilitySlot + (*BookingRequest)(nil), // 11: BookingRequest + (*Booking)(nil), // 12: Booking + (*Car)(nil), // 13: Car + (*Preferences)(nil), // 14: Preferences + (*Price)(nil), // 15: Price + (*User)(nil), // 16: User + (*timestamp.Timestamp)(nil), // 17: google.protobuf.Timestamp +} +var file_solidarity_api_types_proto_depIdxs = []int32{ + 16, // 0: DriverJourney.user:type_name -> User + 13, // 1: DriverJourney.car:type_name -> Car + 17, // 2: DriverJourney.driver_departure_Date:type_name -> google.protobuf.Timestamp + 15, // 3: DriverJourney.price:type_name -> Price + 6, // 4: DriverJourney.repeated_punctual_availabilities:type_name -> RepeatedPunctualAvailabilitySlot + 7, // 5: DriverJourney.repeated_regular_availabilities:type_name -> RepeatedRegularAvailabilitySlot + 9, // 6: RepeatedPunctualAvailabilitySlot.punctual_availabilities:type_name -> PunctualAvailabilitySlot + 10, // 7: RepeatedRegularAvailabilitySlot.regular_availabilities:type_name -> RegularAvailabilitySlot + 4, // 8: DriverRequest.driver_address:type_name -> Feature + 16, // 9: DriverRequest.driver:type_name -> User + 14, // 10: DriverRequest.preferences:type_name -> Preferences + 13, // 11: DriverRequest.car:type_name -> Car + 17, // 12: PunctualAvailabilitySlot.date:type_name -> google.protobuf.Timestamp + 0, // 13: RegularAvailabilitySlot.dayOfWeek:type_name -> DayOfWeek + 2, // 14: BookingRequest.status:type_name -> BookingStatus + 16, // 15: Booking.driver:type_name -> User + 16, // 16: Booking.passenger:type_name -> User + 17, // 17: Booking.passengerPickupDate:type_name -> google.protobuf.Timestamp + 4, // 18: Booking.passenger_departure_route:type_name -> Feature + 4, // 19: Booking.passenger_destination_route:type_name -> Feature + 2, // 20: Booking.status:type_name -> BookingStatus + 15, // 21: Booking.price:type_name -> Price + 13, // 22: Booking.car:type_name -> Car + 1, // 23: Price.type:type_name -> PriceType + 24, // [24:24] is the sub-list for method output_type + 24, // [24:24] is the sub-list for method input_type + 24, // [24:24] is the sub-list for extension type_name + 24, // [24:24] is the sub-list for extension extendee + 0, // [0:24] is the sub-list for field type_name +} + +func init() { file_solidarity_api_types_proto_init() } +func file_solidarity_api_types_proto_init() { + if File_solidarity_api_types_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_solidarity_api_types_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Feature); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_solidarity_api_types_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DriverJourney); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_solidarity_api_types_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RepeatedPunctualAvailabilitySlot); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_solidarity_api_types_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RepeatedRegularAvailabilitySlot); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_solidarity_api_types_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DriverRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_solidarity_api_types_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PunctualAvailabilitySlot); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_solidarity_api_types_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RegularAvailabilitySlot); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_solidarity_api_types_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*BookingRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_solidarity_api_types_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Booking); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_solidarity_api_types_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Car); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_solidarity_api_types_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Preferences); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_solidarity_api_types_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Price); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_solidarity_api_types_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*User); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + file_solidarity_api_types_proto_msgTypes[1].OneofWrappers = []interface{}{ + (*DriverJourney_RepeatedPunctualAvailabilities)(nil), + (*DriverJourney_RepeatedRegularAvailabilities)(nil), + } + file_solidarity_api_types_proto_msgTypes[4].OneofWrappers = []interface{}{} + file_solidarity_api_types_proto_msgTypes[8].OneofWrappers = []interface{}{} + file_solidarity_api_types_proto_msgTypes[9].OneofWrappers = []interface{}{} + file_solidarity_api_types_proto_msgTypes[10].OneofWrappers = []interface{}{} + file_solidarity_api_types_proto_msgTypes[11].OneofWrappers = []interface{}{} + file_solidarity_api_types_proto_msgTypes[12].OneofWrappers = []interface{}{} + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_solidarity_api_types_proto_rawDesc, + NumEnums: 4, + NumMessages: 13, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_solidarity_api_types_proto_goTypes, + DependencyIndexes: file_solidarity_api_types_proto_depIdxs, + EnumInfos: file_solidarity_api_types_proto_enumTypes, + MessageInfos: file_solidarity_api_types_proto_msgTypes, + }.Build() + File_solidarity_api_types_proto = out.File + file_solidarity_api_types_proto_rawDesc = nil + file_solidarity_api_types_proto_goTypes = nil + file_solidarity_api_types_proto_depIdxs = nil +} diff --git a/servers/grpc/proto/solidarity-api-types.proto b/servers/grpc/proto/solidarity-api-types.proto new file mode 100644 index 0000000..b40e22d --- /dev/null +++ b/servers/grpc/proto/solidarity-api-types.proto @@ -0,0 +1,133 @@ +syntax = "proto3"; +option go_package = "git.coopgo.io/coopgo-platform/solidarity-service/servers/grpc/proto"; +import "google/protobuf/timestamp.proto"; + + + +message Feature { + double lat = 1; + double long = 2; + string address = 3; +} + +message DriverJourney { + User user = 1; + optional Car car = 2; + google.protobuf.Timestamp driver_departure_Date = 3; + optional Price price = 4; + string driver_departure_Address = 5; + oneof availabilities { + RepeatedPunctualAvailabilitySlot repeated_punctual_availabilities = 6; + RepeatedRegularAvailabilitySlot repeated_regular_availabilities = 7; + } +} +message RepeatedPunctualAvailabilitySlot { + repeated PunctualAvailabilitySlot punctual_availabilities = 1; +} + +message RepeatedRegularAvailabilitySlot { + repeated RegularAvailabilitySlot regular_availabilities = 1; +} + +message DriverRequest{ + Feature driver_address = 1; + int32 driver_radius = 2; + User driver = 3; + optional Preferences preferences = 4; + optional Car car = 5; +} + +message PunctualAvailabilitySlot { + google.protobuf.Timestamp date = 1; + string startTime = 2; + string endTime = 3; +} +message RegularAvailabilitySlot { + DayOfWeek dayOfWeek = 1; + string startTime = 2; + string endTime = 3; +} + +enum DayOfWeek { + MON = 0; + TUE = 1; + WED = 3; + THU = 4; + FRI = 5; + SAT = 6; + SUN = 7; +} + +message BookingRequest { + string id = 1; + string passengerId = 2; + string driverId = 3; + BookingStatus status = 4; +} + +message Booking { + string id = 1; + User driver = 2; + User passenger = 3; + google.protobuf.Timestamp passengerPickupDate =4; + Feature passenger_departure_route = 5; + Feature passenger_destination_route = 6; + BookingStatus status = 7; + optional int64 duration = 8; + optional int64 distance = 9; + Price price = 10; + optional Car car = 11; +} + + +message Car { + optional string model = 1; + optional string brand = 2; +} + +message Preferences { + optional bool smoking = 1; + optional bool animals = 2; + optional bool music = 3; + optional bool is_talker = 4; + optional int64 luggage_size = 5; +} + + +enum PriceType { + FREE = 0; + PAYING = 1; + UNKNOWN = 2; +} + +message Price { + optional PriceType type = 1; + optional double amount = 2; + optional string currency = 3; +} + +message User { + string id = 1; + string alias = 2; + optional string first_name = 3; + optional string last_name = 4; + optional int64 grade = 5; + optional string picture = 6; + optional string gender = 7; + optional bool verified_identity = 8; +} + +enum BookingStatus { + INITIATED = 0; + WAITING_DRIVER_CONFIRMATION = 1; + WAITING_PASSENGER_CONFIRMATION = 2; + CONFIRMED = 3; + CANCELLED = 4; + COMPLETED_PENDING_VALIDATION = 5; + VALIDATED = 6; +} + +enum UserType{ + driver = 0; + passenger = 1; +} \ No newline at end of file diff --git a/servers/grpc/proto/solidarity-api.pb.go b/servers/grpc/proto/solidarity-api.pb.go new file mode 100644 index 0000000..3e6311a --- /dev/null +++ b/servers/grpc/proto/solidarity-api.pb.go @@ -0,0 +1,1303 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.30.0 +// protoc v3.12.4 +// source: solidarity-api.proto + +package proto + +import ( + timestamp "github.com/golang/protobuf/ptypes/timestamp" + 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) +) + +type PassengerTripRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + PassengerDepartureAddress *Feature `protobuf:"bytes,1,opt,name=passenger_departure_address,json=passengerDepartureAddress,proto3" json:"passenger_departure_address,omitempty"` + PassengerDestinationAddress *Feature `protobuf:"bytes,2,opt,name=passenger_destination_address,json=passengerDestinationAddress,proto3" json:"passenger_destination_address,omitempty"` + PassengerPickupDate *timestamp.Timestamp `protobuf:"bytes,3,opt,name=passenger_pickup_date,json=passengerPickupDate,proto3" json:"passenger_pickup_date,omitempty"` + Passenger *User `protobuf:"bytes,4,opt,name=passenger,proto3" json:"passenger,omitempty"` + Preferences *Preferences `protobuf:"bytes,5,opt,name=preferences,proto3,oneof" json:"preferences,omitempty"` +} + +func (x *PassengerTripRequest) Reset() { + *x = PassengerTripRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_solidarity_api_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PassengerTripRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PassengerTripRequest) ProtoMessage() {} + +func (x *PassengerTripRequest) ProtoReflect() protoreflect.Message { + mi := &file_solidarity_api_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 PassengerTripRequest.ProtoReflect.Descriptor instead. +func (*PassengerTripRequest) Descriptor() ([]byte, []int) { + return file_solidarity_api_proto_rawDescGZIP(), []int{0} +} + +func (x *PassengerTripRequest) GetPassengerDepartureAddress() *Feature { + if x != nil { + return x.PassengerDepartureAddress + } + return nil +} + +func (x *PassengerTripRequest) GetPassengerDestinationAddress() *Feature { + if x != nil { + return x.PassengerDestinationAddress + } + return nil +} + +func (x *PassengerTripRequest) GetPassengerPickupDate() *timestamp.Timestamp { + if x != nil { + return x.PassengerPickupDate + } + return nil +} + +func (x *PassengerTripRequest) GetPassenger() *User { + if x != nil { + return x.Passenger + } + return nil +} + +func (x *PassengerTripRequest) GetPreferences() *Preferences { + if x != nil { + return x.Preferences + } + return nil +} + +type DriverRegularAvailabilities struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + DriverRequest *DriverRequest `protobuf:"bytes,1,opt,name=driver_request,json=driverRequest,proto3" json:"driver_request,omitempty"` + DriverAvailabilities []*RegularAvailabilitySlot `protobuf:"bytes,2,rep,name=driver_availabilities,json=driverAvailabilities,proto3" json:"driver_availabilities,omitempty"` +} + +func (x *DriverRegularAvailabilities) Reset() { + *x = DriverRegularAvailabilities{} + if protoimpl.UnsafeEnabled { + mi := &file_solidarity_api_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DriverRegularAvailabilities) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DriverRegularAvailabilities) ProtoMessage() {} + +func (x *DriverRegularAvailabilities) ProtoReflect() protoreflect.Message { + mi := &file_solidarity_api_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 DriverRegularAvailabilities.ProtoReflect.Descriptor instead. +func (*DriverRegularAvailabilities) Descriptor() ([]byte, []int) { + return file_solidarity_api_proto_rawDescGZIP(), []int{1} +} + +func (x *DriverRegularAvailabilities) GetDriverRequest() *DriverRequest { + if x != nil { + return x.DriverRequest + } + return nil +} + +func (x *DriverRegularAvailabilities) GetDriverAvailabilities() []*RegularAvailabilitySlot { + if x != nil { + return x.DriverAvailabilities + } + return nil +} + +type DriverPunctualAvailabilities struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + DriverRequest *DriverRequest `protobuf:"bytes,1,opt,name=driver_request,json=driverRequest,proto3" json:"driver_request,omitempty"` + DriverAvailabilities []*PunctualAvailabilitySlot `protobuf:"bytes,2,rep,name=driver_availabilities,json=driverAvailabilities,proto3" json:"driver_availabilities,omitempty"` +} + +func (x *DriverPunctualAvailabilities) Reset() { + *x = DriverPunctualAvailabilities{} + if protoimpl.UnsafeEnabled { + mi := &file_solidarity_api_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DriverPunctualAvailabilities) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DriverPunctualAvailabilities) ProtoMessage() {} + +func (x *DriverPunctualAvailabilities) ProtoReflect() protoreflect.Message { + mi := &file_solidarity_api_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 DriverPunctualAvailabilities.ProtoReflect.Descriptor instead. +func (*DriverPunctualAvailabilities) Descriptor() ([]byte, []int) { + return file_solidarity_api_proto_rawDescGZIP(), []int{2} +} + +func (x *DriverPunctualAvailabilities) GetDriverRequest() *DriverRequest { + if x != nil { + return x.DriverRequest + } + return nil +} + +func (x *DriverPunctualAvailabilities) GetDriverAvailabilities() []*PunctualAvailabilitySlot { + if x != nil { + return x.DriverAvailabilities + } + return nil +} + +type PassengerTripResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Success bool `protobuf:"varint,1,opt,name=success,proto3" json:"success,omitempty"` + Message *string `protobuf:"bytes,2,opt,name=message,proto3,oneof" json:"message,omitempty"` +} + +func (x *PassengerTripResponse) Reset() { + *x = PassengerTripResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_solidarity_api_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PassengerTripResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PassengerTripResponse) ProtoMessage() {} + +func (x *PassengerTripResponse) ProtoReflect() protoreflect.Message { + mi := &file_solidarity_api_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 PassengerTripResponse.ProtoReflect.Descriptor instead. +func (*PassengerTripResponse) Descriptor() ([]byte, []int) { + return file_solidarity_api_proto_rawDescGZIP(), []int{3} +} + +func (x *PassengerTripResponse) GetSuccess() bool { + if x != nil { + return x.Success + } + return false +} + +func (x *PassengerTripResponse) GetMessage() string { + if x != nil && x.Message != nil { + return *x.Message + } + return "" +} + +type DriverAvailabilitiesResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Success bool `protobuf:"varint,1,opt,name=success,proto3" json:"success,omitempty"` + Message *string `protobuf:"bytes,2,opt,name=message,proto3,oneof" json:"message,omitempty"` +} + +func (x *DriverAvailabilitiesResponse) Reset() { + *x = DriverAvailabilitiesResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_solidarity_api_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DriverAvailabilitiesResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DriverAvailabilitiesResponse) ProtoMessage() {} + +func (x *DriverAvailabilitiesResponse) ProtoReflect() protoreflect.Message { + mi := &file_solidarity_api_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 DriverAvailabilitiesResponse.ProtoReflect.Descriptor instead. +func (*DriverAvailabilitiesResponse) Descriptor() ([]byte, []int) { + return file_solidarity_api_proto_rawDescGZIP(), []int{4} +} + +func (x *DriverAvailabilitiesResponse) GetSuccess() bool { + if x != nil { + return x.Success + } + return false +} + +func (x *DriverAvailabilitiesResponse) GetMessage() string { + if x != nil && x.Message != nil { + return *x.Message + } + return "" +} + +type CreateBookingRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Booking *BookingRequest `protobuf:"bytes,1,opt,name=booking,proto3" json:"booking,omitempty"` +} + +func (x *CreateBookingRequest) Reset() { + *x = CreateBookingRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_solidarity_api_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreateBookingRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateBookingRequest) ProtoMessage() {} + +func (x *CreateBookingRequest) ProtoReflect() protoreflect.Message { + mi := &file_solidarity_api_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 CreateBookingRequest.ProtoReflect.Descriptor instead. +func (*CreateBookingRequest) Descriptor() ([]byte, []int) { + return file_solidarity_api_proto_rawDescGZIP(), []int{5} +} + +func (x *CreateBookingRequest) GetBooking() *BookingRequest { + if x != nil { + return x.Booking + } + return nil +} + +type CreateBookingResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Booking *Booking `protobuf:"bytes,1,opt,name=booking,proto3" json:"booking,omitempty"` +} + +func (x *CreateBookingResponse) Reset() { + *x = CreateBookingResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_solidarity_api_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreateBookingResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateBookingResponse) ProtoMessage() {} + +func (x *CreateBookingResponse) ProtoReflect() protoreflect.Message { + mi := &file_solidarity_api_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 CreateBookingResponse.ProtoReflect.Descriptor instead. +func (*CreateBookingResponse) Descriptor() ([]byte, []int) { + return file_solidarity_api_proto_rawDescGZIP(), []int{6} +} + +func (x *CreateBookingResponse) GetBooking() *Booking { + if x != nil { + return x.Booking + } + return nil +} + +type UpdateBookingRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + BookingId string `protobuf:"bytes,1,opt,name=booking_id,json=bookingId,proto3" json:"booking_id,omitempty"` + Status BookingStatus `protobuf:"varint,2,opt,name=status,proto3,enum=BookingStatus" json:"status,omitempty"` + Message *string `protobuf:"bytes,3,opt,name=message,proto3,oneof" json:"message,omitempty"` +} + +func (x *UpdateBookingRequest) Reset() { + *x = UpdateBookingRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_solidarity_api_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateBookingRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateBookingRequest) ProtoMessage() {} + +func (x *UpdateBookingRequest) ProtoReflect() protoreflect.Message { + mi := &file_solidarity_api_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 UpdateBookingRequest.ProtoReflect.Descriptor instead. +func (*UpdateBookingRequest) Descriptor() ([]byte, []int) { + return file_solidarity_api_proto_rawDescGZIP(), []int{7} +} + +func (x *UpdateBookingRequest) GetBookingId() string { + if x != nil { + return x.BookingId + } + return "" +} + +func (x *UpdateBookingRequest) GetStatus() BookingStatus { + if x != nil { + return x.Status + } + return BookingStatus_INITIATED +} + +func (x *UpdateBookingRequest) GetMessage() string { + if x != nil && x.Message != nil { + return *x.Message + } + return "" +} + +type UpdateBookingResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Success bool `protobuf:"varint,1,opt,name=success,proto3" json:"success,omitempty"` + Message *string `protobuf:"bytes,2,opt,name=message,proto3,oneof" json:"message,omitempty"` +} + +func (x *UpdateBookingResponse) Reset() { + *x = UpdateBookingResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_solidarity_api_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateBookingResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateBookingResponse) ProtoMessage() {} + +func (x *UpdateBookingResponse) ProtoReflect() protoreflect.Message { + mi := &file_solidarity_api_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 UpdateBookingResponse.ProtoReflect.Descriptor instead. +func (*UpdateBookingResponse) Descriptor() ([]byte, []int) { + return file_solidarity_api_proto_rawDescGZIP(), []int{8} +} + +func (x *UpdateBookingResponse) GetSuccess() bool { + if x != nil { + return x.Success + } + return false +} + +func (x *UpdateBookingResponse) GetMessage() string { + if x != nil && x.Message != nil { + return *x.Message + } + return "" +} + +type GetBookingRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + BookingId string `protobuf:"bytes,1,opt,name=booking_id,json=bookingId,proto3" json:"booking_id,omitempty"` +} + +func (x *GetBookingRequest) Reset() { + *x = GetBookingRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_solidarity_api_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetBookingRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetBookingRequest) ProtoMessage() {} + +func (x *GetBookingRequest) ProtoReflect() protoreflect.Message { + mi := &file_solidarity_api_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 GetBookingRequest.ProtoReflect.Descriptor instead. +func (*GetBookingRequest) Descriptor() ([]byte, []int) { + return file_solidarity_api_proto_rawDescGZIP(), []int{9} +} + +func (x *GetBookingRequest) GetBookingId() string { + if x != nil { + return x.BookingId + } + return "" +} + +type GetBookingResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Booking *Booking `protobuf:"bytes,1,opt,name=booking,proto3" json:"booking,omitempty"` +} + +func (x *GetBookingResponse) Reset() { + *x = GetBookingResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_solidarity_api_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetBookingResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetBookingResponse) ProtoMessage() {} + +func (x *GetBookingResponse) ProtoReflect() protoreflect.Message { + mi := &file_solidarity_api_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 GetBookingResponse.ProtoReflect.Descriptor instead. +func (*GetBookingResponse) Descriptor() ([]byte, []int) { + return file_solidarity_api_proto_rawDescGZIP(), []int{10} +} + +func (x *GetBookingResponse) GetBooking() *Booking { + if x != nil { + return x.Booking + } + return nil +} + +type GetBookingsByStatusRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Status BookingStatus `protobuf:"varint,1,opt,name=status,proto3,enum=BookingStatus" json:"status,omitempty"` + Type UserType `protobuf:"varint,2,opt,name=type,proto3,enum=UserType" json:"type,omitempty"` + UserId string `protobuf:"bytes,3,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` +} + +func (x *GetBookingsByStatusRequest) Reset() { + *x = GetBookingsByStatusRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_solidarity_api_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetBookingsByStatusRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetBookingsByStatusRequest) ProtoMessage() {} + +func (x *GetBookingsByStatusRequest) ProtoReflect() protoreflect.Message { + mi := &file_solidarity_api_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 GetBookingsByStatusRequest.ProtoReflect.Descriptor instead. +func (*GetBookingsByStatusRequest) Descriptor() ([]byte, []int) { + return file_solidarity_api_proto_rawDescGZIP(), []int{11} +} + +func (x *GetBookingsByStatusRequest) GetStatus() BookingStatus { + if x != nil { + return x.Status + } + return BookingStatus_INITIATED +} + +func (x *GetBookingsByStatusRequest) GetType() UserType { + if x != nil { + return x.Type + } + return UserType_driver +} + +func (x *GetBookingsByStatusRequest) GetUserId() string { + if x != nil { + return x.UserId + } + return "" +} + +type DriverJourneysRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Departure *Feature `protobuf:"bytes,1,opt,name=departure,proto3" json:"departure,omitempty"` + DepartureDate *timestamp.Timestamp `protobuf:"bytes,2,opt,name=departure_date,json=departureDate,proto3" json:"departure_date,omitempty"` +} + +func (x *DriverJourneysRequest) Reset() { + *x = DriverJourneysRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_solidarity_api_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DriverJourneysRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DriverJourneysRequest) ProtoMessage() {} + +func (x *DriverJourneysRequest) ProtoReflect() protoreflect.Message { + mi := &file_solidarity_api_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 DriverJourneysRequest.ProtoReflect.Descriptor instead. +func (*DriverJourneysRequest) Descriptor() ([]byte, []int) { + return file_solidarity_api_proto_rawDescGZIP(), []int{12} +} + +func (x *DriverJourneysRequest) GetDeparture() *Feature { + if x != nil { + return x.Departure + } + return nil +} + +func (x *DriverJourneysRequest) GetDepartureDate() *timestamp.Timestamp { + if x != nil { + return x.DepartureDate + } + return nil +} + +type DriverJourneysResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + DriverJourneys []*DriverJourney `protobuf:"bytes,1,rep,name=driver_journeys,json=driverJourneys,proto3" json:"driver_journeys,omitempty"` +} + +func (x *DriverJourneysResponse) Reset() { + *x = DriverJourneysResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_solidarity_api_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DriverJourneysResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DriverJourneysResponse) ProtoMessage() {} + +func (x *DriverJourneysResponse) ProtoReflect() protoreflect.Message { + mi := &file_solidarity_api_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 DriverJourneysResponse.ProtoReflect.Descriptor instead. +func (*DriverJourneysResponse) Descriptor() ([]byte, []int) { + return file_solidarity_api_proto_rawDescGZIP(), []int{13} +} + +func (x *DriverJourneysResponse) GetDriverJourneys() []*DriverJourney { + if x != nil { + return x.DriverJourneys + } + return nil +} + +type GetBookingsByStatusResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Booking []*Booking `protobuf:"bytes,1,rep,name=booking,proto3" json:"booking,omitempty"` +} + +func (x *GetBookingsByStatusResponse) Reset() { + *x = GetBookingsByStatusResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_solidarity_api_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetBookingsByStatusResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetBookingsByStatusResponse) ProtoMessage() {} + +func (x *GetBookingsByStatusResponse) ProtoReflect() protoreflect.Message { + mi := &file_solidarity_api_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 GetBookingsByStatusResponse.ProtoReflect.Descriptor instead. +func (*GetBookingsByStatusResponse) Descriptor() ([]byte, []int) { + return file_solidarity_api_proto_rawDescGZIP(), []int{14} +} + +func (x *GetBookingsByStatusResponse) GetBooking() []*Booking { + if x != nil { + return x.Booking + } + return nil +} + +var File_solidarity_api_proto protoreflect.FileDescriptor + +var file_solidarity_api_proto_rawDesc = []byte{ + 0x0a, 0x14, 0x73, 0x6f, 0x6c, 0x69, 0x64, 0x61, 0x72, 0x69, 0x74, 0x79, 0x2d, 0x61, 0x70, 0x69, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, + 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1a, 0x73, 0x6f, 0x6c, 0x69, 0x64, 0x61, 0x72, + 0x69, 0x74, 0x79, 0x2d, 0x61, 0x70, 0x69, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x22, 0xe8, 0x02, 0x0a, 0x14, 0x50, 0x61, 0x73, 0x73, 0x65, 0x6e, 0x67, 0x65, + 0x72, 0x54, 0x72, 0x69, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x48, 0x0a, 0x1b, + 0x70, 0x61, 0x73, 0x73, 0x65, 0x6e, 0x67, 0x65, 0x72, 0x5f, 0x64, 0x65, 0x70, 0x61, 0x72, 0x74, + 0x75, 0x72, 0x65, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x08, 0x2e, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x19, 0x70, 0x61, 0x73, + 0x73, 0x65, 0x6e, 0x67, 0x65, 0x72, 0x44, 0x65, 0x70, 0x61, 0x72, 0x74, 0x75, 0x72, 0x65, 0x41, + 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x4c, 0x0a, 0x1d, 0x70, 0x61, 0x73, 0x73, 0x65, 0x6e, + 0x67, 0x65, 0x72, 0x5f, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, + 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x08, 0x2e, + 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x1b, 0x70, 0x61, 0x73, 0x73, 0x65, 0x6e, 0x67, + 0x65, 0x72, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x64, 0x64, + 0x72, 0x65, 0x73, 0x73, 0x12, 0x4e, 0x0a, 0x15, 0x70, 0x61, 0x73, 0x73, 0x65, 0x6e, 0x67, 0x65, + 0x72, 0x5f, 0x70, 0x69, 0x63, 0x6b, 0x75, 0x70, 0x5f, 0x64, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, + 0x13, 0x70, 0x61, 0x73, 0x73, 0x65, 0x6e, 0x67, 0x65, 0x72, 0x50, 0x69, 0x63, 0x6b, 0x75, 0x70, + 0x44, 0x61, 0x74, 0x65, 0x12, 0x23, 0x0a, 0x09, 0x70, 0x61, 0x73, 0x73, 0x65, 0x6e, 0x67, 0x65, + 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x05, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x09, + 0x70, 0x61, 0x73, 0x73, 0x65, 0x6e, 0x67, 0x65, 0x72, 0x12, 0x33, 0x0a, 0x0b, 0x70, 0x72, 0x65, + 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, + 0x2e, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x48, 0x00, 0x52, 0x0b, + 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x88, 0x01, 0x01, 0x42, 0x0e, + 0x0a, 0x0c, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x22, 0xa3, + 0x01, 0x0a, 0x1b, 0x44, 0x72, 0x69, 0x76, 0x65, 0x72, 0x52, 0x65, 0x67, 0x75, 0x6c, 0x61, 0x72, + 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x12, 0x35, + 0x0a, 0x0e, 0x64, 0x72, 0x69, 0x76, 0x65, 0x72, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x44, 0x72, 0x69, 0x76, 0x65, 0x72, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x0d, 0x64, 0x72, 0x69, 0x76, 0x65, 0x72, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x4d, 0x0a, 0x15, 0x64, 0x72, 0x69, 0x76, 0x65, 0x72, 0x5f, + 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x18, 0x02, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x52, 0x65, 0x67, 0x75, 0x6c, 0x61, 0x72, 0x41, 0x76, + 0x61, 0x69, 0x6c, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x53, 0x6c, 0x6f, 0x74, 0x52, 0x14, + 0x64, 0x72, 0x69, 0x76, 0x65, 0x72, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x69, 0x6c, 0x69, + 0x74, 0x69, 0x65, 0x73, 0x22, 0xa5, 0x01, 0x0a, 0x1c, 0x44, 0x72, 0x69, 0x76, 0x65, 0x72, 0x50, + 0x75, 0x6e, 0x63, 0x74, 0x75, 0x61, 0x6c, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x69, 0x6c, + 0x69, 0x74, 0x69, 0x65, 0x73, 0x12, 0x35, 0x0a, 0x0e, 0x64, 0x72, 0x69, 0x76, 0x65, 0x72, 0x5f, + 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, + 0x44, 0x72, 0x69, 0x76, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x0d, 0x64, + 0x72, 0x69, 0x76, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x4e, 0x0a, 0x15, + 0x64, 0x72, 0x69, 0x76, 0x65, 0x72, 0x5f, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x69, 0x6c, + 0x69, 0x74, 0x69, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x50, 0x75, + 0x6e, 0x63, 0x74, 0x75, 0x61, 0x6c, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x69, 0x6c, 0x69, + 0x74, 0x79, 0x53, 0x6c, 0x6f, 0x74, 0x52, 0x14, 0x64, 0x72, 0x69, 0x76, 0x65, 0x72, 0x41, 0x76, + 0x61, 0x69, 0x6c, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x22, 0x5c, 0x0a, 0x15, + 0x50, 0x61, 0x73, 0x73, 0x65, 0x6e, 0x67, 0x65, 0x72, 0x54, 0x72, 0x69, 0x70, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, + 0x1d, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x48, 0x00, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x88, 0x01, 0x01, 0x42, 0x0a, + 0x0a, 0x08, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x63, 0x0a, 0x1c, 0x44, 0x72, + 0x69, 0x76, 0x65, 0x72, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, + 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x12, 0x1d, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x88, 0x01, 0x01, 0x42, 0x0a, 0x0a, 0x08, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, + 0x41, 0x0a, 0x14, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x42, 0x6f, 0x6f, 0x6b, 0x69, 0x6e, 0x67, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x29, 0x0a, 0x07, 0x62, 0x6f, 0x6f, 0x6b, 0x69, + 0x6e, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x42, 0x6f, 0x6f, 0x6b, 0x69, + 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x07, 0x62, 0x6f, 0x6f, 0x6b, 0x69, + 0x6e, 0x67, 0x22, 0x3b, 0x0a, 0x15, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x42, 0x6f, 0x6f, 0x6b, + 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x22, 0x0a, 0x07, 0x62, + 0x6f, 0x6f, 0x6b, 0x69, 0x6e, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x08, 0x2e, 0x42, + 0x6f, 0x6f, 0x6b, 0x69, 0x6e, 0x67, 0x52, 0x07, 0x62, 0x6f, 0x6f, 0x6b, 0x69, 0x6e, 0x67, 0x22, + 0x88, 0x01, 0x0a, 0x14, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x42, 0x6f, 0x6f, 0x6b, 0x69, 0x6e, + 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x6f, 0x6f, 0x6b, + 0x69, 0x6e, 0x67, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x62, 0x6f, + 0x6f, 0x6b, 0x69, 0x6e, 0x67, 0x49, 0x64, 0x12, 0x26, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0e, 0x2e, 0x42, 0x6f, 0x6f, 0x6b, 0x69, 0x6e, + 0x67, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, + 0x1d, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x48, 0x00, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x88, 0x01, 0x01, 0x42, 0x0a, + 0x0a, 0x08, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x5c, 0x0a, 0x15, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x42, 0x6f, 0x6f, 0x6b, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x1d, 0x0a, + 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, + 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x88, 0x01, 0x01, 0x42, 0x0a, 0x0a, 0x08, + 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x32, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x42, + 0x6f, 0x6f, 0x6b, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, + 0x0a, 0x62, 0x6f, 0x6f, 0x6b, 0x69, 0x6e, 0x67, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x09, 0x62, 0x6f, 0x6f, 0x6b, 0x69, 0x6e, 0x67, 0x49, 0x64, 0x22, 0x38, 0x0a, 0x12, + 0x47, 0x65, 0x74, 0x42, 0x6f, 0x6f, 0x6b, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x22, 0x0a, 0x07, 0x62, 0x6f, 0x6f, 0x6b, 0x69, 0x6e, 0x67, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x08, 0x2e, 0x42, 0x6f, 0x6f, 0x6b, 0x69, 0x6e, 0x67, 0x52, 0x07, 0x62, + 0x6f, 0x6f, 0x6b, 0x69, 0x6e, 0x67, 0x22, 0x7c, 0x0a, 0x1a, 0x47, 0x65, 0x74, 0x42, 0x6f, 0x6f, + 0x6b, 0x69, 0x6e, 0x67, 0x73, 0x42, 0x79, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x26, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0e, 0x2e, 0x42, 0x6f, 0x6f, 0x6b, 0x69, 0x6e, 0x67, 0x53, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1d, 0x0a, 0x04, + 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x09, 0x2e, 0x55, 0x73, 0x65, + 0x72, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 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, 0x22, 0x82, 0x01, 0x0a, 0x15, 0x44, 0x72, 0x69, 0x76, 0x65, 0x72, 0x4a, + 0x6f, 0x75, 0x72, 0x6e, 0x65, 0x79, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x26, + 0x0a, 0x09, 0x64, 0x65, 0x70, 0x61, 0x72, 0x74, 0x75, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x08, 0x2e, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x09, 0x64, 0x65, 0x70, + 0x61, 0x72, 0x74, 0x75, 0x72, 0x65, 0x12, 0x41, 0x0a, 0x0e, 0x64, 0x65, 0x70, 0x61, 0x72, 0x74, + 0x75, 0x72, 0x65, 0x5f, 0x64, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0d, 0x64, 0x65, 0x70, 0x61, + 0x72, 0x74, 0x75, 0x72, 0x65, 0x44, 0x61, 0x74, 0x65, 0x22, 0x51, 0x0a, 0x16, 0x44, 0x72, 0x69, + 0x76, 0x65, 0x72, 0x4a, 0x6f, 0x75, 0x72, 0x6e, 0x65, 0x79, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x37, 0x0a, 0x0f, 0x64, 0x72, 0x69, 0x76, 0x65, 0x72, 0x5f, 0x6a, 0x6f, + 0x75, 0x72, 0x6e, 0x65, 0x79, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x44, + 0x72, 0x69, 0x76, 0x65, 0x72, 0x4a, 0x6f, 0x75, 0x72, 0x6e, 0x65, 0x79, 0x52, 0x0e, 0x64, 0x72, + 0x69, 0x76, 0x65, 0x72, 0x4a, 0x6f, 0x75, 0x72, 0x6e, 0x65, 0x79, 0x73, 0x22, 0x41, 0x0a, 0x1b, + 0x47, 0x65, 0x74, 0x42, 0x6f, 0x6f, 0x6b, 0x69, 0x6e, 0x67, 0x73, 0x42, 0x79, 0x53, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x22, 0x0a, 0x07, 0x62, + 0x6f, 0x6f, 0x6b, 0x69, 0x6e, 0x67, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x08, 0x2e, 0x42, + 0x6f, 0x6f, 0x6b, 0x69, 0x6e, 0x67, 0x52, 0x07, 0x62, 0x6f, 0x6f, 0x6b, 0x69, 0x6e, 0x67, 0x32, + 0xf2, 0x04, 0x0a, 0x11, 0x53, 0x6f, 0x6c, 0x69, 0x64, 0x61, 0x72, 0x69, 0x74, 0x79, 0x53, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x5f, 0x0a, 0x1e, 0x53, 0x65, 0x74, 0x44, 0x72, 0x69, 0x76, + 0x65, 0x72, 0x52, 0x65, 0x67, 0x75, 0x6c, 0x61, 0x72, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, + 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x12, 0x1c, 0x2e, 0x44, 0x72, 0x69, 0x76, 0x65, 0x72, + 0x52, 0x65, 0x67, 0x75, 0x6c, 0x61, 0x72, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x69, 0x6c, + 0x69, 0x74, 0x69, 0x65, 0x73, 0x1a, 0x1d, 0x2e, 0x44, 0x72, 0x69, 0x76, 0x65, 0x72, 0x41, 0x76, + 0x61, 0x69, 0x6c, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x61, 0x0a, 0x1f, 0x53, 0x65, 0x74, 0x44, 0x72, 0x69, + 0x76, 0x65, 0x72, 0x50, 0x75, 0x6e, 0x63, 0x74, 0x75, 0x61, 0x6c, 0x41, 0x76, 0x61, 0x69, 0x6c, + 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x12, 0x1d, 0x2e, 0x44, 0x72, 0x69, 0x76, + 0x65, 0x72, 0x50, 0x75, 0x6e, 0x63, 0x74, 0x75, 0x61, 0x6c, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, + 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x1a, 0x1d, 0x2e, 0x44, 0x72, 0x69, 0x76, 0x65, + 0x72, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x40, 0x0a, 0x0d, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x42, 0x6f, 0x6f, 0x6b, 0x69, 0x6e, 0x67, 0x12, 0x15, 0x2e, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x42, 0x6f, 0x6f, 0x6b, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x16, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x42, 0x6f, 0x6f, 0x6b, 0x69, 0x6e, + 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x40, 0x0a, 0x0d, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x42, 0x6f, 0x6f, 0x6b, 0x69, 0x6e, 0x67, 0x12, 0x15, 0x2e, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x42, 0x6f, 0x6f, 0x6b, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x42, 0x6f, 0x6f, 0x6b, + 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x37, 0x0a, + 0x0a, 0x47, 0x65, 0x74, 0x42, 0x6f, 0x6f, 0x6b, 0x69, 0x6e, 0x67, 0x12, 0x12, 0x2e, 0x47, 0x65, + 0x74, 0x42, 0x6f, 0x6f, 0x6b, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x13, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x6f, 0x6f, 0x6b, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x52, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x42, 0x6f, 0x6f, + 0x6b, 0x69, 0x6e, 0x67, 0x73, 0x42, 0x79, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1b, 0x2e, + 0x47, 0x65, 0x74, 0x42, 0x6f, 0x6f, 0x6b, 0x69, 0x6e, 0x67, 0x73, 0x42, 0x79, 0x53, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x47, 0x65, 0x74, + 0x42, 0x6f, 0x6f, 0x6b, 0x69, 0x6e, 0x67, 0x73, 0x42, 0x79, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x43, 0x0a, 0x0e, 0x44, 0x72, + 0x69, 0x76, 0x65, 0x72, 0x4a, 0x6f, 0x75, 0x72, 0x6e, 0x65, 0x79, 0x73, 0x12, 0x16, 0x2e, 0x44, + 0x72, 0x69, 0x76, 0x65, 0x72, 0x4a, 0x6f, 0x75, 0x72, 0x6e, 0x65, 0x79, 0x73, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x44, 0x72, 0x69, 0x76, 0x65, 0x72, 0x4a, 0x6f, 0x75, + 0x72, 0x6e, 0x65, 0x79, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, + 0x43, 0x0a, 0x10, 0x53, 0x65, 0x74, 0x50, 0x61, 0x73, 0x73, 0x65, 0x6e, 0x67, 0x65, 0x72, 0x54, + 0x72, 0x69, 0x70, 0x12, 0x15, 0x2e, 0x50, 0x61, 0x73, 0x73, 0x65, 0x6e, 0x67, 0x65, 0x72, 0x54, + 0x72, 0x69, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x50, 0x61, 0x73, + 0x73, 0x65, 0x6e, 0x67, 0x65, 0x72, 0x54, 0x72, 0x69, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x00, 0x42, 0x45, 0x5a, 0x43, 0x67, 0x69, 0x74, 0x2e, 0x63, 0x6f, 0x6f, 0x70, + 0x67, 0x6f, 0x2e, 0x69, 0x6f, 0x2f, 0x63, 0x6f, 0x6f, 0x70, 0x67, 0x6f, 0x2d, 0x70, 0x6c, 0x61, + 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x2f, 0x73, 0x6f, 0x6c, 0x69, 0x64, 0x61, 0x72, 0x69, 0x74, 0x79, + 0x2d, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, + 0x2f, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x33, +} + +var ( + file_solidarity_api_proto_rawDescOnce sync.Once + file_solidarity_api_proto_rawDescData = file_solidarity_api_proto_rawDesc +) + +func file_solidarity_api_proto_rawDescGZIP() []byte { + file_solidarity_api_proto_rawDescOnce.Do(func() { + file_solidarity_api_proto_rawDescData = protoimpl.X.CompressGZIP(file_solidarity_api_proto_rawDescData) + }) + return file_solidarity_api_proto_rawDescData +} + +var file_solidarity_api_proto_msgTypes = make([]protoimpl.MessageInfo, 15) +var file_solidarity_api_proto_goTypes = []interface{}{ + (*PassengerTripRequest)(nil), // 0: PassengerTripRequest + (*DriverRegularAvailabilities)(nil), // 1: DriverRegularAvailabilities + (*DriverPunctualAvailabilities)(nil), // 2: DriverPunctualAvailabilities + (*PassengerTripResponse)(nil), // 3: PassengerTripResponse + (*DriverAvailabilitiesResponse)(nil), // 4: DriverAvailabilitiesResponse + (*CreateBookingRequest)(nil), // 5: CreateBookingRequest + (*CreateBookingResponse)(nil), // 6: CreateBookingResponse + (*UpdateBookingRequest)(nil), // 7: UpdateBookingRequest + (*UpdateBookingResponse)(nil), // 8: UpdateBookingResponse + (*GetBookingRequest)(nil), // 9: GetBookingRequest + (*GetBookingResponse)(nil), // 10: GetBookingResponse + (*GetBookingsByStatusRequest)(nil), // 11: GetBookingsByStatusRequest + (*DriverJourneysRequest)(nil), // 12: DriverJourneysRequest + (*DriverJourneysResponse)(nil), // 13: DriverJourneysResponse + (*GetBookingsByStatusResponse)(nil), // 14: GetBookingsByStatusResponse + (*Feature)(nil), // 15: Feature + (*timestamp.Timestamp)(nil), // 16: google.protobuf.Timestamp + (*User)(nil), // 17: User + (*Preferences)(nil), // 18: Preferences + (*DriverRequest)(nil), // 19: DriverRequest + (*RegularAvailabilitySlot)(nil), // 20: RegularAvailabilitySlot + (*PunctualAvailabilitySlot)(nil), // 21: PunctualAvailabilitySlot + (*BookingRequest)(nil), // 22: BookingRequest + (*Booking)(nil), // 23: Booking + (BookingStatus)(0), // 24: BookingStatus + (UserType)(0), // 25: UserType + (*DriverJourney)(nil), // 26: DriverJourney +} +var file_solidarity_api_proto_depIdxs = []int32{ + 15, // 0: PassengerTripRequest.passenger_departure_address:type_name -> Feature + 15, // 1: PassengerTripRequest.passenger_destination_address:type_name -> Feature + 16, // 2: PassengerTripRequest.passenger_pickup_date:type_name -> google.protobuf.Timestamp + 17, // 3: PassengerTripRequest.passenger:type_name -> User + 18, // 4: PassengerTripRequest.preferences:type_name -> Preferences + 19, // 5: DriverRegularAvailabilities.driver_request:type_name -> DriverRequest + 20, // 6: DriverRegularAvailabilities.driver_availabilities:type_name -> RegularAvailabilitySlot + 19, // 7: DriverPunctualAvailabilities.driver_request:type_name -> DriverRequest + 21, // 8: DriverPunctualAvailabilities.driver_availabilities:type_name -> PunctualAvailabilitySlot + 22, // 9: CreateBookingRequest.booking:type_name -> BookingRequest + 23, // 10: CreateBookingResponse.booking:type_name -> Booking + 24, // 11: UpdateBookingRequest.status:type_name -> BookingStatus + 23, // 12: GetBookingResponse.booking:type_name -> Booking + 24, // 13: GetBookingsByStatusRequest.status:type_name -> BookingStatus + 25, // 14: GetBookingsByStatusRequest.type:type_name -> UserType + 15, // 15: DriverJourneysRequest.departure:type_name -> Feature + 16, // 16: DriverJourneysRequest.departure_date:type_name -> google.protobuf.Timestamp + 26, // 17: DriverJourneysResponse.driver_journeys:type_name -> DriverJourney + 23, // 18: GetBookingsByStatusResponse.booking:type_name -> Booking + 1, // 19: SolidarityService.SetDriverRegularAvailabilities:input_type -> DriverRegularAvailabilities + 2, // 20: SolidarityService.SetDriverPunctualAvailabilities:input_type -> DriverPunctualAvailabilities + 5, // 21: SolidarityService.CreateBooking:input_type -> CreateBookingRequest + 7, // 22: SolidarityService.UpdateBooking:input_type -> UpdateBookingRequest + 9, // 23: SolidarityService.GetBooking:input_type -> GetBookingRequest + 11, // 24: SolidarityService.GetBookingsByStatus:input_type -> GetBookingsByStatusRequest + 12, // 25: SolidarityService.DriverJourneys:input_type -> DriverJourneysRequest + 0, // 26: SolidarityService.SetPassengerTrip:input_type -> PassengerTripRequest + 4, // 27: SolidarityService.SetDriverRegularAvailabilities:output_type -> DriverAvailabilitiesResponse + 4, // 28: SolidarityService.SetDriverPunctualAvailabilities:output_type -> DriverAvailabilitiesResponse + 6, // 29: SolidarityService.CreateBooking:output_type -> CreateBookingResponse + 8, // 30: SolidarityService.UpdateBooking:output_type -> UpdateBookingResponse + 10, // 31: SolidarityService.GetBooking:output_type -> GetBookingResponse + 14, // 32: SolidarityService.GetBookingsByStatus:output_type -> GetBookingsByStatusResponse + 13, // 33: SolidarityService.DriverJourneys:output_type -> DriverJourneysResponse + 3, // 34: SolidarityService.SetPassengerTrip:output_type -> PassengerTripResponse + 27, // [27:35] is the sub-list for method output_type + 19, // [19:27] is the sub-list for method input_type + 19, // [19:19] is the sub-list for extension type_name + 19, // [19:19] is the sub-list for extension extendee + 0, // [0:19] is the sub-list for field type_name +} + +func init() { file_solidarity_api_proto_init() } +func file_solidarity_api_proto_init() { + if File_solidarity_api_proto != nil { + return + } + file_solidarity_api_types_proto_init() + if !protoimpl.UnsafeEnabled { + file_solidarity_api_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PassengerTripRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_solidarity_api_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DriverRegularAvailabilities); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_solidarity_api_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DriverPunctualAvailabilities); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_solidarity_api_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PassengerTripResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_solidarity_api_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DriverAvailabilitiesResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_solidarity_api_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreateBookingRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_solidarity_api_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreateBookingResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_solidarity_api_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateBookingRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_solidarity_api_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateBookingResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_solidarity_api_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetBookingRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_solidarity_api_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetBookingResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_solidarity_api_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetBookingsByStatusRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_solidarity_api_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DriverJourneysRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_solidarity_api_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DriverJourneysResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_solidarity_api_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetBookingsByStatusResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + file_solidarity_api_proto_msgTypes[0].OneofWrappers = []interface{}{} + file_solidarity_api_proto_msgTypes[3].OneofWrappers = []interface{}{} + file_solidarity_api_proto_msgTypes[4].OneofWrappers = []interface{}{} + file_solidarity_api_proto_msgTypes[7].OneofWrappers = []interface{}{} + file_solidarity_api_proto_msgTypes[8].OneofWrappers = []interface{}{} + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_solidarity_api_proto_rawDesc, + NumEnums: 0, + NumMessages: 15, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_solidarity_api_proto_goTypes, + DependencyIndexes: file_solidarity_api_proto_depIdxs, + MessageInfos: file_solidarity_api_proto_msgTypes, + }.Build() + File_solidarity_api_proto = out.File + file_solidarity_api_proto_rawDesc = nil + file_solidarity_api_proto_goTypes = nil + file_solidarity_api_proto_depIdxs = nil +} diff --git a/servers/grpc/proto/solidarity-api.proto b/servers/grpc/proto/solidarity-api.proto new file mode 100644 index 0000000..3378256 --- /dev/null +++ b/servers/grpc/proto/solidarity-api.proto @@ -0,0 +1,91 @@ +syntax = "proto3"; +option go_package = "git.coopgo.io/coopgo-platform/solidarity-service/servers/grpc/proto"; +import "google/protobuf/timestamp.proto"; +import "solidarity-api-types.proto"; + +service SolidarityService { + rpc SetDriverRegularAvailabilities(DriverRegularAvailabilities) returns (DriverAvailabilitiesResponse) {} + rpc SetDriverPunctualAvailabilities(DriverPunctualAvailabilities) returns (DriverAvailabilitiesResponse) {} + rpc CreateBooking(CreateBookingRequest) returns (CreateBookingResponse) {} + rpc UpdateBooking(UpdateBookingRequest) returns (UpdateBookingResponse) {} + rpc GetBooking(GetBookingRequest) returns (GetBookingResponse) {} + rpc GetBookingsByStatus(GetBookingsByStatusRequest) returns (GetBookingsByStatusResponse) {} + rpc DriverJourneys(DriverJourneysRequest) returns (DriverJourneysResponse) {} + rpc SetPassengerTrip(PassengerTripRequest) returns (PassengerTripResponse) {} +} + + +message PassengerTripRequest{ + Feature passenger_departure_address = 1; + Feature passenger_destination_address = 2; + google.protobuf.Timestamp passenger_pickup_date = 3; + User passenger = 4; + optional Preferences preferences = 5; +} + +message DriverRegularAvailabilities{ + + DriverRequest driver_request = 1; + repeated RegularAvailabilitySlot driver_availabilities = 2; +} + +message DriverPunctualAvailabilities{ + DriverRequest driver_request = 1; + repeated PunctualAvailabilitySlot driver_availabilities = 2; +} + +message PassengerTripResponse { + bool success = 1; + optional string message = 2; +} + +message DriverAvailabilitiesResponse { + bool success = 1; + optional string message = 2; +} + +message CreateBookingRequest { + BookingRequest booking = 1; +} +message CreateBookingResponse { + Booking booking = 1; +} + +message UpdateBookingRequest { + string booking_id = 1; + BookingStatus status = 2; + optional string message = 3; +} + +message UpdateBookingResponse { + bool success = 1; + optional string message = 2; +} + +message GetBookingRequest { + string booking_id = 1; +} + + +message GetBookingResponse { + Booking booking = 1; +} + +message GetBookingsByStatusRequest{ + BookingStatus status = 1; + UserType type = 2; + string user_id = 3; +} + +message DriverJourneysRequest { + Feature departure = 1; + google.protobuf.Timestamp departure_date = 2; +} + +message DriverJourneysResponse { + repeated DriverJourney driver_journeys = 1; +} + +message GetBookingsByStatusResponse{ + repeated Booking booking = 1; +} \ No newline at end of file diff --git a/servers/grpc/proto/solidarity-api_grpc.pb.go b/servers/grpc/proto/solidarity-api_grpc.pb.go new file mode 100644 index 0000000..7fcf400 --- /dev/null +++ b/servers/grpc/proto/solidarity-api_grpc.pb.go @@ -0,0 +1,368 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.3.0 +// - protoc v3.12.4 +// source: solidarity-api.proto + +package proto + +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 + +const ( + SolidarityService_SetDriverRegularAvailabilities_FullMethodName = "/SolidarityService/SetDriverRegularAvailabilities" + SolidarityService_SetDriverPunctualAvailabilities_FullMethodName = "/SolidarityService/SetDriverPunctualAvailabilities" + SolidarityService_CreateBooking_FullMethodName = "/SolidarityService/CreateBooking" + SolidarityService_UpdateBooking_FullMethodName = "/SolidarityService/UpdateBooking" + SolidarityService_GetBooking_FullMethodName = "/SolidarityService/GetBooking" + SolidarityService_GetBookingsByStatus_FullMethodName = "/SolidarityService/GetBookingsByStatus" + SolidarityService_DriverJourneys_FullMethodName = "/SolidarityService/DriverJourneys" + SolidarityService_SetPassengerTrip_FullMethodName = "/SolidarityService/SetPassengerTrip" +) + +// SolidarityServiceClient is the client API for SolidarityService 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 SolidarityServiceClient interface { + SetDriverRegularAvailabilities(ctx context.Context, in *DriverRegularAvailabilities, opts ...grpc.CallOption) (*DriverAvailabilitiesResponse, error) + SetDriverPunctualAvailabilities(ctx context.Context, in *DriverPunctualAvailabilities, opts ...grpc.CallOption) (*DriverAvailabilitiesResponse, error) + CreateBooking(ctx context.Context, in *CreateBookingRequest, opts ...grpc.CallOption) (*CreateBookingResponse, error) + UpdateBooking(ctx context.Context, in *UpdateBookingRequest, opts ...grpc.CallOption) (*UpdateBookingResponse, error) + GetBooking(ctx context.Context, in *GetBookingRequest, opts ...grpc.CallOption) (*GetBookingResponse, error) + GetBookingsByStatus(ctx context.Context, in *GetBookingsByStatusRequest, opts ...grpc.CallOption) (*GetBookingsByStatusResponse, error) + DriverJourneys(ctx context.Context, in *DriverJourneysRequest, opts ...grpc.CallOption) (*DriverJourneysResponse, error) + SetPassengerTrip(ctx context.Context, in *PassengerTripRequest, opts ...grpc.CallOption) (*PassengerTripResponse, error) +} + +type solidarityServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewSolidarityServiceClient(cc grpc.ClientConnInterface) SolidarityServiceClient { + return &solidarityServiceClient{cc} +} + +func (c *solidarityServiceClient) SetDriverRegularAvailabilities(ctx context.Context, in *DriverRegularAvailabilities, opts ...grpc.CallOption) (*DriverAvailabilitiesResponse, error) { + out := new(DriverAvailabilitiesResponse) + err := c.cc.Invoke(ctx, SolidarityService_SetDriverRegularAvailabilities_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *solidarityServiceClient) SetDriverPunctualAvailabilities(ctx context.Context, in *DriverPunctualAvailabilities, opts ...grpc.CallOption) (*DriverAvailabilitiesResponse, error) { + out := new(DriverAvailabilitiesResponse) + err := c.cc.Invoke(ctx, SolidarityService_SetDriverPunctualAvailabilities_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *solidarityServiceClient) CreateBooking(ctx context.Context, in *CreateBookingRequest, opts ...grpc.CallOption) (*CreateBookingResponse, error) { + out := new(CreateBookingResponse) + err := c.cc.Invoke(ctx, SolidarityService_CreateBooking_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *solidarityServiceClient) UpdateBooking(ctx context.Context, in *UpdateBookingRequest, opts ...grpc.CallOption) (*UpdateBookingResponse, error) { + out := new(UpdateBookingResponse) + err := c.cc.Invoke(ctx, SolidarityService_UpdateBooking_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *solidarityServiceClient) GetBooking(ctx context.Context, in *GetBookingRequest, opts ...grpc.CallOption) (*GetBookingResponse, error) { + out := new(GetBookingResponse) + err := c.cc.Invoke(ctx, SolidarityService_GetBooking_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *solidarityServiceClient) GetBookingsByStatus(ctx context.Context, in *GetBookingsByStatusRequest, opts ...grpc.CallOption) (*GetBookingsByStatusResponse, error) { + out := new(GetBookingsByStatusResponse) + err := c.cc.Invoke(ctx, SolidarityService_GetBookingsByStatus_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *solidarityServiceClient) DriverJourneys(ctx context.Context, in *DriverJourneysRequest, opts ...grpc.CallOption) (*DriverJourneysResponse, error) { + out := new(DriverJourneysResponse) + err := c.cc.Invoke(ctx, SolidarityService_DriverJourneys_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *solidarityServiceClient) SetPassengerTrip(ctx context.Context, in *PassengerTripRequest, opts ...grpc.CallOption) (*PassengerTripResponse, error) { + out := new(PassengerTripResponse) + err := c.cc.Invoke(ctx, SolidarityService_SetPassengerTrip_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// SolidarityServiceServer is the server API for SolidarityService service. +// All implementations must embed UnimplementedSolidarityServiceServer +// for forward compatibility +type SolidarityServiceServer interface { + SetDriverRegularAvailabilities(context.Context, *DriverRegularAvailabilities) (*DriverAvailabilitiesResponse, error) + SetDriverPunctualAvailabilities(context.Context, *DriverPunctualAvailabilities) (*DriverAvailabilitiesResponse, error) + CreateBooking(context.Context, *CreateBookingRequest) (*CreateBookingResponse, error) + UpdateBooking(context.Context, *UpdateBookingRequest) (*UpdateBookingResponse, error) + GetBooking(context.Context, *GetBookingRequest) (*GetBookingResponse, error) + GetBookingsByStatus(context.Context, *GetBookingsByStatusRequest) (*GetBookingsByStatusResponse, error) + DriverJourneys(context.Context, *DriverJourneysRequest) (*DriverJourneysResponse, error) + SetPassengerTrip(context.Context, *PassengerTripRequest) (*PassengerTripResponse, error) + mustEmbedUnimplementedSolidarityServiceServer() +} + +// UnimplementedSolidarityServiceServer must be embedded to have forward compatible implementations. +type UnimplementedSolidarityServiceServer struct { +} + +func (UnimplementedSolidarityServiceServer) SetDriverRegularAvailabilities(context.Context, *DriverRegularAvailabilities) (*DriverAvailabilitiesResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method SetDriverRegularAvailabilities not implemented") +} +func (UnimplementedSolidarityServiceServer) SetDriverPunctualAvailabilities(context.Context, *DriverPunctualAvailabilities) (*DriverAvailabilitiesResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method SetDriverPunctualAvailabilities not implemented") +} +func (UnimplementedSolidarityServiceServer) CreateBooking(context.Context, *CreateBookingRequest) (*CreateBookingResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method CreateBooking not implemented") +} +func (UnimplementedSolidarityServiceServer) UpdateBooking(context.Context, *UpdateBookingRequest) (*UpdateBookingResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateBooking not implemented") +} +func (UnimplementedSolidarityServiceServer) GetBooking(context.Context, *GetBookingRequest) (*GetBookingResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetBooking not implemented") +} +func (UnimplementedSolidarityServiceServer) GetBookingsByStatus(context.Context, *GetBookingsByStatusRequest) (*GetBookingsByStatusResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetBookingsByStatus not implemented") +} +func (UnimplementedSolidarityServiceServer) DriverJourneys(context.Context, *DriverJourneysRequest) (*DriverJourneysResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method DriverJourneys not implemented") +} +func (UnimplementedSolidarityServiceServer) SetPassengerTrip(context.Context, *PassengerTripRequest) (*PassengerTripResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method SetPassengerTrip not implemented") +} +func (UnimplementedSolidarityServiceServer) mustEmbedUnimplementedSolidarityServiceServer() {} + +// UnsafeSolidarityServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to SolidarityServiceServer will +// result in compilation errors. +type UnsafeSolidarityServiceServer interface { + mustEmbedUnimplementedSolidarityServiceServer() +} + +func RegisterSolidarityServiceServer(s grpc.ServiceRegistrar, srv SolidarityServiceServer) { + s.RegisterService(&SolidarityService_ServiceDesc, srv) +} + +func _SolidarityService_SetDriverRegularAvailabilities_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DriverRegularAvailabilities) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SolidarityServiceServer).SetDriverRegularAvailabilities(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: SolidarityService_SetDriverRegularAvailabilities_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SolidarityServiceServer).SetDriverRegularAvailabilities(ctx, req.(*DriverRegularAvailabilities)) + } + return interceptor(ctx, in, info, handler) +} + +func _SolidarityService_SetDriverPunctualAvailabilities_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DriverPunctualAvailabilities) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SolidarityServiceServer).SetDriverPunctualAvailabilities(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: SolidarityService_SetDriverPunctualAvailabilities_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SolidarityServiceServer).SetDriverPunctualAvailabilities(ctx, req.(*DriverPunctualAvailabilities)) + } + return interceptor(ctx, in, info, handler) +} + +func _SolidarityService_CreateBooking_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CreateBookingRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SolidarityServiceServer).CreateBooking(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: SolidarityService_CreateBooking_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SolidarityServiceServer).CreateBooking(ctx, req.(*CreateBookingRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _SolidarityService_UpdateBooking_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UpdateBookingRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SolidarityServiceServer).UpdateBooking(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: SolidarityService_UpdateBooking_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SolidarityServiceServer).UpdateBooking(ctx, req.(*UpdateBookingRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _SolidarityService_GetBooking_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetBookingRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SolidarityServiceServer).GetBooking(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: SolidarityService_GetBooking_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SolidarityServiceServer).GetBooking(ctx, req.(*GetBookingRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _SolidarityService_GetBookingsByStatus_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetBookingsByStatusRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SolidarityServiceServer).GetBookingsByStatus(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: SolidarityService_GetBookingsByStatus_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SolidarityServiceServer).GetBookingsByStatus(ctx, req.(*GetBookingsByStatusRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _SolidarityService_DriverJourneys_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DriverJourneysRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SolidarityServiceServer).DriverJourneys(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: SolidarityService_DriverJourneys_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SolidarityServiceServer).DriverJourneys(ctx, req.(*DriverJourneysRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _SolidarityService_SetPassengerTrip_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(PassengerTripRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SolidarityServiceServer).SetPassengerTrip(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: SolidarityService_SetPassengerTrip_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SolidarityServiceServer).SetPassengerTrip(ctx, req.(*PassengerTripRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// SolidarityService_ServiceDesc is the grpc.ServiceDesc for SolidarityService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var SolidarityService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "SolidarityService", + HandlerType: (*SolidarityServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "SetDriverRegularAvailabilities", + Handler: _SolidarityService_SetDriverRegularAvailabilities_Handler, + }, + { + MethodName: "SetDriverPunctualAvailabilities", + Handler: _SolidarityService_SetDriverPunctualAvailabilities_Handler, + }, + { + MethodName: "CreateBooking", + Handler: _SolidarityService_CreateBooking_Handler, + }, + { + MethodName: "UpdateBooking", + Handler: _SolidarityService_UpdateBooking_Handler, + }, + { + MethodName: "GetBooking", + Handler: _SolidarityService_GetBooking_Handler, + }, + { + MethodName: "GetBookingsByStatus", + Handler: _SolidarityService_GetBookingsByStatus_Handler, + }, + { + MethodName: "DriverJourneys", + Handler: _SolidarityService_DriverJourneys_Handler, + }, + { + MethodName: "SetPassengerTrip", + Handler: _SolidarityService_SetPassengerTrip_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "solidarity-api.proto", +} diff --git a/servers/grpc/server/booking_status.go b/servers/grpc/server/booking_status.go new file mode 100644 index 0000000..85dd0a3 --- /dev/null +++ b/servers/grpc/server/booking_status.go @@ -0,0 +1,27 @@ +package grpcserver + +import ( + "solidarity-service/internal" + "solidarity-service/servers/grpc/proto" +) + +func ConvertInternalToProtoBookingStatus(internalStatus internal.BookingStatus) proto.BookingStatus { + switch internalStatus { + case internal.BookingStatusINITIATED: + return proto.BookingStatus_INITIATED + case internal.BookingStatusWAITINGPASSENGERCONFIRMATION: + return proto.BookingStatus_WAITING_PASSENGER_CONFIRMATION + case internal.BookingStatusWAITINGDRIVERCONFIRMATION: + return proto.BookingStatus_WAITING_DRIVER_CONFIRMATION + case internal.BookingStatusCONFIRMED: + return proto.BookingStatus_CONFIRMED + case internal.BookingStatusCANCELLED: + return proto.BookingStatus_CANCELLED + case internal.BookingStatusCOMPLETEDPENDINGVALIDATION: + return proto.BookingStatus_COMPLETED_PENDING_VALIDATION + case internal.BookingStatusVALIDATED: + return proto.BookingStatus_VALIDATED + default: + return proto.BookingStatus_CONFIRMED + } +} diff --git a/servers/grpc/server/days.go b/servers/grpc/server/days.go new file mode 100644 index 0000000..b3de66f --- /dev/null +++ b/servers/grpc/server/days.go @@ -0,0 +1,26 @@ +package grpcserver + +import ( + "solidarity-service/servers/grpc/proto" +) + +func ConvertToProtoDayOfTheWeek(day string) proto.DayOfWeek { + switch day { + case "MON": + return proto.DayOfWeek_MON + case "TUE": + return proto.DayOfWeek_TUE + case "WED": + return proto.DayOfWeek_WED + case "THU": + return proto.DayOfWeek_THU + case "FRI": + return proto.DayOfWeek_FRI + case "SAT": + return proto.DayOfWeek_FRI + case "SUN": + return proto.DayOfWeek_SAT + default: + return proto.DayOfWeek_MON + } +} diff --git a/servers/grpc/server/server.go b/servers/grpc/server/server.go new file mode 100644 index 0000000..db86cf1 --- /dev/null +++ b/servers/grpc/server/server.go @@ -0,0 +1,40 @@ +package grpcserver + +import ( + "fmt" + "github.com/rs/zerolog/log" + "github.com/spf13/viper" + "google.golang.org/grpc" + "net" + "solidarity-service/handler" + "solidarity-service/servers/grpc/proto" +) + +type SolidarityServiceServerImpl struct { + Handler *handler.SolidarityServiceHandler + proto.UnimplementedSolidarityServiceServer +} + +func NewSolidarityServiceServer(handler *handler.SolidarityServiceHandler) *SolidarityServiceServerImpl { + return &SolidarityServiceServerImpl{ + Handler: handler, + } +} + +func Run(done chan error, cfg *viper.Viper, handler *handler.SolidarityServiceHandler) { + var ( + address = ":" + cfg.GetString("services.grpc.port") + ) + + server := grpc.NewServer() + proto.RegisterSolidarityServiceServer(server, NewSolidarityServiceServer(handler)) + l, err := net.Listen("tcp", address) + if err != nil { + log.Fatal().Err(err) + return + } + if err := server.Serve(l); err != nil { + fmt.Println("gRPC service ended") + done <- err + } +} diff --git a/servers/grpc/server/services.go b/servers/grpc/server/services.go new file mode 100644 index 0000000..a80d3e9 --- /dev/null +++ b/servers/grpc/server/services.go @@ -0,0 +1,543 @@ +package grpcserver + +import ( + "context" + "errors" + "github.com/golang/protobuf/ptypes/timestamp" + "github.com/paulmach/orb" + "github.com/paulmach/orb/geojson" + "solidarity-service/internal" + "solidarity-service/servers/grpc/proto" +) + +func (s *SolidarityServiceServerImpl) SetDriverRegularAvailabilities(ctx context.Context, req *proto.DriverRegularAvailabilities) (resp *proto.DriverAvailabilitiesResponse, err error) { + if req.DriverRequest.Driver.Id == "" || req.DriverRequest.Driver.Alias == "" || req.DriverAvailabilities == nil || req.DriverRequest.DriverAddress == nil || req.DriverRequest.DriverRadius == 0 { + return &proto.DriverAvailabilitiesResponse{ + Success: false, + }, errors.New("missing required fields") + } + driver := internal.Driver{ + Driver_departure_address: &geojson.Feature{ + Type: "Feature", + Geometry: orb.Geometry(orb.Point{req.DriverRequest.DriverAddress.Lat, req.DriverRequest.DriverAddress.Long}), + Properties: geojson.Properties{ + "name": req.DriverRequest.DriverAddress.Address, + }, + }, + Radius: req.DriverRequest.DriverRadius, + Driver: internal.User{ + ID: req.DriverRequest.Driver.Id, + Alias: req.DriverRequest.Driver.Alias, + }, + AvailabilitiesType: internal.Regular, + } + + if req.DriverRequest.Driver.FirstName != nil { + driver.Driver.FirstName = *req.DriverRequest.Driver.FirstName + } + if req.DriverRequest.Driver.LastName != nil { + driver.Driver.LastName = *req.DriverRequest.Driver.LastName + } + if req.DriverRequest.Driver.Grade != nil { + driver.Driver.Grade = *req.DriverRequest.Driver.Grade + } + if req.DriverRequest.Driver.Picture != nil { + driver.Driver.Picture = *req.DriverRequest.Driver.Picture + } + if req.DriverRequest.Driver.Gender != nil { + driver.Driver.Gender = *req.DriverRequest.Driver.Gender + } + if req.DriverRequest.Driver.VerifiedIdentity != nil { + driver.Driver.VerifiedIdentity = *req.DriverRequest.Driver.VerifiedIdentity + } + + if req.DriverRequest.Car != nil { + driver.Car = internal.Car{ + Model: *req.DriverRequest.Car.Model, + Brand: *req.DriverRequest.Car.Brand, + } + } + if req.DriverRequest.Preferences != nil { + driver.Preferences = internal.Preferences{ + Smoking: *req.DriverRequest.Preferences.Smoking, + Animals: *req.DriverRequest.Preferences.Animals, + Music: *req.DriverRequest.Preferences.Music, + Is_talker: *req.DriverRequest.Preferences.IsTalker, + Luggage_size: *req.DriverRequest.Preferences.LuggageSize, + } + } + for _, v := range req.DriverAvailabilities { + driver.RegularAvailabilities = append(driver.RegularAvailabilities, internal.RegularAvailabilities{ + DayOfWeek: v.DayOfWeek.String(), + StartTime: v.StartTime, + EndTime: v.EndTime, + }) + } + + err = s.Handler.SetDriverAvailabilities(context.Background(), driver) + if err != nil { + return &proto.DriverAvailabilitiesResponse{ + Success: false, + }, err + } + return &proto.DriverAvailabilitiesResponse{ + Success: true, + }, nil +} + +func (s *SolidarityServiceServerImpl) SetDriverPunctualAvailabilities(ctx context.Context, req *proto.DriverPunctualAvailabilities) (resp *proto.DriverAvailabilitiesResponse, err error) { + if req.DriverRequest.Driver.Id == "" || req.DriverRequest.Driver.Alias == "" || req.DriverAvailabilities == nil || req.DriverRequest.DriverAddress == nil || req.DriverRequest.DriverRadius == 0 { + return &proto.DriverAvailabilitiesResponse{ + Success: false, + }, errors.New("missing required fields") + } + driver := internal.Driver{ + Driver_departure_address: &geojson.Feature{ + Type: "Feature", + Geometry: orb.Geometry(orb.Point{req.DriverRequest.DriverAddress.Lat, req.DriverRequest.DriverAddress.Long}), + Properties: geojson.Properties{ + "name": req.DriverRequest.DriverAddress.Address, + }, + }, + Radius: req.DriverRequest.DriverRadius, + Driver: internal.User{ + ID: req.DriverRequest.Driver.Id, + Alias: req.DriverRequest.Driver.Alias, + }, + AvailabilitiesType: internal.Punctual, + } + + if req.DriverRequest.Driver.FirstName != nil { + driver.Driver.FirstName = *req.DriverRequest.Driver.FirstName + } + if req.DriverRequest.Driver.LastName != nil { + driver.Driver.LastName = *req.DriverRequest.Driver.LastName + } + if req.DriverRequest.Driver.Grade != nil { + driver.Driver.Grade = *req.DriverRequest.Driver.Grade + } + if req.DriverRequest.Driver.Picture != nil { + driver.Driver.Picture = *req.DriverRequest.Driver.Picture + } + if req.DriverRequest.Driver.Gender != nil { + driver.Driver.Gender = *req.DriverRequest.Driver.Gender + } + if req.DriverRequest.Driver.VerifiedIdentity != nil { + driver.Driver.VerifiedIdentity = *req.DriverRequest.Driver.VerifiedIdentity + } + + if req.DriverRequest.Car != nil { + driver.Car = internal.Car{ + Model: *req.DriverRequest.Car.Model, + Brand: *req.DriverRequest.Car.Brand, + } + } + if req.DriverRequest.Preferences != nil { + driver.Preferences = internal.Preferences{ + Smoking: *req.DriverRequest.Preferences.Smoking, + Animals: *req.DriverRequest.Preferences.Animals, + Music: *req.DriverRequest.Preferences.Music, + Is_talker: *req.DriverRequest.Preferences.IsTalker, + Luggage_size: *req.DriverRequest.Preferences.LuggageSize, + } + } + for _, v := range req.DriverAvailabilities { + driver.PunctualAvailabilities = append(driver.PunctualAvailabilities, internal.PunctualAvailabilities{ + Date: v.Date.Seconds, + StartTime: v.StartTime, + EndTime: v.EndTime, + }) + } + + err = s.Handler.SetDriverAvailabilities(context.Background(), driver) + if err != nil { + return &proto.DriverAvailabilitiesResponse{ + Success: false, + }, err + } + return &proto.DriverAvailabilitiesResponse{ + Success: true, + }, nil +} + +func (s *SolidarityServiceServerImpl) CreateBooking(ctx context.Context, req *proto.CreateBookingRequest) (resp *proto.CreateBookingResponse, err error) { + if req.Booking.DriverId == "" || req.Booking.PassengerId == "" || req.Booking.Id == "" || req.Booking.Status.String() == "" { + return nil, errors.New("missing required fields") + } + bookingRequest := internal.BookingRequest{ + ID: req.Booking.Id, + Passenger_id: req.Booking.PassengerId, + Driver_id: req.Booking.DriverId, + Status: internal.BookingStatus(req.Booking.Status), + } + passenger, driver, err := s.Handler.CreateBooking(context.Background(), bookingRequest) + if err != nil { + return nil, err + } + duration, err := s.Handler.CalculateDurationBetweenFeatures(passenger.Passenger_departure_address, passenger.Passenger_destination_address) + if err != nil { + duration = 0 + } + distance := s.Handler.CalculateDistanceBetweenFeatures(passenger.Passenger_departure_address, passenger.Passenger_destination_address) + priceType := proto.PriceType_FREE + resp.Booking = &proto.Booking{ + Id: bookingRequest.ID, + Driver: &proto.User{ + Id: driver.Driver.ID, + Alias: driver.Driver.Alias, + FirstName: &driver.Driver.FirstName, + LastName: &driver.Driver.LastName, + Grade: &driver.Driver.Grade, + Picture: &driver.Driver.Picture, + Gender: &driver.Driver.Gender, + VerifiedIdentity: &driver.Driver.VerifiedIdentity, + }, + Passenger: &proto.User{ + Id: passenger.Passenger.ID, + Alias: passenger.Passenger.Alias, + FirstName: &passenger.Passenger.FirstName, + LastName: &passenger.Passenger.LastName, + Grade: &passenger.Passenger.Grade, + Picture: &passenger.Passenger.Picture, + Gender: &passenger.Passenger.Gender, + VerifiedIdentity: &passenger.Passenger.VerifiedIdentity, + }, + PassengerPickupDate: ×tamp.Timestamp{ + Seconds: passenger.Passenger_pickup_date, + }, + PassengerDepartureRoute: &proto.Feature{ + Lat: passenger.Passenger_departure_address.Point().Lat(), + Long: passenger.Passenger_departure_address.Point().Lon(), + Address: passenger.Passenger_departure_address.Properties.MustString("name"), + }, + PassengerDestinationRoute: &proto.Feature{ + Lat: passenger.Passenger_destination_address.Point().Lat(), + Long: passenger.Passenger_destination_address.Point().Lon(), + Address: passenger.Passenger_destination_address.Properties.MustString("name"), + }, + Status: ConvertInternalToProtoBookingStatus(bookingRequest.Status), + Duration: &duration, + Distance: &distance, + Price: &proto.Price{ + Type: &priceType, + }, + Car: &proto.Car{ + Model: &driver.Car.Model, + Brand: &driver.Car.Brand, + }, + } + return resp, nil +} + +func (s *SolidarityServiceServerImpl) UpdateBooking(ctx context.Context, req *proto.UpdateBookingRequest) (resp *proto.UpdateBookingResponse, err error) { + if req.BookingId == "" || req.Status.String() == "" { + return &proto.UpdateBookingResponse{ + Success: false, + }, errors.New("missing required fields") + } + bookingStatus := internal.BookingStatus(req.Status.String()) + err = s.Handler.UpdateBooking(context.Background(), req.BookingId, bookingStatus) + if err != nil { + return &proto.UpdateBookingResponse{ + Success: false, + }, err + } + return &proto.UpdateBookingResponse{ + Success: true, + }, nil +} + +func (s *SolidarityServiceServerImpl) GetBooking(ctx context.Context, req *proto.GetBookingRequest) (resp *proto.GetBookingResponse, err error) { + if req.BookingId == "" { + return nil, errors.New("empty booking ID") + } + booking, passenger, driver, err := s.Handler.GetBooking(context.Background(), req.BookingId) + if err != nil { + return nil, err + } + duration, err := s.Handler.CalculateDurationBetweenFeatures(passenger.Passenger_departure_address, passenger.Passenger_destination_address) + if err != nil { + duration = 0 + } + distance := s.Handler.CalculateDistanceBetweenFeatures(passenger.Passenger_departure_address, passenger.Passenger_destination_address) + priceType := proto.PriceType_FREE + resp.Booking = &proto.Booking{ + Id: booking.ID, + Driver: &proto.User{ + Id: driver.Driver.ID, + Alias: driver.Driver.Alias, + FirstName: &driver.Driver.FirstName, + LastName: &driver.Driver.LastName, + Grade: &driver.Driver.Grade, + Picture: &driver.Driver.Picture, + Gender: &driver.Driver.Gender, + VerifiedIdentity: &driver.Driver.VerifiedIdentity, + }, + Passenger: &proto.User{ + Id: passenger.Passenger.ID, + Alias: passenger.Passenger.Alias, + FirstName: &passenger.Passenger.FirstName, + LastName: &passenger.Passenger.LastName, + Grade: &passenger.Passenger.Grade, + Picture: &passenger.Passenger.Picture, + Gender: &passenger.Passenger.Gender, + VerifiedIdentity: &passenger.Passenger.VerifiedIdentity, + }, + PassengerPickupDate: ×tamp.Timestamp{ + Seconds: passenger.Passenger_pickup_date, + }, + PassengerDepartureRoute: &proto.Feature{ + Lat: passenger.Passenger_departure_address.Point().Lat(), + Long: passenger.Passenger_departure_address.Point().Lon(), + Address: passenger.Passenger_departure_address.Properties.MustString("name"), + }, + PassengerDestinationRoute: &proto.Feature{ + Lat: passenger.Passenger_destination_address.Point().Lat(), + Long: passenger.Passenger_destination_address.Point().Lon(), + Address: passenger.Passenger_destination_address.Properties.MustString("name"), + }, + Status: ConvertInternalToProtoBookingStatus(booking.Status), + Duration: &duration, + Distance: &distance, + Price: &proto.Price{ + Type: &priceType, + }, + Car: &proto.Car{ + Model: &driver.Car.Model, + Brand: &driver.Car.Brand, + }, + } + return resp, nil + +} + +func (s *SolidarityServiceServerImpl) GetBookingsByStatus(ctx context.Context, req *proto.GetBookingsByStatusRequest) (resp *proto.GetBookingsByStatusResponse, err error) { + if req.Type.String() == "" || req.Status.String() == "" || req.UserId == "" { + return nil, errors.New("missing required fields") + } + bookings, err := s.Handler.GetBookingsByStatus(context.Background(), req.Status.String(), req.Type.String(), req.UserId) + if err != nil { + return nil, err + } + responses := []*proto.Booking{} + for _, v := range bookings { + passenger, err := s.Handler.GetPassenger(context.Background(), v.Passenger.ID) + if err != nil { + return nil, err + } + driver, err := s.Handler.GetDriver(context.Background(), v.Driver.ID) + if err != nil { + return nil, err + } + duration, err := s.Handler.CalculateDurationBetweenFeatures(passenger.Passenger_departure_address, passenger.Passenger_destination_address) + if err != nil { + duration = 0 + } + priceType := proto.PriceType_FREE + distance := s.Handler.CalculateDistanceBetweenFeatures(passenger.Passenger_departure_address, passenger.Passenger_destination_address) + responses = append(responses, &proto.Booking{ + Id: v.ID, + Status: ConvertInternalToProtoBookingStatus(v.Status), + Driver: &proto.User{ + Id: v.Driver.ID, + Alias: driver.Driver.Alias, + FirstName: &driver.Driver.FirstName, + LastName: &driver.Driver.LastName, + Grade: &driver.Driver.Grade, + Picture: &driver.Driver.Picture, + Gender: &driver.Driver.Gender, + VerifiedIdentity: &driver.Driver.VerifiedIdentity, + }, + Passenger: &proto.User{ + Id: v.Passenger.ID, + Alias: passenger.Passenger.Alias, + FirstName: &passenger.Passenger.FirstName, + LastName: &passenger.Passenger.LastName, + Grade: &passenger.Passenger.Grade, + Picture: &passenger.Passenger.Picture, + Gender: &passenger.Passenger.Gender, + VerifiedIdentity: &passenger.Passenger.VerifiedIdentity, + }, + PassengerPickupDate: ×tamp.Timestamp{ + Seconds: passenger.Passenger_pickup_date, + }, + PassengerDepartureRoute: &proto.Feature{ + Lat: passenger.Passenger_departure_address.Point().Lat(), + Long: passenger.Passenger_departure_address.Point().Lon(), + Address: passenger.Passenger_departure_address.Properties.MustString("name"), + }, + PassengerDestinationRoute: &proto.Feature{ + Lat: passenger.Passenger_destination_address.Point().Lat(), + Long: passenger.Passenger_destination_address.Point().Lon(), + Address: passenger.Passenger_destination_address.Properties.MustString("name"), + }, + Duration: &duration, + Distance: &distance, + Car: &proto.Car{ + Model: &driver.Car.Model, + Brand: &driver.Car.Brand, + }, + Price: &proto.Price{ + Type: &priceType, + }, + }) + } + resp.Booking = responses + return resp, nil +} + +func (s *SolidarityServiceServerImpl) DriverJourneys(ctx context.Context, req *proto.DriverJourneysRequest) (resp *proto.DriverJourneysResponse, err error) { + + if req.DepartureDate.Seconds == 0 || req.Departure == nil { + return nil, errors.New("missing required fields") + } + drivers, err := s.Handler.GetDriverJourneys(context.Background(), &geojson.Feature{ + Type: "Feature", + Geometry: orb.Geometry(orb.Point{req.Departure.Lat, req.Departure.Long}), + Properties: geojson.Properties{ + "name": req.Departure.Address, + }}, + req.DepartureDate.Seconds) + if err != nil { + return nil, err + } + response := []*proto.DriverJourney{} + for _, v := range drivers { + temp := &proto.DriverJourney{} + if v.AvailabilitiesType == internal.Regular && v.RegularAvailabilities != nil { + regularAvailabilities := make([]*proto.RegularAvailabilitySlot, 0) // Initialize an empty slice + for _, v := range v.RegularAvailabilities { + day := ConvertToProtoDayOfTheWeek(v.DayOfWeek) + regularAvailabilities = append(regularAvailabilities, &proto.RegularAvailabilitySlot{ + DayOfWeek: day, + StartTime: v.StartTime, + EndTime: v.EndTime, + }) + } + convertedAvailability := &proto.RepeatedRegularAvailabilitySlot{ + RegularAvailabilities: regularAvailabilities, + } + temp.Availabilities = &proto.DriverJourney_RepeatedRegularAvailabilities{ + RepeatedRegularAvailabilities: convertedAvailability, + } + + } else if v.AvailabilitiesType == internal.Punctual && v.PunctualAvailabilities != nil { + punctualAvailabilities := make([]*proto.PunctualAvailabilitySlot, 0) // Initialize an empty slice + for _, v := range v.PunctualAvailabilities { + punctualAvailabilities = append(punctualAvailabilities, &proto.PunctualAvailabilitySlot{ + Date: ×tamp.Timestamp{ + Seconds: v.Date, + }, + StartTime: v.StartTime, + EndTime: v.EndTime, + }) + } + convertedAvailability := &proto.RepeatedPunctualAvailabilitySlot{ + PunctualAvailabilities: punctualAvailabilities, + } + + temp.Availabilities = &proto.DriverJourney_RepeatedPunctualAvailabilities{ + RepeatedPunctualAvailabilities: convertedAvailability, + } + } + priceType := proto.PriceType_FREE + tamp := &proto.DriverJourney{ + User: &proto.User{ + Id: v.Driver.ID, + Alias: v.Driver.Alias, + FirstName: &v.Driver.FirstName, + LastName: &v.Driver.LastName, + Grade: &v.Driver.Grade, + Picture: &v.Driver.Picture, + Gender: &v.Driver.Gender, + VerifiedIdentity: &v.Driver.VerifiedIdentity, + }, + Car: &proto.Car{ + Model: &v.Car.Model, + Brand: &v.Car.Brand, + }, + DriverDeparture_Date: ×tamp.Timestamp{ + Seconds: req.DepartureDate.Seconds, + }, + Price: &proto.Price{ + Type: &priceType, + }, + DriverDeparture_Address: v.Driver_departure_address.Properties.MustString("name"), + } + temp.DriverDeparture_Address = tamp.DriverDeparture_Address + temp.Car = tamp.Car + temp.User = tamp.User + temp.DriverDeparture_Date = tamp.DriverDeparture_Date + temp.Price = tamp.Price + response = append(response, temp) + } + resp.DriverJourneys = response + return resp, nil +} +func (s *SolidarityServiceServerImpl) SetPassengerTrip(ctx context.Context, req *proto.PassengerTripRequest) (resp *proto.PassengerTripResponse, err error) { + if req.Passenger.Id == "" || req.Passenger.Alias == "" || req.PassengerPickupDate.Seconds == 0 || req.PassengerDestinationAddress == nil || req.PassengerDestinationAddress == nil { + return &proto.PassengerTripResponse{ + Success: false, + }, errors.New("missing required fields") + } + passenger := internal.Passenger{ + Passenger_departure_address: &geojson.Feature{ + Type: "Feature", + Geometry: orb.Geometry(orb.Point{req.PassengerDepartureAddress.Lat, req.PassengerDepartureAddress.Long}), + Properties: geojson.Properties{ + "name": req.PassengerDepartureAddress.Address, + }, + }, + Passenger_destination_address: &geojson.Feature{ + Type: "Feature", + Geometry: orb.Geometry(orb.Point{req.PassengerDestinationAddress.Lat, req.PassengerDestinationAddress.Long}), + Properties: geojson.Properties{ + "name": req.PassengerDestinationAddress.Address, + }, + }, + Passenger_pickup_date: req.PassengerPickupDate.Seconds, + Passenger: internal.User{ + ID: req.Passenger.Id, + Alias: req.Passenger.Alias, + }, + } + + if req.Passenger.FirstName != nil { + passenger.Passenger.FirstName = *req.Passenger.FirstName + } + if req.Passenger.LastName != nil { + passenger.Passenger.LastName = *req.Passenger.LastName + } + if req.Passenger.Grade != nil { + passenger.Passenger.Grade = *req.Passenger.Grade + } + if req.Passenger.Picture != nil { + passenger.Passenger.Picture = *req.Passenger.Picture + } + if req.Passenger.Gender != nil { + passenger.Passenger.Gender = *req.Passenger.Gender + } + if req.Passenger.VerifiedIdentity != nil { + passenger.Passenger.VerifiedIdentity = *req.Passenger.VerifiedIdentity + } + if req.Preferences != nil { + passenger.Preferences = internal.Preferences{ + Smoking: *req.Preferences.Smoking, + Animals: *req.Preferences.Animals, + Music: *req.Preferences.Music, + Is_talker: *req.Preferences.IsTalker, + Luggage_size: *req.Preferences.LuggageSize, + } + } + + err = s.Handler.SetPassengerTrip(context.Background(), passenger) + if err != nil { + return &proto.PassengerTripResponse{ + Success: false, + }, nil + } + return &proto.PassengerTripResponse{ + Success: true, + }, nil + +} diff --git a/servers/utils/utils.go b/servers/utils/utils.go new file mode 100644 index 0000000..b2c42df --- /dev/null +++ b/servers/utils/utils.go @@ -0,0 +1,22 @@ +package utils + +import "math" + +func Haversine(lat1, lon1, lat2, lon2 float64) float64 { + // Radius of the Earth in kilometers + R := 6371.0 + + lat1 = lat1 * math.Pi / 180 + lon1 = lon1 * math.Pi / 180 + lat2 = lat2 * math.Pi / 180 + lon2 = lon2 * math.Pi / 180 + + dlat := lat2 - lat1 + dlon := lon2 - lon1 + + a := math.Sin(dlat/2)*math.Sin(dlat/2) + math.Cos(lat1)*math.Cos(lat2)*math.Sin(dlon/2)*math.Sin(dlon/2) + c := 2 * math.Atan2(math.Sqrt(a), math.Sqrt(1-a)) + + distance := R * c + return distance +} diff --git a/storage/postgresql.go b/storage/postgresql.go new file mode 100644 index 0000000..7b795a7 --- /dev/null +++ b/storage/postgresql.go @@ -0,0 +1,558 @@ +package storage + +import ( + "database/sql" + "encoding/json" + "errors" + "fmt" + "github.com/google/uuid" + _ "github.com/lib/pq" + "github.com/paulmach/orb" + "github.com/paulmach/orb/geojson" + "github.com/rs/zerolog/log" + "github.com/spf13/viper" + "solidarity-service/internal" + "solidarity-service/servers/utils" + "strconv" + "strings" + "time" +) + +type PostgresqlStorage struct { + DbConnection *sql.DB + Schema string + Tables map[string]string +} + +func NewPostgresqlStorage(cfg *viper.Viper) (PostgresqlStorage, error) { + var ( + host = cfg.GetString("storage.db.psql.host") + port = cfg.GetString("storage.db.psql.port") + user = cfg.GetString("storage.db.psql.user") + password = cfg.GetString("storage.db.psql.password") + dbname = cfg.GetString("storage.db.psql.dbname") + sslmode = cfg.GetString("storage.db.psql.sslmode") + pg_schema = cfg.GetString("storage.db.psql.schema") + pgtables_drivers = cfg.GetString("storage.db.psql.tables.drivers") + pgtables_passengers = cfg.GetString("storage.db.psql.tables.passengers") + pgtables_bookings = cfg.GetString("storage.db.psql.tables.bookings") + ) + portInt, _ := strconv.Atoi(port) + psqlconn := fmt.Sprintf("host=%s port=%d user=%s password=%s dbname=%s sslmode=%s", host, portInt, user, password, dbname, sslmode) + db, err := sql.Open("postgres", psqlconn) + if err != nil { + log.Error().Err(err).Msg("opening connection to postgresql failed") + return PostgresqlStorage{}, fmt.Errorf("connection to postgresql failed") + } + err = db.Ping() + if err != nil { + log.Error().Err(err).Msg("ping to postgresql failed") + return PostgresqlStorage{}, fmt.Errorf("connection to postgresql database failed") + } + return PostgresqlStorage{ + DbConnection: db, + Schema: pg_schema, + Tables: map[string]string{ + "drivers": fmt.Sprintf("%s.%s", pg_schema, pgtables_drivers), + "bookings": fmt.Sprintf("%s.%s", pg_schema, pgtables_bookings), + "passengers": fmt.Sprintf("%s.%s", pg_schema, pgtables_passengers), + }, + }, nil +} + +func (s PostgresqlStorage) CreatePassenger(passenger internal.Passenger) (err error) { + _, err = uuid.Parse(passenger.Passenger.ID) + if err != nil { + log.Error().Err(err).Msg("Postgresql Storage CreatePassenger invalid ID") + return err + } + if passenger.Passenger_pickup_date == 0 { + errMsg := "Postgresql Storage CreatePassenger empty UNIX pickup Date timestamp" + log.Error().Err(err).Msg(errMsg) + return errors.New(errMsg) + } + if passenger.Passenger.Alias == "" || passenger.Passenger.Operator == "" { + errMsg := "Postgresql Storage CreatePassenger empty alias or operator FQDN." + log.Error().Msg(errMsg) + return errors.New(errMsg) + } + preferencesJSON, err := json.Marshal(passenger.Preferences) + if err != nil { + errMsg := "Postgresql Storage CreatePassenger Error encoding Preferences to JSON" + log.Error().Err(err).Msg(errMsg) + return errors.New(errMsg) + } + departureJSON, err := json.Marshal(passenger.Passenger_departure_address) + if err != nil { + errMsg := "Postgresql Storage CreatePassenger Error encoding departure Feature to JSON" + log.Error().Err(err).Msg(errMsg) + return errors.New(errMsg) + } + + destinationJSON, err := json.Marshal(passenger.Passenger_destination_address) + if err != nil { + errMsg := "Postgresql Storage CreatePassenger Error converting destination Feature to JSON" + log.Error().Err(err).Msg(errMsg) + return errors.New(errMsg) + } + _, err = s.DbConnection.Exec(fmt.Sprintf("INSERT INTO %s (passenger_id, passenger_departure_route, passenger_destination_route, alias, last_name, first_name, grade, picture, verified_identity, operator, preferences, passenger_pickup_date) VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12)", s.Tables["passengers"]), + passenger.Passenger.ID, + departureJSON, + destinationJSON, + passenger.Passenger.Alias, + passenger.Passenger.LastName, + passenger.Passenger.FirstName, + passenger.Passenger.Grade, + passenger.Passenger.Picture, + passenger.Passenger.VerifiedIdentity, + passenger.Passenger.Operator, + preferencesJSON, + passenger.Passenger_pickup_date) + if err != nil { + errMsg := "Postgresql Storage CreatePassenger Error inserting data into the database" + log.Error().Err(err).Msg(errMsg) + return errors.New(errMsg) + } + return nil +} + +func (s PostgresqlStorage) GetPassenger(passengerID string) (passenger internal.Passenger, err error) { + var preferencesJSON []byte + var departure_address []byte + var destination_address []byte + err = s.DbConnection.QueryRow(fmt.Sprintf("SELECT passenger_departure_route, passenger_destination_route, alias, last_name, first_name, grade, picture, verified_identity, operator, preferences, passenger_pickup_date , passenger_id FROM %s WHERE passenger_id = $1", s.Tables["passengers"]), passengerID). + Scan( + &departure_address, + &destination_address, + &passenger.Passenger.Alias, + &passenger.Passenger.LastName, + &passenger.Passenger.FirstName, + &passenger.Passenger.Grade, + &passenger.Passenger.Picture, + &passenger.Passenger.VerifiedIdentity, + &passenger.Passenger.Operator, + &preferencesJSON, + &passenger.Passenger_pickup_date, + &passenger.Passenger.ID, + ) + if err != nil { + fmt.Println(err) + errMsg := "Postgresql Storage GetPassenger Error querying data from the database" + log.Error().Err(err).Msg(errMsg) + return passenger, errors.New(errMsg) + } + + err = json.Unmarshal(preferencesJSON, &passenger.Preferences) + if err != nil { + errMsg := "Postgresql Storage GetPassenger Error decoding Preferences from JSON" + log.Error().Err(err).Msg(errMsg) + return passenger, errors.New(errMsg) + } + passenger.Passenger_destination_address, err = geojson.UnmarshalFeature(destination_address) + if err != nil { + errMsg := "Postgresql Storage GetPassenger Error decoding Passenger destination route into GeoJSON" + log.Error().Err(err).Msg(errMsg) + return passenger, errors.New(errMsg) + } + passenger.Passenger_departure_address, err = geojson.UnmarshalFeature(departure_address) + if err != nil { + errMsg := "Postgresql Storage GetPassenger Error decoding Passenger departure route into GeoJSON" + log.Error().Err(err).Msg(errMsg) + return passenger, errors.New(errMsg) + } + return passenger, nil +} + +func (s PostgresqlStorage) CreateDriver(driver internal.Driver) (err error) { + var availabilities []byte + _, err = uuid.Parse(driver.Driver.ID) + if err != nil { + log.Error().Err(err).Msg("Postgresql Storage CreateDriver invalid ID") + return err + } + departureJSON, err := json.Marshal(driver.Driver_departure_address) + if err != nil { + errMsg := "Postgresql Storage CreateDriver Error encoding departure Feature to JSON" + log.Error().Err(err).Msg(errMsg) + return errors.New(errMsg) + } + preferencesJSON, err := json.Marshal(driver.Preferences) + if err != nil { + errMsg := "Postgresql Storage CreateDriver Error encoding Preferences to JSON" + log.Error().Err(err).Msg(errMsg) + return errors.New(errMsg) + } + carJSON, err := json.Marshal(driver.Car) + if err != nil { + errMsg := "Postgresql Storage CreateDriver Error encoding Car to JSON" + log.Error().Err(err).Msg(errMsg) + return errors.New(errMsg) + } + if driver.Driver.Alias == "" || driver.Driver.Operator == "" { + errMsg := "Postgresql Storage CreateDriver empty alias or operator FQDN." + log.Error().Msg(errMsg) + return errors.New(errMsg) + } + if driver.AvailabilitiesType != internal.Punctual && driver.AvailabilitiesType != internal.Regular { + errMsg := "Postgresql Storage CreateDriver invalid Availabilities Type" + log.Error().Msg(errMsg) + return errors.New(errMsg) + } + if driver.Radius == 0 { + errMsg := "Postgresql Storage CreateDriver Radius has to be defined" + log.Error().Msg(errMsg) + return errors.New(errMsg) + } + switch driver.AvailabilitiesType { + case internal.Punctual: + availabilities, err = json.Marshal(driver.PunctualAvailabilities) + if err != nil { + errMsg := "Postgresql Storage CreateDriver error converting Punctual availabilities" + log.Error().Msg(errMsg) + return errors.New(errMsg) + } + case internal.Regular: + availabilities, err = json.Marshal(driver.RegularAvailabilities) + if err != nil { + errMsg := "Postgresql Storage CreateDriver error converting Regular availabilities" + log.Error().Msg(errMsg) + return errors.New(errMsg) + } + } + _, err = s.DbConnection.Exec(fmt.Sprintf("INSERT INTO %s (driver_id,driver_departure_route,driver_radius,last_name,first_name,grade,alias,picture,verified_identity,preferences,availabilities_type,availabilities,operator , car) VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14)", s.Tables["drivers"]), + driver.Driver.ID, + departureJSON, + driver.Radius, + driver.Driver.LastName, + driver.Driver.FirstName, + driver.Driver.Grade, + driver.Driver.Alias, + driver.Driver.Picture, + driver.Driver.VerifiedIdentity, + preferencesJSON, + driver.AvailabilitiesType, + string(availabilities), + driver.Driver.Operator, + carJSON, + ) + if err != nil { + fmt.Println(err) + errMsg := "Postgresql Storage CreateDriver Error inserting data into the database" + log.Error().Err(err).Msg(errMsg) + return errors.New(errMsg) + } + return nil +} + +func (s PostgresqlStorage) GetDriver(driverID string) (driver internal.Driver, err error) { + var preferencesJSON []byte + var departureAddress []byte + var availabilitiesJSON []byte + var carJSON []byte + err = s.DbConnection.QueryRow(fmt.Sprintf("SELECT driver_departure_route, driver_radius, last_name, first_name, grade, alias, picture, verified_identity, preferences, availabilities_type, availabilities, operator , driver_id , car FROM %s WHERE driver_id = $1", s.Tables["drivers"]), driverID). + Scan( + &departureAddress, + &driver.Radius, + &driver.Driver.LastName, + &driver.Driver.FirstName, + &driver.Driver.Grade, + &driver.Driver.Alias, + &driver.Driver.Picture, + &driver.Driver.VerifiedIdentity, + &preferencesJSON, + &driver.AvailabilitiesType, + &availabilitiesJSON, + &driver.Driver.Operator, + &driver.Driver.ID, + &carJSON, + ) + if err != nil { + errMsg := "Postgresql Storage GetDriver Error querying data from the database" + log.Error().Err(err).Msg(errMsg) + return driver, errors.New(errMsg) + } + + err = json.Unmarshal(preferencesJSON, &driver.Preferences) + if err != nil { + errMsg := "Postgresql Storage GetDriver Error decoding Preferences from JSON" + log.Error().Err(err).Msg(errMsg) + return driver, errors.New(errMsg) + } + err = json.Unmarshal(carJSON, &driver.Car) + if err != nil { + errMsg := "Postgresql Storage GetDriver Error decoding Car from JSON" + log.Error().Err(err).Msg(errMsg) + return driver, errors.New(errMsg) + } + driver.Driver_departure_address, err = geojson.UnmarshalFeature(departureAddress) + if err != nil { + errMsg := "Postgresql Storage GetDriver Error decoding Driver departure route into GeoJSON" + log.Error().Err(err).Msg(errMsg) + return driver, errors.New(errMsg) + } + + switch driver.AvailabilitiesType { + case internal.Regular: + err = json.Unmarshal(availabilitiesJSON, &driver.RegularAvailabilities) + if err != nil { + errMsg := "Postgresql Storage GetDriver Error decoding Regular Availabilities from JSON" + log.Error().Err(err).Msg(errMsg) + return driver, errors.New(errMsg) + } + case internal.Punctual: + err = json.Unmarshal(availabilitiesJSON, &driver.PunctualAvailabilities) + if err != nil { + errMsg := "Postgresql Storage GetDriver Error decoding Punctual Availabilities from JSON" + log.Error().Err(err).Msg(errMsg) + return driver, errors.New(errMsg) + } + default: + errMsg := "Postgresql Storage GetDriver Invalid Availabilities Type" + log.Error().Msg(errMsg) + return driver, errors.New(errMsg) + } + + return driver, nil +} + +func (s PostgresqlStorage) CreateBooking(booking internal.BookingRequest) (err error) { + _, err = uuid.Parse(booking.Driver_id) + if err != nil { + log.Error().Err(err).Msg("Postgresql Storage CreateBooking invalid Driver ID") + return err + } + _, err = uuid.Parse(booking.Passenger_id) + if err != nil { + log.Error().Err(err).Msg("Postgresql Storage CreateBooking invalid Passenger ID") + return err + } + _, err = uuid.Parse(booking.ID) + if err != nil { + log.Error().Err(err).Msg("Postgresql Storage CreateBooking invalid Booking ID") + return err + } + if booking.Operator == "" { + log.Error().Err(err).Msg("Postgresql Storage CreateBooking empty operator") + return err + } + _, err = s.DbConnection.Exec(fmt.Sprintf("INSERT INTO %s (booking_id , passenger_id , driver_id , operator, booking_status) VALUES ($1,$2,$3,$4,$5)", s.Tables["bookings"]), + booking.ID, + booking.Passenger_id, + booking.Driver_id, + booking.Operator, + booking.Status, + ) + if err != nil { + errMsg := "Postgresql Storage CreateBooking Error inserting data into the database" + log.Error().Err(err).Msg(errMsg) + return errors.New(errMsg) + } + return nil +} + +func (s PostgresqlStorage) GetBooking(id string) (booking internal.Booking, err error) { + err = s.DbConnection.QueryRow(fmt.Sprintf("SELECT booking_id , passenger_id , driver_id , booking_status FROM %s WHERE booking_id = $1", s.Tables["bookings"]), id). + Scan( + &booking.ID, + &booking.Passenger.ID, + &booking.Driver.ID, + &booking.Status, + ) + fmt.Println(err) + if err != nil { + errMsg := "Postgresql Storage GetBooking Error getting booking" + log.Error().Err(err).Msg(errMsg) + return booking, errors.New(errMsg + err.Error()) + } + passenger, err := s.GetPassenger(booking.Passenger.ID) + if err != nil { + errMsg := "Postgresql Storage GetBooking Error getting passenger" + log.Error().Err(err).Msg(errMsg) + return booking, errors.New(errMsg + err.Error()) + } + booking.Passenger = passenger.Passenger + booking.PassengerPickupAddress = passenger.Passenger_departure_address + booking.PassengerDropAddress = passenger.Passenger_destination_address + driver, err := s.GetDriver(booking.Driver.ID) + if err != nil { + errMsg := "Postgresql Storage GetBooking Error getting driver" + log.Error().Err(err).Msg(errMsg) + return booking, errors.New(errMsg + err.Error()) + } + booking.Driver = driver.Driver + return booking, nil +} + +func (s PostgresqlStorage) UpdateBookingStatus(id string, status internal.BookingStatus) (err error) { + _, err = uuid.Parse(id) + if err != nil { + log.Error().Err(err).Msg("Postgresql Storage UpdateBookingStatus invalid Booking ID") + return err + } + _, err = s.GetBooking(id) + if err != nil { + return errors.New(err.Error()) + } + query := fmt.Sprintf("UPDATE %s SET booking_status = $1 WHERE booking_id = $2", s.Tables["bookings"]) + _, err = s.DbConnection.Exec(query, status, id) + if err != nil { + errMsg := "Postgresql Storage UpdateBookingStatus Error updating booking status" + log.Error().Err(err).Msg(errMsg) + return errors.New(errMsg) + } + + return nil +} + +func (s PostgresqlStorage) FilterUserBookingsByStatus(user_type string, status internal.BookingStatus, user_id string) (bookings []internal.Booking, err error) { + _, err = uuid.Parse(user_id) + if err != nil { + return nil, errors.New("invalid uuid") + } + + if user_type != "driver" && user_type != "passenger" { + return nil, errors.New("invalid user type") + } + switch user_type { + case "driver": + rows, err := s.DbConnection.Query(fmt.Sprintf("SELECT booking_id, passenger_id, driver_id, booking_status FROM %s WHERE driver_id = $1 AND booking_status = $2", s.Tables["bookings"]), + user_id, status) + if err != nil { + return nil, err + } + defer rows.Close() + for rows.Next() { + var booking internal.Booking + if err := rows.Scan(&booking.ID, &booking.Passenger.ID, &booking.Driver.ID, &booking.Status); err != nil { + return nil, err + } + bookings = append(bookings, booking) + } + if err := rows.Err(); err != nil { + return nil, err + } + case "passenger": + rows, err := s.DbConnection.Query(fmt.Sprintf("SELECT booking_id, passenger_id, driver_id, booking_status FROM %s WHERE passenger_id = $1 AND booking_status = $2", s.Tables["bookings"]), + user_id, status) + if err != nil { + return nil, err + } + defer rows.Close() + for rows.Next() { + var booking internal.Booking + if err := rows.Scan(&booking.ID, &booking.Passenger.ID, &booking.Driver.ID, &booking.Status); err != nil { + return nil, err + } + bookings = append(bookings, booking) + } + if err := rows.Err(); err != nil { + return nil, err + } + + } + return bookings, nil +} + +func (s PostgresqlStorage) GetAllDrivers(date int64) (drivers []internal.Driver, err error) { + rows, err := s.DbConnection.Query(fmt.Sprintf("SELECT driver_id, driver_departure_route, driver_radius, last_name, first_name, grade, alias, picture, verified_identity, preferences, availabilities_type, availabilities, operator, car FROM %s", s.Tables["drivers"])) + if err != nil { + return nil, err + } + defer rows.Close() + + for rows.Next() { + var driver internal.Driver + var departureRoute []byte + var preferencesJSON []byte + var availabilitiesJSON []byte + var carJSON []byte + + if err := rows.Scan( + &driver.Driver.ID, + &departureRoute, + &driver.Radius, + &driver.Driver.LastName, + &driver.Driver.FirstName, + &driver.Driver.Grade, + &driver.Driver.Alias, + &driver.Driver.Picture, + &driver.Driver.VerifiedIdentity, + &preferencesJSON, + &driver.AvailabilitiesType, + &availabilitiesJSON, + &driver.Driver.Operator, + &carJSON, + ); err != nil { + return nil, err + } + + if err := json.Unmarshal(departureRoute, &driver.Driver_departure_address); err != nil { + return nil, err + } + if err := json.Unmarshal(preferencesJSON, &driver.Preferences); err != nil { + return nil, err + } + if err := json.Unmarshal(carJSON, &driver.Car); err != nil { + return nil, err + } + + // Filter drivers based on date matching punctual or regular availabilities. + if driver.AvailabilitiesType == internal.Punctual { + if err := json.Unmarshal(availabilitiesJSON, &driver.PunctualAvailabilities); err != nil { + return nil, err + } + // Convert the date to the day of the week and make it lowercase. + dayOfWeek := strings.ToLower(time.Unix(date, 0).UTC().Format("Mon")) + + for _, avail := range driver.PunctualAvailabilities { + // Extract the day part of the punctual driver's date and compare. + availDate := time.Unix(avail.Date, 0) + if strings.ToLower(availDate.Format("Mon")) == dayOfWeek { + drivers = append(drivers, driver) + break + } + } + } else if driver.AvailabilitiesType == internal.Regular { + if err := json.Unmarshal(availabilitiesJSON, &driver.RegularAvailabilities); err != nil { + return nil, err + } + // Convert the date to the day of the week and make it lowercase. + dayOfWeek := strings.ToLower(time.Unix(date, 0).UTC().Format("Mon")) + for _, avail := range driver.RegularAvailabilities { + if strings.ToLower(avail.DayOfWeek) == dayOfWeek { + drivers = append(drivers, driver) + break + } + } + } + } + + if err := rows.Err(); err != nil { + return nil, err + } + + return drivers, nil +} + +func (s PostgresqlStorage) DriverJourneys(departure_route *geojson.Feature, departure_date int64) (drivers []internal.Driver, err error) { + allDrivers, err := s.GetAllDrivers(departure_date) + if err != nil { + return nil, err + } + for _, driver := range allDrivers { + // Check if the departure route is the same as the driver's departure route. + if departure_route.Point().Y() == driver.Driver_departure_address.Point().Y() && departure_route.Point().X() == driver.Driver_departure_address.Point().X() { + drivers = append(drivers, driver) + } else { + // Calculate the distance between the departure point and the driver's departure route. + coords1 := departure_route.Geometry.(orb.Point) + coords2 := driver.Driver_departure_address.Geometry.(orb.Point) + distance := utils.Haversine(coords1[1], coords1[0], coords2[1], coords2[0]) + if int64(distance) <= int64(driver.Radius) { + drivers = append(drivers, driver) + } + } + } + + return drivers, nil +} diff --git a/storage/postgresql/schema.hcl b/storage/postgresql/schema.hcl new file mode 100644 index 0000000..9f22758 --- /dev/null +++ b/storage/postgresql/schema.hcl @@ -0,0 +1,168 @@ + +table "passengers" { + schema = schema.solidarity_service + column "passenger_id" { + null = false + type = uuid + } + column "passenger_departure_route" { + null = false + type = jsonb + } + column "passenger_destination_route" { + null = false + type = jsonb + } + column "alias" { + null = false + type = varchar(15) + } + column "last_name" { + null = true + type = text + } + column "first_name" { + null = true + type = text + } + column "grade" { + null = true + type = int + } + column "picture" { + null = true + type = varchar(200) + } + column "verified_identity"{ + null = true + type = bool + } + column "operator" { + null = false + type = varchar(35) + } + column "preferences" { + null = true + type = jsonb + } + column "passenger_pickup_date" { + null = false + type = int + } + primary_key { + columns = [column.passenger_id] + } +} + + +table "drivers" { + schema = schema.solidarity_service + column "driver_id" { + null = false + type = uuid + } + column "driver_departure_route" { + null = false + type = jsonb + } + column "driver_radius" { + null = false + type = integer + } + column "last_name" { + null = true + type = text + } + column "first_name" { + null = true + type = text + } + column "grade" { + null = true + type = int + } + column "alias" { + null = false + type = varchar(15) + } + column "picture" { + null = true + type = text + } + column "verified_identity"{ + null = true + type = bool + } + column "preferences" { + null = true + type = jsonb + } + column "availabilities_type" { + null = false + type = enum.availabilities_type + } + column "availabilities" { + null = false + type = jsonb + } + column "car" { + null = true + type = jsonb + } + column "operator" { + null = false + type = varchar(35) + } + primary_key { + columns = [column.driver_id] + } +} + + +table "bookings" { + schema = schema.solidarity_service + column "booking_id" { + null = false + type = uuid + } + column "driver_id" { + null = false + type = uuid + } + column "operator" { + null = false + type = varchar(35) + } + column "passenger_id" { + null = false + type = uuid + } + column "booking_status" { + null = false + type = enum.booking_status + } + primary_key { + columns = [column.booking_id] + } + foreign_key "bookings_driver_id_fkey" { + columns = [column.driver_id] + ref_columns = [table.drivers.column.driver_id] + } + foreign_key "group_members_passenger_id_fkey" { + columns = [column.passenger_id] + ref_columns = [table.passengers.column.passenger_id] + } +} + + +enum "booking_status" { + schema = schema.solidarity_service + values = ["INITIATED", "WAITING_PASSENGER_CONFIRMATION", "WAITING_DRIVER_CONFIRMATION", "CONFIRMED", "CANCELLED", "COMPLETED_PENDING_VALIDATION", "VALIDATED"] +} +enum "availabilities_type" { + schema = schema.solidarity_service + values = ["PUNCTUAL","REGULAR"] +} + +schema "solidarity_service" { +} diff --git a/storage/storage.go b/storage/storage.go new file mode 100644 index 0000000..cbca33d --- /dev/null +++ b/storage/storage.go @@ -0,0 +1,34 @@ +package storage + +import ( + "fmt" + "github.com/paulmach/orb/geojson" + "github.com/spf13/viper" + "solidarity-service/internal" +) + +type Storage interface { + CreatePassenger(passenger internal.Passenger) (err error) + GetPassenger(passengerID string) (passenger internal.Passenger, err error) + CreateDriver(driver internal.Driver) (err error) + GetDriver(driverID string) (driver internal.Driver, err error) + GetBooking(id string) (booking internal.Booking, err error) + CreateBooking(booking internal.BookingRequest) (err error) + UpdateBookingStatus(id string, status internal.BookingStatus) (err error) + FilterUserBookingsByStatus(user_type string, status internal.BookingStatus, user_id string) (bookings []internal.Booking, err error) + DriverJourneys(departure_route *geojson.Feature, departure_date int64) (drivers []internal.Driver, err error) + GetAllDrivers(date int64) (drivers []internal.Driver, err error) +} + +func NewStorage(cfg *viper.Viper) (Storage, error) { + var ( + storage_type = cfg.GetString("storage.db.type") + ) + switch storage_type { + case "psql": + s, err := NewPostgresqlStorage(cfg) + return s, err + default: + return nil, fmt.Errorf("storage type %v is not supported", storage_type) + } +}