| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,67 @@ | ||
| module github.com/hiteshrepo/grpc-loadbalancing | ||
|
|
||
| go 1.19 | ||
|
|
||
| require ( | ||
| github.com/gin-gonic/gin v1.9.0 | ||
| google.golang.org/grpc v1.55.0 | ||
| google.golang.org/protobuf v1.30.0 | ||
| k8s.io/client-go v0.27.1 | ||
| ) | ||
|
|
||
| require ( | ||
| github.com/bytedance/sonic v1.8.8 // indirect | ||
| github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect | ||
| github.com/davecgh/go-spew v1.1.1 // indirect | ||
| github.com/emicklei/go-restful/v3 v3.10.2 // indirect | ||
| github.com/gin-contrib/sse v0.1.0 // indirect | ||
| github.com/go-logr/logr v1.2.4 // indirect | ||
| github.com/go-openapi/jsonpointer v0.19.6 // indirect | ||
| github.com/go-openapi/jsonreference v0.20.2 // indirect | ||
| github.com/go-openapi/swag v0.22.3 // indirect | ||
| github.com/go-playground/locales v0.14.1 // indirect | ||
| github.com/go-playground/universal-translator v0.18.1 // indirect | ||
| github.com/go-playground/validator/v10 v10.13.0 // indirect | ||
| github.com/goccy/go-json v0.10.2 // indirect | ||
| github.com/gogo/protobuf v1.3.2 // indirect | ||
| github.com/golang/protobuf v1.5.3 // indirect | ||
| github.com/google/gnostic v0.6.9 // indirect | ||
| github.com/google/go-cmp v0.5.9 // indirect | ||
| github.com/google/gofuzz v1.2.0 // indirect | ||
| github.com/google/uuid v1.3.0 // indirect | ||
| github.com/imdario/mergo v0.3.15 // indirect | ||
| github.com/josharian/intern v1.0.0 // indirect | ||
| github.com/json-iterator/go v1.1.12 // indirect | ||
| github.com/klauspost/cpuid/v2 v2.2.4 // indirect | ||
| github.com/leodido/go-urn v1.2.4 // indirect | ||
| github.com/mailru/easyjson v0.7.7 // indirect | ||
| github.com/mattn/go-isatty v0.0.18 // indirect | ||
| github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect | ||
| github.com/modern-go/reflect2 v1.0.2 // indirect | ||
| github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect | ||
| github.com/pelletier/go-toml/v2 v2.0.7 // indirect | ||
| github.com/spf13/pflag v1.0.5 // indirect | ||
| github.com/twitchyliquid64/golang-asm v0.15.1 // indirect | ||
| github.com/ugorji/go/codec v1.2.11 // indirect | ||
| golang.org/x/arch v0.3.0 // indirect | ||
| golang.org/x/crypto v0.9.0 // indirect | ||
| golang.org/x/net v0.10.0 // indirect | ||
| golang.org/x/oauth2 v0.8.0 // indirect | ||
| golang.org/x/sys v0.8.0 // indirect | ||
| golang.org/x/term v0.8.0 // indirect | ||
| golang.org/x/text v0.9.0 // indirect | ||
| golang.org/x/time v0.3.0 // indirect | ||
| google.golang.org/appengine v1.6.7 // indirect | ||
| google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect | ||
| gopkg.in/inf.v0 v0.9.1 // indirect | ||
| gopkg.in/yaml.v2 v2.4.0 // indirect | ||
| gopkg.in/yaml.v3 v3.0.1 // indirect | ||
| k8s.io/api v0.27.1 // indirect | ||
| k8s.io/apimachinery v0.27.1 // indirect | ||
| k8s.io/klog/v2 v2.100.1 // indirect | ||
| k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f // indirect | ||
| k8s.io/utils v0.0.0-20230505201702-9f6742963106 // indirect | ||
| sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect | ||
| sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect | ||
| sigs.k8s.io/yaml v1.3.0 // indirect | ||
| ) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,110 @@ | ||
| package greetclient | ||
|
|
||
| import ( | ||
| "context" | ||
| "fmt" | ||
| "log" | ||
| "net/http" | ||
| "os" | ||
|
|
||
| "github.com/gin-gonic/gin" | ||
| "github.com/hiteshrepo/grpc-loadbalancing/internal/pkg/proto" | ||
| "google.golang.org/grpc" | ||
| ) | ||
|
|
||
| type App struct { | ||
| client proto.GreetServiceClient | ||
| conn *grpc.ClientConn | ||
| } | ||
|
|
||
| type GreetingRequest struct { | ||
| FirstName string `json:"first_name"` | ||
| LastName string `json:"last_name"` | ||
| } | ||
|
|
||
| func (a *App) Start() { | ||
| err := a.setupGreetClient() | ||
| if err != nil { | ||
| log.Printf("could not setup greet client: %v", err) | ||
| return | ||
| } | ||
|
|
||
| fmt.Println("Starting gateway") | ||
|
|
||
| router := gin.Default() | ||
| router.POST("/greet", a.greet) | ||
|
|
||
| port := "9091" | ||
| if len(os.Getenv("GATEWAY_PORT")) > 0 { | ||
| port = os.Getenv("GATEWAY_PORT") | ||
| } | ||
|
|
||
| fmt.Println("Starting REST Gateway") | ||
|
|
||
| router.Run(fmt.Sprintf("0.0.0.0:%s", port)) | ||
| } | ||
|
|
||
| func (a *App) setupGreetClient() error { | ||
| var err error | ||
|
|
||
| fmt.Println("Starting greet client") | ||
|
|
||
| opts := grpc.WithInsecure() | ||
| serverHost := "localhost" | ||
| serverPort := "50051" | ||
|
|
||
| if host, ok := os.LookupEnv("GRPC_SERVER_HOST"); ok { | ||
| serverHost = host | ||
| } | ||
|
|
||
| if port, ok := os.LookupEnv("GRPC_SERVER_PORT"); ok { | ||
| serverPort = port | ||
| } | ||
|
|
||
| servAddr := fmt.Sprintf("%s:%s", serverHost, serverPort) | ||
|
|
||
| fmt.Println("dialing", servAddr) | ||
|
|
||
| a.conn, err = grpc.Dial( | ||
| servAddr, | ||
| opts, | ||
| ) | ||
| if err != nil { | ||
| log.Printf("could not connect: %v", err) | ||
| return err | ||
| } | ||
|
|
||
| a.client = proto.NewGreetServiceClient(a.conn) | ||
|
|
||
| return nil | ||
| } | ||
|
|
||
| func (a *App) Shutdown() { | ||
| a.conn.Close() | ||
| } | ||
|
|
||
| func (a *App) doUnary(firstName, lastName string) string { | ||
| req := &proto.GreetingRequest{ | ||
| Greeting: &proto.Greeting{ | ||
| FirstName: firstName, | ||
| LastName: lastName, | ||
| }, | ||
| } | ||
| res, err := a.client.Greet(context.Background(), req) | ||
| if err != nil { | ||
| log.Fatalf("error while calling greet rpc : %v", err) | ||
| } | ||
| return fmt.Sprintf("reponse from Greet rpc: %v", res.Result) | ||
| } | ||
|
|
||
| func (a *App) greet(c *gin.Context) { | ||
| fmt.Println("got request - REST Gateway") | ||
|
|
||
| var gr GreetingRequest | ||
| if err := c.BindJSON(&gr); err != nil { | ||
| return | ||
| } | ||
|
|
||
| resp := a.doUnary(gr.FirstName, gr.LastName) | ||
| c.String(http.StatusOK, resp) | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,62 @@ | ||
| package greetserver | ||
|
|
||
| import ( | ||
| "context" | ||
| "fmt" | ||
| "log" | ||
| "net" | ||
| "os" | ||
|
|
||
| "github.com/hiteshrepo/grpc-loadbalancing/internal/pkg/proto" | ||
| "google.golang.org/grpc" | ||
| ) | ||
|
|
||
| type App struct { | ||
| proto.UnimplementedGreetServiceServer | ||
| } | ||
|
|
||
| func (a *App) Start() { | ||
| fmt.Println("Starting greet server") | ||
|
|
||
| port := "50051" | ||
| if len(os.Getenv("GRPC_PORT")) > 0 { | ||
| port = os.Getenv("GRPC_PORT") | ||
| } | ||
|
|
||
| servAddr := fmt.Sprintf("0.0.0.0:%s", port) | ||
|
|
||
| lis, err := net.Listen("tcp", servAddr) | ||
| if err != nil { | ||
| log.Fatalf("Failed to listen: %v", err) | ||
| } | ||
| opts := []grpc.ServerOption{} | ||
| s := grpc.NewServer(opts...) | ||
| proto.RegisterGreetServiceServer(s, &App{}) | ||
| if err := s.Serve(lis); err != nil { | ||
| log.Fatalf("Failed to serve: %v", err) | ||
| } | ||
| } | ||
|
|
||
| func (a *App) Shutdown() { | ||
|
|
||
| } | ||
|
|
||
| func (a *App) Greet(_ context.Context, req *proto.GreetingRequest) (*proto.GreetingResponse, error) { | ||
| firstName := req.GetGreeting().GetFirstName() | ||
| lastName := req.GetGreeting().GetLastName() | ||
|
|
||
| var podIp string | ||
| var podName string | ||
| if len(os.Getenv("POD_IP")) > 0 { | ||
| podIp = os.Getenv("POD_IP") | ||
| } | ||
|
|
||
| if len(os.Getenv("POD_NAME")) > 0 { | ||
| podName = os.Getenv("POD_NAME") | ||
| } | ||
|
|
||
| result := fmt.Sprintf("Hello, %s %s from pod: name(%s), ip(%s).", firstName, lastName, podName, podIp) | ||
| return &proto.GreetingResponse{ | ||
| Result: result, | ||
| }, nil | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| syntax = "proto3"; | ||
|
|
||
| package greet; | ||
| option go_package="./proto"; | ||
|
|
||
| message Greeting { | ||
| string first_name = 1; | ||
| string last_name = 2; | ||
| } | ||
|
|
||
| message GreetingRequest { | ||
| Greeting greeting = 1; | ||
| } | ||
|
|
||
| message GreetingResponse { | ||
| string Result = 1; | ||
| } | ||
|
|
||
| service GreetService{ | ||
| // Unary | ||
| rpc Greet(GreetingRequest) returns (GreetingResponse) {}; | ||
| } |