Compare commits

..

2 Commits

50 changed files with 3912 additions and 907 deletions

View File

@ -2,38 +2,67 @@
COOPGO Carpool Service is a carpool management microservice. It is part of the COOPGO Technical Platform and the base carpool component of COOPGO's [RIDYGO](https://ridygo.fr) application. It was redesigned from scratch to implement natively the new OCSS carpool standard and bring interoperability.
This is not a full featured carpooling application. There is no UI and it only implements basic carpooling functionalities (create and find, book journeys). The objective of this service is to be embedded in a bigger carpool or Mobility as a Service platform.
This is not a full featured carpooling application. There is no UI and it only implements basic carpooling functionalities (create, search, book journeys). The objective of this service is to be embedded in a bigger carpool or Mobility as a Service platform.
It provides a gRPC service to interact with other microservices, and an HTTP API to provide interoperability with external carpooling operators.
It provides a gRPC service to interact with other microservices or the main application, and an HTTP API to provide interoperability with external carpooling operators.
## Technical architecture
### Managing trips and journeys
Trips and journeys are managed through the provided gRPC service and stored in the database (MongoDB for the moment). They are stored in the database as GeoJSON feature collections with extra members defining the trips and journeys non-geographical parameters.
Trips and journeys are managed through the provided gRPC service and stored in the database (PostgreSQL or MongoDB for the moment). They are stored in the database as GeoJSON feature collections with extra members defining the trips and journeys non-geographical parameters.
### Tiles architecture and cache
Many thanks to [https://github.com/paulmach/orb](https://github.com/paulmach/orb) !
To reduce dependencies on the chosen database, we decided to manage geographical calculations directly in our code instead of relying completely on MongoDB geographical features.
### Tiles architecture
To reduce dependencies on the chosen database, we decided to manage geographical calculations directly in our code instead of relying completely on MongoDB or PostgreSQL/Postgis geographical features.
We use a tiles system to retrieve relevant journeys easily. Each tile is defined by :
- driver or passenger status of the journey
- date of the journey
- Tile ID in the tiles grid. The tiles grid is inspired by Valhalla https://github.com/Telenav/open-source-spec/blob/master/valhalla/doc/valhalla-tiles-basic.md. We use a level 0 grid
- Tile ID in the tiles grid. The tiles grid is inspired by Valhalla https://github.com/Telenav/open-source-spec/blob/master/valhalla/doc/valhalla-tiles-basic.md. We use a level 0 grid.
Journeys are stored in each relevant tile (where a departure, destination or part of the polyline enters the tile)
Tile IDs from each journey/trip is processed at creation time and stored with the journeys or regular trips in the database.
We can simply generate tiles by retrieving the appropriate data from the database.
### Search
### Booking
Search is handled by generating the appropriate tiles for the fiven departure/destination/date/driver/passenger state, and filter the journeys included in these tiles.
TODO : Performance could probably be improved by parallelilizing the filtering flow with goroutines, and adding some tiles caching with [groupcache](https://github.com/golang/groupcache)
## Database
Supported databases :
- [x] PostgreSQL
- [x] MongoDB
TODO : add the option for a simple embedded key-value store like [bbolt](https://github.com/etcd-io/bbolt) or [badgerdb](https://github.com/dgraph-io/badger), with a distributed consensus mechanism (like [raft](https://github.com/hashicorp/raft)) to allow for even simpler deployments when the overall infrastructure doesn't use PostgreSQL or MongoDB
## OCSS standard
The OCSS standard is the new carpooling interoperability standard defined by the french carpooling ecosystem.
COOPGO Carpool Service implements all of this standard, except the messages endpoint which we think should be handled outside of this service, as different carpooling or MaaS applications may handle messaging differently.
COOPGO Carpool Service intends to support this standard completely.
State of the implementation :
- Server side :
- [x] GET `/driver_journeys`
- [x] GET `/passenger_journeys`
- [ ] GET `/driver_regular_trips`
- [ ] GET `/passenger_regular_trips`
- [x] POST `/bookings`
- [x] PATCH `/bookings`
- [x] GET `/bookings`
- [ ] GET `/messages`
- [x] GET `/status`
- Client side : ongoing
## Licence
COOPGP Carpool Service is released under the terms of the AGPL version 3 licence
COOPGO Carpool Service is released under the terms of the AGPL version 3 licence

View File

@ -8,8 +8,61 @@ import (
func ReadConfig() (*viper.Viper, error) {
defaults := map[string]any{
"name": "COOPGO Mobility Accounts",
"name": "COOPGO Carpool Service",
"dev_env": false,
"storage": map[string]any{
"db": map[string]any{
"type": "psql",
"mongodb": map[string]any{
"host": "localhost",
"port": 27017,
"db_name": "coopgo_platform",
"collections": map[string]any{
"regular_routes": "carpool_regular_routes",
"punctual_routes": "carpool_punctual_routes",
"bookings": "carpool_bookings",
"driver_candidate_journeys": "carpool_driver_candidate_journeys",
"passenger_candidate_journeys": "carpool_passenger_candidate_journeys",
"persisted_kv": "carpool_persisted_kv",
},
},
"psql": map[string]any{
"host": "localhost",
"port": 5432,
"user": "postgres",
"password": "postgres",
"dbname": "coopgo_platform",
"schema": "carpool_service",
"sslmode": "disable",
"tables": map[string]any{
"regular_routes": "regular_routes",
"regular_route_schedules": "regular_route_schedules",
"bookings": "bookings",
"journeys_cache": "journeys_cache",
},
},
},
},
"services": map[string]any{
"grpc": map[string]any{
"enable": true,
"port": 8080,
},
"ocss_api": map[string]any{
"enable": true,
"port": 80,
},
},
"interoperability": map[string]any{
"internal_operator_id": "example.coopgo.fr",
"ocss": map[string]any{
"operator_id": "example.coopgo.fr",
"web_urls": map[string]string{
"driver_journeys": "https://example.coopgo.fr/driver_journeys/%s",
"passenger_journeys": "https://example.coopgo.fr/passenger_journeys/%s",
},
},
},
}
v := viper.New()

View File

@ -1,3 +1,4 @@
// Package geoutils provides utility functions to handler geographic calculations such as distance between geometries.
package geoutils
import (
@ -5,9 +6,10 @@ import (
"github.com/paulmach/orb"
"github.com/paulmach/orb/geo"
"github.com/rs/zerolog/log"
)
// DistanceFromLineString provides the shorteds distance between a point and a linestring.
// It returns the distance in meters, and the index of the closest linestring segment to the point
func DistanceFromLineString(point orb.Point, lineString orb.LineString) (distance float64, closestIndex int) {
minDistance := math.Inf(1)
closest := -1
@ -23,14 +25,16 @@ func DistanceFromLineString(point orb.Point, lineString orb.LineString) (distanc
}
}
log.Debug().
Float64("min distance", minDistance).
Int("index", closest).
Any("point", point).
Msg("minimum distance to polyline")
// log.Debug().
// Float64("min distance", minDistance).
// Int("index", closest).
// Any("point", point).
// Msg("minimum distance to polyline")
return minDistance, closest
}
// projectToSegment projects the point to the segment. This function is used in DistanceFromLineString for point-to-segment distance calculation
func projectToSegment(point, a, b orb.Point) orb.Point {
x := a[0]
y := a[1]

13
go.mod
View File

@ -17,31 +17,44 @@ require (
)
require (
ariga.io/atlas v0.10.1 // indirect
git.coopgo.io/coopgo-platform/carpool-service/interoperability/ocss v0.0.0-20230329224518-bf6453b9639a // indirect
git.coopgo.io/coopgo-platform/routing-service v0.0.0-20230329165521-1442647132b9 // indirect
github.com/agext/levenshtein v1.2.1 // indirect
github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/fsnotify/fsnotify v1.6.0 // indirect
github.com/go-openapi/inflect v0.19.0 // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/golang/snappy v0.0.1 // indirect
github.com/google/go-cmp v0.5.9 // indirect
github.com/gorilla/schema v1.2.0 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/hashicorp/hcl/v2 v2.10.0 // indirect
github.com/klauspost/compress v1.13.6 // indirect
github.com/lib/pq v1.10.9 // indirect
github.com/magiconair/properties v1.8.7 // indirect
github.com/mattn/go-colorable v0.1.12 // indirect
github.com/mattn/go-isatty v0.0.14 // indirect
github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe // indirect
github.com/pelletier/go-toml/v2 v2.0.6 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/spf13/afero v1.9.3 // indirect
github.com/spf13/cast v1.5.0 // indirect
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/stretchr/objx v0.5.0 // indirect
github.com/stretchr/testify v1.8.2 // indirect
github.com/subosito/gotenv v1.4.2 // indirect
github.com/twpayne/go-polyline v1.1.1 // indirect
github.com/xdg-go/pbkdf2 v1.0.0 // indirect
github.com/xdg-go/scram v1.1.1 // indirect
github.com/xdg-go/stringprep v1.0.3 // indirect
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect
github.com/zclconf/go-cty v1.8.0 // indirect
golang.org/x/crypto v0.7.0 // indirect
golang.org/x/net v0.8.0 // indirect
golang.org/x/sync v0.1.0 // indirect

36
go.sum
View File

@ -1,3 +1,5 @@
ariga.io/atlas v0.10.1 h1:zub8+r1P4OqUYoDl6AgUxqPRwl8A9oeI5q3LucfsnUE=
ariga.io/atlas v0.10.1/go.mod h1:+TR129FJZ5Lvzms6dvCeGWh1yR6hMvmXBhug4hrNIGk=
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=
@ -52,6 +54,12 @@ git.coopgo.io/coopgo-platform/routing-service v0.0.0-20230329165521-1442647132b9
git.coopgo.io/coopgo-platform/routing-service v0.0.0-20230329165521-1442647132b9/go.mod h1:qKf4kan3/vJXVywIBHa4omSlxIOMYyR11xZrrE5v9D0=
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/agext/levenshtein v1.2.1 h1:QmvMAjj2aEICytGiWzmxoE0x2KZvE0fvmqMOfy2tjT8=
github.com/agext/levenshtein v1.2.1/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558=
github.com/apparentlymart/go-dump v0.0.0-20180507223929-23540a00eaa3/go.mod h1:oL81AME2rN47vu18xqj1S1jPIPuN7afo62yKTNn3XMM=
github.com/apparentlymart/go-textseg v1.0.0/go.mod h1:z96Txxhf3xSFMPmb5X/1W05FF/Nj9VFpLOpjS5yuumk=
github.com/apparentlymart/go-textseg/v13 v13.0.0 h1:Y+KvPE1NYz0xl601PVImeQfFyEy6iT90AvPUL1NNfNw=
github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkEghdlcqw7yxLeM89kiTRPUo=
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=
@ -77,6 +85,9 @@ github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbS
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/go-openapi/inflect v0.19.0 h1:9jCH9scKIbHeV9m12SmPilScz6krDxKRasNNSNPXu/4=
github.com/go-openapi/inflect v0.19.0/go.mod h1:lHpZVlpIQqLyKwJ4N+YSc9hchQy/i12fJykb83CRBH4=
github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
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=
@ -90,6 +101,7 @@ github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt
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.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
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=
@ -122,6 +134,7 @@ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
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/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
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=
@ -148,6 +161,8 @@ github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ
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/hashicorp/hcl/v2 v2.10.0 h1:1S1UnuhDGlv3gRFV4+0EdwB+znNP5HmcGbIqwnSCByg=
github.com/hashicorp/hcl/v2 v2.10.0/go.mod h1:FwWsfWEjyV/CMj8s/gqAuiviY72rJ1/oayI9WftqcKg=
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=
@ -162,12 +177,17 @@ github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
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/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k=
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.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40=
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7 h1:DpOJ2HYzCv8LZP15IdmG+YdwD2luVPHITV96TkirNBM=
github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
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 h1:iruDEfMl2E6fbMZ9s0scYfZQ84/6SPL6zC8ACM2oIL0=
@ -188,12 +208,14 @@ github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBO
github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
github.com/rs/zerolog v1.29.0 h1:Zes4hju04hjbvkVkOhdl2HpZa+0PmVwigmo8XoORE5w=
github.com/rs/zerolog v1.29.0/go.mod h1:NILgTygv/Uej1ra5XxGf82ZFSLk58MFGAUS2o6usyD0=
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
github.com/spf13/afero v1.9.3 h1:41FoI0fD7OR7mGcKE/aOiLkGreyf8ifIOQmJANWogMk=
github.com/spf13/afero v1.9.3/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y=
github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w=
github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU=
github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
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.15.0 h1:js3yy885G8xwJa6iOISGFwd+qlUo5AvyXb7CiihdtiU=
@ -201,6 +223,7 @@ github.com/spf13/viper v1.15.0/go.mod h1:fFcTBJxvhhzSJiZy8n+PeW6t8l+KeT/uTARa0jH
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 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
@ -212,12 +235,17 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8=
github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0=
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/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk=
github.com/vmihailenco/msgpack/v4 v4.3.12/go.mod h1:gborTTJjAo/GWTqqRjrLCn9pgNN+NXzzngzBKDPIqw4=
github.com/vmihailenco/tagparser v0.1.1/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI=
github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c=
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
github.com/xdg-go/scram v1.1.1 h1:VOMT+81stJgXW3CpHyqHN3AXDYIMsx56mEFrB37Mb/E=
@ -230,6 +258,10 @@ github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de
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=
github.com/zclconf/go-cty v1.2.0/go.mod h1:hOPWgoHbaTUnI5k4D2ld+GRpFJSCe6bCM7m1q/N4PQ8=
github.com/zclconf/go-cty v1.8.0 h1:s4AvqaeQzJIu3ndv4gVIhplVD0krU+bgrcLSVUnaWuA=
github.com/zclconf/go-cty v1.8.0/go.mod h1:vVKLxnk3puL4qRAv72AO+W99LUD4da90g3uUAzyuvAk=
github.com/zclconf/go-cty-debug v0.0.0-20191215020915-b22d67c1ba0b/go.mod h1:ZRKQfBXbGkpdV6QMzT3rU1kSTAnfu1dO8dPKjYprgj8=
go.mongodb.org/mongo-driver v1.11.1/go.mod h1:s7p5vEtfbeR1gYi6pnj3c3/urpbLv2T5Sfd6Rp2HBB8=
go.mongodb.org/mongo-driver v1.11.3 h1:Ql6K6qYHEzB6xvu4+AU0BoRoqf9vFPcc4o7MUIdPW8Y=
go.mongodb.org/mongo-driver v1.11.3/go.mod h1:PTSz5yu21bkT/wXpkS7WR5f0ddqw5quethTUn9WM+2g=
@ -240,6 +272,7 @@ 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=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
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=
@ -283,6 +316,7 @@ 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-20180811021610-c39426892332/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=
@ -343,6 +377,7 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h
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-20190502175342-a43fa875dd82/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=
@ -385,6 +420,7 @@ golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3
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.5/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.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68=

View File

@ -1,64 +0,0 @@
package handler
import (
"errors"
"git.coopgo.io/coopgo-platform/carpool-service/internal"
"git.coopgo.io/coopgo-platform/carpool-service/interoperability/ocss"
"github.com/google/uuid"
"github.com/rs/zerolog/log"
)
func (h *CarpoolServiceHandler) Book(booking ocss.Booking) (*internal.Booking, error) {
futureBooking := internal.Booking{}
futureBooking.Roles = []string{}
if booking.Driver.Operator == "ridygo.fr" {
futureBooking.Roles = append(futureBooking.Roles, "driver")
previous_search_result, err := h.Storage.GetSearchResult(booking.DriverJourneyID)
if err == nil {
futureBooking.DriverJourney = &internal.PlannedJourney{
Route: internal.RegularRoute(*previous_search_result.Route),
DepartureDate: previous_search_result.DepartureDate,
}
}
}
if booking.Passenger.Operator == "ridygo.fr" {
futureBooking.Roles = append(futureBooking.Roles, "passenger")
previous_search_result, err := h.Storage.GetSearchResult(booking.PassengerJourneyID)
if err == nil {
futureBooking.PassengerJourney = &internal.PlannedJourney{
Route: internal.RegularRoute(*previous_search_result.Route),
DepartureDate: previous_search_result.DepartureDate,
}
}
}
if len(futureBooking.Roles) == 0 {
return nil, errors.New("couldn't find the right operator id : \"ridygo.fr\" should be set for driver or passenger")
}
if _, err := uuid.Parse(booking.ID); err != nil {
return nil, errors.New("bookingid is not a valid uuid")
}
futureBooking.ID = booking.ID
futureBooking.BookingDefinition = booking
err := h.Storage.CreateBooking(futureBooking)
if err != nil {
log.Error().Err(err).Msg("issue creating booking in database")
return nil, err
}
return &futureBooking, nil
}
func (h *CarpoolServiceHandler) GetBooking(id string) (*internal.Booking, error) {
booking, err := h.Storage.GetBooking(id)
if err != nil {
log.Error().Err(err).Msg("issue retrieving booking in storage")
return nil, errors.New("booking id not found")
}
return booking, nil
}

101
handler/bookings.go Normal file
View File

@ -0,0 +1,101 @@
package handler
import (
"errors"
"fmt"
"time"
"git.coopgo.io/coopgo-platform/carpool-service/internal"
"git.coopgo.io/coopgo-platform/carpool-service/interoperability/ocss"
"github.com/google/uuid"
"github.com/rs/zerolog/log"
)
// Book handles the booking flow
func (h *CarpoolServiceHandler) Book(booking ocss.Booking) (*internal.Booking, error) {
log.Debug().Any("booking", booking).Msg("handler - Book")
log.Debug().Str("passengerPickupDate", booking.PassengerPickupDate.ToTime().Format(time.RFC3339)).Msg("handler - Book")
futureBooking := internal.Booking{}
roles := []string{}
if booking.Driver.Operator == h.InternalOperatorID {
roles = append(roles, "driver")
previous_search_result, err := h.Storage.GetRouteSchedule(booking.DriverJourneyID)
if err == nil {
futureBooking.DriverRoute = previous_search_result.Route
}
}
if booking.Passenger.Operator == h.InternalOperatorID {
roles = append(roles, "passenger")
previous_search_result, err := h.Storage.GetRouteSchedule(booking.PassengerJourneyID)
if err != nil {
log.Error().Err(err).Msg("could not get previous result")
}
if err == nil {
futureBooking.PassengerRoute = previous_search_result.Route
}
}
if len(roles) == 0 {
return nil, fmt.Errorf("couldn't find the right operator id : \"%s\" should be set for driver or passenger", h.InternalOperatorID)
}
if _, err := uuid.Parse(booking.ID); err != nil {
return nil, errors.New("bookingid is not a valid uuid")
}
futureBooking.Booking = booking
err := h.Storage.CreateBooking(futureBooking)
if err != nil {
log.Error().Err(err).Msg("issue creating booking in database")
return nil, err
}
return &futureBooking, nil
}
// GetBooking returns the booking with the given ID
func (h *CarpoolServiceHandler) GetBooking(id string) (*internal.Booking, error) {
booking, err := h.Storage.GetBooking(id)
if err != nil {
log.Error().Err(err).Msg("issue retrieving booking in storage")
return nil, errors.New("booking id not found")
}
return booking, nil
}
// GetUserBookings retrieves all the bookings for a specified user id
func (h *CarpoolServiceHandler) GetUserBookings(user_id string, mindate *time.Time, maxdate *time.Time) ([]internal.Booking, error) {
bookings, err := h.Storage.GetUserBookings(user_id)
if err != nil {
return nil, err
}
results := []internal.Booking{}
for _, b := range bookings {
if mindate != nil {
if b.PassengerPickupDate.ToTime().Before(*mindate) {
continue
}
}
if maxdate != nil {
if b.PassengerPickupDate.ToTime().After(*maxdate) {
continue
}
}
results = append(results, b)
}
return results, nil
}
func (h *CarpoolServiceHandler) UpdateBookingStatus(id string, status ocss.BookingStatus) error {
err := h.Storage.UpdateBookingStatus(id, status.String())
if err != nil {
log.Error().Err(err).Msg("not able to update booking status")
return err
}
return nil
}

View File

@ -1,3 +1,4 @@
// Package handler provides the business logic for the carpool service
package handler
import (
@ -12,13 +13,16 @@ type CarpoolServiceHandler struct {
Storage storage.Storage
Tiles *tiles.TilesHandler
Routing routing.RoutingService
InternalOperatorID string
}
func NewCarpoolServiceHandler(cfg *viper.Viper, storage storage.Storage, tilesHandler *tiles.TilesHandler, routing routing.RoutingService) (*CarpoolServiceHandler, error) {
operator := cfg.GetString("interoperability.internal_operator_id")
return &CarpoolServiceHandler{
Config: cfg,
Storage: storage,
Tiles: tilesHandler,
Routing: routing,
InternalOperatorID: operator,
}, nil
}

View File

@ -14,6 +14,7 @@ import (
"github.com/rs/zerolog/log"
)
// CreateRegularRoutes creates and stores a regular route
func (h *CarpoolServiceHandler) CreateRegularRoutes(routes []*geojson.FeatureCollection) error {
groupid := uuid.NewString()
for _, r := range routes {
@ -57,6 +58,7 @@ func (h *CarpoolServiceHandler) CreateRegularRoutes(routes []*geojson.FeatureCol
return nil
}
// GetUserPlanning returns the planned routes for a user between 2 dates. It transforms regular routes to multiple indivual planned route schedules
func (h *CarpoolServiceHandler) GetUserPlanning(userid string, minDepartureDate time.Time, maxDepartureDate time.Time) (map[string][]internal.PlannedRouteSchedule, error) {
log.Debug().
Str("user_id", userid).
@ -82,9 +84,9 @@ func (h *CarpoolServiceHandler) GetUserPlanning(userid string, minDepartureDate
for _, r := range routes {
rr := internal.RegularRoute(*r)
schedules, err := rr.PlannedJourneySchedules(minDepartureDate, maxDepartureDate)
schedules, err := rr.PlannedRouteSchedules(minDepartureDate, maxDepartureDate)
if err != nil {
log.Error().Err(err)
log.Error().Err(err).Msg("PlannedRouteSchedules error")
return nil, err
}
@ -112,6 +114,7 @@ func (h *CarpoolServiceHandler) GetUserPlanning(userid string, minDepartureDate
return results, nil
}
// GetPlannedTrip returns a planned trip, given an ID. This should be called after getting the user planning from regular routes
func (h *CarpoolServiceHandler) GetPlannedTrip(id string) (*internal.PlannedRouteSchedule, error) {
planned_trip, err := h.Storage.GetRouteSchedule(id)
if err != nil {

View File

@ -10,7 +10,8 @@ import (
"github.com/rs/zerolog/log"
)
func (h *CarpoolServiceHandler) GetDriverJourneys(departure orb.Point, arrival orb.Point, departureRadius *float64, arrivalRadius *float64, minDate time.Time, maxDate time.Time, count *int64) ([]internal.SearchResult, error) {
// GetDriverJourneys searches for matching punctual planned driver journeys.
func (h *CarpoolServiceHandler) GetDriverJourneys(departure orb.Point, arrival orb.Point, departureRadius *float64, arrivalRadius *float64, minDate time.Time, maxDate time.Time, count *int64) ([]internal.PlannedRouteSchedule, error) {
log.Debug().
Any("departure", departure).
@ -51,14 +52,12 @@ func (h *CarpoolServiceHandler) GetDriverJourneys(departure orb.Point, arrival o
candidate_routes := tileset.GetTiledRoutes()
journeys := []internal.SearchResult{}
journeys := []internal.PlannedRouteSchedule{}
counted := int64(0)
for _, r := range candidate_routes {
ls := r.Route.Features[2].Geometry.(orb.LineString)
// distanceFromDeparture, indexDeparture := planar.DistanceFromWithIndex(ls, departure)
// distanceFromArrival, indexArrival := planar.DistanceFromWithIndex(ls, arrival)
distanceFromDeparture, indexDeparture := geoutils.DistanceFromLineString(departure, ls)
distanceFromArrival, indexArrival := geoutils.DistanceFromLineString(arrival, ls)
@ -71,7 +70,7 @@ func (h *CarpoolServiceHandler) GetDriverJourneys(departure orb.Point, arrival o
log.Error().Err(err).Msg("error getting route with viapoints")
continue
}
journeys = append(journeys, internal.SearchResult{
journeys = append(journeys, internal.PlannedRouteSchedule{
ID: r.ID,
Route: r.Route,
DepartureDate: r.DepartureDate,
@ -85,7 +84,7 @@ func (h *CarpoolServiceHandler) GetDriverJourneys(departure orb.Point, arrival o
}
if len(journeys) > 0 {
err = h.Storage.StoreSearchResults(journeys)
err = h.Storage.StoreRouteSchedules(journeys)
if err != nil {
log.Error().Err(err).Msg("Error saving search results")
return nil, err
@ -95,7 +94,8 @@ func (h *CarpoolServiceHandler) GetDriverJourneys(departure orb.Point, arrival o
return journeys, nil
}
func (h *CarpoolServiceHandler) GetPassengerJourneys(departure orb.Point, arrival orb.Point, departureRadius *float64, arrivalRadius *float64, minDate time.Time, maxDate time.Time, count *int64) ([]internal.SearchResult, error) {
// GetPassengerJourneys searches for matching punctual planned passenger journeys.
func (h *CarpoolServiceHandler) GetPassengerJourneys(departure orb.Point, arrival orb.Point, departureRadius *float64, arrivalRadius *float64, minDate time.Time, maxDate time.Time, count *int64) ([]internal.PlannedRouteSchedule, error) {
log.Debug().
Any("departure", departure).
@ -151,7 +151,7 @@ func (h *CarpoolServiceHandler) GetPassengerJourneys(departure orb.Point, arriva
candidate_routes := tileset.GetTiledRoutes()
journeys := []internal.SearchResult{}
journeys := []internal.PlannedRouteSchedule{}
counted := int64(0)
for _, r := range candidate_routes {
@ -167,7 +167,7 @@ func (h *CarpoolServiceHandler) GetPassengerJourneys(departure orb.Point, arriva
log.Error().Err(err).Msg("error getting route with viapoints")
continue
}
journeys = append(journeys, internal.SearchResult{
journeys = append(journeys, internal.PlannedRouteSchedule{
ID: r.ID,
Route: r.Route,
DepartureDate: r.DepartureDate,
@ -181,7 +181,7 @@ func (h *CarpoolServiceHandler) GetPassengerJourneys(departure orb.Point, arriva
}
if len(journeys) > 0 {
err = h.Storage.StoreSearchResults(journeys)
err = h.Storage.StoreRouteSchedules(journeys)
if err != nil {
log.Error().Err(err).Msg("Error saving search results")
return nil, err

View File

@ -1,11 +1,13 @@
package internal
import "git.coopgo.io/coopgo-platform/carpool-service/interoperability/ocss"
import (
"git.coopgo.io/coopgo-platform/carpool-service/interoperability/ocss"
"github.com/paulmach/orb/geojson"
)
type Booking struct {
ID string `bson:"_id"`
Roles []string // At least one of ["driver", "passenger"]
BookingDefinition ocss.Booking
DriverJourney *PlannedJourney
PassengerJourney *PlannedJourney
ocss.Booking `bson:",inline"`
DriverRoute *geojson.FeatureCollection `bson:"driver_route,omitempty"`
PassengerRoute *geojson.FeatureCollection `bson:"passenger_route,omitempty"`
}

View File

@ -1,8 +0,0 @@
package internal
import "time"
type PlannedJourney struct {
Route RegularRoute
DepartureDate time.Time
}

View File

@ -0,0 +1,15 @@
package internal
import (
"time"
"git.coopgo.io/coopgo-platform/routing-service"
"github.com/paulmach/orb/geojson"
)
type PlannedRouteSchedule struct {
ID string `bson:"_id" json:"id"`
Route *geojson.FeatureCollection
DepartureDate time.Time `bson:"departureDate"`
Itinerary *routing.Route `bson:"itinerary,omitempty"`
}

View File

@ -1,3 +1,4 @@
// package internal povides structs used internally within this carpool service
package internal
import (
@ -11,20 +12,11 @@ import (
"github.com/rs/zerolog/log"
)
type PlannedRouteSchedule struct {
ID string `bson:"_id"`
Route RegularRoute
DepartureDate time.Time
}
// RegularRoute is a utility struct to manipulate regular routes. It's just a GeoJSON feature collection with additional functions
type RegularRoute geojson.FeatureCollection
func (rr RegularRoute) PlannedJourneySchedules(mindate time.Time, maxdate time.Time) ([]PlannedRouteSchedule, error) {
log.Debug().
Str("regular_route.id", rr.ExtraMembers.MustString("id", "")).
Str("mindate", mindate.Format(time.RFC3339)).
Str("maxdate", maxdate.Format(time.RFC3339)).
Msg("carpool service handler - PlannedJourneySchedules")
// PlannedRouteSchedules returns individual planned route schedules with 2 dates, from a regular schedule
func (rr RegularRoute) PlannedRouteSchedules(mindate time.Time, maxdate time.Time) ([]PlannedRouteSchedule, error) {
results := []PlannedRouteSchedule{}
@ -44,12 +36,14 @@ func (rr RegularRoute) PlannedJourneySchedules(mindate time.Time, maxdate time.T
h, _ := strconv.Atoi(splitted[0])
m, _ := strconv.Atoi(splitted[1])
t := time.Date(current_date.Year(), current_date.Month(), current_date.Day(), h, m, 0, 0, time.Local)
if t.After(time.Now().Add(-1 * time.Hour)) {
results = append(results, PlannedRouteSchedule{
ID: uuid.NewString(),
Route: rr,
Route: rr.FeatureCollection(),
DepartureDate: t,
})
}
}
current_date = current_date.Add(24 * time.Hour)
}

View File

@ -1,15 +0,0 @@
package internal
import (
"time"
"git.coopgo.io/coopgo-platform/routing-service"
"github.com/paulmach/orb/geojson"
)
type SearchResult struct {
ID string `bson:"_id"`
Route *geojson.FeatureCollection
DepartureDate time.Time
Itinerary *routing.Route
}

View File

@ -3,13 +3,21 @@ package ocss
import (
"bytes"
"encoding/json"
"fmt"
"time"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/bsontype"
"go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
)
type BookingStatus int64
const (
BookingWaitingConfirmation BookingStatus = iota
BookingInitiated BookingStatus = iota
// BookingWaitingConfirmation
BookingWaitingDriverConfirmation
BookingWaitingPassengerConfirmation
BookingConfirmed
BookingCancelled
BookingCompletedPendingValidation
@ -17,7 +25,10 @@ const (
)
var bookingStatustoID = map[string]BookingStatus{
"WAITING_CONFIRMATION": BookingWaitingConfirmation,
"INITIATED": BookingInitiated,
// "WAITING_CONFIRMATION": BookingWaitingConfirmation,
"WAITING_DRIVER_CONFIRMATION": BookingWaitingDriverConfirmation,
"WAITING_PASSENGER_CONFIRMATION": BookingWaitingPassengerConfirmation,
"CONFIRMED": BookingConfirmed,
"CANCELLED": BookingCancelled,
"COMPLETED_PENDING_VALIDATION": BookingCompletedPendingValidation,
@ -25,7 +36,10 @@ var bookingStatustoID = map[string]BookingStatus{
}
var bookingStatustoString = map[BookingStatus]string{
BookingWaitingConfirmation: "WAITING_CONFIRMATION",
BookingInitiated: "INITIATED",
// BookingWaitingConfirmation: "WAITING_CONFIRMATION",
BookingWaitingDriverConfirmation: "WAITING_DRIVER_CONFIRMATION",
BookingWaitingPassengerConfirmation: "WAITING_PASSENGER_CONFIRMATION",
BookingConfirmed: "CONFIRMED",
BookingCancelled: "CANCELLED",
BookingCompletedPendingValidation: "COMPLETED_PENDING_VALIDATION",
@ -39,34 +53,60 @@ func (s BookingStatus) MarshalJSON() ([]byte, error) {
return buffer.Bytes(), nil
}
func (s BookingStatus) MarshalBSONValue() (bsontype.Type, []byte, error) {
return bson.MarshalValue(bookingStatustoString[s])
}
func (bs *BookingStatus) UnmarshalJSON(b []byte) error {
var j string
err := json.Unmarshal(b, &j)
if err != nil {
return err
}
// Note that if the string cannot be found then it will be set to the zero value, 'Created' in this case.
*bs = bookingStatustoID[j]
return nil
}
func (bs *BookingStatus) UnmarshalBSONValue(t bsontype.Type, b []byte) error {
if t == bsontype.Null || len(b) == 0 {
return nil
}
j, _, ok := bsoncore.ReadString(b)
if !ok {
return fmt.Errorf("cannot parse status")
}
*bs = bookingStatustoID[j]
return nil
}
func (bs *BookingStatus) String() string {
if bs == nil {
return ""
}
return bookingStatustoString[*bs]
}
func BookingStatusFromString(bs string) BookingStatus {
return bookingStatustoID[bs]
}
type Booking struct {
ID string `json:"id",bson:"_id"` // TODO check uuidv4
ID string `json:"id" bson:"_id"`
Driver User `json:"driver"`
Passenger User `json:"passenger"`
PassengerPickupDate JSONTime `json:"passengerPickupDate"`
PassengerPickupLat float64 `json:"passengerPickupLat"`
PassengerPickupLng float64 `json:"passengerPickupLng"`
PassengerDropLat float64 `json:"passengerDropLat"`
PassengerDropLng float64 `json:"passengerDropLng"`
PassengerPickupAddress *string `json:"passengerPickupAddress,omitempty"`
PassengerDropAddress *string `json:"passengerDropAddress,omitempty"`
PassengerPickupDate OCSSTime `json:"passengerPickupDate" bson:"passengerPickupDate"`
PassengerPickupLat float64 `json:"passengerPickupLat" bson:"passengerPickupLat"`
PassengerPickupLng float64 `json:"passengerPickupLng" bson:"passengerPickupLng"`
PassengerDropLat float64 `json:"passengerDropLat" bson:"passengerDropLat"`
PassengerDropLng float64 `json:"passengerDropLng" bson:"passengerDropLng"`
PassengerPickupAddress *string `json:"passengerPickupAddress,omitempty" bson:"passengerPickupAddress,omitempty"`
PassengerDropAddress *string `json:"passengerDropAddress,omitempty" bson:"passengerDropAddress,omitempty"`
Status BookingStatus `json:"status"`
Distance *int64 `json:"distance,omitempty"`
Duration *time.Duration `json:"duration,omitempty"`
WebUrl *string `json:"webUrl,omitempty"`
Distance *int64 `json:"distance,omitempty" bson:"distance,omitempty"`
Duration *time.Duration `json:"duration,omitempty" bson:"duration,omitempty"`
WebUrl *string `json:"webUrl,omitempty" bson:"webUrl,omitempty"`
Price Price `json:"price"`
Car *Car `json:"car,omitempty"`
DriverJourneyID string `json:"driverJourneyId"`
PassengerJourneyID string `json:"passengerJourneyId"`
Car *Car `json:"car,omitempty" bson:"car,omitempty"`
DriverJourneyID string `json:"driverJourneyId" bson:"driverJourneyId"`
PassengerJourneyID string `json:"passengerJourneyId" bson:"passengerJourneyId"`
}

View File

@ -4,6 +4,9 @@ import (
"bytes"
"encoding/json"
"time"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/bsontype"
)
type CarpoolBookingStatus int64
@ -39,6 +42,10 @@ func (s CarpoolBookingStatus) MarshalJSON() ([]byte, error) {
return buffer.Bytes(), nil
}
func (s CarpoolBookingStatus) MarshalBSONValue() (bsontype.Type, []byte, error) {
return bson.MarshalValue(carpoolBookingStatustoString[s])
}
func (bs *CarpoolBookingStatus) UnmarshalJSON(b []byte) error {
var j string
err := json.Unmarshal(b, &j)
@ -50,6 +57,17 @@ func (bs *CarpoolBookingStatus) UnmarshalJSON(b []byte) error {
return nil
}
func (bs *CarpoolBookingStatus) UnmarshalBSON(t bsontype.Type, b []byte) error {
var j string
err := bson.Unmarshal(b, &j)
if err != nil {
return err
}
// Note that if the string cannot be found then it will be set to the zero value, 'Created' in this case.
*bs = carpoolBookingStatustoID[j]
return nil
}
type CarpoolBookingEventData struct {
CarpoolBooking
DriverCarpoolBooking
@ -57,24 +75,24 @@ type CarpoolBookingEventData struct {
}
type CarpoolBookingEvent struct {
ID string `json:"id"` // TODO validate UUID
ID string `json:"id"`
IDToken string `json:"idToken"`
Data CarpoolBookingEventData `json:"data"`
}
type CarpoolBooking struct {
ID string `json:"id"`
PassengerPickupDate time.Time `json:"passengerPickupDate"`
PassengerPickupLat float64 `json:"passengerPickupLat"`
PassengerPickupLng float64 `json:"passengerPickupLng"`
PassengerDropLat float64 `json:"passengerDropLat"`
PassengerDropLng float64 `json:"passengerDropLng"`
PassengerPickupAddress *string `json:"passengerPickupAddress,omitempty"`
PassengerDropAddress *string `json:"passengerDropAddress,omitempty"`
ID string `json:"id" bson:"_id"`
PassengerPickupDate time.Time `json:"passengerPickupDate" bson:"passengerPickupDate"`
PassengerPickupLat float64 `json:"passengerPickupLat" bson:"passengerPickupLat"`
PassengerPickupLng float64 `json:"passengerPickupLng" bson:"passengerPickupLng"`
PassengerDropLat float64 `json:"passengerDropLat" bson:"passengerDropLat"`
PassengerDropLng float64 `json:"passengerDropLng" bson:"passengerDropLng"`
PassengerPickupAddress *string `json:"passengerPickupAddress,omitempty" bson:"passengerPickupAddress,omitempty"`
PassengerDropAddress *string `json:"passengerDropAddress,omitempty" bson:"passengerDropAddress,omitempty"`
Status CarpoolBookingStatus `json:"status"`
Distance *int64 `json:"distance,omitempty"`
Duration *time.Duration `json:"duration,omitempty"`
WebUrl string `json:"webUrl"`
Distance *int64 `json:"distance,omitempty" bson:"distance,omitempty"`
Duration *time.Duration `json:"duration,omitempty" bson:"duration,omitempty"`
WebUrl string `json:"webUrl" bson:"webUrl"`
}
type PassengerCarpoolBooking struct {
@ -84,5 +102,5 @@ type PassengerCarpoolBooking struct {
type DriverCarpoolBooking struct {
Driver User `json:"driver"`
Price Price `json:"price"`
Car *Car `json:"car,omitempty"`
Car *Car `json:"car,omitempty" bson:"car,omitempty"`
}

View File

@ -1,6 +1,6 @@
package ocss
type Car struct {
Model *string `json:"model,omitempty"`
Brand *string `json:"brand,omitempty"`
Model *string `json:"model,omitempty" bson:"model,omitempty"`
Brand *string `json:"brand,omitempty" bson:"brand,omitempty"`
}

View File

@ -2,7 +2,15 @@ package ocss
import "errors"
type Client struct{}
type Client struct {
BaseURL string
}
func NewClient(baseUrl string) *Client {
return &Client{
BaseURL: baseUrl,
}
}
func (c Client) GetDriverJourneys() ([]DriverJourney, error) {
return nil, errors.New("not implemented")

View File

@ -6,3 +6,8 @@ require (
github.com/gorilla/schema v1.2.0
golang.org/x/crypto v0.7.0
)
require (
github.com/paulmach/orb v0.9.0 // indirect
go.mongodb.org/mongo-driver v1.11.1 // indirect
)

View File

@ -1,4 +1,74 @@
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/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/gorilla/schema v1.2.0 h1:YufUaxZYCKGFuAq3c96BOhjgd5nmXiOY9NGzF247Tsc=
github.com/gorilla/schema v1.2.0/go.mod h1:kgLaKoK1FELgZqMAVxx/5cbj0kT+57qxUrAlIO2eleU=
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/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
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/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
github.com/paulmach/orb v0.9.0 h1:MwA1DqOKtvCgm7u9RZ/pnYejTeDJPnr0+0oFajBbJqk=
github.com/paulmach/orb v0.9.0/go.mod h1:SudmOk85SXtmXAB3sLGyJ6tZy/8pdfrV0o6ef98Xc30=
github.com/paulmach/protoscan v0.2.1/go.mod h1:SpcSwydNLrxUGSDvXvO0P7g7AuhJ7lcKfDlhJCDw2gY=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
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.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
go.mongodb.org/mongo-driver v1.11.1 h1:QP0znIRTuL0jf1oBQoAoM0C6ZJfBK4kx0Uumtv1A7w8=
go.mongodb.org/mongo-driver v1.11.1/go.mod h1:s7p5vEtfbeR1gYi6pnj3c3/urpbLv2T5Sfd6Rp2HBB8=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A=
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
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/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/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-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
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-20201020160332-67f06af15bc9/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-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/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-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
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/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
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/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View File

@ -1,11 +1,5 @@
package ocss
import (
"encoding/json"
"fmt"
"time"
)
type JourneyScheduleType int64
const (
@ -24,45 +18,12 @@ func (t JourneyScheduleType) MarshalJSON() ([]byte, error) {
return []byte(types[t]), nil
}
type JSONTime time.Time
func (t JSONTime) MarshalJSON() ([]byte, error) {
//do your serializing here
stamp := fmt.Sprintf("%v", time.Time(t).Unix())
return []byte(stamp), nil
}
func (t *JSONTime) UnmarshalJSON(b []byte) error {
var timestamp int64
err := json.Unmarshal(b, &timestamp)
if err != nil {
return err
}
parsed := time.Unix(timestamp, 0)
if err != nil {
return err
}
jsontime := JSONTime(parsed)
*t = jsontime
return nil
}
func (t *JSONTime) ToTime() *time.Time {
if t == nil {
return nil
}
time := time.Time(*t)
return &time
}
type JourneySchedule struct {
ID *string `json:"id,omitempty"`
PassengerPickupDate JSONTime `json:"passengerPickupDate"`
PassengerDepartureDate *JSONTime `json:"passengerDepartureDate,omitempty"`
DriverDepartureDate *JSONTime `json:"driverDepartureDate,omitempty"`
WebUrl *string `json:"webUrl,omitempty"`
PassengerPickupDate OCSSTime `json:"passengerPickupDate" bson:"passengerPickupDate"`
//PassengerDepartureDate *OCSSTime `json:"passengerDepartureDate,omitempty"`
DriverDepartureDate *OCSSTime `json:"driverDepartureDate,omitempty" bson:"driverDepartureDate,omitempty"`
WebUrl *string `json:"webUrl,omitempty" bson:"webUrl,omitempty"`
Type JourneyScheduleType `json:"type"`
}
@ -70,8 +31,8 @@ type DriverJourney struct {
DriverTrip
JourneySchedule
AvailableSteats *int64 `json:"requestedSeats,omitempty"`
Price *Price `json:"price,omitempty"`
AvailableSteats *int64 `json:"requestedSeats,omitempty" bson:"requestedSeats,omitempty"`
Price *Price `json:"price,omitempty" bson:"price,omitempty"`
}
type PassengerJourney struct {
@ -79,5 +40,5 @@ type PassengerJourney struct {
JourneySchedule
//TODO how to handle requested driverDepartureDate
RequestedSteats *int64 `json:"requestedSeats,omitempty"`
RequestedSteats *int64 `json:"requestedSeats,omitempty" bson:"requestedSeats,omitempty"`
}

View File

@ -0,0 +1,136 @@
package ocss
import (
"time"
geojson "github.com/paulmach/orb/geojson"
)
func NewDriverJourney(
id string,
operator string,
driver User,
passengerPickup geojson.Feature,
passengerDrop geojson.Feature,
duration time.Duration,
passengerPickupDate time.Time,
journeyType JourneyScheduleType,
) *DriverJourney {
var pickupAddress *string
if addr := passengerPickup.Properties.MustString("label", ""); addr != "" {
pickupAddress = &addr
}
var dropAddress *string
if addr := passengerDrop.Properties.MustString("label", ""); addr != "" {
dropAddress = &addr
}
return &DriverJourney{
DriverTrip: DriverTrip{
Driver: driver,
Trip: Trip{
Operator: operator,
PassengerPickupLat: passengerPickup.Point().Lat(),
PassengerPickupLng: passengerPickup.Point().Lon(),
PassengerPickupAddress: pickupAddress,
PassengerDropLat: passengerDrop.Point().Lat(),
PassengerDropLng: passengerDrop.Point().Lon(),
PassengerDropAddress: dropAddress,
Duration: duration,
},
},
JourneySchedule: JourneySchedule{
ID: &id,
PassengerPickupDate: OCSSTime(passengerPickupDate),
Type: journeyType,
},
}
}
func (j *DriverJourney) AddDepartureToPickupWalkingDistance(distance int64) *DriverJourney {
j.DepartureToPickupWalkingDistance = &distance
return j
}
func (j *DriverJourney) AddDepartureToPickupWalkingDuration(duration time.Duration) *DriverJourney {
j.DepartureToPickupWalkingDuration = &duration
return j
}
func (j *DriverJourney) AddDepartureToPickupWalkingPolyline(polyline string) *DriverJourney {
j.DepartureToPickupWalkingPolyline = &polyline
return j
}
func (j *DriverJourney) AddDropoffToArrivalWalkingDistance(distance int64) *DriverJourney {
j.DropoffToArrivalWalkingDistance = &distance
return j
}
func (j *DriverJourney) AddDropoffToArrivalWalkingDuration(duration time.Duration) *DriverJourney {
j.DropoffToArrivalWalkingDuration = &duration
return j
}
func (j *DriverJourney) AddDropoffToArrivalWalkingPolyline(polyline string) *DriverJourney {
j.DropoffToArrivalWalkingPolyline = &polyline
return j
}
func (j *DriverJourney) AddCar(car Car) *DriverJourney {
j.Car = &car
return j
}
func (j *DriverJourney) AddDriverDeparture(location geojson.Feature) *DriverJourney {
lat := location.Point().Lat()
lon := location.Point().Lon()
j.DriverDepartureLat = &lat
j.DriverDepartureLng = &lon
if addr := location.Properties.MustString("label", ""); addr != "" {
j.DriverDepartureAddress = &addr
}
return j
}
func (j *DriverJourney) AddDriverArrival(location geojson.Feature) *DriverJourney {
lat := location.Point().Lat()
lon := location.Point().Lon()
j.DriverArrivalLat = &lat
j.DriverArrivalLng = &lon
if addr := location.Properties.MustString("label", ""); addr != "" {
j.DriverArrivalAddress = &addr
}
return j
}
func (j *DriverJourney) AddDistance(distance int64) *DriverJourney {
j.Distance = &distance
return j
}
func (j *DriverJourney) AddJourneyPolyline(polyline string) *DriverJourney {
j.JourneyPolyline = &polyline
return j
}
func (j *DriverJourney) AddPreferences(preferences Preferences) *DriverJourney {
j.Preferences = &preferences
return j
}
func (j *DriverJourney) AddAvailableSeats(seats int64) *DriverJourney {
j.AvailableSteats = &seats
return j
}
func (j *DriverJourney) AddDriverDepartureDate(date time.Time) *DriverJourney {
d := OCSSTime(date)
j.DriverDepartureDate = &d
return j
}
func (j *DriverJourney) AddWebUrl(url string) *DriverJourney {
j.WebUrl = &url
return j
}

View File

@ -0,0 +1,105 @@
package ocss
import (
"time"
geojson "github.com/paulmach/orb/geojson"
)
func NewPassengerJourney(
id string,
operator string,
driver User,
passengerPickup geojson.Feature,
passengerDrop geojson.Feature,
duration time.Duration,
passengerPickupDate time.Time,
journeyType JourneyScheduleType,
) *PassengerJourney {
var pickupAddress *string
if addr := passengerPickup.Properties.MustString("label", ""); addr != "" {
pickupAddress = &addr
}
var dropAddress *string
if addr := passengerDrop.Properties.MustString("label", ""); addr != "" {
dropAddress = &addr
}
return &PassengerJourney{
PassengerTrip: PassengerTrip{
Passenger: driver,
Trip: Trip{
Operator: operator,
PassengerPickupLat: passengerPickup.Point().Lat(),
PassengerPickupLng: passengerPickup.Point().Lon(),
PassengerPickupAddress: pickupAddress,
PassengerDropLat: passengerDrop.Point().Lat(),
PassengerDropLng: passengerDrop.Point().Lon(),
PassengerDropAddress: dropAddress,
Duration: duration,
},
},
JourneySchedule: JourneySchedule{
ID: &id,
PassengerPickupDate: OCSSTime(passengerPickupDate),
Type: journeyType,
},
}
}
func (j *PassengerJourney) AddDriverDeparture(location geojson.Feature) *PassengerJourney {
lat := location.Point().Lat()
lon := location.Point().Lon()
j.DriverDepartureLat = &lat
j.DriverDepartureLng = &lon
if addr := location.Properties.MustString("label", ""); addr != "" {
j.DriverDepartureAddress = &addr
}
return j
}
func (j *PassengerJourney) AddDriverArrival(location geojson.Feature) *PassengerJourney {
lat := location.Point().Lat()
lon := location.Point().Lon()
j.DriverArrivalLat = &lat
j.DriverArrivalLng = &lon
if addr := location.Properties.MustString("label", ""); addr != "" {
j.DriverArrivalAddress = &addr
}
return j
}
func (j *PassengerJourney) AddDistance(distance int64) *PassengerJourney {
j.Distance = &distance
return j
}
func (j *PassengerJourney) AddJourneyPolyline(polyline string) *PassengerJourney {
j.JourneyPolyline = &polyline
return j
}
func (j *PassengerJourney) AddPreferences(preferences Preferences) *PassengerJourney {
j.Preferences = &preferences
return j
}
func (j *PassengerJourney) AddAvailableSeats(seats int64) *PassengerJourney {
j.RequestedSteats = &seats
return j
}
func (j *PassengerJourney) AddDriverDepartureDate(date time.Time) *PassengerJourney {
d := OCSSTime(date)
j.DriverDepartureDate = &d
return j
}
func (j *PassengerJourney) AddWebUrl(url string) *PassengerJourney {
j.WebUrl = &url
return j
}

View File

@ -1,9 +1,9 @@
package ocss
type Preferences struct {
Smoking *bool `json:"smoking,omitempty"`
Animals *bool `json:"animals,omitempty"`
Music *bool `json:"music,omitempty"`
IsTalker *bool `json:"isTalker,omitempty"`
LuggageSize *int64 `json:"luggageSize,omitempty"`
Smoking *bool `json:"smoking,omitempty" bson:"smoking,omitempty"`
Animals *bool `json:"animals,omitempty" bson:"animals,omitempty"`
Music *bool `json:"music,omitempty" bson:"music,omitempty"`
IsTalker *bool `json:"isTalker,omitempty" bson:"isTalker,omitempty"`
LuggageSize *int64 `json:"luggageSize,omitempty" bson:"luggageSize,omitempty"`
}

View File

@ -3,6 +3,11 @@ package ocss
import (
"bytes"
"encoding/json"
"fmt"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/bsontype"
"go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
)
type PriceType int64
@ -32,6 +37,10 @@ func (s PriceType) MarshalJSON() ([]byte, error) {
return buffer.Bytes(), nil
}
func (s PriceType) MarshalBSONValue() (bsontype.Type, []byte, error) {
return bson.MarshalValue(priceTypeToString[s])
}
func (bs *PriceType) UnmarshalJSON(b []byte) error {
var j string
err := json.Unmarshal(b, &j)
@ -43,8 +52,20 @@ func (bs *PriceType) UnmarshalJSON(b []byte) error {
return nil
}
type Price struct {
Type *PriceType `json:"type,omitempty"`
Amount *float64 `json:"amount,omitempty"`
Currency *string `json:"currency,omitempty"`
func (bs *PriceType) UnmarshalBSONValue(t bsontype.Type, b []byte) error {
if t == bsontype.Null || len(b) == 0 {
return nil
}
j, _, ok := bsoncore.ReadString(b)
if !ok {
return fmt.Errorf("cannot parse status")
}
*bs = priceTypeToID[j]
return nil
}
type Price struct {
Type *PriceType `json:"type,omitempty" bson:"type,omitempty"`
Amount *float64 `json:"amount,omitempty" bson:"amount,omitempty"`
Currency *string `json:"currency,omitempty" bson:"currency,omitempty"`
}

View File

@ -56,7 +56,7 @@ func (bs *Day) UnmarshalJSON(b []byte) error {
}
type Schedule struct {
PassengerPickupDay *Day `json:"passengerPickupDay,omitempty"`
PassengerPickupDay *Day `json:"passengerPickupDay,omitempty" bson:"passengerPickupDay,omitempty"`
JourneySchedules *[]JourneySchedule `json:"journeySchedules,omitempty"`
JourneySchedules *[]JourneySchedule `json:"journeySchedules,omitempty" bson:"journeySchedules,omitempty"`
}

View File

@ -97,7 +97,7 @@ type GetPassengerRegularTripsRequest struct {
type PatchBookingsRequest struct {
BookingId string `json:"bookingId"`
Status string `json:"status"`
Message string `json:message"`
Message string `json:"message"`
}
type Server struct {

View File

@ -0,0 +1,62 @@
package ocss
import (
"encoding/json"
"fmt"
"time"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/bsontype"
"go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
)
type OCSSTime time.Time
func (t OCSSTime) MarshalJSON() ([]byte, error) {
//do your serializing here
stamp := fmt.Sprintf("%v", time.Time(t).Unix())
return []byte(stamp), nil
}
func (v OCSSTime) MarshalBSONValue() (bsontype.Type, []byte, error) {
return bson.MarshalValue(time.Time(v))
}
func (t *OCSSTime) UnmarshalJSON(b []byte) error {
var timestamp int64
err := json.Unmarshal(b, &timestamp)
if err != nil {
return err
}
parsed := time.Unix(timestamp, 0)
if err != nil {
return err
}
ocsstime := OCSSTime(parsed)
*t = ocsstime
return nil
}
func (t *OCSSTime) UnmarshalBSONValue(bt bsontype.Type, b []byte) error {
if bt == bsontype.Null || len(b) == 0 {
return nil
}
datetime, _, ok := bsoncore.ReadTime(b)
if !ok {
return fmt.Errorf("cannot parse time")
}
*t = OCSSTime(datetime)
return nil
}
func (t *OCSSTime) ToTime() *time.Time {
if t == nil {
return nil
}
time := time.Time(*t)
return &time
}

View File

@ -4,34 +4,34 @@ import "time"
type Trip struct {
Operator string `json:"operator"`
PassengerPickupLat float64 `json:"passengerPickupLat"`
PassengerPickupLng float64 `json:"passengerPickupLng"`
PassengerDropLat float64 `json:"passengerDropLat"`
PassengerDropLng float64 `json:"passengerDropLng"`
PassengerPickupLat float64 `json:"passengerPickupLat" bson:"passengerPickupLat"`
PassengerPickupLng float64 `json:"passengerPickupLng" bson:"passengerPickupLng"`
PassengerDropLat float64 `json:"passengerDropLat" bson:"passengerDropLat"`
PassengerDropLng float64 `json:"passengerDropLng" bson:"passengerDropLng"`
Duration time.Duration `json:"duration"`
PassengerPickupAddress *string `json:"passengerPickupAddress,omitempty"`
PassengerDropAddress *string `json:"passengerDropAddress,omitempty"`
Distance *int64 `json:"distance,omitempty"`
DriverDepartureLat *float64 `json:"driverDepartureLat,omitempty"`
DriverDepartureLng *float64 `json:"driverDepartureLng,omitempty"`
DriverArrivalLat *float64 `json:"driverArrivalLat,omitempty"`
DriverArrivalLng *float64 `json:"driverArrivalLng,omitempty"`
DriverDepartureAddress *string `json:"driverDepartureAddress,omitempty"`
DriverArrivalAddress *string `json:"driverArrivalAddress,omitempty"`
JourneyPolyline *string `json:"journeyPolyline,omitempty"`
PassengerPickupAddress *string `json:"passengerPickupAddress,omitempty" bson:"passengerPickupAddress,omitempty"`
PassengerDropAddress *string `json:"passengerDropAddress,omitempty" bson:"passengerDropAddress,omitempty"`
Distance *int64 `json:"distance,omitempty" bson:"distance,omitempty"`
DriverDepartureLat *float64 `json:"driverDepartureLat,omitempty" bson:"driverDepartureLat,omitempty"`
DriverDepartureLng *float64 `json:"driverDepartureLng,omitempty" bson:"driverDepartureLng,omitempty"`
DriverArrivalLat *float64 `json:"driverArrivalLat,omitempty" bson:"driverArrivalLat,omitempty"`
DriverArrivalLng *float64 `json:"driverArrivalLng,omitempty" bson:"driverArrivalLng,omitempty"`
DriverDepartureAddress *string `json:"driverDepartureAddress,omitempty" bson:"driverDepartureAddress,omitempty"`
DriverArrivalAddress *string `json:"driverArrivalAddress,omitempty" bson:"driverArrivalAddress,omitempty"`
JourneyPolyline *string `json:"journeyPolyline,omitempty" bson:"journeyPolyline,omitempty"`
//WebUrl *string `json:"webUrl,omitempty"`
Preferences *Preferences `json:"preferences,omitempty"`
Preferences *Preferences `json:"preferences,omitempty" bson:"preferences,omitempty"`
}
type DriverTrip struct {
Driver User `json:"driver"`
DepartureToPickupWalkingDistance *int64 `json:"departureToPickupWalkingDistance,omitempty"`
DepartureToPickupWalkingDuration *time.Duration `json:"departureToPickupWalkingDuration,omitempty"`
DepartureToPickupWalkingPolyline *string `json:"departureToPickupWalkingPolyline,omitempty"`
DropoffToArrivalWalkingDistance *int64 `json:"dropoffToArrivalWalkingDistance,omitempty"`
DropoffToArrivalWalkingDuration *time.Duration `json:"dropoffToArrivalWalkingDuration,omitempty"`
DropoffToArrivalWalkingPolyline *string `json:"dropoffToArrivalWalkingPolyline,omitempty"`
Car *Car `json:"car,omitempty"`
DepartureToPickupWalkingDistance *int64 `json:"departureToPickupWalkingDistance,omitempty" bson:"departureToPickupWalkingDistance,omitempty"`
DepartureToPickupWalkingDuration *time.Duration `json:"departureToPickupWalkingDuration,omitempty" bson:"departureToPickupWalkingDuration,omitempty"`
DepartureToPickupWalkingPolyline *string `json:"departureToPickupWalkingPolyline,omitempty" bson:"departureToPickupWalkingPolyline,omitempty"`
DropoffToArrivalWalkingDistance *int64 `json:"dropoffToArrivalWalkingDistance,omitempty" bson:"dropoffToArrivalWalkingDistance,omitempty"`
DropoffToArrivalWalkingDuration *time.Duration `json:"dropoffToArrivalWalkingDuration,omitempty" bson:"dropoffToArrivalWalkingDuration,omitempty"`
DropoffToArrivalWalkingPolyline *string `json:"dropoffToArrivalWalkingPolyline,omitempty" bson:"dropoffToArrivalWalkingPolyline,omitempty"`
Car *Car `json:"car,omitempty" bson:"car,omitempty"`
Trip
}

View File

@ -43,14 +43,24 @@ func (bs *Gender) UnmarshalJSON(b []byte) error {
return nil
}
func (g *Gender) ToString() *string {
if g == nil {
return nil
}
res := gendertoString[*g]
return &res
}
type User struct {
ID string `json:"id"`
Operator string `json:"operator"`
Alias string `json:"alias"`
FirstName *string `json:"firstName,omitempty"`
LastName *string `json:"lastName,omitempty"`
Grade *int64 `json:"grade,omitempty"`
Picture *string `json:"picture,omitempty"`
Gender *Gender `json:"gender,omitempty"`
VerifiedIdentity *bool `json:"verifiedIdentity,omitempty"`
FirstName *string `json:"firstName,omitempty" bson:"firstName,omitempty"`
LastName *string `json:"lastName,omitempty" bson:"lastName,omitempty"`
Grade *int64 `json:"grade,omitempty" bson:"grade,omitempty"`
Picture *string `json:"picture,omitempty" bson:"picture,omitempty"`
Gender *Gender `json:"gender,omitempty" bson:"gender,omitempty"`
VerifiedIdentity *bool `json:"verifiedIdentity,omitempty" bson:"verifiedIdentity,omitempty"`
}

View File

@ -123,30 +123,33 @@ type CarpoolServiceBookingStatus int32
const (
CarpoolServiceBookingStatus_INITIATED CarpoolServiceBookingStatus = 0
CarpoolServiceBookingStatus_WAITING_CONFIRMATION CarpoolServiceBookingStatus = 1
CarpoolServiceBookingStatus_CONFIRMED CarpoolServiceBookingStatus = 2
CarpoolServiceBookingStatus_CANCELLED CarpoolServiceBookingStatus = 3
CarpoolServiceBookingStatus_COMPLETED_PENDING_VALIDATION CarpoolServiceBookingStatus = 4
CarpoolServiceBookingStatus_VALIDATED CarpoolServiceBookingStatus = 5
CarpoolServiceBookingStatus_WAITING_DRIVER_CONFIRMATION CarpoolServiceBookingStatus = 1
CarpoolServiceBookingStatus_WAITING_PASSENGER_CONFIRMATION CarpoolServiceBookingStatus = 2
CarpoolServiceBookingStatus_CONFIRMED CarpoolServiceBookingStatus = 3
CarpoolServiceBookingStatus_CANCELLED CarpoolServiceBookingStatus = 4
CarpoolServiceBookingStatus_COMPLETED_PENDING_VALIDATION CarpoolServiceBookingStatus = 5
CarpoolServiceBookingStatus_VALIDATED CarpoolServiceBookingStatus = 6
)
// Enum value maps for CarpoolServiceBookingStatus.
var (
CarpoolServiceBookingStatus_name = map[int32]string{
0: "INITIATED",
1: "WAITING_CONFIRMATION",
2: "CONFIRMED",
3: "CANCELLED",
4: "COMPLETED_PENDING_VALIDATION",
5: "VALIDATED",
1: "WAITING_DRIVER_CONFIRMATION",
2: "WAITING_PASSENGER_CONFIRMATION",
3: "CONFIRMED",
4: "CANCELLED",
5: "COMPLETED_PENDING_VALIDATION",
6: "VALIDATED",
}
CarpoolServiceBookingStatus_value = map[string]int32{
"INITIATED": 0,
"WAITING_CONFIRMATION": 1,
"CONFIRMED": 2,
"CANCELLED": 3,
"COMPLETED_PENDING_VALIDATION": 4,
"VALIDATED": 5,
"WAITING_DRIVER_CONFIRMATION": 1,
"WAITING_PASSENGER_CONFIRMATION": 2,
"CONFIRMED": 3,
"CANCELLED": 4,
"COMPLETED_PENDING_VALIDATION": 5,
"VALIDATED": 6,
}
)
@ -1290,6 +1293,9 @@ type CarpoolServiceBooking struct {
Car *CarpoolServiceCar `protobuf:"bytes,16,opt,name=car,proto3,oneof" json:"car,omitempty"`
DriverJourneyId string `protobuf:"bytes,17,opt,name=driver_journey_id,json=driverJourneyId,proto3" json:"driver_journey_id,omitempty"`
PassengerJourneyId string `protobuf:"bytes,18,opt,name=passenger_journey_id,json=passengerJourneyId,proto3" json:"passenger_journey_id,omitempty"`
DriverRoute *CarpoolFeatureCollection `protobuf:"bytes,30,opt,name=driver_route,json=driverRoute,proto3,oneof" json:"driver_route,omitempty"`
PassengerRoute *CarpoolFeatureCollection `protobuf:"bytes,31,opt,name=passenger_route,json=passengerRoute,proto3,oneof" json:"passenger_route,omitempty"`
DriverDepartureDate *timestamppb.Timestamp `protobuf:"bytes,32,opt,name=driverDepartureDate,proto3,oneof" json:"driverDepartureDate,omitempty"`
}
func (x *CarpoolServiceBooking) Reset() {
@ -1450,6 +1456,27 @@ func (x *CarpoolServiceBooking) GetPassengerJourneyId() string {
return ""
}
func (x *CarpoolServiceBooking) GetDriverRoute() *CarpoolFeatureCollection {
if x != nil {
return x.DriverRoute
}
return nil
}
func (x *CarpoolServiceBooking) GetPassengerRoute() *CarpoolFeatureCollection {
if x != nil {
return x.PassengerRoute
}
return nil
}
func (x *CarpoolServiceBooking) GetDriverDepartureDate() *timestamppb.Timestamp {
if x != nil {
return x.DriverDepartureDate
}
return nil
}
type CarpoolServicePreferences struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
@ -2378,7 +2405,7 @@ var file_carpool_service_types_proto_rawDesc = []byte{
0x42, 0x13, 0x0a, 0x11, 0x5f, 0x6a, 0x6f, 0x75, 0x72, 0x6e, 0x65, 0x79, 0x5f, 0x70, 0x6f, 0x6c,
0x79, 0x6c, 0x69, 0x6e, 0x65, 0x42, 0x0a, 0x0a, 0x08, 0x5f, 0x77, 0x65, 0x62, 0x5f, 0x75, 0x72,
0x6c, 0x42, 0x0e, 0x0a, 0x0c, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65,
0x73, 0x22, 0xc2, 0x07, 0x0a, 0x15, 0x43, 0x61, 0x72, 0x70, 0x6f, 0x6f, 0x6c, 0x53, 0x65, 0x72,
0x73, 0x22, 0xde, 0x09, 0x0a, 0x15, 0x43, 0x61, 0x72, 0x70, 0x6f, 0x6f, 0x6c, 0x53, 0x65, 0x72,
0x76, 0x69, 0x63, 0x65, 0x42, 0x6f, 0x6f, 0x6b, 0x69, 0x6e, 0x67, 0x12, 0x0e, 0x0a, 0x02, 0x69,
0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x2b, 0x0a, 0x06, 0x64,
0x72, 0x69, 0x76, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x43, 0x61,
@ -2432,126 +2459,146 @@ var file_carpool_service_types_proto_rawDesc = []byte{
0x0a, 0x14, 0x70, 0x61, 0x73, 0x73, 0x65, 0x6e, 0x67, 0x65, 0x72, 0x5f, 0x6a, 0x6f, 0x75, 0x72,
0x6e, 0x65, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x12, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x70, 0x61,
0x73, 0x73, 0x65, 0x6e, 0x67, 0x65, 0x72, 0x4a, 0x6f, 0x75, 0x72, 0x6e, 0x65, 0x79, 0x49, 0x64,
0x42, 0x1b, 0x0a, 0x19, 0x5f, 0x70, 0x61, 0x73, 0x73, 0x65, 0x6e, 0x67, 0x65, 0x72, 0x5f, 0x70,
0x69, 0x63, 0x6b, 0x75, 0x70, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x42, 0x19, 0x0a,
0x17, 0x5f, 0x70, 0x61, 0x73, 0x73, 0x65, 0x6e, 0x67, 0x65, 0x72, 0x5f, 0x64, 0x72, 0x6f, 0x70,
0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x64, 0x69, 0x73,
0x74, 0x61, 0x6e, 0x63, 0x65, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69,
0x6f, 0x6e, 0x42, 0x0a, 0x0a, 0x08, 0x5f, 0x77, 0x65, 0x62, 0x5f, 0x75, 0x72, 0x6c, 0x42, 0x06,
0x0a, 0x04, 0x5f, 0x63, 0x61, 0x72, 0x22, 0xff, 0x01, 0x0a, 0x19, 0x43, 0x61, 0x72, 0x70, 0x6f,
0x6f, 0x6c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 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, 0xf9, 0x02, 0x0a, 0x12, 0x43, 0x61, 0x72,
0x70, 0x6f, 0x6f, 0x6c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, 0x73, 0x65, 0x72, 0x12,
0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12,
0x1a, 0x0a, 0x08, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28,
0x09, 0x52, 0x08, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x61,
0x6c, 0x69, 0x61, 0x73, 0x18, 0x03, 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,
0x04, 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, 0x05, 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, 0x06, 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, 0x07, 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, 0x08, 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, 0x09, 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, 0x22, 0x5d, 0x0a, 0x11, 0x43, 0x61, 0x72, 0x70, 0x6f, 0x6f, 0x6c, 0x53,
0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 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, 0xa7, 0x01, 0x0a, 0x13, 0x43, 0x61, 0x72, 0x70, 0x6f, 0x6f, 0x6c, 0x53,
0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, 0x72, 0x69, 0x63, 0x65, 0x12, 0x31, 0x0a, 0x04, 0x74,
0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x43, 0x61, 0x72, 0x70,
0x6f, 0x6f, 0x6c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 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, 0xd7, 0x01,
0x0a, 0x16, 0x43, 0x61, 0x72, 0x70, 0x6f, 0x6f, 0x6c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x12, 0x30, 0x0a, 0x14, 0x70, 0x61, 0x73, 0x73,
0x65, 0x6e, 0x67, 0x65, 0x72, 0x5f, 0x70, 0x69, 0x63, 0x6b, 0x75, 0x70, 0x5f, 0x64, 0x61, 0x79,
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x70, 0x61, 0x73, 0x73, 0x65, 0x6e, 0x67, 0x65,
0x72, 0x50, 0x69, 0x63, 0x6b, 0x75, 0x70, 0x44, 0x61, 0x79, 0x12, 0x3e, 0x0a, 0x1c, 0x70, 0x61,
0x73, 0x73, 0x65, 0x6e, 0x67, 0x65, 0x72, 0x5f, 0x70, 0x69, 0x63, 0x6b, 0x75, 0x70, 0x5f, 0x74,
0x69, 0x6d, 0x65, 0x5f, 0x6f, 0x66, 0x5f, 0x64, 0x61, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
0x52, 0x18, 0x70, 0x61, 0x73, 0x73, 0x65, 0x6e, 0x67, 0x65, 0x72, 0x50, 0x69, 0x63, 0x6b, 0x75,
0x70, 0x54, 0x69, 0x6d, 0x65, 0x4f, 0x66, 0x44, 0x61, 0x79, 0x12, 0x4b, 0x0a, 0x11, 0x6a, 0x6f,
0x75, 0x72, 0x6e, 0x65, 0x79, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x18,
0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x43, 0x61, 0x72, 0x70, 0x6f, 0x6f, 0x6c, 0x53,
0x12, 0x41, 0x0a, 0x0c, 0x64, 0x72, 0x69, 0x76, 0x65, 0x72, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65,
0x18, 0x1e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x43, 0x61, 0x72, 0x70, 0x6f, 0x6f, 0x6c,
0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f,
0x6e, 0x48, 0x06, 0x52, 0x0b, 0x64, 0x72, 0x69, 0x76, 0x65, 0x72, 0x52, 0x6f, 0x75, 0x74, 0x65,
0x88, 0x01, 0x01, 0x12, 0x47, 0x0a, 0x0f, 0x70, 0x61, 0x73, 0x73, 0x65, 0x6e, 0x67, 0x65, 0x72,
0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x18, 0x1f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x43,
0x61, 0x72, 0x70, 0x6f, 0x6f, 0x6c, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x43, 0x6f, 0x6c,
0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x07, 0x52, 0x0e, 0x70, 0x61, 0x73, 0x73, 0x65,
0x6e, 0x67, 0x65, 0x72, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x88, 0x01, 0x01, 0x12, 0x51, 0x0a, 0x13,
0x64, 0x72, 0x69, 0x76, 0x65, 0x72, 0x44, 0x65, 0x70, 0x61, 0x72, 0x74, 0x75, 0x72, 0x65, 0x44,
0x61, 0x74, 0x65, 0x18, 0x20, 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, 0x48, 0x08, 0x52, 0x13, 0x64, 0x72, 0x69, 0x76, 0x65, 0x72, 0x44,
0x65, 0x70, 0x61, 0x72, 0x74, 0x75, 0x72, 0x65, 0x44, 0x61, 0x74, 0x65, 0x88, 0x01, 0x01, 0x42,
0x1b, 0x0a, 0x19, 0x5f, 0x70, 0x61, 0x73, 0x73, 0x65, 0x6e, 0x67, 0x65, 0x72, 0x5f, 0x70, 0x69,
0x63, 0x6b, 0x75, 0x70, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x42, 0x19, 0x0a, 0x17,
0x5f, 0x70, 0x61, 0x73, 0x73, 0x65, 0x6e, 0x67, 0x65, 0x72, 0x5f, 0x64, 0x72, 0x6f, 0x70, 0x5f,
0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x64, 0x69, 0x73, 0x74,
0x61, 0x6e, 0x63, 0x65, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f,
0x6e, 0x42, 0x0a, 0x0a, 0x08, 0x5f, 0x77, 0x65, 0x62, 0x5f, 0x75, 0x72, 0x6c, 0x42, 0x06, 0x0a,
0x04, 0x5f, 0x63, 0x61, 0x72, 0x42, 0x0f, 0x0a, 0x0d, 0x5f, 0x64, 0x72, 0x69, 0x76, 0x65, 0x72,
0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x42, 0x12, 0x0a, 0x10, 0x5f, 0x70, 0x61, 0x73, 0x73, 0x65,
0x6e, 0x67, 0x65, 0x72, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x42, 0x16, 0x0a, 0x14, 0x5f, 0x64,
0x72, 0x69, 0x76, 0x65, 0x72, 0x44, 0x65, 0x70, 0x61, 0x72, 0x74, 0x75, 0x72, 0x65, 0x44, 0x61,
0x74, 0x65, 0x22, 0xff, 0x01, 0x0a, 0x19, 0x43, 0x61, 0x72, 0x70, 0x6f, 0x6f, 0x6c, 0x53, 0x65,
0x72, 0x76, 0x69, 0x63, 0x65, 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, 0xf9, 0x02, 0x0a, 0x12, 0x43, 0x61, 0x72, 0x70, 0x6f, 0x6f, 0x6c,
0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, 0x73, 0x65, 0x72, 0x12, 0x0e, 0x0a, 0x02, 0x69,
0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x6f,
0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6f,
0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x6c, 0x69, 0x61, 0x73,
0x18, 0x03, 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, 0x04, 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, 0x05,
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, 0x06, 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, 0x07, 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, 0x08, 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,
0x09, 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,
0x22, 0x5d, 0x0a, 0x11, 0x43, 0x61, 0x72, 0x70, 0x6f, 0x6f, 0x6c, 0x53, 0x65, 0x72, 0x76, 0x69,
0x63, 0x65, 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,
0xa7, 0x01, 0x0a, 0x13, 0x43, 0x61, 0x72, 0x70, 0x6f, 0x6f, 0x6c, 0x53, 0x65, 0x72, 0x76, 0x69,
0x63, 0x65, 0x50, 0x72, 0x69, 0x63, 0x65, 0x12, 0x31, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18,
0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x43, 0x61, 0x72, 0x70, 0x6f, 0x6f, 0x6c, 0x53,
0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 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, 0xd7, 0x01, 0x0a, 0x16, 0x43, 0x61,
0x72, 0x70, 0x6f, 0x6f, 0x6c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x53, 0x63, 0x68, 0x65,
0x64, 0x75, 0x6c, 0x65, 0x12, 0x30, 0x0a, 0x14, 0x70, 0x61, 0x73, 0x73, 0x65, 0x6e, 0x67, 0x65,
0x72, 0x5f, 0x70, 0x69, 0x63, 0x6b, 0x75, 0x70, 0x5f, 0x64, 0x61, 0x79, 0x18, 0x01, 0x20, 0x01,
0x28, 0x09, 0x52, 0x12, 0x70, 0x61, 0x73, 0x73, 0x65, 0x6e, 0x67, 0x65, 0x72, 0x50, 0x69, 0x63,
0x6b, 0x75, 0x70, 0x44, 0x61, 0x79, 0x12, 0x3e, 0x0a, 0x1c, 0x70, 0x61, 0x73, 0x73, 0x65, 0x6e,
0x67, 0x65, 0x72, 0x5f, 0x70, 0x69, 0x63, 0x6b, 0x75, 0x70, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f,
0x6f, 0x66, 0x5f, 0x64, 0x61, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x18, 0x70, 0x61,
0x73, 0x73, 0x65, 0x6e, 0x67, 0x65, 0x72, 0x50, 0x69, 0x63, 0x6b, 0x75, 0x70, 0x54, 0x69, 0x6d,
0x65, 0x4f, 0x66, 0x44, 0x61, 0x79, 0x12, 0x4b, 0x0a, 0x11, 0x6a, 0x6f, 0x75, 0x72, 0x6e, 0x65,
0x79, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28,
0x0b, 0x32, 0x1e, 0x2e, 0x43, 0x61, 0x72, 0x70, 0x6f, 0x6f, 0x6c, 0x53, 0x65, 0x72, 0x76, 0x69,
0x63, 0x65, 0x4a, 0x6f, 0x75, 0x72, 0x6e, 0x65, 0x79, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c,
0x65, 0x52, 0x10, 0x6a, 0x6f, 0x75, 0x72, 0x6e, 0x65, 0x79, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75,
0x6c, 0x65, 0x73, 0x22, 0xc8, 0x02, 0x0a, 0x1d, 0x43, 0x61, 0x72, 0x70, 0x6f, 0x6f, 0x6c, 0x53,
0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4a, 0x6f, 0x75, 0x72, 0x6e, 0x65, 0x79, 0x53, 0x63, 0x68,
0x65, 0x64, 0x75, 0x6c, 0x65, 0x52, 0x10, 0x6a, 0x6f, 0x75, 0x72, 0x6e, 0x65, 0x79, 0x53, 0x63,
0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x22, 0xc8, 0x02, 0x0a, 0x1d, 0x43, 0x61, 0x72, 0x70,
0x6f, 0x6f, 0x6c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4a, 0x6f, 0x75, 0x72, 0x6e, 0x65,
0x79, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18,
0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 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, 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, 0x13, 0x70, 0x61, 0x73, 0x73, 0x65, 0x6e, 0x67, 0x65, 0x72, 0x50,
0x69, 0x63, 0x6b, 0x75, 0x70, 0x44, 0x61, 0x74, 0x65, 0x12, 0x53, 0x0a, 0x15, 0x64, 0x72, 0x69,
0x65, 0x64, 0x75, 0x6c, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28,
0x09, 0x52, 0x02, 0x69, 0x64, 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, 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, 0x13, 0x70, 0x61, 0x73, 0x73, 0x65, 0x6e, 0x67, 0x65, 0x72, 0x50, 0x69, 0x63, 0x6b, 0x75,
0x70, 0x44, 0x61, 0x74, 0x65, 0x12, 0x53, 0x0a, 0x15, 0x64, 0x72, 0x69, 0x76, 0x65, 0x72, 0x5f,
0x64, 0x65, 0x70, 0x61, 0x72, 0x74, 0x75, 0x72, 0x65, 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,
0x48, 0x00, 0x52, 0x13, 0x64, 0x72, 0x69, 0x76, 0x65, 0x72, 0x44, 0x65, 0x70, 0x61, 0x72, 0x74,
0x75, 0x72, 0x65, 0x44, 0x61, 0x74, 0x65, 0x88, 0x01, 0x01, 0x12, 0x1c, 0x0a, 0x07, 0x77, 0x65,
0x62, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x48, 0x01, 0x52, 0x06, 0x77,
0x65, 0x62, 0x55, 0x72, 0x6c, 0x88, 0x01, 0x01, 0x12, 0x2e, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65,
0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x43, 0x61, 0x72, 0x70, 0x6f, 0x6f, 0x6c,
0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4a, 0x6f, 0x75, 0x72, 0x6e, 0x65, 0x79, 0x54, 0x79,
0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x42, 0x18, 0x0a, 0x16, 0x5f, 0x64, 0x72, 0x69,
0x76, 0x65, 0x72, 0x5f, 0x64, 0x65, 0x70, 0x61, 0x72, 0x74, 0x75, 0x72, 0x65, 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, 0x48, 0x00, 0x52, 0x13, 0x64, 0x72, 0x69, 0x76, 0x65, 0x72, 0x44, 0x65,
0x70, 0x61, 0x72, 0x74, 0x75, 0x72, 0x65, 0x44, 0x61, 0x74, 0x65, 0x88, 0x01, 0x01, 0x12, 0x1c,
0x0a, 0x07, 0x77, 0x65, 0x62, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x48,
0x01, 0x52, 0x06, 0x77, 0x65, 0x62, 0x55, 0x72, 0x6c, 0x88, 0x01, 0x01, 0x12, 0x2e, 0x0a, 0x04,
0x74, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x43, 0x61, 0x72,
0x70, 0x6f, 0x6f, 0x6c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4a, 0x6f, 0x75, 0x72, 0x6e,
0x65, 0x79, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x42, 0x18, 0x0a, 0x16,
0x5f, 0x64, 0x72, 0x69, 0x76, 0x65, 0x72, 0x5f, 0x64, 0x65, 0x70, 0x61, 0x72, 0x74, 0x75, 0x72,
0x65, 0x5f, 0x64, 0x61, 0x74, 0x65, 0x42, 0x0a, 0x0a, 0x08, 0x5f, 0x77, 0x65, 0x62, 0x5f, 0x75,
0x72, 0x6c, 0x2a, 0x3f, 0x0a, 0x19, 0x43, 0x61, 0x72, 0x70, 0x6f, 0x6f, 0x6c, 0x53, 0x65, 0x72,
0x76, 0x69, 0x63, 0x65, 0x4a, 0x6f, 0x75, 0x72, 0x6e, 0x65, 0x79, 0x54, 0x79, 0x70, 0x65, 0x12,
0x0b, 0x0a, 0x07, 0x50, 0x4c, 0x41, 0x4e, 0x4e, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07,
0x44, 0x59, 0x4e, 0x41, 0x4d, 0x49, 0x43, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x4c, 0x49, 0x4e,
0x45, 0x10, 0x02, 0x2a, 0x3c, 0x0a, 0x17, 0x43, 0x61, 0x72, 0x70, 0x6f, 0x6f, 0x6c, 0x53, 0x65,
0x72, 0x76, 0x69, 0x63, 0x65, 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, 0x95, 0x01, 0x0a, 0x1b, 0x43, 0x61, 0x72, 0x70, 0x6f, 0x6f, 0x6c, 0x53, 0x65, 0x72,
0x76, 0x69, 0x63, 0x65, 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, 0x18, 0x0a, 0x14, 0x57, 0x41, 0x49, 0x54, 0x49, 0x4e, 0x47, 0x5f, 0x43, 0x4f, 0x4e, 0x46,
0x49, 0x52, 0x4d, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x01, 0x12, 0x0d, 0x0a, 0x09, 0x43, 0x4f,
0x4e, 0x46, 0x49, 0x52, 0x4d, 0x45, 0x44, 0x10, 0x02, 0x12, 0x0d, 0x0a, 0x09, 0x43, 0x41, 0x4e,
0x43, 0x45, 0x4c, 0x4c, 0x45, 0x44, 0x10, 0x03, 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, 0x04, 0x12, 0x0d, 0x0a, 0x09, 0x56, 0x41,
0x4c, 0x49, 0x44, 0x41, 0x54, 0x45, 0x44, 0x10, 0x05, 0x42, 0x42, 0x5a, 0x40, 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, 0x63, 0x61, 0x72, 0x70, 0x6f,
0x6f, 0x6c, 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,
0x74, 0x65, 0x42, 0x0a, 0x0a, 0x08, 0x5f, 0x77, 0x65, 0x62, 0x5f, 0x75, 0x72, 0x6c, 0x2a, 0x3f,
0x0a, 0x19, 0x43, 0x61, 0x72, 0x70, 0x6f, 0x6f, 0x6c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
0x4a, 0x6f, 0x75, 0x72, 0x6e, 0x65, 0x79, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x50,
0x4c, 0x41, 0x4e, 0x4e, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x44, 0x59, 0x4e, 0x41,
0x4d, 0x49, 0x43, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x4c, 0x49, 0x4e, 0x45, 0x10, 0x02, 0x2a,
0x3c, 0x0a, 0x17, 0x43, 0x61, 0x72, 0x70, 0x6f, 0x6f, 0x6c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63,
0x65, 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, 0xc0, 0x01,
0x0a, 0x1b, 0x43, 0x61, 0x72, 0x70, 0x6f, 0x6f, 0x6c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
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,
0x42, 0x42, 0x5a, 0x40, 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, 0x63, 0x61, 0x72, 0x70, 0x6f, 0x6f, 0x6c, 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 (
@ -2614,16 +2661,19 @@ var file_carpool_service_types_proto_depIdxs = []int32{
2, // 23: CarpoolServiceBooking.status:type_name -> CarpoolServiceBookingStatus
13, // 24: CarpoolServiceBooking.price:type_name -> CarpoolServicePrice
12, // 25: CarpoolServiceBooking.car:type_name -> CarpoolServiceCar
1, // 26: CarpoolServicePrice.type:type_name -> CarpoolServicePriceType
15, // 27: CarpoolServiceSchedule.journey_schedules:type_name -> CarpoolServiceJourneySchedule
16, // 28: CarpoolServiceJourneySchedule.passenger_pickup_date:type_name -> google.protobuf.Timestamp
16, // 29: CarpoolServiceJourneySchedule.driver_departure_date:type_name -> google.protobuf.Timestamp
0, // 30: CarpoolServiceJourneySchedule.type:type_name -> CarpoolServiceJourneyType
31, // [31:31] is the sub-list for method output_type
31, // [31:31] is the sub-list for method input_type
31, // [31:31] is the sub-list for extension type_name
31, // [31:31] is the sub-list for extension extendee
0, // [0:31] is the sub-list for field type_name
4, // 26: CarpoolServiceBooking.driver_route:type_name -> CarpoolFeatureCollection
4, // 27: CarpoolServiceBooking.passenger_route:type_name -> CarpoolFeatureCollection
16, // 28: CarpoolServiceBooking.driverDepartureDate:type_name -> google.protobuf.Timestamp
1, // 29: CarpoolServicePrice.type:type_name -> CarpoolServicePriceType
15, // 30: CarpoolServiceSchedule.journey_schedules:type_name -> CarpoolServiceJourneySchedule
16, // 31: CarpoolServiceJourneySchedule.passenger_pickup_date:type_name -> google.protobuf.Timestamp
16, // 32: CarpoolServiceJourneySchedule.driver_departure_date:type_name -> google.protobuf.Timestamp
0, // 33: CarpoolServiceJourneySchedule.type:type_name -> CarpoolServiceJourneyType
34, // [34:34] is the sub-list for method output_type
34, // [34:34] is the sub-list for method input_type
34, // [34:34] is the sub-list for extension type_name
34, // [34:34] is the sub-list for extension extendee
0, // [0:34] is the sub-list for field type_name
}
func init() { file_carpool_service_types_proto_init() }

View File

@ -150,6 +150,10 @@ message CarpoolServiceBooking {
optional CarpoolServiceCar car = 16;
string driver_journey_id = 17;
string passenger_journey_id = 18;
optional CarpoolFeatureCollection driver_route = 30;
optional CarpoolFeatureCollection passenger_route = 31;
optional google.protobuf.Timestamp driverDepartureDate = 32;
}
message CarpoolServicePreferences {
@ -211,9 +215,10 @@ enum CarpoolServicePriceType {
enum CarpoolServiceBookingStatus {
INITIATED = 0;
WAITING_CONFIRMATION = 1;
CONFIRMED = 2;
CANCELLED = 3;
COMPLETED_PENDING_VALIDATION = 4;
VALIDATED = 5;
WAITING_DRIVER_CONFIRMATION = 1;
WAITING_PASSENGER_CONFIRMATION = 2;
CONFIRMED = 3;
CANCELLED = 4;
COMPLETED_PENDING_VALIDATION = 5;
VALIDATED = 6;
}

File diff suppressed because it is too large Load Diff

View File

@ -10,11 +10,11 @@ service CarpoolService {
// rpc XXXX(Request) returns (Response) {}
rpc CreateRegularRoutes(CreateRegularRoutesRequest) returns (CreateRegularRoutesResponse) {}
rpc DeleteRegularRoutes(DeleteRegularRoutesRequest) returns (DeleteRegularRoutesResponse) {}
rpc GetUserPlanning(GetUserPlanningRequest) returns (GetUserPlanningResponse) {}
rpc GetPlannedTrip(GetPlannedTripRequest) returns (GetPlannedTripResponse) {}
rpc GetUserBookings(GetUserBookingsRequest) returns (GetUserBookingsResponse) {}
// OCSS-like interaction
// OCSS interactions
rpc DriverJourneys(DriverJourneysRequest) returns (DriverJourneysResponse) {}
rpc PassengerJourneys(PassengerJourneysRequest) returns (PassengerJourneysResponse) {}
rpc DriverRegularTrips(DriverRegularTripsRequest) returns (DriverRegularTripsResponse) {}
@ -55,6 +55,16 @@ message GetPlannedTripResponse {
CarpoolFeatureCollection planned_trip = 1;
}
message GetUserBookingsRequest {
string user_id = 1;
optional google.protobuf.Timestamp min_date = 2;
optional google.protobuf.Timestamp max_date = 3;
}
message GetUserBookingsResponse {
repeated CarpoolServiceBooking bookings = 1;
}
// OCSS-like interaction messages

View File

@ -28,7 +28,8 @@ type CarpoolServiceClient interface {
DeleteRegularRoutes(ctx context.Context, in *DeleteRegularRoutesRequest, opts ...grpc.CallOption) (*DeleteRegularRoutesResponse, error)
GetUserPlanning(ctx context.Context, in *GetUserPlanningRequest, opts ...grpc.CallOption) (*GetUserPlanningResponse, error)
GetPlannedTrip(ctx context.Context, in *GetPlannedTripRequest, opts ...grpc.CallOption) (*GetPlannedTripResponse, error)
// OCSS-like interaction
GetUserBookings(ctx context.Context, in *GetUserBookingsRequest, opts ...grpc.CallOption) (*GetUserBookingsResponse, error)
// OCSS interactions
DriverJourneys(ctx context.Context, in *DriverJourneysRequest, opts ...grpc.CallOption) (*DriverJourneysResponse, error)
PassengerJourneys(ctx context.Context, in *PassengerJourneysRequest, opts ...grpc.CallOption) (*PassengerJourneysResponse, error)
DriverRegularTrips(ctx context.Context, in *DriverRegularTripsRequest, opts ...grpc.CallOption) (*DriverRegularTripsResponse, error)
@ -82,6 +83,15 @@ func (c *carpoolServiceClient) GetPlannedTrip(ctx context.Context, in *GetPlanne
return out, nil
}
func (c *carpoolServiceClient) GetUserBookings(ctx context.Context, in *GetUserBookingsRequest, opts ...grpc.CallOption) (*GetUserBookingsResponse, error) {
out := new(GetUserBookingsResponse)
err := c.cc.Invoke(ctx, "/CarpoolService/GetUserBookings", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *carpoolServiceClient) DriverJourneys(ctx context.Context, in *DriverJourneysRequest, opts ...grpc.CallOption) (*DriverJourneysResponse, error) {
out := new(DriverJourneysResponse)
err := c.cc.Invoke(ctx, "/CarpoolService/DriverJourneys", in, out, opts...)
@ -155,7 +165,8 @@ type CarpoolServiceServer interface {
DeleteRegularRoutes(context.Context, *DeleteRegularRoutesRequest) (*DeleteRegularRoutesResponse, error)
GetUserPlanning(context.Context, *GetUserPlanningRequest) (*GetUserPlanningResponse, error)
GetPlannedTrip(context.Context, *GetPlannedTripRequest) (*GetPlannedTripResponse, error)
// OCSS-like interaction
GetUserBookings(context.Context, *GetUserBookingsRequest) (*GetUserBookingsResponse, error)
// OCSS interactions
DriverJourneys(context.Context, *DriverJourneysRequest) (*DriverJourneysResponse, error)
PassengerJourneys(context.Context, *PassengerJourneysRequest) (*PassengerJourneysResponse, error)
DriverRegularTrips(context.Context, *DriverRegularTripsRequest) (*DriverRegularTripsResponse, error)
@ -182,6 +193,9 @@ func (UnimplementedCarpoolServiceServer) GetUserPlanning(context.Context, *GetUs
func (UnimplementedCarpoolServiceServer) GetPlannedTrip(context.Context, *GetPlannedTripRequest) (*GetPlannedTripResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetPlannedTrip not implemented")
}
func (UnimplementedCarpoolServiceServer) GetUserBookings(context.Context, *GetUserBookingsRequest) (*GetUserBookingsResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetUserBookings not implemented")
}
func (UnimplementedCarpoolServiceServer) DriverJourneys(context.Context, *DriverJourneysRequest) (*DriverJourneysResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method DriverJourneys not implemented")
}
@ -288,6 +302,24 @@ func _CarpoolService_GetPlannedTrip_Handler(srv interface{}, ctx context.Context
return interceptor(ctx, in, info, handler)
}
func _CarpoolService_GetUserBookings_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(GetUserBookingsRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(CarpoolServiceServer).GetUserBookings(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/CarpoolService/GetUserBookings",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(CarpoolServiceServer).GetUserBookings(ctx, req.(*GetUserBookingsRequest))
}
return interceptor(ctx, in, info, handler)
}
func _CarpoolService_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 {
@ -437,6 +469,10 @@ var CarpoolService_ServiceDesc = grpc.ServiceDesc{
MethodName: "GetPlannedTrip",
Handler: _CarpoolService_GetPlannedTrip_Handler,
},
{
MethodName: "GetUserBookings",
Handler: _CarpoolService_GetUserBookings_Handler,
},
{
MethodName: "DriverJourneys",
Handler: _CarpoolService_DriverJourneys_Handler,

View File

@ -3,11 +3,12 @@ package proto
import (
"time"
"git.coopgo.io/coopgo-platform/carpool-service/internal"
"git.coopgo.io/coopgo-platform/carpool-service/interoperability/ocss"
"google.golang.org/protobuf/types/known/timestamppb"
)
func (j *CarpoolServiceDriverJourney) ToOCSS() ocss.DriverJourney {
var departureToPickupWalkingDuration *time.Duration
if j.DepartureToPickupWalkingDuration != nil {
dtpw := time.Duration(*j.DepartureToPickupWalkingDuration)
@ -39,9 +40,9 @@ func (j *CarpoolServiceDriverJourney) ToOCSS() ocss.DriverJourney {
}
}
var driverDepartureDate *ocss.JSONTime
var driverDepartureDate *ocss.OCSSTime
if j.DriverDepartureDate != nil {
ddd := ocss.JSONTime(j.DriverDepartureDate.AsTime())
ddd := ocss.OCSSTime(j.DriverDepartureDate.AsTime())
driverDepartureDate = &ddd
}
@ -108,7 +109,8 @@ func (j *CarpoolServiceDriverJourney) ToOCSS() ocss.DriverJourney {
},
},
JourneySchedule: ocss.JourneySchedule{
PassengerPickupDate: ocss.JSONTime(j.PassengerPickupDate.AsTime()),
ID: &j.Id,
PassengerPickupDate: ocss.OCSSTime(j.PassengerPickupDate.AsTime()),
DriverDepartureDate: driverDepartureDate,
WebUrl: j.WebUrl,
Type: j.Type.ToOCSS(),
@ -131,9 +133,9 @@ func (j *CarpoolServicePassengerJourney) ToOCSS() ocss.PassengerJourney {
}
}
var driverDepartureDate *ocss.JSONTime
var driverDepartureDate *ocss.OCSSTime
if j.DriverDepartureDate != nil {
ddd := ocss.JSONTime(j.DriverDepartureDate.AsTime())
ddd := ocss.OCSSTime(j.DriverDepartureDate.AsTime())
driverDepartureDate = &ddd
}
@ -171,7 +173,8 @@ func (j *CarpoolServicePassengerJourney) ToOCSS() ocss.PassengerJourney {
},
},
JourneySchedule: ocss.JourneySchedule{
PassengerPickupDate: ocss.JSONTime(j.PassengerPickupDate.AsTime()),
ID: &j.Id,
PassengerPickupDate: ocss.OCSSTime(j.PassengerPickupDate.AsTime()),
DriverDepartureDate: driverDepartureDate,
WebUrl: j.WebUrl,
Type: j.Type.ToOCSS(),
@ -180,6 +183,218 @@ func (j *CarpoolServicePassengerJourney) ToOCSS() ocss.PassengerJourney {
}
}
func (b *CarpoolServiceBooking) ToOCSS() ocss.Booking {
var duration *time.Duration
if b.Duration != nil {
d := time.Duration(*b.Duration) * time.Second
duration = &d
}
pt := ocss.Free
am := 0.0
cu := "EUR"
price := ocss.Price{
Type: &pt,
Amount: &am,
Currency: &cu,
}
if b.Price != nil {
pricetype := ocss.Unknown
if *b.Price.Type == CarpoolServicePriceType_FREE {
pricetype = ocss.Free
} else if *b.Price.Type == CarpoolServicePriceType_PAYING {
pricetype = ocss.Paying
}
price = ocss.Price{
Type: &pricetype,
Amount: b.Price.Amount,
Currency: b.Price.Currency,
}
}
status := ocss.BookingInitiated
if b.Status == CarpoolServiceBookingStatus_WAITING_DRIVER_CONFIRMATION {
status = ocss.BookingWaitingDriverConfirmation
} else if b.Status == CarpoolServiceBookingStatus_WAITING_PASSENGER_CONFIRMATION {
status = ocss.BookingWaitingPassengerConfirmation
} else if b.Status == CarpoolServiceBookingStatus_CONFIRMED {
status = ocss.BookingConfirmed
} else if b.Status == CarpoolServiceBookingStatus_COMPLETED_PENDING_VALIDATION {
status = ocss.BookingCompletedPendingValidation
} else if b.Status == CarpoolServiceBookingStatus_VALIDATED {
status = ocss.BookingValidated
} else if b.Status == CarpoolServiceBookingStatus_CANCELLED {
status = ocss.BookingCancelled
}
return ocss.Booking{
ID: b.Id,
Driver: ocss.User{
ID: b.Driver.Id,
Operator: b.Driver.Operator,
Alias: b.Driver.Alias,
FirstName: b.Driver.FirstName,
LastName: b.Driver.LastName,
Grade: b.Driver.Grade,
Picture: b.Driver.Picture,
Gender: GenderToOCSS(b.Driver.Gender),
VerifiedIdentity: b.Driver.VerifiedIdentity,
},
Passenger: ocss.User{
ID: b.Passenger.Id,
Operator: b.Passenger.Operator,
Alias: b.Passenger.Alias,
FirstName: b.Passenger.FirstName,
LastName: b.Passenger.LastName,
Grade: b.Passenger.Grade,
Picture: b.Passenger.Picture,
Gender: GenderToOCSS(b.Passenger.Gender),
VerifiedIdentity: b.Passenger.VerifiedIdentity,
},
PassengerPickupDate: ocss.OCSSTime(b.PassengerPickupDate.AsTime()),
PassengerPickupLat: b.PassengerPickupLat,
PassengerPickupLng: b.PassengerPickupLng,
PassengerDropLat: b.PassengerDropLat,
PassengerDropLng: b.PassengerDropLng,
PassengerPickupAddress: b.PassengerPickupAddress,
PassengerDropAddress: b.PassengerDropAddress,
Distance: b.Distance,
Duration: duration,
WebUrl: b.WebUrl,
Price: price,
Status: status,
DriverJourneyID: b.DriverJourneyId,
PassengerJourneyID: b.PassengerJourneyId,
}
}
func BookingFromOCSS(b ocss.Booking) *CarpoolServiceBooking {
passengerPickupDate := b.PassengerPickupDate.ToTime()
status := CarpoolServiceBookingStatus_INITIATED
if b.Status == ocss.BookingWaitingDriverConfirmation {
status = CarpoolServiceBookingStatus_WAITING_DRIVER_CONFIRMATION
} else if b.Status == ocss.BookingWaitingPassengerConfirmation {
status = CarpoolServiceBookingStatus_WAITING_PASSENGER_CONFIRMATION
} else if b.Status == ocss.BookingConfirmed {
status = CarpoolServiceBookingStatus_CONFIRMED
} else if b.Status == ocss.BookingCompletedPendingValidation {
status = CarpoolServiceBookingStatus_COMPLETED_PENDING_VALIDATION
} else if b.Status == ocss.BookingValidated {
status = CarpoolServiceBookingStatus_VALIDATED
} else if b.Status == ocss.BookingCancelled {
status = CarpoolServiceBookingStatus_CANCELLED
}
var duration *int64
if b.Duration != nil {
d := int64(b.Duration.Seconds())
duration = &d
}
var pricetype *CarpoolServicePriceType
if b.Price.Type != nil {
if *b.Price.Type == ocss.Free {
pt := CarpoolServicePriceType_FREE
pricetype = &pt
} else if *b.Price.Type == ocss.Paying {
pt := CarpoolServicePriceType_PAYING
pricetype = &pt
} else if *b.Price.Type == ocss.Unknown {
pt := CarpoolServicePriceType_UNKNOWN
pricetype = &pt
}
}
price := CarpoolServicePrice{
Amount: b.Price.Amount,
Currency: b.Price.Currency,
Type: pricetype,
}
return &CarpoolServiceBooking{
Id: b.ID,
Driver: &CarpoolServiceUser{
Id: b.Driver.ID,
Operator: b.Driver.Operator,
Alias: b.Driver.Alias,
FirstName: b.Driver.FirstName,
LastName: b.Driver.LastName,
Grade: b.Driver.Grade,
Picture: b.Driver.Picture,
Gender: b.Driver.Gender.ToString(),
VerifiedIdentity: b.Driver.VerifiedIdentity,
},
Passenger: &CarpoolServiceUser{
Id: b.Passenger.ID,
Operator: b.Passenger.Operator,
Alias: b.Passenger.Alias,
FirstName: b.Passenger.FirstName,
LastName: b.Passenger.LastName,
Grade: b.Passenger.Grade,
Picture: b.Passenger.Picture,
Gender: b.Passenger.Gender.ToString(),
VerifiedIdentity: b.Passenger.VerifiedIdentity,
},
PassengerPickupDate: timestamppb.New(*passengerPickupDate),
PassengerPickupLat: b.PassengerPickupLat,
PassengerPickupLng: b.PassengerPickupLng,
PassengerDropLat: b.PassengerDropLat,
PassengerDropLng: b.PassengerDropLng,
PassengerPickupAddress: b.PassengerPickupAddress,
PassengerDropAddress: b.PassengerDropAddress,
Status: status,
Distance: b.Distance,
Duration: duration,
WebUrl: b.WebUrl,
Price: &price,
DriverJourneyId: b.DriverJourneyID,
PassengerJourneyId: b.PassengerJourneyID,
}
}
func BookingFromInternal(b internal.Booking) *CarpoolServiceBooking {
booking := BookingFromOCSS(b.Booking)
if b.DriverRoute != nil {
serializedDriverRoute, err := b.DriverRoute.MarshalJSON()
if err == nil {
booking.DriverRoute = &CarpoolFeatureCollection{
Serialized: string(serializedDriverRoute),
}
}
}
if b.PassengerRoute != nil {
serializedPassengerRoute, err := b.PassengerRoute.MarshalJSON()
if err == nil {
booking.PassengerRoute = &CarpoolFeatureCollection{
Serialized: string(serializedPassengerRoute),
}
}
}
return booking
}
func (s CarpoolServiceBookingStatus) ToOCSS() ocss.BookingStatus {
if s == CarpoolServiceBookingStatus_INITIATED {
return ocss.BookingInitiated
} else if s == CarpoolServiceBookingStatus_WAITING_DRIVER_CONFIRMATION {
return ocss.BookingWaitingDriverConfirmation
} else if s == CarpoolServiceBookingStatus_WAITING_PASSENGER_CONFIRMATION {
return ocss.BookingWaitingPassengerConfirmation
} else if s == CarpoolServiceBookingStatus_CONFIRMED {
return ocss.BookingConfirmed
} else if s == CarpoolServiceBookingStatus_COMPLETED_PENDING_VALIDATION {
return ocss.BookingCompletedPendingValidation
} else if s == CarpoolServiceBookingStatus_VALIDATED {
return ocss.BookingValidated
} else if s == CarpoolServiceBookingStatus_CANCELLED {
return ocss.BookingCancelled
}
return ocss.BookingInitiated
}
func (t CarpoolServiceJourneyType) ToOCSS() ocss.JourneyScheduleType {
if t == CarpoolServiceJourneyType_DYNAMIC {
return ocss.Dynamic

View File

@ -0,0 +1,75 @@
package grpcserver
import (
"context"
"time"
"git.coopgo.io/coopgo-platform/carpool-service/servers/grpc/proto"
"github.com/rs/zerolog/log"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
)
func (s *CarpoolServiceServerImpl) CreateBooking(ctx context.Context, req *proto.CreateBookingRequest) (*proto.CreateBookingResponse, error) {
booking := req.Booking.ToOCSS()
_, err := s.Handler.Book(booking)
if err != nil {
return nil, status.Errorf(codes.Internal, "could not create booking - %s", err.Error())
}
return &proto.CreateBookingResponse{}, nil
}
func (s *CarpoolServiceServerImpl) GetUserBookings(ctx context.Context, req *proto.GetUserBookingsRequest) (*proto.GetUserBookingsResponse, error) {
log.Debug().
Str("user", req.UserId).
Str("mindate", req.MinDate.AsTime().Format(time.RFC3339)).
Any("maxdate", req.MaxDate).
Msg("grpc server - GetUserBookings")
userid := req.UserId
var mindate *time.Time
if req.MinDate != nil {
d := req.MinDate.AsTime()
mindate = &d
}
var maxdate *time.Time
if req.MaxDate != nil {
d := req.MaxDate.AsTime()
maxdate = &d
}
bookings, err := s.Handler.GetUserBookings(userid, mindate, maxdate)
if err != nil {
return nil, status.Errorf(codes.Internal, "error retrieving user bookings - %s", err.Error())
}
results := []*proto.CarpoolServiceBooking{}
for _, b := range bookings {
nb := proto.BookingFromInternal(b)
results = append(results, nb)
}
return &proto.GetUserBookingsResponse{
Bookings: results,
}, nil
}
func (s *CarpoolServiceServerImpl) UpdateBooking(ctx context.Context, req *proto.UpdateBookingRequest) (*proto.UpdateBookingResponse, error) {
err := s.Handler.UpdateBookingStatus(req.BookingId, req.Status.ToOCSS())
if err != nil {
return nil, status.Errorf(codes.Internal, "could not update booking status")
}
return &proto.UpdateBookingResponse{}, nil
}
func (s *CarpoolServiceServerImpl) GetBooking(ctx context.Context, req *proto.GetBookingRequest) (*proto.GetBookingResponse, error) {
result, err := s.Handler.GetBooking(req.BookingId)
if err != nil {
log.Error().Err(err).Msg("issue retrieving booking in handler")
return nil, err
}
return &proto.GetBookingResponse{
Booking: proto.BookingFromInternal(*result),
}, nil
}

View File

@ -55,7 +55,7 @@ func (s *CarpoolServiceServerImpl) GetUserPlanning(ctx context.Context, req *pro
for _, s := range scheds {
s.Route.ExtraMembers["departure_date"] = s.DepartureDate
s.Route.ExtraMembers["id"] = s.ID
fcraw, _ := s.Route.FeatureCollection().MarshalJSON()
fcraw, _ := s.Route.MarshalJSON()
results[k].Collection = append(results[k].Collection, &proto.CarpoolFeatureCollection{
Serialized: string(fcraw),
})
@ -73,9 +73,10 @@ func (s *CarpoolServiceServerImpl) GetPlannedTrip(ctx context.Context, req *prot
return nil, status.Errorf(codes.Internal, "could not retrieve planned trip - %s", err.Error())
}
planned_trip.Route.ExtraMembers["id"] = planned_trip.ID
planned_trip.Route.ExtraMembers["departure_date"] = planned_trip.DepartureDate
serialized, err := planned_trip.Route.FeatureCollection().MarshalJSON()
serialized, err := planned_trip.Route.MarshalJSON()
if err != nil {
log.Error().Err(err).Msg("grpc GetPlannedTrip - could not serialize feature collection")
return nil, status.Errorf(codes.Internal, "could not serialize feature collection")

View File

@ -13,13 +13,16 @@ import (
)
func (s *CarpoolServiceServerImpl) DriverJourneys(ctx context.Context, req *proto.DriverJourneysRequest) (*proto.DriverJourneysResponse, error) {
log.Debug().
Str("departure date", req.DepartureDate.String()).
Msg("grpc server - DriverJourneys")
departure := orb.Point{req.DepartureLng, req.DepartureLat}
arrival := orb.Point{req.ArrivalLng, req.ArrivalLat}
log.Debug().
Str("departure date", req.DepartureDate.String()).
Any("departure", departure).
Any("arrival", arrival).
Msg("grpc server - DriverJourneys")
td := 900 * time.Second
if req.TimeDelta != nil {
td = time.Duration(*req.TimeDelta) * time.Second
@ -65,17 +68,18 @@ func (s *CarpoolServiceServerImpl) DriverJourneys(ctx context.Context, req *prot
var distance *int64
if len(j.Itinerary.Legs) > 2 {
duration = j.Itinerary.Legs[1].Duration
dist := int64(j.Itinerary.Legs[1].Distance)
dist := j.Itinerary.Legs[1].Distance
distance = &dist
}
results = append(results, &proto.CarpoolServiceDriverJourney{
Id: journeyId,
Driver: &proto.CarpoolServiceUser{
Id: usermap["id"].(string),
Operator: usermap["operator"].(string),
Alias: usermap["alias"].(string),
},
Operator: "ridygo.fr",
Operator: s.Handler.InternalOperatorID,
PassengerPickupLat: req.DepartureLat,
PassengerPickupLng: req.DepartureLng,
PassengerDropLat: req.ArrivalLat,
@ -86,9 +90,8 @@ func (s *CarpoolServiceServerImpl) DriverJourneys(ctx context.Context, req *prot
DriverArrivalLng: &driverArrivalLng,
DriverDepartureAddress: driverDepartureAddress,
DriverArrivalAddress: driverArrivalAddress,
Duration: int64(duration),
Duration: int64(duration.Seconds()),
Distance: distance,
Id: journeyId,
PassengerPickupDate: timestamppb.New(j.DepartureDate.Add(j.Itinerary.Legs[0].Duration)),
DriverDepartureDate: timestamppb.New(j.DepartureDate),
Type: proto.CarpoolServiceJourneyType_PLANNED,
@ -137,25 +140,26 @@ func (s *CarpoolServiceServerImpl) PassengerJourneys(ctx context.Context, req *p
passengerPickupAddress = &ppa
}
var passengerDropAddress *string
if pda := j.Route.Features[0].Properties.MustString("label", ""); pda != "" {
if pda := j.Route.Features[1].Properties.MustString("label", ""); pda != "" {
passengerDropAddress = &pda
}
driverDepartureDate := timestamppb.New(j.DepartureDate.Add(-j.Itinerary.Legs[0].Duration))
duration := time.Duration(0)
var distance *int64
if len(j.Itinerary.Legs) > 2 {
duration = j.Itinerary.Legs[1].Duration / time.Second
dist := int64(j.Itinerary.Legs[1].Distance)
duration = j.Itinerary.Legs[1].Duration
dist := j.Itinerary.Legs[1].Distance
distance = &dist
}
results = append(results, &proto.CarpoolServicePassengerJourney{
Id: journeyId,
Passenger: &proto.CarpoolServiceUser{
Id: usermap["id"].(string),
Operator: usermap["operator"].(string),
Alias: usermap["alias"].(string),
},
Operator: "ridygo.fr",
Operator: s.Handler.InternalOperatorID,
PassengerPickupLat: passengerDepartureLat,
PassengerPickupLng: passengerDepartureLng,
PassengerDropLat: passengerArrivalLat,
@ -166,9 +170,8 @@ func (s *CarpoolServiceServerImpl) PassengerJourneys(ctx context.Context, req *p
DriverDepartureLng: &req.DepartureLng,
DriverArrivalLat: &req.ArrivalLat,
DriverArrivalLng: &req.ArrivalLng,
Duration: int64(duration),
Duration: int64(duration.Seconds()),
Distance: distance,
Id: journeyId,
PassengerPickupDate: passengerDepartureDate,
DriverDepartureDate: driverDepartureDate,
Type: proto.CarpoolServiceJourneyType_PLANNED,

View File

@ -1,7 +1,6 @@
package grpcserver
import (
"context"
"fmt"
"net"
@ -10,9 +9,7 @@ import (
"github.com/rs/zerolog/log"
"github.com/spf13/viper"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/reflection"
"google.golang.org/grpc/status"
)
type CarpoolServiceServerImpl struct {
@ -27,16 +24,6 @@ func NewCarpoolServiceServer(handler *handler.CarpoolServiceHandler) *CarpoolSer
}
}
func (s *CarpoolServiceServerImpl) CreateBooking(context.Context, *proto.CreateBookingRequest) (*proto.CreateBookingResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method CreateBooking not implemented")
}
func (s *CarpoolServiceServerImpl) UpdateBooking(context.Context, *proto.UpdateBookingRequest) (*proto.UpdateBookingResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method UpdateBooking not implemented")
}
func (s *CarpoolServiceServerImpl) GetBooking(context.Context, *proto.GetBookingRequest) (*proto.GetBookingResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetBooking not implemented")
}
func Run(done chan error, cfg *viper.Viper, handler *handler.CarpoolServiceHandler) {
var (
dev_env = cfg.GetBool("dev_env")

View File

@ -2,7 +2,6 @@ package ocssapi
import (
"context"
"errors"
"git.coopgo.io/coopgo-platform/carpool-service/interoperability/ocss"
"github.com/rs/zerolog/log"
@ -15,10 +14,14 @@ func (s *OCSSApiService) PostBookings(ctx context.Context, booking ocss.Booking)
return nil, err
}
return &result.BookingDefinition, nil
return &result.Booking, nil
}
func (s *OCSSApiService) PatchBookings(ctx context.Context, bookingId string, status ocss.BookingStatus, message *string) error {
return errors.New("booking not found")
err := s.Handler.UpdateBookingStatus(bookingId, status)
if err != nil {
return err
}
return nil
}
func (s *OCSSApiService) GetBookings(ctx context.Context, bookingId string) (*ocss.Booking, error) {
result, err := s.Handler.GetBooking(bookingId)
@ -27,5 +30,5 @@ func (s *OCSSApiService) GetBookings(ctx context.Context, bookingId string) (*oc
return nil, err
}
return &result.BookingDefinition, nil
return &result.Booking, nil
}

View File

@ -36,7 +36,7 @@ func (s *OCSSApiService) GetDriverJourneys(ctx context.Context, departureLat flo
driverDepartureLng := j.Route.Features[0].Point().Lon()
driverArrivalLat := j.Route.Features[1].Point().Lat()
driverArrivalLng := j.Route.Features[1].Point().Lon()
driverDepartureDate := ocss.JSONTime(j.DepartureDate)
driverDepartureDate := ocss.OCSSTime(j.DepartureDate)
duration := time.Duration(0)
var distance *int64
if len(j.Itinerary.Legs) > 2 {
@ -53,7 +53,7 @@ func (s *OCSSApiService) GetDriverJourneys(ctx context.Context, departureLat flo
Alias: usermap["alias"].(string),
},
Trip: ocss.Trip{
Operator: "ridygo.fr",
Operator: s.Handler.InternalOperatorID,
PassengerPickupLat: departureLat,
PassengerPickupLng: departureLng,
PassengerDropLat: arrivalLat,
@ -68,7 +68,7 @@ func (s *OCSSApiService) GetDriverJourneys(ctx context.Context, departureLat flo
},
JourneySchedule: ocss.JourneySchedule{
ID: &journeyId,
PassengerPickupDate: ocss.JSONTime(j.DepartureDate.Add(j.Itinerary.Legs[0].Duration)),
PassengerPickupDate: ocss.OCSSTime(j.DepartureDate.Add(j.Itinerary.Legs[0].Duration)),
DriverDepartureDate: &driverDepartureDate,
Type: ocss.Planned,
},
@ -109,8 +109,8 @@ func (s *OCSSApiService) GetPassengerJourneys(ctx context.Context, departureLat
passengerDepartureLng := j.Route.Features[0].Point().Lon()
passengerArrivalLat := j.Route.Features[1].Point().Lat()
passengerArrivalLng := j.Route.Features[1].Point().Lon()
passengerDepartureDate := ocss.JSONTime(j.DepartureDate)
driverDepartureDate := ocss.JSONTime(j.DepartureDate.Add(-j.Itinerary.Legs[0].Duration))
passengerDepartureDate := ocss.OCSSTime(j.DepartureDate)
driverDepartureDate := ocss.OCSSTime(j.DepartureDate.Add(-j.Itinerary.Legs[0].Duration))
duration := time.Duration(0)
var distance *int64
log.Debug().Any("itinerary", j.Itinerary).Msg("debug itinerary")
@ -128,7 +128,7 @@ func (s *OCSSApiService) GetPassengerJourneys(ctx context.Context, departureLat
Alias: usermap["alias"].(string),
},
Trip: ocss.Trip{
Operator: "ridygo.fr",
Operator: s.Handler.InternalOperatorID,
PassengerPickupLat: passengerDepartureLat,
PassengerPickupLng: passengerDepartureLng,
PassengerDropLat: passengerArrivalLat,

View File

@ -3,6 +3,7 @@ package storage
import (
"context"
"encoding/json"
"errors"
"fmt"
"git.coopgo.io/coopgo-platform/carpool-service/internal"
@ -222,6 +223,61 @@ func (s MongoDBStorage) GetPassengerRegularRoutesForTile(day string, gridId int6
return results, nil
}
func (s MongoDBStorage) CreateBooking(booking internal.Booking) error {
collection := s.Client.Database(s.DbName).Collection(s.Collections["bookings"])
_, err := collection.InsertOne(context.TODO(), booking)
if err != nil {
return err
}
return nil
}
func (s MongoDBStorage) GetBooking(id string) (booking *internal.Booking, err error) {
var b internal.Booking
log.Debug().Str("booking id", id).Msg("get booking in DB")
collection := s.Client.Database(s.DbName).Collection(s.Collections["bookings"])
err = collection.FindOne(context.TODO(), bson.M{"_id": id}).Decode(&b)
if err != nil {
log.Error().Err(err).Msg("error")
return nil, err
}
return &b, nil
}
func (s MongoDBStorage) GetUserBookings(userid string) ([]internal.Booking, error) {
findOptions := options.Find()
collection := s.Client.Database(s.DbName).Collection(s.Collections["bookings"])
cur, err := collection.Find(context.TODO(), bson.M{
"$or": []bson.M{
{"driver.id": userid},
{"passenger.id": userid},
},
}, findOptions)
if err != nil {
return nil, err
}
var bookings []internal.Booking
for cur.Next(context.TODO()) {
var elem internal.Booking
if err := cur.Decode(&elem); err != nil {
log.Error().Err(err).Msg("error reading bookings response")
return nil, err
}
bookings = append(bookings, elem)
}
return bookings, nil
}
func (s MongoDBStorage) UpdateBookingStatus(bookingid string, status string) error {
//TODO implement UpdateBookingStatus
return errors.New("MongoDB Storage - UpdateBookingStatus not implemented")
}
func (s MongoDBStorage) PersistedKVPut(documents []any) error {
collection := s.Client.Database(s.DbName).Collection(s.Collections["persisted_kv"])
if _, err := collection.InsertMany(context.TODO(), documents); err != nil {
@ -239,29 +295,6 @@ func (s MongoDBStorage) PersistedKVGet(id string, document any) error {
return nil
}
func (s MongoDBStorage) StoreSearchResults(searchresults []internal.SearchResult) error {
log.Debug().Msg("Storage - StoreSearchResults")
documents := []any{}
for _, sr := range searchresults {
documents = append(documents, sr)
}
return s.PersistedKVPut(documents)
}
func (s MongoDBStorage) GetSearchResult(id string) (*internal.SearchResult, error) {
var result internal.SearchResult
err := s.PersistedKVGet(id, &result)
if err != nil {
return nil, err
}
return &result, nil
}
func (s MongoDBStorage) StoreRouteSchedules(js []internal.PlannedRouteSchedule) error {
log.Debug().Msg("Storage - StoreRouteSchedules")
@ -282,31 +315,18 @@ func (s MongoDBStorage) GetRouteSchedule(id string) (*internal.PlannedRouteSched
return nil, err
}
for k, v := range result.Route.ExtraMembers {
if val, ok := v.(primitive.D); ok {
em := map[string]any{}
jsonbytes, _ := bson.MarshalExtJSON(val, true, true)
json.Unmarshal(jsonbytes, &em)
result.Route.ExtraMembers[k] = em
}
}
return &result, nil
}
func (s MongoDBStorage) CreateBooking(booking internal.Booking) error {
collection := s.Client.Database(s.DbName).Collection(s.Collections["bookings"])
_, err := collection.InsertOne(context.TODO(), booking)
if err != nil {
return err
}
return nil
}
func (s MongoDBStorage) GetBooking(id string) (booking *internal.Booking, err error) {
var b internal.Booking
log.Debug().Str("booking id", id).Msg("get booking in DB")
collection := s.Client.Database(s.DbName).Collection(s.Collections["bookings"])
err = collection.FindOne(context.TODO(), bson.M{"_id": id}).Decode(&b)
if err != nil {
log.Error().Err(err).Msg("error")
return nil, err
}
return &b, nil
}
// func (s MongoDBStorage) CreatePassengerRegularTrips(trips []*geojson.FeatureCollection) error {
// log.Debug().Msg("Storage - CreatePassengerRegularTrips")
@ -328,3 +348,7 @@ func (s MongoDBStorage) GetBooking(id string) (booking *internal.Booking, err er
// return nil
// }
func (s MongoDBStorage) Migrate() error {
return nil
}

494
storage/postgresql.go Normal file
View File

@ -0,0 +1,494 @@
package storage
import (
"context"
"database/sql"
"encoding/json"
"errors"
"fmt"
"os"
"strconv"
"ariga.io/atlas/sql/postgres"
"ariga.io/atlas/sql/schema"
"git.coopgo.io/coopgo-platform/carpool-service/internal"
"git.coopgo.io/coopgo-platform/carpool-service/interoperability/ocss"
"github.com/lib/pq"
_ "github.com/lib/pq"
"github.com/paulmach/orb/geojson"
"github.com/rs/zerolog/log"
"github.com/spf13/viper"
"github.com/stretchr/objx"
)
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_regular_routes = cfg.GetString("storage.db.psql.tables.regular_routes")
pgtables_regular_route_schedules = cfg.GetString("storage.db.psql.tables.regular_route_schedules")
pgtables_punctual_routes = cfg.GetString("storage.db.psql.tables.punctual_routes")
pgtables_bookings = cfg.GetString("storage.db.psql.tables.bookings")
pgtables_journeys_cache = cfg.GetString("storage.db.psql.tables.journeys_cache")
)
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{
"regular_routes": fmt.Sprintf("%s.%s", pg_schema, pgtables_regular_routes),
"regular_route_schedules": fmt.Sprintf("%s.%s", pg_schema, pgtables_regular_route_schedules),
"punctual_routes": fmt.Sprintf("%s.%s", pg_schema, pgtables_punctual_routes),
"bookings": fmt.Sprintf("%s.%s", pg_schema, pgtables_bookings),
"journeys_cache": fmt.Sprintf("%s.%s", pg_schema, pgtables_journeys_cache),
},
}, nil
}
func (s PostgresqlStorage) CreateRegularRoutes(routes []*geojson.FeatureCollection) error {
log.Debug().Msg("Postgresql Storage - CreateRegularRoutes")
tx, err := s.DbConnection.Begin()
if err != nil {
log.Error().Err(err).Msg("error initializing transaction")
return err
}
defer tx.Rollback()
req_routes := fmt.Sprintf(`INSERT INTO %s (id, user_id, routes_group_id, grid_ids, is_driver, is_passenger, route)
VALUES ($1, $2, $3, $4,$5, $6, $7)`, s.Tables["regular_routes"])
stmt_routes, err := tx.Prepare(req_routes)
if err != nil {
log.Error().Err(err).Msg("error preparing regular routes statement for multiple inserts")
return err
}
defer stmt_routes.Close()
req_schedules := fmt.Sprintf(`INSERT INTO %s (route_id, day, time_of_day) VALUES ($1, $2, $3)`, s.Tables["regular_route_schedules"])
stmt_schedules, err := tx.Prepare(req_schedules)
if err != nil {
log.Error().Err(err).Msg("error preparing schedules statement for multiple inserts")
return err
}
defer stmt_schedules.Close()
for _, fc := range routes {
if fc != nil {
id := fc.ExtraMembers.MustString("id")
properties := objx.New(fc.ExtraMembers["properties"])
userid := properties.Get("user.id").Str()
gridids := fc.ExtraMembers["grid_ids"]
groupid := fc.ExtraMembers["routes_group_id"]
isdriver := properties.Get("is_driver").Bool()
ispassenger := properties.Get("is_passenger").Bool()
route, err := fc.MarshalJSON()
if err != nil {
log.Error().Err(err).Msg("error creating regular route")
return err
}
_, err = stmt_routes.Exec(id, userid, groupid, pq.Array(gridids), isdriver, ispassenger, route)
if err != nil {
log.Error().Err(err).Msg("error inserting regular route")
return err
}
schedules := properties.Get("schedules")
if schedules == nil {
err = errors.New("could not get schedules for route")
log.Error().Err(err).Str("route id", id).Msg("issue in CreateRegularRoute")
return err
}
for _, schedule := range schedules.MustObjxMapSlice() {
day := schedule.Get("day").Str()
timeOfDay := schedule.Get("time_of_day").Str()
_, err = stmt_schedules.Exec(id, day, timeOfDay)
if err != nil {
log.Error().Err(err).Msg("issue creating route schedule")
return err
}
}
}
}
if err = tx.Commit(); err != nil {
log.Error().Err(err).Msg("issue committing transaction")
return err
}
return nil
}
func (s PostgresqlStorage) GetUserRegularRoutes(userid string) ([]*geojson.FeatureCollection, error) {
req := fmt.Sprintf(`select id, route
from %s where user_id = $1`, s.Tables["regular_routes"])
rows, err := s.DbConnection.Query(req, userid)
if err != nil {
log.Error().Err(err).Str("request", req).Str("user id", userid).Msg("GetUserRegularRoutes query issue")
return nil, err
}
results := []*geojson.FeatureCollection{}
for rows.Next() {
var id string
var route []byte
err := rows.Scan(
&id,
&route,
)
if err != nil {
return nil, err
}
fc, err := geojson.UnmarshalFeatureCollection(route)
if err != nil {
return nil, err
}
results = append(results, fc)
}
return results, nil
}
func (s PostgresqlStorage) GetDriverRegularRoutesForTile(day string, gridId int64) (regular_routes []*geojson.FeatureCollection, err error) {
req := fmt.Sprintf(`select id, route
from %s inner join %s on id = route_id
where is_driver = true and day = $1 and $2 = ANY (grid_ids)`, s.Tables["regular_routes"], s.Tables["regular_route_schedules"])
rows, err := s.DbConnection.Query(req, day, gridId)
if err != nil {
log.Error().Err(err).Msg("GetDriverRegularRoutesForTile query error")
return nil, err
}
results := []*geojson.FeatureCollection{}
for rows.Next() {
var id string
var route []byte
err := rows.Scan(
&id,
&route,
)
if err != nil {
return nil, err
}
fc, err := geojson.UnmarshalFeatureCollection(route)
if err != nil {
return nil, err
}
results = append(results, fc)
}
return results, nil
}
func (s PostgresqlStorage) GetPassengerRegularRoutesForTile(day string, gridId int64) (regular_routes []*geojson.FeatureCollection, err error) {
req := fmt.Sprintf(`select id, route
from %s join %s on id = route_id
where is_passenger = true and day = $1 and $2 = ANY (grid_ids)`, s.Tables["regular_routes"], s.Tables["regular_route_schedules"])
rows, err := s.DbConnection.Query(req, day, gridId)
if err != nil {
return nil, err
}
results := []*geojson.FeatureCollection{}
for rows.Next() {
var id string
var route []byte
err := rows.Scan(
&id,
&route,
)
if err != nil {
return nil, err
}
fc, err := geojson.UnmarshalFeatureCollection(route)
if err != nil {
return nil, err
}
results = append(results, fc)
}
return results, nil
}
func (s PostgresqlStorage) CreateBooking(booking internal.Booking) error {
req := fmt.Sprintf(`insert into %s (id, booking, status, driver_route, passenger_route)
values($1, $2, $3, $4, $5)`, s.Tables["bookings"])
id := booking.ID
status := booking.Status.String()
jsonbooking, err := json.Marshal(booking)
if err != nil {
log.Error().Err(err).Msg("issue marshalling booking to json")
return err
}
var jsondriverroute, jsonpassengerroute *[]byte
if booking.DriverRoute != nil {
jdr, err := booking.DriverRoute.MarshalJSON()
if err != nil {
log.Error().Err(err).Msg("error marshalling driver route")
return err
}
jsondriverroute = &jdr
}
if booking.PassengerRoute != nil {
jpr, err := booking.PassengerRoute.MarshalJSON()
if err != nil {
log.Error().Err(err).Msg("error marshalling passenger route")
return err
}
jsonpassengerroute = &jpr
}
_, err = s.DbConnection.Exec(req, id, jsonbooking, status, jsondriverroute, jsonpassengerroute)
if err != nil {
log.Error().Err(err).Str("request", req).Msg("error creating booking")
return err
}
return nil
}
func (s PostgresqlStorage) GetBooking(id string) (*internal.Booking, error) {
req := fmt.Sprintf(`select booking, status, driver_route, passenger_route
from %s where id=$1`, s.Tables["bookings"])
var booking ocss.Booking
var status string
var bookingbytes, driverroute, passengerroute []byte
err := s.DbConnection.QueryRow(req, id).Scan(
&bookingbytes,
&status,
&driverroute,
&passengerroute,
)
if err != nil {
log.Error().Err(err).Str("booking id", id).Msg("not able to get and scan booking")
return nil, err
}
err = json.Unmarshal(bookingbytes, &booking)
if err != nil {
log.Error().Err(err).Msg("issue unmarshalling booking")
return nil, err
}
// Override booking status
booking.Status = ocss.BookingStatusFromString(status)
var dr, pr *geojson.FeatureCollection
if driverroute != nil {
dr, err = geojson.UnmarshalFeatureCollection(driverroute)
if err != nil {
log.Error().Err(err).Msg("could not unmarshal driver route feature collection")
return nil, err
}
}
if passengerroute != nil {
pr, err = geojson.UnmarshalFeatureCollection(passengerroute)
if err != nil {
log.Error().Err(err).Msg("could not unmarshal passenger route feature collection")
return nil, err
}
}
return &internal.Booking{
Booking: booking,
DriverRoute: dr,
PassengerRoute: pr,
}, nil
}
func (s PostgresqlStorage) UpdateBookingStatus(bookingid string, status string) error {
req := fmt.Sprintf(`update %s set status = $1 where id=$2`, s.Tables["bookings"])
_, err := s.DbConnection.Exec(req, status, bookingid)
if err != nil {
log.Error().Err(err).Str("request", req).Str("booking id", bookingid).Str("status", status).Msg("error while updating booking status")
}
return nil
}
func (s PostgresqlStorage) GetUserBookings(userid string) ([]internal.Booking, error) {
req := fmt.Sprintf(`select booking, status, driver_route, passenger_route from %s
where booking->'driver'->>'id' = $1 or booking->'passenger'->>'id' = $2`, s.Tables["bookings"])
rows, err := s.DbConnection.Query(req, userid, userid)
if err != nil {
log.Error().Err(err).Str("user id", userid).Msg("GetUserBookings query issue")
}
results := []internal.Booking{}
for rows.Next() {
var booking ocss.Booking
var status string
var bookingbytes, driverroute, passengerroute []byte
err := rows.Scan(
&bookingbytes,
&status,
&driverroute,
&passengerroute,
)
if err != nil {
log.Error().Err(err).Msg("not able to get and scan booking in GetUsersBooking")
return nil, err
}
err = json.Unmarshal(bookingbytes, &booking)
if err != nil {
log.Error().Err(err).Msg("issue unmarshalling booking in GetUsersBooking")
return nil, err
}
// Override booking status
booking.Status = ocss.BookingStatusFromString(status)
var dr, pr *geojson.FeatureCollection
if driverroute != nil {
dr, err = geojson.UnmarshalFeatureCollection(driverroute)
if err != nil {
log.Error().Err(err).Msg("could not unmarshal driver route feature collection")
return nil, err
}
}
if passengerroute != nil {
pr, err = geojson.UnmarshalFeatureCollection(passengerroute)
if err != nil {
log.Error().Err(err).Msg("could not unmarshal passenger route feature collection")
return nil, err
}
}
results = append(results, internal.Booking{
Booking: booking,
DriverRoute: dr,
PassengerRoute: pr,
})
}
return results, nil
}
func (s PostgresqlStorage) StoreRouteSchedules(journeys []internal.PlannedRouteSchedule) error {
tx, err := s.DbConnection.Begin()
if err != nil {
log.Error().Err(err).Msg("issue starting pg transaction")
return err
}
defer tx.Rollback()
req := fmt.Sprintf("insert into %s (id, data) values ($1, $2)", s.Tables["journeys_cache"])
stmt, err := tx.Prepare(req)
if err != nil {
log.Error().Err(err).Msg("issue creating prepared statement in StoreRouteSchedules")
return err
}
for _, j := range journeys {
jsonjourney, err := json.Marshal(j)
if err != nil {
log.Error().Err(err).Msg("error unmarshalling Route Schedule")
return err
}
stmt.Exec(j.ID, jsonjourney)
}
if err = tx.Commit(); err != nil {
log.Error().Err(err).Msg("issue while commiting transaction in StoreRouteSchedules")
return err
}
return nil
}
func (s PostgresqlStorage) GetRouteSchedule(id string) (*internal.PlannedRouteSchedule, error) {
req := fmt.Sprintf("select data from %s where id = $1", s.Tables["journeys_cache"])
var jsonjourney []byte
err := s.DbConnection.QueryRow(req, id).Scan(
&jsonjourney,
)
if err != nil {
log.Error().Err(err).Msg("issue scanning result in GetRouteSchedule")
return nil, err
}
var result internal.PlannedRouteSchedule
err = json.Unmarshal(jsonjourney, &result)
if err != nil {
log.Error().Err(err).Msg("error unmarshalling returned route schedule")
}
return &result, nil
}
func (s PostgresqlStorage) Migrate() error {
ctx := context.Background()
driver, err := postgres.Open(s.DbConnection)
if err != nil {
return err
}
existing, err := driver.InspectRealm(ctx, &schema.InspectRealmOption{Schemas: []string{s.Schema}})
if err != nil {
return err
}
var desired schema.Realm
hcl, err := os.ReadFile("postgresql/schema.hcl")
if err != nil {
return err
}
err = postgres.EvalHCLBytes(hcl, &desired, nil)
if err != nil {
return err
}
diff, err := driver.RealmDiff(existing, &desired)
if err != nil {
return err
}
err = driver.ApplyChanges(ctx, diff)
if err != nil {
return err
}
return nil
}

View File

@ -0,0 +1,104 @@
table "bookings" {
schema = schema.carpool_service
column "id" {
null = false
type = uuid
}
column "booking" {
null = false
type = jsonb
}
column "status" {
null = false
type = enum.booking_status
}
column "driver_route" {
null = true
type = jsonb
}
column "passenger_route" {
null = true
type = jsonb
}
primary_key {
columns = [column.id]
}
}
table "journeys_cache" {
schema = schema.carpool_service
column "id" {
null = false
type = uuid
}
column "data" {
null = false
type = jsonb
}
column "created_at" {
null = false
type = timestamptz
default = sql("now()")
}
primary_key {
columns = [column.id]
}
}
table "regular_route_schedules" {
schema = schema.carpool_service
column "route_id" {
null = false
type = uuid
}
column "day" {
null = false
type = enum.day
}
column "time_of_day" {
null = false
type = time
}
}
table "regular_routes" {
schema = schema.carpool_service
column "id" {
null = false
type = uuid
}
column "user_id" {
null = false
type = uuid
}
column "routes_group_id" {
null = true
type = uuid
}
column "grid_ids" {
null = true
type = sql("numeric[]")
}
column "is_driver" {
null = true
type = boolean
}
column "is_passenger" {
null = true
type = boolean
}
column "route" {
null = false
type = jsonb
}
primary_key {
columns = [column.id]
}
}
enum "booking_status" {
schema = schema.carpool_service
values = ["INITIATED", "WAITING_PASSENGER_CONFIRMATION", "WAITING_DRIVER_CONFIRMATION", "CONFIRMED", "CANCELLED", "COMPLETED_PENDING_VALIDATION", "VALIDATED"]
}
enum "day" {
schema = schema.carpool_service
values = ["MON", "TUE", "WED", "THU", "FRI", "SAT", "SUN"]
}
schema "carpool_service" {
}

134
storage/postgresql_test.go Normal file
View File

@ -0,0 +1,134 @@
package storage
import (
"fmt"
"testing"
"github.com/paulmach/orb/geojson"
"github.com/spf13/viper"
"github.com/stretchr/testify/require"
)
var cfg *viper.Viper
func init() {
cfg = viper.New()
cfg.SetDefault("storage.db.psql.host", "localhost")
cfg.SetDefault("storage.db.psql.port", "5432")
cfg.SetDefault("storage.db.psql.user", "postgres")
cfg.SetDefault("storage.db.psql.password", "postgres")
cfg.SetDefault("storage.db.psql.dbname", "carpool_service_tests")
cfg.SetDefault("storage.db.psql.sslmode", "disable")
cfg.SetDefault("storage.db.psql.schema", "carpool_service")
cfg.SetDefault("storage.db.psql.tables.regular_routes", "regular_routes")
cfg.SetDefault("storage.db.psql.tables.regular_route_schedules", "regular_route_schedules")
cfg.SetDefault("storage.db.psql.tables.punctual_routes", "punctual_routes")
cfg.SetDefault("storage.db.psql.tables.bookings", "bookings")
cfg.SetDefault("storage.db.psql.tables.journeys_cache", "journeys_cache")
cfg.SetConfigName("config") // Override default values in a config.yaml file within this directory
cfg.AddConfigPath(".")
cfg.ReadInConfig()
}
func TestPostgresqlStorage_Initialize(t *testing.T) {
storage, err := NewPostgresqlStorage(cfg)
require.NoError(t, err)
defer storage.DbConnection.Close()
err = storage.Migrate()
require.NoError(t, err)
_, err = storage.DbConnection.Exec(fmt.Sprintf("DELETE FROM %s;", storage.Tables["regular_routes"]))
require.NoError(t, err)
_, err = storage.DbConnection.Exec(fmt.Sprintf("DELETE FROM %s;", storage.Tables["regular_route_schedules"]))
require.NoError(t, err)
// _, err = storage.DbConnection.Exec(fmt.Sprintf("DELETE FROM %s;", storage.Tables["punctual_routes"]))
// require.NoError(t, err)
_, err = storage.DbConnection.Exec(fmt.Sprintf("DELETE FROM %s;", storage.Tables["journeys_cache"]))
require.NoError(t, err)
}
func TestPostgresqlStorage_CreateRegularRoutes(t *testing.T) {
storage, err := NewPostgresqlStorage(cfg)
require.NoError(t, err)
defer storage.DbConnection.Close()
fc1, err := geojson.UnmarshalFeatureCollection([]byte(regularroute1))
require.NoError(t, err)
fc2, err := geojson.UnmarshalFeatureCollection([]byte(regularroute2))
require.NoError(t, err)
fc3, err := geojson.UnmarshalFeatureCollection([]byte(regularroute3))
require.NoError(t, err)
fc4, err := geojson.UnmarshalFeatureCollection([]byte(regularroute4))
require.NoError(t, err)
fc5, err := geojson.UnmarshalFeatureCollection([]byte(regularroute5))
require.NoError(t, err)
fc6, err := geojson.UnmarshalFeatureCollection([]byte(regularroute6))
require.NoError(t, err)
err = storage.CreateRegularRoutes([]*geojson.FeatureCollection{fc1, fc2, fc3, fc4, fc5, fc6})
require.NoError(t, err)
}
func TestPostgresqlStorage_GetUserRegularRoutes(t *testing.T) {
storage, err := NewPostgresqlStorage(cfg)
require.NoError(t, err)
defer storage.DbConnection.Close()
results, err := storage.GetUserRegularRoutes("ca435b62-3162-4c79-983a-2a0f4fb16aa0")
require.NoError(t, err)
require.Len(t, results, 2)
}
func TestPostgresqlStorage_GetRegularRoutesForTile(t *testing.T) {
storage, err := NewPostgresqlStorage(cfg)
require.NoError(t, err)
defer storage.DbConnection.Close()
results, err := storage.GetDriverRegularRoutesForTile("MON", 48067)
require.NoError(t, err)
require.Len(t, results, 3)
results, err = storage.GetPassengerRegularRoutesForTile("MON", 48067)
require.NoError(t, err)
require.Len(t, results, 3)
}
func TestPostgresqlStorage_CreateBooking(t *testing.T) {
storage, err := NewPostgresqlStorage(cfg)
require.NoError(t, err)
defer storage.DbConnection.Close()
err = storage.CreateBooking(booking1)
require.NoError(t, err)
err = storage.CreateBooking(booking2)
require.NoError(t, err)
err = storage.CreateBooking(booking3)
require.NoError(t, err)
}
func TestPostgresqlStorage_GetBooking(t *testing.T) {
storage, err := NewPostgresqlStorage(cfg)
require.NoError(t, err)
defer storage.DbConnection.Close()
_, err = storage.GetBooking(booking1id)
require.NoError(t, err)
}
func TestPostgresqlStorage_GetUserBookings(t *testing.T) {
storage, err := NewPostgresqlStorage(cfg)
require.NoError(t, err)
defer storage.DbConnection.Close()
results, err := storage.GetUserBookings(bookinguser1)
require.NoError(t, err)
require.Len(t, results, 2)
}

View File

@ -16,14 +16,16 @@ type Storage interface {
CreateBooking(internal.Booking) error
GetBooking(id string) (*internal.Booking, error)
GetUserBookings(userid string) ([]internal.Booking, error)
UpdateBookingStatus(bookingid string, status string) error
// Caching temporary results
PersistedKVPut(documents []any) error
PersistedKVGet(id string, document any) error
StoreSearchResults([]internal.SearchResult) error
GetSearchResult(id string) (*internal.SearchResult, error)
// PersistedKVPut(documents []any) error
// PersistedKVGet(id string, document any) error
StoreRouteSchedules([]internal.PlannedRouteSchedule) error
GetRouteSchedule(id string) (*internal.PlannedRouteSchedule, error)
Migrate() error
}
func NewStorage(cfg *viper.Viper) (Storage, error) {
@ -35,6 +37,9 @@ func NewStorage(cfg *viper.Viper) (Storage, error) {
case "mongodb":
s, err := NewMongoDBStorage(cfg)
return s, err
case "psql":
s, err := NewPostgresqlStorage(cfg)
return s, err
default:
return nil, fmt.Errorf("storage type %v is not supported", storage_type)
}

1092
storage/storage_test.go Normal file

File diff suppressed because it is too large Load Diff

View File

@ -63,7 +63,7 @@ func (h *TilesHandler) GetTile(driverOrPassenger string, date time.Time, gridid
for _, r := range routes {
rr := internal.RegularRoute(*r)
schedules, err := rr.PlannedJourneySchedules(date0h, date24h)
schedules, err := rr.PlannedRouteSchedules(date0h, date24h)
if err != nil {
log.Error().Err(err)
return nil, err