productcatalogservice: implementation
This commit is contained in:
parent
9af0ca0eda
commit
914f07f307
4 changed files with 2556 additions and 0 deletions
6
src/productcatalogservice/genproto.sh
Executable file
6
src/productcatalogservice/genproto.sh
Executable file
|
@ -0,0 +1,6 @@
|
||||||
|
#!/bin/bash -e
|
||||||
|
|
||||||
|
PATH=$PATH:$GOPATH/bin
|
||||||
|
protodir=../../pb
|
||||||
|
|
||||||
|
protoc --go_out=plugins=grpc:genproto -I $protodir $protodir/demo.proto
|
2433
src/productcatalogservice/genproto/demo.pb.go
Normal file
2433
src/productcatalogservice/genproto/demo.pb.go
Normal file
File diff suppressed because it is too large
Load diff
66
src/productcatalogservice/server.go
Normal file
66
src/productcatalogservice/server.go
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"net"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
pb "./genproto"
|
||||||
|
"google.golang.org/grpc"
|
||||||
|
"google.golang.org/grpc/codes"
|
||||||
|
"google.golang.org/grpc/status"
|
||||||
|
)
|
||||||
|
|
||||||
|
var port = flag.Int("port", 3550, "port to listen at")
|
||||||
|
|
||||||
|
var catalog = []*pb.Product{
|
||||||
|
{Id: 1, Name: "shirt", Description: "nice shirt", Picture: "picture1", PriceUsd: &pb.MoneyAmount{Decimal: 53}},
|
||||||
|
{Id: 2, Name: "pants", Description: "nice pants", Picture: "picture2", PriceUsd: &pb.MoneyAmount{Decimal: 81}},
|
||||||
|
{Id: 3, Name: "hat", Description: "nice hat", Picture: "picture3", PriceUsd: &pb.MoneyAmount{Decimal: 20}},
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
flag.Parse()
|
||||||
|
run(*port)
|
||||||
|
select {}
|
||||||
|
}
|
||||||
|
|
||||||
|
func run(port int) string {
|
||||||
|
l, err := net.Listen("tcp", fmt.Sprintf(":%d", port))
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
srv := grpc.NewServer()
|
||||||
|
pb.RegisterProductCatalogServiceServer(srv, &productCatalog{})
|
||||||
|
go srv.Serve(l)
|
||||||
|
return l.Addr().String()
|
||||||
|
}
|
||||||
|
|
||||||
|
type productCatalog struct{}
|
||||||
|
|
||||||
|
func (p *productCatalog) ListProducts(context.Context, *pb.Empty) (*pb.ListProductsResponse, error) {
|
||||||
|
return &pb.ListProductsResponse{Products: catalog}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *productCatalog) GetProduct(ctx context.Context, req *pb.GetProductRequest) (*pb.Product, error) {
|
||||||
|
for _, p := range catalog {
|
||||||
|
if req.Id == p.Id {
|
||||||
|
return p, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, status.Errorf(codes.NotFound, "no product with ID %d", req.Id)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *productCatalog) SearchProducts(ctx context.Context, req *pb.SearchProductsRequest) (*pb.SearchProductsResponse, error) {
|
||||||
|
// Intepret query as a substring match in name or description.
|
||||||
|
var ps []*pb.Product
|
||||||
|
for _, p := range catalog {
|
||||||
|
if strings.Contains(p.Name, req.Query) || strings.Contains(p.Description, req.Query) {
|
||||||
|
ps = append(ps, p)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return &pb.SearchProductsResponse{Results: ps}, nil
|
||||||
|
}
|
51
src/productcatalogservice/server_test.go
Normal file
51
src/productcatalogservice/server_test.go
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
pb "./genproto"
|
||||||
|
"github.com/golang/protobuf/proto"
|
||||||
|
"github.com/google/go-cmp/cmp"
|
||||||
|
"google.golang.org/grpc"
|
||||||
|
"google.golang.org/grpc/codes"
|
||||||
|
"google.golang.org/grpc/status"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestServer(t *testing.T) {
|
||||||
|
ctx := context.Background()
|
||||||
|
addr := run(0)
|
||||||
|
conn, err := grpc.Dial(addr, grpc.WithInsecure())
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
defer conn.Close()
|
||||||
|
client := pb.NewProductCatalogServiceClient(conn)
|
||||||
|
res, err := client.ListProducts(ctx, &pb.Empty{})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if diff := cmp.Diff(res.Products, catalog, cmp.Comparer(proto.Equal)); diff != "" {
|
||||||
|
t.Error(diff)
|
||||||
|
}
|
||||||
|
|
||||||
|
got, err := client.GetProduct(ctx, &pb.GetProductRequest{Id: 2})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if want := catalog[1]; !proto.Equal(got, want) {
|
||||||
|
t.Errorf("got %v, want %v", got, want)
|
||||||
|
}
|
||||||
|
_, err = client.GetProduct(ctx, &pb.GetProductRequest{Id: -1})
|
||||||
|
if got, want := status.Code(err), codes.NotFound; got != want {
|
||||||
|
t.Errorf("got %s, want %s", got, want)
|
||||||
|
}
|
||||||
|
|
||||||
|
sres, err := client.SearchProducts(ctx, &pb.SearchProductsRequest{Query: "nice"})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if diff := cmp.Diff(sres.Results, catalog, cmp.Comparer(proto.Equal)); diff != "" {
|
||||||
|
t.Error(diff)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue