From c3058431057444affa736d4fbd1c3299784bc8a6 Mon Sep 17 00:00:00 2001 From: JayKaku Date: Mon, 20 Nov 2023 16:18:07 +0530 Subject: [PATCH 1/5] restructured api to api/http, api/grpc, pkg http --- cmd/podinfo/main.go | 8 ++++---- pkg/{ => api}/grpc/server.go | 0 pkg/api/{ => http}/cache.go | 2 +- pkg/api/{ => http}/chunked.go | 2 +- pkg/api/{ => http}/chunked_test.go | 2 +- pkg/api/{ => http}/configs.go | 2 +- pkg/api/{ => http}/delay.go | 2 +- pkg/api/{ => http}/delay_test.go | 2 +- pkg/api/{ => http}/docs/docs.go | 0 pkg/api/{ => http}/docs/swagger.json | 0 pkg/api/{ => http}/docs/swagger.yaml | 0 pkg/api/{ => http}/echo.go | 2 +- pkg/api/{ => http}/echo_test.go | 2 +- pkg/api/{ => http}/echows.go | 2 +- pkg/api/{ => http}/env.go | 2 +- pkg/api/{ => http}/env_test.go | 2 +- pkg/api/{ => http}/headers.go | 2 +- pkg/api/{ => http}/headers_test.go | 2 +- pkg/api/{ => http}/health.go | 2 +- pkg/api/{ => http}/health_test.go | 2 +- pkg/api/{ => http}/http.go | 2 +- pkg/api/{ => http}/index.go | 2 +- pkg/api/{ => http}/info.go | 2 +- pkg/api/{ => http}/info_test.go | 2 +- pkg/api/{ => http}/logging.go | 2 +- pkg/api/{ => http}/metrics.go | 2 +- pkg/api/{ => http}/mock.go | 2 +- pkg/api/{ => http}/panic.go | 2 +- pkg/api/{ => http}/server.go | 4 ++-- pkg/api/{ => http}/status.go | 2 +- pkg/api/{ => http}/status_test.go | 2 +- pkg/api/{ => http}/store.go | 2 +- pkg/api/{ => http}/token.go | 2 +- pkg/api/{ => http}/token_test.go | 2 +- pkg/api/{ => http}/tracer.go | 2 +- pkg/api/{ => http}/version.go | 2 +- pkg/api/{ => http}/version_test.go | 2 +- 37 files changed, 37 insertions(+), 37 deletions(-) rename pkg/{ => api}/grpc/server.go (100%) rename pkg/api/{ => http}/cache.go (99%) rename pkg/api/{ => http}/chunked.go (98%) rename pkg/api/{ => http}/chunked_test.go (98%) rename pkg/api/{ => http}/configs.go (96%) rename pkg/api/{ => http}/delay.go (99%) rename pkg/api/{ => http}/delay_test.go (98%) rename pkg/api/{ => http}/docs/docs.go (100%) rename pkg/api/{ => http}/docs/swagger.json (100%) rename pkg/api/{ => http}/docs/swagger.yaml (100%) rename pkg/api/{ => http}/echo.go (99%) rename pkg/api/{ => http}/echo_test.go (99%) rename pkg/api/{ => http}/echows.go (99%) rename pkg/api/{ => http}/env.go (97%) rename pkg/api/{ => http}/env_test.go (98%) rename pkg/api/{ => http}/headers.go (97%) rename pkg/api/{ => http}/headers_test.go (98%) rename pkg/api/{ => http}/health.go (99%) rename pkg/api/{ => http}/health_test.go (98%) rename pkg/api/{ => http}/http.go (99%) rename pkg/api/{ => http}/index.go (98%) rename pkg/api/{ => http}/info.go (99%) rename pkg/api/{ => http}/info_test.go (98%) rename pkg/api/{ => http}/logging.go (97%) rename pkg/api/{ => http}/metrics.go (99%) rename pkg/api/{ => http}/mock.go (98%) rename pkg/api/{ => http}/panic.go (95%) rename pkg/api/{ => http}/server.go (99%) rename pkg/api/{ => http}/status.go (98%) rename pkg/api/{ => http}/status_test.go (97%) rename pkg/api/{ => http}/store.go (99%) rename pkg/api/{ => http}/token.go (99%) rename pkg/api/{ => http}/token_test.go (98%) rename pkg/api/{ => http}/tracer.go (99%) rename pkg/api/{ => http}/version.go (97%) rename pkg/api/{ => http}/version_test.go (98%) diff --git a/cmd/podinfo/main.go b/cmd/podinfo/main.go index 08a6be62..6d7aa265 100644 --- a/cmd/podinfo/main.go +++ b/cmd/podinfo/main.go @@ -13,8 +13,8 @@ import ( "go.uber.org/zap" "go.uber.org/zap/zapcore" - "github.com/stefanprodan/podinfo/pkg/api" - "github.com/stefanprodan/podinfo/pkg/grpc" + "github.com/stefanprodan/podinfo/pkg/api/grpc" + "github.com/stefanprodan/podinfo/pkg/api/http" "github.com/stefanprodan/podinfo/pkg/signals" "github.com/stefanprodan/podinfo/pkg/version" go_grpc "google.golang.org/grpc" @@ -142,7 +142,7 @@ func main() { } // load HTTP server config - var srvCfg api.Config + var srvCfg http.Config if err := viper.Unmarshal(&srvCfg); err != nil { logger.Panic("config unmarshal failed", zap.Error(err)) } @@ -155,7 +155,7 @@ func main() { ) // start HTTP server - srv, _ := api.NewServer(&srvCfg, logger) + srv, _ := http.NewServer(&srvCfg, logger) httpServer, httpsServer, healthy, ready := srv.ListenAndServe() // graceful shutdown diff --git a/pkg/grpc/server.go b/pkg/api/grpc/server.go similarity index 100% rename from pkg/grpc/server.go rename to pkg/api/grpc/server.go diff --git a/pkg/api/cache.go b/pkg/api/http/cache.go similarity index 99% rename from pkg/api/cache.go rename to pkg/api/http/cache.go index ac678737..228e858d 100644 --- a/pkg/api/cache.go +++ b/pkg/api/http/cache.go @@ -1,4 +1,4 @@ -package api +package http import ( "fmt" diff --git a/pkg/api/chunked.go b/pkg/api/http/chunked.go similarity index 98% rename from pkg/api/chunked.go rename to pkg/api/http/chunked.go index 0bf668e9..f8b7b69d 100644 --- a/pkg/api/chunked.go +++ b/pkg/api/http/chunked.go @@ -1,4 +1,4 @@ -package api +package http import ( "math/rand" diff --git a/pkg/api/chunked_test.go b/pkg/api/http/chunked_test.go similarity index 98% rename from pkg/api/chunked_test.go rename to pkg/api/http/chunked_test.go index 090dd2fe..167b3b17 100644 --- a/pkg/api/chunked_test.go +++ b/pkg/api/http/chunked_test.go @@ -1,4 +1,4 @@ -package api +package http import ( "net/http" diff --git a/pkg/api/configs.go b/pkg/api/http/configs.go similarity index 96% rename from pkg/api/configs.go rename to pkg/api/http/configs.go index 9b084153..fb8bbebc 100644 --- a/pkg/api/configs.go +++ b/pkg/api/http/configs.go @@ -1,4 +1,4 @@ -package api +package http import "net/http" diff --git a/pkg/api/delay.go b/pkg/api/http/delay.go similarity index 99% rename from pkg/api/delay.go rename to pkg/api/http/delay.go index 6655cf75..19893b05 100644 --- a/pkg/api/delay.go +++ b/pkg/api/http/delay.go @@ -1,4 +1,4 @@ -package api +package http import ( "math/rand" diff --git a/pkg/api/delay_test.go b/pkg/api/http/delay_test.go similarity index 98% rename from pkg/api/delay_test.go rename to pkg/api/http/delay_test.go index 88d5ab71..9309692d 100644 --- a/pkg/api/delay_test.go +++ b/pkg/api/http/delay_test.go @@ -1,4 +1,4 @@ -package api +package http import ( "net/http" diff --git a/pkg/api/docs/docs.go b/pkg/api/http/docs/docs.go similarity index 100% rename from pkg/api/docs/docs.go rename to pkg/api/http/docs/docs.go diff --git a/pkg/api/docs/swagger.json b/pkg/api/http/docs/swagger.json similarity index 100% rename from pkg/api/docs/swagger.json rename to pkg/api/http/docs/swagger.json diff --git a/pkg/api/docs/swagger.yaml b/pkg/api/http/docs/swagger.yaml similarity index 100% rename from pkg/api/docs/swagger.yaml rename to pkg/api/http/docs/swagger.yaml diff --git a/pkg/api/echo.go b/pkg/api/http/echo.go similarity index 99% rename from pkg/api/echo.go rename to pkg/api/http/echo.go index 5bf7d8ff..e2447ecf 100644 --- a/pkg/api/echo.go +++ b/pkg/api/http/echo.go @@ -1,4 +1,4 @@ -package api +package http import ( "bytes" diff --git a/pkg/api/echo_test.go b/pkg/api/http/echo_test.go similarity index 99% rename from pkg/api/echo_test.go rename to pkg/api/http/echo_test.go index 74e472a0..056e3b99 100644 --- a/pkg/api/echo_test.go +++ b/pkg/api/http/echo_test.go @@ -1,4 +1,4 @@ -package api +package http import ( "net/http" diff --git a/pkg/api/echows.go b/pkg/api/http/echows.go similarity index 99% rename from pkg/api/echows.go rename to pkg/api/http/echows.go index bcf693c3..d92abcbd 100644 --- a/pkg/api/echows.go +++ b/pkg/api/http/echows.go @@ -1,4 +1,4 @@ -package api +package http import ( "net/http" diff --git a/pkg/api/env.go b/pkg/api/http/env.go similarity index 97% rename from pkg/api/env.go rename to pkg/api/http/env.go index c9951ccf..e664bc37 100644 --- a/pkg/api/env.go +++ b/pkg/api/http/env.go @@ -1,4 +1,4 @@ -package api +package http import ( "net/http" diff --git a/pkg/api/env_test.go b/pkg/api/http/env_test.go similarity index 98% rename from pkg/api/env_test.go rename to pkg/api/http/env_test.go index 0d53ce68..79c08bcf 100644 --- a/pkg/api/env_test.go +++ b/pkg/api/http/env_test.go @@ -1,4 +1,4 @@ -package api +package http import ( "net/http" diff --git a/pkg/api/headers.go b/pkg/api/http/headers.go similarity index 97% rename from pkg/api/headers.go rename to pkg/api/http/headers.go index 2cc995a9..311108f5 100644 --- a/pkg/api/headers.go +++ b/pkg/api/http/headers.go @@ -1,4 +1,4 @@ -package api +package http import ( "net/http" diff --git a/pkg/api/headers_test.go b/pkg/api/http/headers_test.go similarity index 98% rename from pkg/api/headers_test.go rename to pkg/api/http/headers_test.go index 8a7b37fc..59cf8530 100644 --- a/pkg/api/headers_test.go +++ b/pkg/api/http/headers_test.go @@ -1,4 +1,4 @@ -package api +package http import ( "fmt" diff --git a/pkg/api/health.go b/pkg/api/http/health.go similarity index 99% rename from pkg/api/health.go rename to pkg/api/http/health.go index 61742ec5..a1631c4a 100644 --- a/pkg/api/health.go +++ b/pkg/api/http/health.go @@ -1,4 +1,4 @@ -package api +package http import ( "net/http" diff --git a/pkg/api/health_test.go b/pkg/api/http/health_test.go similarity index 98% rename from pkg/api/health_test.go rename to pkg/api/http/health_test.go index 646ff051..d34625d4 100644 --- a/pkg/api/health_test.go +++ b/pkg/api/http/health_test.go @@ -1,4 +1,4 @@ -package api +package http import ( "net/http" diff --git a/pkg/api/http.go b/pkg/api/http/http.go similarity index 99% rename from pkg/api/http.go rename to pkg/api/http/http.go index 0061bb79..360a525c 100644 --- a/pkg/api/http.go +++ b/pkg/api/http/http.go @@ -1,4 +1,4 @@ -package api +package http import ( "bytes" diff --git a/pkg/api/index.go b/pkg/api/http/index.go similarity index 98% rename from pkg/api/index.go rename to pkg/api/http/index.go index a501dea8..15855762 100644 --- a/pkg/api/index.go +++ b/pkg/api/http/index.go @@ -1,4 +1,4 @@ -package api +package http import ( "html/template" diff --git a/pkg/api/info.go b/pkg/api/http/info.go similarity index 99% rename from pkg/api/info.go rename to pkg/api/http/info.go index 2cd4f473..c4e82371 100644 --- a/pkg/api/info.go +++ b/pkg/api/http/info.go @@ -1,4 +1,4 @@ -package api +package http import ( "net/http" diff --git a/pkg/api/info_test.go b/pkg/api/http/info_test.go similarity index 98% rename from pkg/api/info_test.go rename to pkg/api/http/info_test.go index c076be91..e1883da2 100644 --- a/pkg/api/info_test.go +++ b/pkg/api/http/info_test.go @@ -1,4 +1,4 @@ -package api +package http import ( "net/http" diff --git a/pkg/api/logging.go b/pkg/api/http/logging.go similarity index 97% rename from pkg/api/logging.go rename to pkg/api/http/logging.go index 47e5c2b5..c67b4123 100644 --- a/pkg/api/logging.go +++ b/pkg/api/http/logging.go @@ -1,4 +1,4 @@ -package api +package http import ( "net/http" diff --git a/pkg/api/metrics.go b/pkg/api/http/metrics.go similarity index 99% rename from pkg/api/metrics.go rename to pkg/api/http/metrics.go index c45c86fe..f85ae41f 100644 --- a/pkg/api/metrics.go +++ b/pkg/api/http/metrics.go @@ -1,4 +1,4 @@ -package api +package http import ( "bufio" diff --git a/pkg/api/mock.go b/pkg/api/http/mock.go similarity index 98% rename from pkg/api/mock.go rename to pkg/api/http/mock.go index 75629194..244649c2 100644 --- a/pkg/api/mock.go +++ b/pkg/api/http/mock.go @@ -1,4 +1,4 @@ -package api +package http import ( "time" diff --git a/pkg/api/panic.go b/pkg/api/http/panic.go similarity index 95% rename from pkg/api/panic.go rename to pkg/api/http/panic.go index 3ca5fc38..fbf151db 100644 --- a/pkg/api/panic.go +++ b/pkg/api/http/panic.go @@ -1,4 +1,4 @@ -package api +package http import ( "net/http" diff --git a/pkg/api/server.go b/pkg/api/http/server.go similarity index 99% rename from pkg/api/server.go rename to pkg/api/http/server.go index b4224f45..4eabe32d 100644 --- a/pkg/api/server.go +++ b/pkg/api/http/server.go @@ -1,4 +1,4 @@ -package api +package http import ( "context" @@ -14,7 +14,7 @@ import ( "github.com/gomodule/redigo/redis" "github.com/gorilla/mux" "github.com/prometheus/client_golang/prometheus/promhttp" - _ "github.com/stefanprodan/podinfo/pkg/api/docs" + _ "github.com/stefanprodan/podinfo/pkg/api/http/docs" "github.com/stefanprodan/podinfo/pkg/fscache" httpSwagger "github.com/swaggo/http-swagger" "github.com/swaggo/swag" diff --git a/pkg/api/status.go b/pkg/api/http/status.go similarity index 98% rename from pkg/api/status.go rename to pkg/api/http/status.go index e9e33ae0..1ccd4d04 100644 --- a/pkg/api/status.go +++ b/pkg/api/http/status.go @@ -1,4 +1,4 @@ -package api +package http import ( "net/http" diff --git a/pkg/api/status_test.go b/pkg/api/http/status_test.go similarity index 97% rename from pkg/api/status_test.go rename to pkg/api/http/status_test.go index f85f2b2c..3c8fda9b 100644 --- a/pkg/api/status_test.go +++ b/pkg/api/http/status_test.go @@ -1,4 +1,4 @@ -package api +package http import ( "net/http" diff --git a/pkg/api/store.go b/pkg/api/http/store.go similarity index 99% rename from pkg/api/store.go rename to pkg/api/http/store.go index a97db5e8..307fb8b2 100644 --- a/pkg/api/store.go +++ b/pkg/api/http/store.go @@ -1,4 +1,4 @@ -package api +package http import ( "crypto/sha1" diff --git a/pkg/api/token.go b/pkg/api/http/token.go similarity index 99% rename from pkg/api/token.go rename to pkg/api/http/token.go index c3918603..cb1cbb7f 100644 --- a/pkg/api/token.go +++ b/pkg/api/http/token.go @@ -1,4 +1,4 @@ -package api +package http import ( "fmt" diff --git a/pkg/api/token_test.go b/pkg/api/http/token_test.go similarity index 98% rename from pkg/api/token_test.go rename to pkg/api/http/token_test.go index a82824b7..f8d194eb 100644 --- a/pkg/api/token_test.go +++ b/pkg/api/http/token_test.go @@ -1,4 +1,4 @@ -package api +package http import ( "encoding/json" diff --git a/pkg/api/tracer.go b/pkg/api/http/tracer.go similarity index 99% rename from pkg/api/tracer.go rename to pkg/api/http/tracer.go index ec7c208b..8d9fbdae 100644 --- a/pkg/api/tracer.go +++ b/pkg/api/http/tracer.go @@ -1,4 +1,4 @@ -package api +package http import ( "context" diff --git a/pkg/api/version.go b/pkg/api/http/version.go similarity index 97% rename from pkg/api/version.go rename to pkg/api/http/version.go index 037691e7..82823476 100644 --- a/pkg/api/version.go +++ b/pkg/api/http/version.go @@ -1,4 +1,4 @@ -package api +package http import ( "net/http" diff --git a/pkg/api/version_test.go b/pkg/api/http/version_test.go similarity index 98% rename from pkg/api/version_test.go rename to pkg/api/http/version_test.go index e7ee256e..eba9fa71 100644 --- a/pkg/api/version_test.go +++ b/pkg/api/http/version_test.go @@ -1,4 +1,4 @@ -package api +package http import ( "fmt" From 22097353d2f5229470c280737e5ad75d174487d4 Mon Sep 17 00:00:00 2001 From: Jay Kaku Date: Mon, 20 Nov 2023 16:46:42 +0530 Subject: [PATCH 2/5] Feature grpc version echo api (#3) added grpc verion and echo apis --------- Co-authored-by: Prashant Dwivedi --- cmd/podinfo/main.go | 2 + pkg/api/grpc/echo.go | 17 ++ pkg/api/grpc/echo/echo.pb.go | 146 ++++++++++++++++ pkg/api/grpc/echo/echo.proto | 14 ++ pkg/api/grpc/echo/echo_grpc.pb.go | 109 ++++++++++++ pkg/api/grpc/echo_test.go | 69 ++++++++ pkg/api/grpc/mock_grpc.go | 31 ++++ pkg/api/grpc/panic.go | 24 +++ pkg/api/grpc/panic/panic.pb.go | 189 +++++++++++++++++++++ pkg/api/grpc/panic/panic.proto | 17 ++ pkg/api/grpc/panic/panic_grpc.pb.go | 105 ++++++++++++ pkg/api/grpc/server.go | 43 +++++ pkg/api/grpc/version.go | 21 +++ pkg/api/grpc/version/version.pb.go | 211 ++++++++++++++++++++++++ pkg/api/grpc/version/version.proto | 18 ++ pkg/api/grpc/version/version_grpc.pb.go | 105 ++++++++++++ pkg/api/grpc/version_test.go | 72 ++++++++ 17 files changed, 1193 insertions(+) create mode 100644 pkg/api/grpc/echo.go create mode 100644 pkg/api/grpc/echo/echo.pb.go create mode 100644 pkg/api/grpc/echo/echo.proto create mode 100644 pkg/api/grpc/echo/echo_grpc.pb.go create mode 100644 pkg/api/grpc/echo_test.go create mode 100644 pkg/api/grpc/mock_grpc.go create mode 100644 pkg/api/grpc/panic.go create mode 100644 pkg/api/grpc/panic/panic.pb.go create mode 100644 pkg/api/grpc/panic/panic.proto create mode 100644 pkg/api/grpc/panic/panic_grpc.pb.go create mode 100644 pkg/api/grpc/version.go create mode 100644 pkg/api/grpc/version/version.pb.go create mode 100644 pkg/api/grpc/version/version.proto create mode 100644 pkg/api/grpc/version/version_grpc.pb.go create mode 100644 pkg/api/grpc/version_test.go diff --git a/cmd/podinfo/main.go b/cmd/podinfo/main.go index 6d7aa265..f05a6de7 100644 --- a/cmd/podinfo/main.go +++ b/cmd/podinfo/main.go @@ -138,6 +138,8 @@ func main() { var grpcServer *go_grpc.Server if grpcCfg.Port > 0 { grpcSrv, _ := grpc.NewServer(&grpcCfg, logger) + //grpcinfoSrv, _ := grpc.NewInfoServer(&grpcCfg) + grpcServer = grpcSrv.ListenAndServe() } diff --git a/pkg/api/grpc/echo.go b/pkg/api/grpc/echo.go new file mode 100644 index 00000000..0d54e6c8 --- /dev/null +++ b/pkg/api/grpc/echo.go @@ -0,0 +1,17 @@ +package grpc + +import ( + "context" + "log" + + "github.com/stefanprodan/podinfo/pkg/api/grpc/echo" +) + +type echoServer struct { + echo.UnimplementedEchoServiceServer +} + +func (s *echoServer) Echo (ctx context.Context, message *echo.Message) (*echo.Message, error){ + log.Printf("Received message body from client: %s", message.Body) + return &echo.Message {Body: message.Body}, nil +} diff --git a/pkg/api/grpc/echo/echo.pb.go b/pkg/api/grpc/echo/echo.pb.go new file mode 100644 index 00000000..b132476d --- /dev/null +++ b/pkg/api/grpc/echo/echo.pb.go @@ -0,0 +1,146 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.26.0 +// protoc v4.24.3 +// source: echo/echo.proto + +package echo + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type Message struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Body string `protobuf:"bytes,1,opt,name=body,proto3" json:"body,omitempty"` +} + +func (x *Message) Reset() { + *x = Message{} + if protoimpl.UnsafeEnabled { + mi := &file_echo_echo_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Message) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Message) ProtoMessage() {} + +func (x *Message) ProtoReflect() protoreflect.Message { + mi := &file_echo_echo_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Message.ProtoReflect.Descriptor instead. +func (*Message) Descriptor() ([]byte, []int) { + return file_echo_echo_proto_rawDescGZIP(), []int{0} +} + +func (x *Message) GetBody() string { + if x != nil { + return x.Body + } + return "" +} + +var File_echo_echo_proto protoreflect.FileDescriptor + +var file_echo_echo_proto_rawDesc = []byte{ + 0x0a, 0x0f, 0x65, 0x63, 0x68, 0x6f, 0x2f, 0x65, 0x63, 0x68, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x12, 0x04, 0x65, 0x63, 0x68, 0x6f, 0x22, 0x1d, 0x0a, 0x07, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x32, 0x35, 0x0a, 0x0b, 0x45, 0x63, 0x68, 0x6f, 0x53, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x26, 0x0a, 0x04, 0x45, 0x63, 0x68, 0x6f, 0x12, 0x0d, 0x2e, + 0x65, 0x63, 0x68, 0x6f, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x0d, 0x2e, 0x65, + 0x63, 0x68, 0x6f, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x42, 0x08, 0x5a, + 0x06, 0x2e, 0x2f, 0x65, 0x63, 0x68, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_echo_echo_proto_rawDescOnce sync.Once + file_echo_echo_proto_rawDescData = file_echo_echo_proto_rawDesc +) + +func file_echo_echo_proto_rawDescGZIP() []byte { + file_echo_echo_proto_rawDescOnce.Do(func() { + file_echo_echo_proto_rawDescData = protoimpl.X.CompressGZIP(file_echo_echo_proto_rawDescData) + }) + return file_echo_echo_proto_rawDescData +} + +var file_echo_echo_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_echo_echo_proto_goTypes = []interface{}{ + (*Message)(nil), // 0: echo.Message +} +var file_echo_echo_proto_depIdxs = []int32{ + 0, // 0: echo.EchoService.Echo:input_type -> echo.Message + 0, // 1: echo.EchoService.Echo:output_type -> echo.Message + 1, // [1:2] is the sub-list for method output_type + 0, // [0:1] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_echo_echo_proto_init() } +func file_echo_echo_proto_init() { + if File_echo_echo_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_echo_echo_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Message); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_echo_echo_proto_rawDesc, + NumEnums: 0, + NumMessages: 1, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_echo_echo_proto_goTypes, + DependencyIndexes: file_echo_echo_proto_depIdxs, + MessageInfos: file_echo_echo_proto_msgTypes, + }.Build() + File_echo_echo_proto = out.File + file_echo_echo_proto_rawDesc = nil + file_echo_echo_proto_goTypes = nil + file_echo_echo_proto_depIdxs = nil +} diff --git a/pkg/api/grpc/echo/echo.proto b/pkg/api/grpc/echo/echo.proto new file mode 100644 index 00000000..efcefba1 --- /dev/null +++ b/pkg/api/grpc/echo/echo.proto @@ -0,0 +1,14 @@ +syntax = "proto3"; + +option go_package = "./echo"; + +package echo; + +message Message { + string body = 1; +} + + +service EchoService { + rpc Echo(Message) returns (Message) {} +} \ No newline at end of file diff --git a/pkg/api/grpc/echo/echo_grpc.pb.go b/pkg/api/grpc/echo/echo_grpc.pb.go new file mode 100644 index 00000000..754d6d83 --- /dev/null +++ b/pkg/api/grpc/echo/echo_grpc.pb.go @@ -0,0 +1,109 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.3.0 +// - protoc v4.24.3 +// source: echo/echo.proto + +package echo + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +const ( + EchoService_Echo_FullMethodName = "/echo.EchoService/Echo" +) + +// EchoServiceClient is the client API for EchoService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type EchoServiceClient interface { + Echo(ctx context.Context, in *Message, opts ...grpc.CallOption) (*Message, error) +} + +type echoServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewEchoServiceClient(cc grpc.ClientConnInterface) EchoServiceClient { + return &echoServiceClient{cc} +} + +func (c *echoServiceClient) Echo(ctx context.Context, in *Message, opts ...grpc.CallOption) (*Message, error) { + out := new(Message) + err := c.cc.Invoke(ctx, EchoService_Echo_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// EchoServiceServer is the server API for EchoService service. +// All implementations must embed UnimplementedEchoServiceServer +// for forward compatibility +type EchoServiceServer interface { + Echo(context.Context, *Message) (*Message, error) + mustEmbedUnimplementedEchoServiceServer() +} + +// UnimplementedEchoServiceServer must be embedded to have forward compatible implementations. +type UnimplementedEchoServiceServer struct { +} + +func (UnimplementedEchoServiceServer) Echo(context.Context, *Message) (*Message, error) { + return nil, status.Errorf(codes.Unimplemented, "method Echo not implemented") +} +func (UnimplementedEchoServiceServer) mustEmbedUnimplementedEchoServiceServer() {} + +// UnsafeEchoServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to EchoServiceServer will +// result in compilation errors. +type UnsafeEchoServiceServer interface { + mustEmbedUnimplementedEchoServiceServer() +} + +func RegisterEchoServiceServer(s grpc.ServiceRegistrar, srv EchoServiceServer) { + s.RegisterService(&EchoService_ServiceDesc, srv) +} + +func _EchoService_Echo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(Message) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(EchoServiceServer).Echo(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: EchoService_Echo_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(EchoServiceServer).Echo(ctx, req.(*Message)) + } + return interceptor(ctx, in, info, handler) +} + +// EchoService_ServiceDesc is the grpc.ServiceDesc for EchoService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var EchoService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "echo.EchoService", + HandlerType: (*EchoServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Echo", + Handler: _EchoService_Echo_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "echo/echo.proto", +} diff --git a/pkg/api/grpc/echo_test.go b/pkg/api/grpc/echo_test.go new file mode 100644 index 00000000..e7a526bd --- /dev/null +++ b/pkg/api/grpc/echo_test.go @@ -0,0 +1,69 @@ +package grpc + +import ( + "context" + "log" + "net" + "regexp" + "testing" + + "github.com/stefanprodan/podinfo/pkg/api/grpc/echo" + "google.golang.org/grpc" + "google.golang.org/grpc/status" + "google.golang.org/grpc/test/bufconn" +) + +func TestGrpcEcho(t *testing.T) { + + // Server initialization + // bufconn => uses in-memory connection instead of system network I/O + lis := bufconn.Listen(1024*1024) + t.Cleanup(func() { + lis.Close() + }) + + srv := grpc.NewServer() + t.Cleanup(func() { + srv.Stop() + }) + + echo.RegisterEchoServiceServer(srv, &echoServer{}) + + go func(){ + if err := srv.Serve(lis); err != nil { + log.Fatalf("srv.Serve %v", err) + } + }() + + // - Test + dialer := func(context.Context, string) (net.Conn, error){ + return lis.Dial() + } + + ctx := context.Background() + + conn, err := grpc.DialContext(ctx, "", grpc.WithContextDialer(dialer), grpc.WithInsecure()) + t.Cleanup(func() { + conn.Close() + }) + + if err != nil { + t.Fatalf("grpc.DialContext %v", err) + } + + client := echo.NewEchoServiceClient(conn) + res , err := client.Echo(context.Background(), &echo.Message{Body:"test123-test"}) + + // Check the status code is what we expect. + if _, ok := status.FromError(err); !ok { + t.Errorf("Echo returned type %T, want %T", err, status.Error) + } + + // Check the response body is what we expect. + expected := ".*body.*test123-test.*" + r := regexp.MustCompile(expected) + if !r.MatchString(res.String()) { + t.Fatalf("Returned unexpected body:\ngot \n%v \nwant \n%s", + res, expected) + } +} \ No newline at end of file diff --git a/pkg/api/grpc/mock_grpc.go b/pkg/api/grpc/mock_grpc.go new file mode 100644 index 00000000..f05827ed --- /dev/null +++ b/pkg/api/grpc/mock_grpc.go @@ -0,0 +1,31 @@ +package grpc + +import ( + "go.uber.org/zap" +) + + +func NewMockGrpcServer() *Server { + config := &Config{ + Port: 9999, + // ServerShutdownTimeout: 5 * time.Second, + // HttpServerTimeout: 30 * time.Second, + BackendURL: []string{}, + ConfigPath: "/config", + DataPath: "/data", + // HttpClientTimeout: 30 * time.Second, + UIColor: "blue", + UIPath: ".ui", + UIMessage: "Greetings", + Hostname: "localhost", + } + + logger, _ := zap.NewDevelopment() + + return &Server{ + //router: mux.NewRouter(), + logger: logger, + config: config, + //tracer: trace.NewNoopTracerProvider().Tracer("mock"), + } +} \ No newline at end of file diff --git a/pkg/api/grpc/panic.go b/pkg/api/grpc/panic.go new file mode 100644 index 00000000..b47b82aa --- /dev/null +++ b/pkg/api/grpc/panic.go @@ -0,0 +1,24 @@ +package grpc + +import ( + "context" + // "log" + "os" + + pb "github.com/stefanprodan/podinfo/pkg/api/grpc/panic" + "go.uber.org/zap" +) + +type PanicServer struct { + pb.UnimplementedPanicServiceServer + config *Config + logger *zap.Logger + +} + +func (s *PanicServer) Panic(ctx context.Context, req *pb.PanicRequest) (*pb.PanicResponse, error) { + s.logger.Info("Panic command received") + os.Exit(225) + return &pb.PanicResponse{}, nil +} + diff --git a/pkg/api/grpc/panic/panic.pb.go b/pkg/api/grpc/panic/panic.pb.go new file mode 100644 index 00000000..bfd10428 --- /dev/null +++ b/pkg/api/grpc/panic/panic.pb.go @@ -0,0 +1,189 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.28.1 +// protoc v3.6.1 +// source: panic.proto + +package panic + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type PanicRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *PanicRequest) Reset() { + *x = PanicRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_panic_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PanicRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PanicRequest) ProtoMessage() {} + +func (x *PanicRequest) ProtoReflect() protoreflect.Message { + mi := &file_panic_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PanicRequest.ProtoReflect.Descriptor instead. +func (*PanicRequest) Descriptor() ([]byte, []int) { + return file_panic_proto_rawDescGZIP(), []int{0} +} + +type PanicResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *PanicResponse) Reset() { + *x = PanicResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_panic_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PanicResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PanicResponse) ProtoMessage() {} + +func (x *PanicResponse) ProtoReflect() protoreflect.Message { + mi := &file_panic_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PanicResponse.ProtoReflect.Descriptor instead. +func (*PanicResponse) Descriptor() ([]byte, []int) { + return file_panic_proto_rawDescGZIP(), []int{1} +} + +var File_panic_proto protoreflect.FileDescriptor + +var file_panic_proto_rawDesc = []byte{ + 0x0a, 0x0b, 0x70, 0x61, 0x6e, 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x05, 0x70, + 0x61, 0x6e, 0x69, 0x63, 0x22, 0x0e, 0x0a, 0x0c, 0x50, 0x61, 0x6e, 0x69, 0x63, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x22, 0x0f, 0x0a, 0x0d, 0x50, 0x61, 0x6e, 0x69, 0x63, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0x44, 0x0a, 0x0c, 0x50, 0x61, 0x6e, 0x69, 0x63, 0x53, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x34, 0x0a, 0x05, 0x50, 0x61, 0x6e, 0x69, 0x63, 0x12, 0x13, + 0x2e, 0x70, 0x61, 0x6e, 0x69, 0x63, 0x2e, 0x50, 0x61, 0x6e, 0x69, 0x63, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x70, 0x61, 0x6e, 0x69, 0x63, 0x2e, 0x50, 0x61, 0x6e, 0x69, + 0x63, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x09, 0x5a, 0x07, 0x2e, + 0x2f, 0x70, 0x61, 0x6e, 0x69, 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_panic_proto_rawDescOnce sync.Once + file_panic_proto_rawDescData = file_panic_proto_rawDesc +) + +func file_panic_proto_rawDescGZIP() []byte { + file_panic_proto_rawDescOnce.Do(func() { + file_panic_proto_rawDescData = protoimpl.X.CompressGZIP(file_panic_proto_rawDescData) + }) + return file_panic_proto_rawDescData +} + +var file_panic_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_panic_proto_goTypes = []interface{}{ + (*PanicRequest)(nil), // 0: panic.PanicRequest + (*PanicResponse)(nil), // 1: panic.PanicResponse +} +var file_panic_proto_depIdxs = []int32{ + 0, // 0: panic.PanicService.Panic:input_type -> panic.PanicRequest + 1, // 1: panic.PanicService.Panic:output_type -> panic.PanicResponse + 1, // [1:2] is the sub-list for method output_type + 0, // [0:1] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_panic_proto_init() } +func file_panic_proto_init() { + if File_panic_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_panic_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PanicRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_panic_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PanicResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_panic_proto_rawDesc, + NumEnums: 0, + NumMessages: 2, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_panic_proto_goTypes, + DependencyIndexes: file_panic_proto_depIdxs, + MessageInfos: file_panic_proto_msgTypes, + }.Build() + File_panic_proto = out.File + file_panic_proto_rawDesc = nil + file_panic_proto_goTypes = nil + file_panic_proto_depIdxs = nil +} diff --git a/pkg/api/grpc/panic/panic.proto b/pkg/api/grpc/panic/panic.proto new file mode 100644 index 00000000..995106d5 --- /dev/null +++ b/pkg/api/grpc/panic/panic.proto @@ -0,0 +1,17 @@ +syntax = "proto3"; + +option go_package = "./panic"; + +package panic; + +// The greeting service definition. +service PanicService { + rpc Panic (PanicRequest) returns (PanicResponse) {} +} + +message PanicRequest { +} + +message PanicResponse { +} + diff --git a/pkg/api/grpc/panic/panic_grpc.pb.go b/pkg/api/grpc/panic/panic_grpc.pb.go new file mode 100644 index 00000000..dccf98b2 --- /dev/null +++ b/pkg/api/grpc/panic/panic_grpc.pb.go @@ -0,0 +1,105 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.2.0 +// - protoc v3.6.1 +// source: panic.proto + +package panic + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +// PanicServiceClient is the client API for PanicService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type PanicServiceClient interface { + Panic(ctx context.Context, in *PanicRequest, opts ...grpc.CallOption) (*PanicResponse, error) +} + +type panicServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewPanicServiceClient(cc grpc.ClientConnInterface) PanicServiceClient { + return &panicServiceClient{cc} +} + +func (c *panicServiceClient) Panic(ctx context.Context, in *PanicRequest, opts ...grpc.CallOption) (*PanicResponse, error) { + out := new(PanicResponse) + err := c.cc.Invoke(ctx, "/panic.PanicService/Panic", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// PanicServiceServer is the server API for PanicService service. +// All implementations must embed UnimplementedPanicServiceServer +// for forward compatibility +type PanicServiceServer interface { + Panic(context.Context, *PanicRequest) (*PanicResponse, error) + mustEmbedUnimplementedPanicServiceServer() +} + +// UnimplementedPanicServiceServer must be embedded to have forward compatible implementations. +type UnimplementedPanicServiceServer struct { +} + +func (UnimplementedPanicServiceServer) Panic(context.Context, *PanicRequest) (*PanicResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Panic not implemented") +} +func (UnimplementedPanicServiceServer) mustEmbedUnimplementedPanicServiceServer() {} + +// UnsafePanicServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to PanicServiceServer will +// result in compilation errors. +type UnsafePanicServiceServer interface { + mustEmbedUnimplementedPanicServiceServer() +} + +func RegisterPanicServiceServer(s grpc.ServiceRegistrar, srv PanicServiceServer) { + s.RegisterService(&PanicService_ServiceDesc, srv) +} + +func _PanicService_Panic_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(PanicRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(PanicServiceServer).Panic(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/panic.PanicService/Panic", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(PanicServiceServer).Panic(ctx, req.(*PanicRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// PanicService_ServiceDesc is the grpc.ServiceDesc for PanicService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var PanicService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "panic.PanicService", + HandlerType: (*PanicServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Panic", + Handler: _PanicService_Panic_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "panic.proto", +} diff --git a/pkg/api/grpc/server.go b/pkg/api/grpc/server.go index 3de371f5..02e2d955 100644 --- a/pkg/api/grpc/server.go +++ b/pkg/api/grpc/server.go @@ -4,13 +4,21 @@ import ( "fmt" "net" + + "github.com/stefanprodan/podinfo/pkg/api/grpc/echo" + "go.uber.org/zap" "google.golang.org/grpc" "google.golang.org/grpc/health" "google.golang.org/grpc/health/grpc_health_v1" "google.golang.org/grpc/reflection" + + + "github.com/stefanprodan/podinfo/pkg/api/grpc/panic" + "github.com/stefanprodan/podinfo/pkg/api/grpc/version" ) + type Server struct { logger *zap.Logger config *Config @@ -19,6 +27,32 @@ type Server struct { type Config struct { Port int `mapstructure:"grpc-port"` ServiceName string `mapstructure:"grpc-service-name"` + + + BackendURL []string `mapstructure:"backend-url"` + UILogo string `mapstructure:"ui-logo"` + UIMessage string `mapstructure:"ui-message"` + UIColor string `mapstructure:"ui-color"` + UIPath string `mapstructure:"ui-path"` + DataPath string `mapstructure:"data-path"` + ConfigPath string `mapstructure:"config-path"` + CertPath string `mapstructure:"cert-path"` + Host string `mapstructure:"host"` + //Port string `mapstructure:"port"` + SecurePort string `mapstructure:"secure-port"` + PortMetrics int `mapstructure:"port-metrics"` + Hostname string `mapstructure:"hostname"` + H2C bool `mapstructure:"h2c"` + RandomDelay bool `mapstructure:"random-delay"` + RandomDelayUnit string `mapstructure:"random-delay-unit"` + RandomDelayMin int `mapstructure:"random-delay-min"` + RandomDelayMax int `mapstructure:"random-delay-max"` + RandomError bool `mapstructure:"random-error"` + Unhealthy bool `mapstructure:"unhealthy"` + Unready bool `mapstructure:"unready"` + JWTSecret string `mapstructure:"jwt-secret"` + CacheServer string `mapstructure:"cache-server"` + } func NewServer(config *Config, logger *zap.Logger) (*Server, error) { @@ -30,6 +64,7 @@ func NewServer(config *Config, logger *zap.Logger) (*Server, error) { return srv, nil } + func (s *Server) ListenAndServe() *grpc.Server { listener, err := net.Listen("tcp", fmt.Sprintf(":%v", s.config.Port)) if err != nil { @@ -38,6 +73,14 @@ func (s *Server) ListenAndServe() *grpc.Server { srv := grpc.NewServer() server := health.NewServer() + + + // Register grpc apis for refection + echo.RegisterEchoServiceServer(srv, &echoServer{}) + + version.RegisterVersionServiceServer(srv, &VersionServer{config: s.config, logger: s.logger}) + panic.RegisterPanicServiceServer(srv, &PanicServer{config: s.config, logger: s.logger}) + reflection.Register(srv) grpc_health_v1.RegisterHealthServer(srv, server) server.SetServingStatus(s.config.ServiceName, grpc_health_v1.HealthCheckResponse_SERVING) diff --git a/pkg/api/grpc/version.go b/pkg/api/grpc/version.go new file mode 100644 index 00000000..8291e2e6 --- /dev/null +++ b/pkg/api/grpc/version.go @@ -0,0 +1,21 @@ +package grpc + +import ( + "context" + + pb "github.com/stefanprodan/podinfo/pkg/api/grpc/version" + "github.com/stefanprodan/podinfo/pkg/version" + "go.uber.org/zap" +) + +type VersionServer struct { + pb.UnimplementedVersionServiceServer + config *Config + logger *zap.Logger + +} + +func (s *VersionServer) Version(ctx context.Context, req *pb.VersionRequest) (*pb.VersionResponse, error) { + return &pb.VersionResponse{Version: version.VERSION, Commit: version.REVISION}, nil +} + diff --git a/pkg/api/grpc/version/version.pb.go b/pkg/api/grpc/version/version.pb.go new file mode 100644 index 00000000..ee66cfab --- /dev/null +++ b/pkg/api/grpc/version/version.pb.go @@ -0,0 +1,211 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.28.1 +// protoc v3.6.1 +// source: version.proto + +package version + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type VersionRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *VersionRequest) Reset() { + *x = VersionRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_version_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *VersionRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*VersionRequest) ProtoMessage() {} + +func (x *VersionRequest) ProtoReflect() protoreflect.Message { + mi := &file_version_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use VersionRequest.ProtoReflect.Descriptor instead. +func (*VersionRequest) Descriptor() ([]byte, []int) { + return file_version_proto_rawDescGZIP(), []int{0} +} + +type VersionResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Version string `protobuf:"bytes,1,opt,name=version,proto3" json:"version,omitempty"` + Commit string `protobuf:"bytes,2,opt,name=commit,proto3" json:"commit,omitempty"` +} + +func (x *VersionResponse) Reset() { + *x = VersionResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_version_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *VersionResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*VersionResponse) ProtoMessage() {} + +func (x *VersionResponse) ProtoReflect() protoreflect.Message { + mi := &file_version_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use VersionResponse.ProtoReflect.Descriptor instead. +func (*VersionResponse) Descriptor() ([]byte, []int) { + return file_version_proto_rawDescGZIP(), []int{1} +} + +func (x *VersionResponse) GetVersion() string { + if x != nil { + return x.Version + } + return "" +} + +func (x *VersionResponse) GetCommit() string { + if x != nil { + return x.Commit + } + return "" +} + +var File_version_proto protoreflect.FileDescriptor + +var file_version_proto_rawDesc = []byte{ + 0x0a, 0x0d, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, + 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x10, 0x0a, 0x0e, 0x56, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x43, 0x0a, 0x0f, 0x56, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, + 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, + 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x69, + 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x32, + 0x50, 0x0a, 0x0e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x12, 0x3e, 0x0a, 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x17, 0x2e, 0x76, + 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x2e, + 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x00, 0x42, 0x0b, 0x5a, 0x09, 0x2e, 0x2f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x62, 0x06, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_version_proto_rawDescOnce sync.Once + file_version_proto_rawDescData = file_version_proto_rawDesc +) + +func file_version_proto_rawDescGZIP() []byte { + file_version_proto_rawDescOnce.Do(func() { + file_version_proto_rawDescData = protoimpl.X.CompressGZIP(file_version_proto_rawDescData) + }) + return file_version_proto_rawDescData +} + +var file_version_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_version_proto_goTypes = []interface{}{ + (*VersionRequest)(nil), // 0: version.VersionRequest + (*VersionResponse)(nil), // 1: version.VersionResponse +} +var file_version_proto_depIdxs = []int32{ + 0, // 0: version.VersionService.Version:input_type -> version.VersionRequest + 1, // 1: version.VersionService.Version:output_type -> version.VersionResponse + 1, // [1:2] is the sub-list for method output_type + 0, // [0:1] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_version_proto_init() } +func file_version_proto_init() { + if File_version_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_version_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*VersionRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_version_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*VersionResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_version_proto_rawDesc, + NumEnums: 0, + NumMessages: 2, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_version_proto_goTypes, + DependencyIndexes: file_version_proto_depIdxs, + MessageInfos: file_version_proto_msgTypes, + }.Build() + File_version_proto = out.File + file_version_proto_rawDesc = nil + file_version_proto_goTypes = nil + file_version_proto_depIdxs = nil +} diff --git a/pkg/api/grpc/version/version.proto b/pkg/api/grpc/version/version.proto new file mode 100644 index 00000000..7ea56b37 --- /dev/null +++ b/pkg/api/grpc/version/version.proto @@ -0,0 +1,18 @@ +syntax = "proto3"; + +option go_package = "./version"; + +package version; + + +service VersionService { + rpc Version (VersionRequest) returns (VersionResponse) {} +} + + +message VersionRequest {} + +message VersionResponse { + string version = 1; + string commit = 2; +} diff --git a/pkg/api/grpc/version/version_grpc.pb.go b/pkg/api/grpc/version/version_grpc.pb.go new file mode 100644 index 00000000..ed4baff2 --- /dev/null +++ b/pkg/api/grpc/version/version_grpc.pb.go @@ -0,0 +1,105 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.2.0 +// - protoc v3.6.1 +// source: version.proto + +package version + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +// VersionServiceClient is the client API for VersionService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type VersionServiceClient interface { + Version(ctx context.Context, in *VersionRequest, opts ...grpc.CallOption) (*VersionResponse, error) +} + +type versionServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewVersionServiceClient(cc grpc.ClientConnInterface) VersionServiceClient { + return &versionServiceClient{cc} +} + +func (c *versionServiceClient) Version(ctx context.Context, in *VersionRequest, opts ...grpc.CallOption) (*VersionResponse, error) { + out := new(VersionResponse) + err := c.cc.Invoke(ctx, "/version.VersionService/Version", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// VersionServiceServer is the server API for VersionService service. +// All implementations must embed UnimplementedVersionServiceServer +// for forward compatibility +type VersionServiceServer interface { + Version(context.Context, *VersionRequest) (*VersionResponse, error) + mustEmbedUnimplementedVersionServiceServer() +} + +// UnimplementedVersionServiceServer must be embedded to have forward compatible implementations. +type UnimplementedVersionServiceServer struct { +} + +func (UnimplementedVersionServiceServer) Version(context.Context, *VersionRequest) (*VersionResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Version not implemented") +} +func (UnimplementedVersionServiceServer) mustEmbedUnimplementedVersionServiceServer() {} + +// UnsafeVersionServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to VersionServiceServer will +// result in compilation errors. +type UnsafeVersionServiceServer interface { + mustEmbedUnimplementedVersionServiceServer() +} + +func RegisterVersionServiceServer(s grpc.ServiceRegistrar, srv VersionServiceServer) { + s.RegisterService(&VersionService_ServiceDesc, srv) +} + +func _VersionService_Version_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(VersionRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(VersionServiceServer).Version(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/version.VersionService/Version", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(VersionServiceServer).Version(ctx, req.(*VersionRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// VersionService_ServiceDesc is the grpc.ServiceDesc for VersionService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var VersionService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "version.VersionService", + HandlerType: (*VersionServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Version", + Handler: _VersionService_Version_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "version.proto", +} diff --git a/pkg/api/grpc/version_test.go b/pkg/api/grpc/version_test.go new file mode 100644 index 00000000..7cdbc21a --- /dev/null +++ b/pkg/api/grpc/version_test.go @@ -0,0 +1,72 @@ +package grpc + +import ( + "context" + "fmt" + "log" + "net" + "regexp" + "testing" + + "github.com/stefanprodan/podinfo/pkg/api/grpc/version" + v "github.com/stefanprodan/podinfo/pkg/version" + "google.golang.org/grpc" + "google.golang.org/grpc/status" + "google.golang.org/grpc/test/bufconn" +) + +func TestGrpcVersion(t *testing.T) { + + // Server initialization + // bufconn => uses in-memory connection instead of system network I/O + lis := bufconn.Listen(1024*1024) + t.Cleanup(func() { + lis.Close() + }) + + + srv := grpc.NewServer() + t.Cleanup(func() { + srv.Stop() + }) + + version.RegisterVersionServiceServer(srv, &VersionServer{}) + + go func(){ + if err := srv.Serve(lis); err != nil { + log.Fatalf("srv.Serve %v", err) + } + }() + + // - Test + dialer := func(context.Context, string) (net.Conn, error){ + return lis.Dial() + } + + ctx := context.Background() + + conn, err := grpc.DialContext(ctx, "", grpc.WithContextDialer(dialer), grpc.WithInsecure()) + t.Cleanup(func() { + conn.Close() + }) + + if err != nil { + t.Fatalf("grpc.DialContext %v", err) + } + + client := version.NewVersionServiceClient(conn) + res , err := client.Version(context.Background(), &version.VersionRequest{}) + + // Check the status code is what we expect. + if _, ok := status.FromError(err); !ok { + t.Errorf("Version returned type %T, want %T", err, status.Error) + } + + // Check the response body is what we expect. + expected := fmt.Sprintf(".*%s.*", v.VERSION) + r := regexp.MustCompile(expected) + if !r.MatchString(res.String()) { + t.Fatalf("Returned unexpected body:\ngot \n%v \nwant \n%s", + res, expected) + } +} \ No newline at end of file From e008d1f26176b09291943a65a7200d8d3f80c996 Mon Sep 17 00:00:00 2001 From: JayKaku Date: Fri, 24 Nov 2023 20:49:48 +0530 Subject: [PATCH 3/5] Added config, logger for grpc echo api --- pkg/api/grpc/echo.go | 5 ++++- pkg/api/grpc/server.go | 4 +--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/pkg/api/grpc/echo.go b/pkg/api/grpc/echo.go index 0d54e6c8..1a654ffe 100644 --- a/pkg/api/grpc/echo.go +++ b/pkg/api/grpc/echo.go @@ -5,10 +5,13 @@ import ( "log" "github.com/stefanprodan/podinfo/pkg/api/grpc/echo" + "go.uber.org/zap" ) type echoServer struct { - echo.UnimplementedEchoServiceServer + echo.UnimplementedEchoServiceServer + config *Config + logger *zap.Logger } func (s *echoServer) Echo (ctx context.Context, message *echo.Message) (*echo.Message, error){ diff --git a/pkg/api/grpc/server.go b/pkg/api/grpc/server.go index 02e2d955..fd328382 100644 --- a/pkg/api/grpc/server.go +++ b/pkg/api/grpc/server.go @@ -4,7 +4,6 @@ import ( "fmt" "net" - "github.com/stefanprodan/podinfo/pkg/api/grpc/echo" "go.uber.org/zap" @@ -13,7 +12,6 @@ import ( "google.golang.org/grpc/health/grpc_health_v1" "google.golang.org/grpc/reflection" - "github.com/stefanprodan/podinfo/pkg/api/grpc/panic" "github.com/stefanprodan/podinfo/pkg/api/grpc/version" ) @@ -76,7 +74,7 @@ func (s *Server) ListenAndServe() *grpc.Server { // Register grpc apis for refection - echo.RegisterEchoServiceServer(srv, &echoServer{}) + echo.RegisterEchoServiceServer(srv, &echoServer{config: s.config, logger: s.logger}) version.RegisterVersionServiceServer(srv, &VersionServer{config: s.config, logger: s.logger}) panic.RegisterPanicServiceServer(srv, &PanicServer{config: s.config, logger: s.logger}) From 8535efccb7118ad687a10268d394ee74d5bc4c7d Mon Sep 17 00:00:00 2001 From: JayKaku Date: Fri, 24 Nov 2023 23:39:39 +0530 Subject: [PATCH 4/5] Implemented zap logger in place of log | gprc echo --- pkg/api/grpc/echo.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/api/grpc/echo.go b/pkg/api/grpc/echo.go index 1a654ffe..33135868 100644 --- a/pkg/api/grpc/echo.go +++ b/pkg/api/grpc/echo.go @@ -2,7 +2,6 @@ package grpc import ( "context" - "log" "github.com/stefanprodan/podinfo/pkg/api/grpc/echo" "go.uber.org/zap" @@ -15,6 +14,7 @@ type echoServer struct { } func (s *echoServer) Echo (ctx context.Context, message *echo.Message) (*echo.Message, error){ - log.Printf("Received message body from client: %s", message.Body) + // Log level 0 for Info + s.logger.Log(0,"Received message body from client:", zap.String("input body", message.Body)) return &echo.Message {Body: message.Body}, nil } From 2251bee6998fe4fa57b3b63fec67f25cb958d403 Mon Sep 17 00:00:00 2001 From: JayKaku Date: Thu, 4 Jan 2024 13:12:54 +0530 Subject: [PATCH 5/5] Fixed parsing logger in echo_test.go service registeration --- pkg/api/grpc/echo.go | 4 ++-- pkg/api/grpc/echo_test.go | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/pkg/api/grpc/echo.go b/pkg/api/grpc/echo.go index 33135868..2e850941 100644 --- a/pkg/api/grpc/echo.go +++ b/pkg/api/grpc/echo.go @@ -14,7 +14,7 @@ type echoServer struct { } func (s *echoServer) Echo (ctx context.Context, message *echo.Message) (*echo.Message, error){ - // Log level 0 for Info - s.logger.Log(0,"Received message body from client:", zap.String("input body", message.Body)) + + s.logger.Info("Received message body from client:", zap.String("input body", message.Body)) return &echo.Message {Body: message.Body}, nil } diff --git a/pkg/api/grpc/echo_test.go b/pkg/api/grpc/echo_test.go index e7a526bd..4f1812d8 100644 --- a/pkg/api/grpc/echo_test.go +++ b/pkg/api/grpc/echo_test.go @@ -22,12 +22,13 @@ func TestGrpcEcho(t *testing.T) { lis.Close() }) + s := NewMockGrpcServer() srv := grpc.NewServer() t.Cleanup(func() { srv.Stop() }) - echo.RegisterEchoServiceServer(srv, &echoServer{}) + echo.RegisterEchoServiceServer(srv, &echoServer{config: s.config, logger: s.logger}) go func(){ if err := srv.Serve(lis); err != nil {