+++ /dev/null
-package routing
-
-import (
- "context"
- "encoding/json"
- "net/http"
- "net/url"
- "time"
-
- "github.com/go-kit/kit/circuitbreaker"
- "github.com/go-kit/kit/endpoint"
- kithttp "github.com/go-kit/kit/transport/http"
-
- "github.com/go-kit/kit/examples/shipping/cargo"
- "github.com/go-kit/kit/examples/shipping/location"
- "github.com/go-kit/kit/examples/shipping/voyage"
-)
-
-type proxyService struct {
- context.Context
- FetchRoutesEndpoint endpoint.Endpoint
- Service
-}
-
-func (s proxyService) FetchRoutesForSpecification(rs cargo.RouteSpecification) []cargo.Itinerary {
- response, err := s.FetchRoutesEndpoint(s.Context, fetchRoutesRequest{
- From: string(rs.Origin),
- To: string(rs.Destination),
- })
- if err != nil {
- return []cargo.Itinerary{}
- }
-
- resp := response.(fetchRoutesResponse)
-
- var itineraries []cargo.Itinerary
- for _, r := range resp.Paths {
- var legs []cargo.Leg
- for _, e := range r.Edges {
- legs = append(legs, cargo.Leg{
- VoyageNumber: voyage.Number(e.Voyage),
- LoadLocation: location.UNLocode(e.Origin),
- UnloadLocation: location.UNLocode(e.Destination),
- LoadTime: e.Departure,
- UnloadTime: e.Arrival,
- })
- }
-
- itineraries = append(itineraries, cargo.Itinerary{Legs: legs})
- }
-
- return itineraries
-}
-
-// ServiceMiddleware defines a middleware for a routing service.
-type ServiceMiddleware func(Service) Service
-
-// NewProxyingMiddleware returns a new instance of a proxying middleware.
-func NewProxyingMiddleware(ctx context.Context, proxyURL string) ServiceMiddleware {
- return func(next Service) Service {
- var e endpoint.Endpoint
- e = makeFetchRoutesEndpoint(ctx, proxyURL)
- e = circuitbreaker.Hystrix("fetch-routes")(e)
- return proxyService{ctx, e, next}
- }
-}
-
-type fetchRoutesRequest struct {
- From string
- To string
-}
-
-type fetchRoutesResponse struct {
- Paths []struct {
- Edges []struct {
- Origin string `json:"origin"`
- Destination string `json:"destination"`
- Voyage string `json:"voyage"`
- Departure time.Time `json:"departure"`
- Arrival time.Time `json:"arrival"`
- } `json:"edges"`
- } `json:"paths"`
-}
-
-func makeFetchRoutesEndpoint(ctx context.Context, instance string) endpoint.Endpoint {
- u, err := url.Parse(instance)
- if err != nil {
- panic(err)
- }
- if u.Path == "" {
- u.Path = "/paths"
- }
- return kithttp.NewClient(
- "GET", u,
- encodeFetchRoutesRequest,
- decodeFetchRoutesResponse,
- ).Endpoint()
-}
-
-func decodeFetchRoutesResponse(_ context.Context, resp *http.Response) (interface{}, error) {
- var response fetchRoutesResponse
- if err := json.NewDecoder(resp.Body).Decode(&response); err != nil {
- return nil, err
- }
- return response, nil
-}
-
-func encodeFetchRoutesRequest(_ context.Context, r *http.Request, request interface{}) error {
- req := request.(fetchRoutesRequest)
-
- vals := r.URL.Query()
- vals.Add("from", req.From)
- vals.Add("to", req.To)
- r.URL.RawQuery = vals.Encode()
-
- return nil
-}