booking.go 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. package endpoint
  2. import (
  3. "context"
  4. "encoding/json"
  5. "github.com/go-chi/chi"
  6. "net/http"
  7. "time"
  8. kitlog "github.com/go-kit/kit/log"
  9. shipping "github.com/longjoy/micro-go-course/section19/cargo/model"
  10. "github.com/longjoy/micro-go-course/section19/cargo/service/booking"
  11. )
  12. type bookingHandler struct {
  13. s booking.Service
  14. logger kitlog.Logger
  15. }
  16. func (h *bookingHandler) router() chi.Router {
  17. r := chi.NewRouter()
  18. r.Route("/cargos", func(r chi.Router) {
  19. r.Post("/", h.bookCargo)
  20. r.Get("/", h.listCargos)
  21. r.Route("/{trackingID}", func(r chi.Router) {
  22. r.Get("/", h.loadCargo)
  23. r.Get("/request_routes", h.requestRoutes)
  24. r.Post("/assign_to_route", h.assignToRoute)
  25. r.Post("/change_destination", h.changeDestination)
  26. })
  27. })
  28. r.Get("/locations", h.listLocations)
  29. r.Method("GET", "/docs", http.StripPrefix("/booking/v1/docs", http.FileServer(http.Dir("booking/docs"))))
  30. return r
  31. }
  32. func (h *bookingHandler) bookCargo(w http.ResponseWriter, r *http.Request) {
  33. ctx := context.Background()
  34. var request struct {
  35. Origin shipping.UNLocode
  36. Destination shipping.UNLocode
  37. ArrivalDeadline time.Time
  38. }
  39. if err := json.NewDecoder(r.Body).Decode(&request); err != nil {
  40. h.logger.Log("error", err)
  41. encodeError(ctx, err, w)
  42. return
  43. }
  44. id, err := h.s.BookNewCargo(request.Origin, request.Destination, request.ArrivalDeadline)
  45. if err != nil {
  46. encodeError(ctx, err, w)
  47. return
  48. }
  49. var response = struct {
  50. ID shipping.TrackingID `json:"tracking_id"`
  51. }{
  52. ID: id,
  53. }
  54. w.Header().Set("Content-Type", "application/json; charset=utf-8")
  55. if err := json.NewEncoder(w).Encode(response); err != nil {
  56. h.logger.Log("error", err)
  57. encodeError(ctx, err, w)
  58. return
  59. }
  60. }
  61. func (h *bookingHandler) loadCargo(w http.ResponseWriter, r *http.Request) {
  62. ctx := context.Background()
  63. trackingID := shipping.TrackingID(chi.URLParam(r, "trackingID"))
  64. c, err := h.s.LoadCargo(trackingID)
  65. if err != nil {
  66. encodeError(ctx, err, w)
  67. return
  68. }
  69. var response = struct {
  70. Cargo booking.Cargo `json:"cargo"`
  71. }{
  72. Cargo: c,
  73. }
  74. w.Header().Set("Content-Type", "application/json; charset=utf-8")
  75. if err := json.NewEncoder(w).Encode(response); err != nil {
  76. h.logger.Log("error", err)
  77. encodeError(ctx, err, w)
  78. return
  79. }
  80. }
  81. func (h *bookingHandler) requestRoutes(w http.ResponseWriter, r *http.Request) {
  82. ctx := context.Background()
  83. trackingID := shipping.TrackingID(chi.URLParam(r, "trackingID"))
  84. itin := h.s.RequestPossibleRoutesForCargo(trackingID)
  85. var response = struct {
  86. Routes []shipping.Itinerary `json:"routes"`
  87. }{
  88. Routes: itin,
  89. }
  90. w.Header().Set("Content-Type", "application/json; charset=utf-8")
  91. if err := json.NewEncoder(w).Encode(response); err != nil {
  92. h.logger.Log("error", err)
  93. encodeError(ctx, err, w)
  94. return
  95. }
  96. }
  97. func (h *bookingHandler) assignToRoute(w http.ResponseWriter, r *http.Request) {
  98. ctx := context.Background()
  99. trackingID := shipping.TrackingID(chi.URLParam(r, "trackingID"))
  100. var request struct {
  101. Itinerary shipping.Itinerary `json:"route"`
  102. }
  103. if err := json.NewDecoder(r.Body).Decode(&request); err != nil {
  104. h.logger.Log("error", err)
  105. encodeError(ctx, err, w)
  106. return
  107. }
  108. _, err := h.s.AssignCargoToRoute(trackingID, request.Itinerary)
  109. if err != nil {
  110. encodeError(ctx, err, w)
  111. return
  112. }
  113. }
  114. func (h *bookingHandler) changeDestination(w http.ResponseWriter, r *http.Request) {
  115. ctx := context.Background()
  116. trackingID := shipping.TrackingID(chi.URLParam(r, "trackingID"))
  117. var request struct {
  118. Destination shipping.UNLocode `json:"destination"`
  119. }
  120. if err := json.NewDecoder(r.Body).Decode(&request); err != nil {
  121. h.logger.Log("error", err)
  122. encodeError(ctx, err, w)
  123. return
  124. }
  125. _, err := h.s.ChangeDestination(trackingID, request.Destination)
  126. if err != nil {
  127. encodeError(ctx, err, w)
  128. return
  129. }
  130. }
  131. func (h *bookingHandler) listCargos(w http.ResponseWriter, r *http.Request) {
  132. ctx := context.Background()
  133. cs := h.s.Cargos()
  134. var response = struct {
  135. Cargos []booking.Cargo `json:"cargos"`
  136. }{
  137. Cargos: cs,
  138. }
  139. w.Header().Set("Content-Type", "application/json; charset=utf-8")
  140. if err := json.NewEncoder(w).Encode(response); err != nil {
  141. h.logger.Log("error", err)
  142. encodeError(ctx, err, w)
  143. return
  144. }
  145. }
  146. func (h *bookingHandler) listLocations(w http.ResponseWriter, r *http.Request) {
  147. ctx := context.Background()
  148. ls := h.s.Locations()
  149. var response = struct {
  150. Locations []booking.Location `json:"locations"`
  151. }{
  152. Locations: ls,
  153. }
  154. w.Header().Set("Content-Type", "application/json; charset=utf-8")
  155. if err := json.NewEncoder(w).Encode(response); err != nil {
  156. h.logger.Log("error", err)
  157. encodeError(ctx, err, w)
  158. return
  159. }
  160. }