| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204 | package endpointimport (	"context"	"encoding/json"	"github.com/go-chi/chi"	"net/http"	"time"	kitlog "github.com/go-kit/kit/log"	shipping "github.com/longjoy/micro-go-course/section19/cargo/model"	"github.com/longjoy/micro-go-course/section19/cargo/service/booking")type bookingHandler struct {	s booking.Service	logger kitlog.Logger}func (h *bookingHandler) router() chi.Router {	r := chi.NewRouter()	r.Route("/cargos", func(r chi.Router) {		r.Post("/", h.bookCargo)		r.Get("/", h.listCargos)		r.Route("/{trackingID}", func(r chi.Router) {			r.Get("/", h.loadCargo)			r.Get("/request_routes", h.requestRoutes)			r.Post("/assign_to_route", h.assignToRoute)			r.Post("/change_destination", h.changeDestination)		})	})	r.Get("/locations", h.listLocations)	r.Method("GET", "/docs", http.StripPrefix("/booking/v1/docs", http.FileServer(http.Dir("booking/docs"))))	return r}func (h *bookingHandler) bookCargo(w http.ResponseWriter, r *http.Request) {	ctx := context.Background()	var request struct {		Origin          shipping.UNLocode		Destination     shipping.UNLocode		ArrivalDeadline time.Time	}	if err := json.NewDecoder(r.Body).Decode(&request); err != nil {		h.logger.Log("error", err)		encodeError(ctx, err, w)		return	}	id, err := h.s.BookNewCargo(request.Origin, request.Destination, request.ArrivalDeadline)	if err != nil {		encodeError(ctx, err, w)		return	}	var response = struct {		ID shipping.TrackingID `json:"tracking_id"`	}{		ID: id,	}	w.Header().Set("Content-Type", "application/json; charset=utf-8")	if err := json.NewEncoder(w).Encode(response); err != nil {		h.logger.Log("error", err)		encodeError(ctx, err, w)		return	}}func (h *bookingHandler) loadCargo(w http.ResponseWriter, r *http.Request) {	ctx := context.Background()	trackingID := shipping.TrackingID(chi.URLParam(r, "trackingID"))	c, err := h.s.LoadCargo(trackingID)	if err != nil {		encodeError(ctx, err, w)		return	}	var response = struct {		Cargo booking.Cargo `json:"cargo"`	}{		Cargo: c,	}	w.Header().Set("Content-Type", "application/json; charset=utf-8")	if err := json.NewEncoder(w).Encode(response); err != nil {		h.logger.Log("error", err)		encodeError(ctx, err, w)		return	}}func (h *bookingHandler) requestRoutes(w http.ResponseWriter, r *http.Request) {	ctx := context.Background()	trackingID := shipping.TrackingID(chi.URLParam(r, "trackingID"))	itin := h.s.RequestPossibleRoutesForCargo(trackingID)	var response = struct {		Routes []shipping.Itinerary `json:"routes"`	}{		Routes: itin,	}	w.Header().Set("Content-Type", "application/json; charset=utf-8")	if err := json.NewEncoder(w).Encode(response); err != nil {		h.logger.Log("error", err)		encodeError(ctx, err, w)		return	}}func (h *bookingHandler) assignToRoute(w http.ResponseWriter, r *http.Request) {	ctx := context.Background()	trackingID := shipping.TrackingID(chi.URLParam(r, "trackingID"))	var request struct {		Itinerary shipping.Itinerary `json:"route"`	}	if err := json.NewDecoder(r.Body).Decode(&request); err != nil {		h.logger.Log("error", err)		encodeError(ctx, err, w)		return	}	_, err := h.s.AssignCargoToRoute(trackingID, request.Itinerary)	if err != nil {		encodeError(ctx, err, w)		return	}}func (h *bookingHandler) changeDestination(w http.ResponseWriter, r *http.Request) {	ctx := context.Background()	trackingID := shipping.TrackingID(chi.URLParam(r, "trackingID"))	var request struct {		Destination shipping.UNLocode `json:"destination"`	}	if err := json.NewDecoder(r.Body).Decode(&request); err != nil {		h.logger.Log("error", err)		encodeError(ctx, err, w)		return	}	_, err := h.s.ChangeDestination(trackingID, request.Destination)	if err != nil {		encodeError(ctx, err, w)		return	}}func (h *bookingHandler) listCargos(w http.ResponseWriter, r *http.Request) {	ctx := context.Background()	cs := h.s.Cargos()	var response = struct {		Cargos []booking.Cargo `json:"cargos"`	}{		Cargos: cs,	}	w.Header().Set("Content-Type", "application/json; charset=utf-8")	if err := json.NewEncoder(w).Encode(response); err != nil {		h.logger.Log("error", err)		encodeError(ctx, err, w)		return	}}func (h *bookingHandler) listLocations(w http.ResponseWriter, r *http.Request) {	ctx := context.Background()	ls := h.s.Locations()	var response = struct {		Locations []booking.Location `json:"locations"`	}{		Locations: ls,	}	w.Header().Set("Content-Type", "application/json; charset=utf-8")	if err := json.NewEncoder(w).Encode(response); err != nil {		h.logger.Log("error", err)		encodeError(ctx, err, w)		return	}}
 |