Files
go-grpc-gateway-template/coverage.html
2025-08-13 19:36:09 +02:00

1042 lines
41 KiB
HTML

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>server: Go Coverage Report</title>
<style>
body {
background: black;
color: rgb(80, 80, 80);
}
body, pre, #legend span {
font-family: Menlo, monospace;
font-weight: bold;
}
#topbar {
background: black;
position: fixed;
top: 0; left: 0; right: 0;
height: 42px;
border-bottom: 1px solid rgb(80, 80, 80);
}
#content {
margin-top: 50px;
}
#nav, #legend {
float: left;
margin-left: 10px;
}
#legend {
margin-top: 12px;
}
#nav {
margin-top: 10px;
}
#legend span {
margin: 0 5px;
}
.cov0 { color: rgb(192, 0, 0) }
.cov1 { color: rgb(128, 128, 128) }
.cov2 { color: rgb(116, 140, 131) }
.cov3 { color: rgb(104, 152, 134) }
.cov4 { color: rgb(92, 164, 137) }
.cov5 { color: rgb(80, 176, 140) }
.cov6 { color: rgb(68, 188, 143) }
.cov7 { color: rgb(56, 200, 146) }
.cov8 { color: rgb(44, 212, 149) }
.cov9 { color: rgb(32, 224, 152) }
.cov10 { color: rgb(20, 236, 155) }
</style>
</head>
<body>
<div id="topbar">
<div id="nav">
<select id="files">
<option value="file0">go-grpc-gateway-template/cmd/server/main.go (0.0%)</option>
<option value="file1">go-grpc-gateway-template/internal/config/config.go (95.2%)</option>
<option value="file2">go-grpc-gateway-template/internal/health/health.go (100.0%)</option>
<option value="file3">go-grpc-gateway-template/internal/server/server.go (0.0%)</option>
<option value="file4">go-grpc-gateway-template/proto/helloworld/hello_world.pb.go (0.0%)</option>
<option value="file5">go-grpc-gateway-template/proto/helloworld/hello_world.pb.gw.go (0.0%)</option>
<option value="file6">go-grpc-gateway-template/proto/helloworld/hello_world_grpc.pb.go (0.0%)</option>
</select>
</div>
<div id="legend">
<span>not tracked</span>
<span class="cov0">not covered</span>
<span class="cov8">covered</span>
</div>
</div>
<div id="content">
<pre class="file" id="file0" style="display: none">package main
import (
"context"
"log"
"os"
"os/signal"
"syscall"
"go-grpc-gateway-template/internal/config"
"go-grpc-gateway-template/internal/server"
)
func main() <span class="cov0" title="0">{
// Load configuration
cfg := config.Load()
if err := cfg.Validate(); err != nil </span><span class="cov0" title="0">{
log.Fatalf("Invalid configuration: %v", err)
}</span>
// Create server
<span class="cov0" title="0">srv := server.New(cfg)
// Setup graceful shutdown
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
// Handle signals
sigChan := make(chan os.Signal, 1)
signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
go func() </span><span class="cov0" title="0">{
&lt;-sigChan
log.Println("Received shutdown signal")
cancel()
}</span>()
// Start server
<span class="cov0" title="0">if err := srv.Start(ctx); err != nil </span><span class="cov0" title="0">{
log.Printf("Server error: %v", err)
}</span>
// Shutdown server
<span class="cov0" title="0">if err := srv.Shutdown(context.Background()); err != nil </span><span class="cov0" title="0">{
log.Printf("Shutdown error: %v", err)
}</span>
}</pre>
<pre class="file" id="file1" style="display: none">package config
import (
"fmt"
"os"
"strconv"
"strings"
)
// Config holds all configuration for the application
type Config struct {
Server ServerConfig
Log LogConfig
Metrics MetricsConfig
}
// ServerConfig holds server-related configuration
type ServerConfig struct {
GRPCPort string
HTTPPort string
}
// LogConfig holds logging configuration
type LogConfig struct {
Level string
Format string
}
// MetricsConfig holds metrics configuration
type MetricsConfig struct {
Enabled bool
}
// Load loads configuration from environment variables with defaults
func Load() *Config <span class="cov8" title="1">{
return &amp;Config{
Server: ServerConfig{
GRPCPort: getEnv("SERVER_GRPC_PORT", "8080"),
HTTPPort: getEnv("SERVER_HTTP_PORT", "8090"),
},
Log: LogConfig{
Level: strings.ToLower(getEnv("LOG_LEVEL", "info")),
Format: strings.ToLower(getEnv("LOG_FORMAT", "json")),
},
Metrics: MetricsConfig{
Enabled: getEnvBool("METRICS_ENABLED", true),
},
}
}</span>
// Validate validates the configuration
func (c *Config) Validate() error <span class="cov8" title="1">{
if c.Server.GRPCPort == "" </span><span class="cov8" title="1">{
return fmt.Errorf("gRPC port cannot be empty")
}</span>
<span class="cov8" title="1">if c.Server.HTTPPort == "" </span><span class="cov0" title="0">{
return fmt.Errorf("HTTP port cannot be empty")
}</span>
<span class="cov8" title="1">if c.Server.GRPCPort == c.Server.HTTPPort </span><span class="cov8" title="1">{
return fmt.Errorf("gRPC and HTTP ports cannot be the same")
}</span>
<span class="cov8" title="1">validLogLevels := map[string]bool{
"debug": true,
"info": true,
"warn": true,
"error": true,
}
if !validLogLevels[c.Log.Level] </span><span class="cov8" title="1">{
return fmt.Errorf("invalid log level: %s", c.Log.Level)
}</span>
<span class="cov8" title="1">validLogFormats := map[string]bool{
"json": true,
"text": true,
}
if !validLogFormats[c.Log.Format] </span><span class="cov8" title="1">{
return fmt.Errorf("invalid log format: %s", c.Log.Format)
}</span>
<span class="cov8" title="1">return nil</span>
}
// getEnv gets an environment variable or returns a default value
func getEnv(key, defaultValue string) string <span class="cov8" title="1">{
if value := os.Getenv(key); value != "" </span><span class="cov8" title="1">{
return value
}</span>
<span class="cov8" title="1">return defaultValue</span>
}
// getEnvBool gets a boolean environment variable or returns a default value
func getEnvBool(key string, defaultValue bool) bool <span class="cov8" title="1">{
if value := os.Getenv(key); value != "" </span><span class="cov8" title="1">{
if parsed, err := strconv.ParseBool(value); err == nil </span><span class="cov8" title="1">{
return parsed
}</span>
}
<span class="cov8" title="1">return defaultValue</span>
}</pre>
<pre class="file" id="file2" style="display: none">package health
import (
"encoding/json"
"net/http"
"time"
)
// Response represents a health check response
type Response struct {
Status string `json:"status"`
Timestamp time.Time `json:"timestamp"`
Version string `json:"version,omitempty"`
Checks []Check `json:"checks,omitempty"`
}
// Check represents an individual health check
type Check struct {
Name string `json:"name"`
Status string `json:"status"`
Error string `json:"error,omitempty"`
}
// Handler handles health check requests
type Handler struct {
version string
checks []HealthChecker
}
// HealthChecker interface for health checks
type HealthChecker interface {
Name() string
Check() error
}
// NewHandler creates a new health check handler
func NewHandler(version string) *Handler <span class="cov8" title="1">{
return &amp;Handler{
version: version,
checks: make([]HealthChecker, 0),
}
}</span>
// AddCheck adds a health checker
func (h *Handler) AddCheck(checker HealthChecker) <span class="cov8" title="1">{
h.checks = append(h.checks, checker)
}</span>
// ServeHTTP implements http.Handler
func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) <span class="cov8" title="1">{
if r.Method != http.MethodGet </span><span class="cov8" title="1">{
w.WriteHeader(http.StatusMethodNotAllowed)
return
}</span>
<span class="cov8" title="1">response := Response{
Status: "ok",
Timestamp: time.Now().UTC(),
Version: h.version,
Checks: make([]Check, 0, len(h.checks)),
}
allHealthy := true
for _, checker := range h.checks </span><span class="cov8" title="1">{
check := Check{
Name: checker.Name(),
Status: "ok",
}
if err := checker.Check(); err != nil </span><span class="cov8" title="1">{
check.Status = "error"
check.Error = err.Error()
allHealthy = false
}</span>
<span class="cov8" title="1">response.Checks = append(response.Checks, check)</span>
}
<span class="cov8" title="1">if !allHealthy </span><span class="cov8" title="1">{
response.Status = "error"
w.WriteHeader(http.StatusServiceUnavailable)
}</span> else<span class="cov8" title="1"> {
w.WriteHeader(http.StatusOK)
}</span>
<span class="cov8" title="1">w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(response)</span>
}
// SimpleChecker is a basic health checker
type SimpleChecker struct {
name string
fn func() error
}
// NewSimpleChecker creates a new simple health checker
func NewSimpleChecker(name string, fn func() error) *SimpleChecker <span class="cov8" title="1">{
return &amp;SimpleChecker{
name: name,
fn: fn,
}
}</span>
// Name returns the checker name
func (c *SimpleChecker) Name() string <span class="cov8" title="1">{
return c.name
}</span>
// Check performs the health check
func (c *SimpleChecker) Check() error <span class="cov8" title="1">{
return c.fn()
}</pre>
<pre class="file" id="file3" style="display: none">package server
import (
"context"
"fmt"
"log/slog"
"net"
"net/http"
"os"
"sync"
"time"
"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
"google.golang.org/grpc/reflection"
"go-grpc-gateway-template/internal/config"
"go-grpc-gateway-template/internal/health"
helloworldpb "go-grpc-gateway-template/proto/helloworld"
)
// Server wraps gRPC and HTTP servers with configuration
type Server struct {
config *config.Config
logger *slog.Logger
grpcServer *grpc.Server
httpServer *http.Server
healthHandler *health.Handler
}
// New creates a new server instance
func New(cfg *config.Config) *Server <span class="cov0" title="0">{
// Setup logger
var handler slog.Handler
if cfg.Log.Format == "json" </span><span class="cov0" title="0">{
handler = slog.NewJSONHandler(os.Stdout, &amp;slog.HandlerOptions{
Level: parseLogLevel(cfg.Log.Level),
})
}</span> else<span class="cov0" title="0"> {
handler = slog.NewTextHandler(os.Stdout, &amp;slog.HandlerOptions{
Level: parseLogLevel(cfg.Log.Level),
})
}</span>
<span class="cov0" title="0">logger := slog.New(handler)
// Create health handler
healthHandler := health.NewHandler("1.0.0")
return &amp;Server{
config: cfg,
logger: logger,
healthHandler: healthHandler,
}</span>
}
// Start starts both gRPC and HTTP servers
func (s *Server) Start(ctx context.Context) error <span class="cov0" title="0">{
var wg sync.WaitGroup
errChan := make(chan error, 2)
// Start gRPC server
wg.Add(1)
go func() </span><span class="cov0" title="0">{
defer wg.Done()
if err := s.startGRPCServer(ctx); err != nil </span><span class="cov0" title="0">{
errChan &lt;- fmt.Errorf("gRPC server error: %w", err)
}</span>
}()
// Start HTTP server
<span class="cov0" title="0">wg.Add(1)
go func() </span><span class="cov0" title="0">{
defer wg.Done()
if err := s.startHTTPServer(ctx); err != nil &amp;&amp; err != http.ErrServerClosed </span><span class="cov0" title="0">{
errChan &lt;- fmt.Errorf("HTTP server error: %w", err)
}</span>
}()
// Wait for servers to start
<span class="cov0" title="0">go func() </span><span class="cov0" title="0">{
wg.Wait()
close(errChan)
}</span>()
// Return first error if any
<span class="cov0" title="0">return &lt;-errChan</span>
}
func (s *Server) startGRPCServer(ctx context.Context) error <span class="cov0" title="0">{
lis, err := net.Listen("tcp", ":"+s.config.Server.GRPCPort)
if err != nil </span><span class="cov0" title="0">{
return fmt.Errorf("failed to listen on port %s: %w", s.config.Server.GRPCPort, err)
}</span>
<span class="cov0" title="0">s.grpcServer = grpc.NewServer()
// Register services
greeter := &amp;GreeterService{}
helloworldpb.RegisterGreeterServer(s.grpcServer, greeter)
// Enable reflection for development
reflection.Register(s.grpcServer)
s.logger.Info("Starting gRPC server", "port", s.config.Server.GRPCPort)
return s.grpcServer.Serve(lis)</span>
}
func (s *Server) startHTTPServer(ctx context.Context) error <span class="cov0" title="0">{
// Create gRPC client connection
conn, err := grpc.DialContext(
ctx,
"localhost:"+s.config.Server.GRPCPort,
grpc.WithBlock(),
grpc.WithTransportCredentials(insecure.NewCredentials()),
)
if err != nil </span><span class="cov0" title="0">{
return fmt.Errorf("failed to dial gRPC server: %w", err)
}</span>
// Create gateway mux
<span class="cov0" title="0">gwMux := runtime.NewServeMux()
// Register gRPC gateway handlers
err = helloworldpb.RegisterGreeterHandler(ctx, gwMux, conn)
if err != nil </span><span class="cov0" title="0">{
return fmt.Errorf("failed to register gateway: %w", err)
}</span>
// Create HTTP mux with health endpoint
<span class="cov0" title="0">mux := http.NewServeMux()
mux.Handle("/", gwMux)
mux.Handle("/health", s.healthHandler)
s.httpServer = &amp;http.Server{
Addr: ":" + s.config.Server.HTTPPort,
Handler: mux,
ReadTimeout: 30 * time.Second,
WriteTimeout: 30 * time.Second,
IdleTimeout: 120 * time.Second,
}
s.logger.Info("Starting HTTP server", "port", s.config.Server.HTTPPort)
return s.httpServer.ListenAndServe()</span>
}
// Shutdown gracefully shuts down the servers
func (s *Server) Shutdown(ctx context.Context) error <span class="cov0" title="0">{
s.logger.Info("Shutting down servers...")
var wg sync.WaitGroup
// Shutdown HTTP server
if s.httpServer != nil </span><span class="cov0" title="0">{
wg.Add(1)
go func() </span><span class="cov0" title="0">{
defer wg.Done()
if err := s.httpServer.Shutdown(ctx); err != nil </span><span class="cov0" title="0">{
s.logger.Error("HTTP server shutdown error", "error", err)
}</span>
}()
}
// Shutdown gRPC server
<span class="cov0" title="0">if s.grpcServer != nil </span><span class="cov0" title="0">{
wg.Add(1)
go func() </span><span class="cov0" title="0">{
defer wg.Done()
s.grpcServer.GracefulStop()
}</span>()
}
<span class="cov0" title="0">wg.Wait()
s.logger.Info("Servers stopped")
return nil</span>
}
// GreeterService implements the helloworld.Greeter service
type GreeterService struct {
helloworldpb.UnimplementedGreeterServer
}
// SayHello implements the SayHello RPC method
func (g *GreeterService) SayHello(ctx context.Context, req *helloworldpb.HelloRequest) (*helloworldpb.HelloReply, error) <span class="cov0" title="0">{
return &amp;helloworldpb.HelloReply{
Message: "Hello " + req.GetName(),
}, nil
}</span>
func parseLogLevel(level string) slog.Level <span class="cov0" title="0">{
switch level </span>{
case "debug":<span class="cov0" title="0">
return slog.LevelDebug</span>
case "info":<span class="cov0" title="0">
return slog.LevelInfo</span>
case "warn":<span class="cov0" title="0">
return slog.LevelWarn</span>
case "error":<span class="cov0" title="0">
return slog.LevelError</span>
default:<span class="cov0" title="0">
return slog.LevelInfo</span>
}
}</pre>
<pre class="file" id="file4" style="display: none">// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.36.7
// protoc (unknown)
// source: proto/helloworld/hello_world.proto
package helloworld
import (
_ "google.golang.org/genproto/googleapis/api/annotations"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
unsafe "unsafe"
)
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 HelloRequest struct {
state protoimpl.MessageState `protogen:"open.v1"`
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *HelloRequest) Reset() <span class="cov0" title="0">{
*x = HelloRequest{}
mi := &amp;file_proto_helloworld_hello_world_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}</span>
func (x *HelloRequest) String() string <span class="cov0" title="0">{
return protoimpl.X.MessageStringOf(x)
}</span>
func (*HelloRequest) ProtoMessage() {<span class="cov0" title="0">}</span>
func (x *HelloRequest) ProtoReflect() protoreflect.Message <span class="cov0" title="0">{
mi := &amp;file_proto_helloworld_hello_world_proto_msgTypes[0]
if x != nil </span><span class="cov0" title="0">{
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil </span><span class="cov0" title="0">{
ms.StoreMessageInfo(mi)
}</span>
<span class="cov0" title="0">return ms</span>
}
<span class="cov0" title="0">return mi.MessageOf(x)</span>
}
// Deprecated: Use HelloRequest.ProtoReflect.Descriptor instead.
func (*HelloRequest) Descriptor() ([]byte, []int) <span class="cov0" title="0">{
return file_proto_helloworld_hello_world_proto_rawDescGZIP(), []int{0}
}</span>
func (x *HelloRequest) GetName() string <span class="cov0" title="0">{
if x != nil </span><span class="cov0" title="0">{
return x.Name
}</span>
<span class="cov0" title="0">return ""</span>
}
type HelloReply struct {
state protoimpl.MessageState `protogen:"open.v1"`
Message string `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *HelloReply) Reset() <span class="cov0" title="0">{
*x = HelloReply{}
mi := &amp;file_proto_helloworld_hello_world_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}</span>
func (x *HelloReply) String() string <span class="cov0" title="0">{
return protoimpl.X.MessageStringOf(x)
}</span>
func (*HelloReply) ProtoMessage() {<span class="cov0" title="0">}</span>
func (x *HelloReply) ProtoReflect() protoreflect.Message <span class="cov0" title="0">{
mi := &amp;file_proto_helloworld_hello_world_proto_msgTypes[1]
if x != nil </span><span class="cov0" title="0">{
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil </span><span class="cov0" title="0">{
ms.StoreMessageInfo(mi)
}</span>
<span class="cov0" title="0">return ms</span>
}
<span class="cov0" title="0">return mi.MessageOf(x)</span>
}
// Deprecated: Use HelloReply.ProtoReflect.Descriptor instead.
func (*HelloReply) Descriptor() ([]byte, []int) <span class="cov0" title="0">{
return file_proto_helloworld_hello_world_proto_rawDescGZIP(), []int{1}
}</span>
func (x *HelloReply) GetMessage() string <span class="cov0" title="0">{
if x != nil </span><span class="cov0" title="0">{
return x.Message
}</span>
<span class="cov0" title="0">return ""</span>
}
var File_proto_helloworld_hello_world_proto protoreflect.FileDescriptor
const file_proto_helloworld_hello_world_proto_rawDesc = "" +
"\n" +
"\"proto/helloworld/hello_world.proto\x12\n" +
"helloworld\x1a\x1cgoogle/api/annotations.proto\"\"\n" +
"\fHelloRequest\x12\x12\n" +
"\x04name\x18\x01 \x01(\tR\x04name\"&amp;\n" +
"\n" +
"HelloReply\x12\x18\n" +
"\amessage\x18\x01 \x01(\tR\amessage2d\n" +
"\aGreeter\x12Y\n" +
"\bSayHello\x12\x18.helloworld.HelloRequest\x1a\x16.helloworld.HelloReply\"\x1b\x82\xd3\xe4\x93\x02\x15:\x01*\"\x10/v1/example/echoB+Z)go-grpc-gateway-template/proto/helloworldb\x06proto3"
var (
file_proto_helloworld_hello_world_proto_rawDescOnce sync.Once
file_proto_helloworld_hello_world_proto_rawDescData []byte
)
func file_proto_helloworld_hello_world_proto_rawDescGZIP() []byte <span class="cov0" title="0">{
file_proto_helloworld_hello_world_proto_rawDescOnce.Do(func() </span><span class="cov0" title="0">{
file_proto_helloworld_hello_world_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_proto_helloworld_hello_world_proto_rawDesc), len(file_proto_helloworld_hello_world_proto_rawDesc)))
}</span>)
<span class="cov0" title="0">return file_proto_helloworld_hello_world_proto_rawDescData</span>
}
var file_proto_helloworld_hello_world_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
var file_proto_helloworld_hello_world_proto_goTypes = []any{
(*HelloRequest)(nil), // 0: helloworld.HelloRequest
(*HelloReply)(nil), // 1: helloworld.HelloReply
}
var file_proto_helloworld_hello_world_proto_depIdxs = []int32{
0, // 0: helloworld.Greeter.SayHello:input_type -&gt; helloworld.HelloRequest
1, // 1: helloworld.Greeter.SayHello:output_type -&gt; helloworld.HelloReply
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() <span class="cov0" title="0">{ file_proto_helloworld_hello_world_proto_init() }</span>
func file_proto_helloworld_hello_world_proto_init() <span class="cov0" title="0">{
if File_proto_helloworld_hello_world_proto != nil </span><span class="cov0" title="0">{
return
}</span>
<span class="cov0" title="0">type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: unsafe.Slice(unsafe.StringData(file_proto_helloworld_hello_world_proto_rawDesc), len(file_proto_helloworld_hello_world_proto_rawDesc)),
NumEnums: 0,
NumMessages: 2,
NumExtensions: 0,
NumServices: 1,
},
GoTypes: file_proto_helloworld_hello_world_proto_goTypes,
DependencyIndexes: file_proto_helloworld_hello_world_proto_depIdxs,
MessageInfos: file_proto_helloworld_hello_world_proto_msgTypes,
}.Build()
File_proto_helloworld_hello_world_proto = out.File
file_proto_helloworld_hello_world_proto_goTypes = nil
file_proto_helloworld_hello_world_proto_depIdxs = nil</span>
}
</pre>
<pre class="file" id="file5" style="display: none">// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT.
// source: proto/helloworld/hello_world.proto
/*
Package helloworld is a reverse proxy.
It translates gRPC into RESTful JSON APIs.
*/
package helloworld
import (
"context"
"errors"
"io"
"net/http"
"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
"github.com/grpc-ecosystem/grpc-gateway/v2/utilities"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/grpclog"
"google.golang.org/grpc/metadata"
"google.golang.org/grpc/status"
"google.golang.org/protobuf/proto"
)
// Suppress "imported and not used" errors
var (
_ codes.Code
_ io.Reader
_ status.Status
_ = errors.New
_ = runtime.String
_ = utilities.NewDoubleArray
_ = metadata.Join
)
func request_Greeter_SayHello_0(ctx context.Context, marshaler runtime.Marshaler, client GreeterClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) <span class="cov0" title="0">{
var (
protoReq HelloRequest
metadata runtime.ServerMetadata
)
if err := marshaler.NewDecoder(req.Body).Decode(&amp;protoReq); err != nil &amp;&amp; !errors.Is(err, io.EOF) </span><span class="cov0" title="0">{
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}</span>
<span class="cov0" title="0">if req.Body != nil </span><span class="cov0" title="0">{
_, _ = io.Copy(io.Discard, req.Body)
}</span>
<span class="cov0" title="0">msg, err := client.SayHello(ctx, &amp;protoReq, grpc.Header(&amp;metadata.HeaderMD), grpc.Trailer(&amp;metadata.TrailerMD))
return msg, metadata, err</span>
}
func local_request_Greeter_SayHello_0(ctx context.Context, marshaler runtime.Marshaler, server GreeterServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) <span class="cov0" title="0">{
var (
protoReq HelloRequest
metadata runtime.ServerMetadata
)
if err := marshaler.NewDecoder(req.Body).Decode(&amp;protoReq); err != nil &amp;&amp; !errors.Is(err, io.EOF) </span><span class="cov0" title="0">{
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}</span>
<span class="cov0" title="0">msg, err := server.SayHello(ctx, &amp;protoReq)
return msg, metadata, err</span>
}
// RegisterGreeterHandlerServer registers the http handlers for service Greeter to "mux".
// UnaryRPC :call GreeterServer directly.
// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906.
// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterGreeterHandlerFromEndpoint instead.
// GRPC interceptors will not work for this type of registration. To use interceptors, you must use the "runtime.WithMiddlewares" option in the "runtime.NewServeMux" call.
func RegisterGreeterHandlerServer(ctx context.Context, mux *runtime.ServeMux, server GreeterServer) error <span class="cov0" title="0">{
mux.Handle(http.MethodPost, pattern_Greeter_SayHello_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) </span><span class="cov0" title="0">{
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &amp;stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/helloworld.Greeter/SayHello", runtime.WithHTTPPathPattern("/v1/example/echo"))
if err != nil </span><span class="cov0" title="0">{
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}</span>
<span class="cov0" title="0">resp, md, err := local_request_Greeter_SayHello_0(annotatedContext, inboundMarshaler, server, req, pathParams)
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
if err != nil </span><span class="cov0" title="0">{
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
return
}</span>
<span class="cov0" title="0">forward_Greeter_SayHello_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)</span>
})
<span class="cov0" title="0">return nil</span>
}
// RegisterGreeterHandlerFromEndpoint is same as RegisterGreeterHandler but
// automatically dials to "endpoint" and closes the connection when "ctx" gets done.
func RegisterGreeterHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) <span class="cov0" title="0">{
conn, err := grpc.NewClient(endpoint, opts...)
if err != nil </span><span class="cov0" title="0">{
return err
}</span>
<span class="cov0" title="0">defer func() </span><span class="cov0" title="0">{
if err != nil </span><span class="cov0" title="0">{
if cerr := conn.Close(); cerr != nil </span><span class="cov0" title="0">{
grpclog.Errorf("Failed to close conn to %s: %v", endpoint, cerr)
}</span>
<span class="cov0" title="0">return</span>
}
<span class="cov0" title="0">go func() </span><span class="cov0" title="0">{
&lt;-ctx.Done()
if cerr := conn.Close(); cerr != nil </span><span class="cov0" title="0">{
grpclog.Errorf("Failed to close conn to %s: %v", endpoint, cerr)
}</span>
}()
}()
<span class="cov0" title="0">return RegisterGreeterHandler(ctx, mux, conn)</span>
}
// RegisterGreeterHandler registers the http handlers for service Greeter to "mux".
// The handlers forward requests to the grpc endpoint over "conn".
func RegisterGreeterHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error <span class="cov0" title="0">{
return RegisterGreeterHandlerClient(ctx, mux, NewGreeterClient(conn))
}</span>
// RegisterGreeterHandlerClient registers the http handlers for service Greeter
// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "GreeterClient".
// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "GreeterClient"
// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in
// "GreeterClient" to call the correct interceptors. This client ignores the HTTP middlewares.
func RegisterGreeterHandlerClient(ctx context.Context, mux *runtime.ServeMux, client GreeterClient) error <span class="cov0" title="0">{
mux.Handle(http.MethodPost, pattern_Greeter_SayHello_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) </span><span class="cov0" title="0">{
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/helloworld.Greeter/SayHello", runtime.WithHTTPPathPattern("/v1/example/echo"))
if err != nil </span><span class="cov0" title="0">{
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}</span>
<span class="cov0" title="0">resp, md, err := request_Greeter_SayHello_0(annotatedContext, inboundMarshaler, client, req, pathParams)
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
if err != nil </span><span class="cov0" title="0">{
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
return
}</span>
<span class="cov0" title="0">forward_Greeter_SayHello_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)</span>
})
<span class="cov0" title="0">return nil</span>
}
var (
pattern_Greeter_SayHello_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1", "example", "echo"}, ""))
)
var (
forward_Greeter_SayHello_0 = runtime.ForwardResponseMessage
)
</pre>
<pre class="file" id="file6" style="display: none">// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
// versions:
// - protoc-gen-go-grpc v1.5.1
// - protoc (unknown)
// source: proto/helloworld/hello_world.proto
package helloworld
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.64.0 or later.
const _ = grpc.SupportPackageIsVersion9
const (
Greeter_SayHello_FullMethodName = "/helloworld.Greeter/SayHello"
)
// GreeterClient is the client API for Greeter 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 GreeterClient interface {
SayHello(ctx context.Context, in *HelloRequest, opts ...grpc.CallOption) (*HelloReply, error)
}
type greeterClient struct {
cc grpc.ClientConnInterface
}
func NewGreeterClient(cc grpc.ClientConnInterface) GreeterClient <span class="cov0" title="0">{
return &amp;greeterClient{cc}
}</span>
func (c *greeterClient) SayHello(ctx context.Context, in *HelloRequest, opts ...grpc.CallOption) (*HelloReply, error) <span class="cov0" title="0">{
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(HelloReply)
err := c.cc.Invoke(ctx, Greeter_SayHello_FullMethodName, in, out, cOpts...)
if err != nil </span><span class="cov0" title="0">{
return nil, err
}</span>
<span class="cov0" title="0">return out, nil</span>
}
// GreeterServer is the server API for Greeter service.
// All implementations must embed UnimplementedGreeterServer
// for forward compatibility.
type GreeterServer interface {
SayHello(context.Context, *HelloRequest) (*HelloReply, error)
mustEmbedUnimplementedGreeterServer()
}
// UnimplementedGreeterServer must be embedded to have
// forward compatible implementations.
//
// NOTE: this should be embedded by value instead of pointer to avoid a nil
// pointer dereference when methods are called.
type UnimplementedGreeterServer struct{}
func (UnimplementedGreeterServer) SayHello(context.Context, *HelloRequest) (*HelloReply, error) <span class="cov0" title="0">{
return nil, status.Errorf(codes.Unimplemented, "method SayHello not implemented")
}</span>
func (UnimplementedGreeterServer) mustEmbedUnimplementedGreeterServer() {<span class="cov0" title="0">}</span>
func (UnimplementedGreeterServer) testEmbeddedByValue() {<span class="cov0" title="0">}</span>
// UnsafeGreeterServer may be embedded to opt out of forward compatibility for this service.
// Use of this interface is not recommended, as added methods to GreeterServer will
// result in compilation errors.
type UnsafeGreeterServer interface {
mustEmbedUnimplementedGreeterServer()
}
func RegisterGreeterServer(s grpc.ServiceRegistrar, srv GreeterServer) <span class="cov0" title="0">{
// If the following call pancis, it indicates UnimplementedGreeterServer was
// embedded by pointer and is nil. This will cause panics if an
// unimplemented method is ever invoked, so we test this at initialization
// time to prevent it from happening at runtime later due to I/O.
if t, ok := srv.(interface{ testEmbeddedByValue() }); ok </span><span class="cov0" title="0">{
t.testEmbeddedByValue()
}</span>
<span class="cov0" title="0">s.RegisterService(&amp;Greeter_ServiceDesc, srv)</span>
}
func _Greeter_SayHello_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) <span class="cov0" title="0">{
in := new(HelloRequest)
if err := dec(in); err != nil </span><span class="cov0" title="0">{
return nil, err
}</span>
<span class="cov0" title="0">if interceptor == nil </span><span class="cov0" title="0">{
return srv.(GreeterServer).SayHello(ctx, in)
}</span>
<span class="cov0" title="0">info := &amp;grpc.UnaryServerInfo{
Server: srv,
FullMethod: Greeter_SayHello_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) </span><span class="cov0" title="0">{
return srv.(GreeterServer).SayHello(ctx, req.(*HelloRequest))
}</span>
<span class="cov0" title="0">return interceptor(ctx, in, info, handler)</span>
}
// Greeter_ServiceDesc is the grpc.ServiceDesc for Greeter service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
var Greeter_ServiceDesc = grpc.ServiceDesc{
ServiceName: "helloworld.Greeter",
HandlerType: (*GreeterServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "SayHello",
Handler: _Greeter_SayHello_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "proto/helloworld/hello_world.proto",
}
</pre>
</div>
</body>
<script>
(function() {
var files = document.getElementById('files');
var visible;
files.addEventListener('change', onChange, false);
function select(part) {
if (visible)
visible.style.display = 'none';
visible = document.getElementById(part);
if (!visible)
return;
files.value = part;
visible.style.display = 'block';
location.hash = part;
}
function onChange() {
select(files.value);
window.scrollTo(0, 0);
}
if (location.hash != "") {
select(location.hash.substr(1));
}
if (!visible) {
select("file0");
}
})();
</script>
</html>