/
main.go
115 lines (92 loc) · 2.96 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
// shippy-service-consignment/main.go
package main
import (
"fmt"
"log"
"sync"
// Import the generated protobuf code
"context"
pb "github.com/corso75/microservice-in-golang/shippy-service-consignment/proto/consignment"
vesselProto "github.com/corso75/microservice-in-golang/shippy-service-vessel/proto/vessel"
"github.com/micro/go-micro"
)
const (
port = ":50051"
)
type repository interface {
Create(*pb.Consignment) (*pb.Consignment, error)
GetAll() []*pb.Consignment
}
// Repository - Dummy repository, this simulates the use of a datastore
// of some kind. We'll replace this with a real implementation later on.
type Repository struct {
mu sync.RWMutex
consignments []*pb.Consignment
}
// Create a new consignment
func (repo *Repository) Create(consignment *pb.Consignment) (*pb.Consignment, error) {
repo.mu.Lock()
updated := append(repo.consignments, consignment)
repo.consignments = updated
repo.mu.Unlock()
return consignment, nil
}
// GetAll consignments
func (repo *Repository) GetAll() []*pb.Consignment {
return repo.consignments
}
// Service should implement all of the methods to satisfy the service
// we defined in our protobuf definition. You can check the interface
// in the generated code itself for the exact method signatures etc
// to give you a better idea.
type service struct {
repo repository
vesselClient vesselProto.VesselServiceClient
}
// CreateConsignment - we created just one method on our service,
// which is a create method, which takes a context and a request as an
// argument, these are handled by the gRPC server.
func (s *service) CreateConsignment(ctx context.Context, req *pb.Consignment, res *pb.Response) error {
// Here we call a client instance of our vessel service with our consignment weight,
// and the amount of containers as the capacity value
vesselResponse, err := s.vesselClient.FindAvailable(context.Background(), &vesselProto.Specification{
MaxWeight: req.Weight,
Capacity: int32(len(req.Containers)),
})
log.Printf("Found vessel: %s \n", vesselResponse.Vessel.Name)
if err != nil {
return err
}
// We set the VesselId as the vessel we got back from our
// vessel service
req.VesselId = vesselResponse.Vessel.Id
// Save our consignment
consignment, err := s.repo.Create(req)
if err != nil {
return err
}
res.Created = true
res.Consignment = consignment
return nil
}
// GetConsignments -
func (s *service) GetConsignments(ctx context.Context, req *pb.GetRequest, res *pb.Response) error {
consignments := s.repo.GetAll()
res.Consignments = consignments
return nil
}
func main() {
repo := &Repository{}
// Set-up micro instance
srv := micro.NewService(
micro.Name("shippy.service.consignment"),
)
srv.Init()
vesselClient := vesselProto.NewVesselServiceClient("shippy.service.vessel", srv.Client())
// Register handlers
pb.RegisterShippingServiceHandler(srv.Server(), &service{repo, vesselClient})
// Run the server
if err := srv.Run(); err != nil {
fmt.Println(err)
}
}