Skip to content

Commit

Permalink
Merge branch 'SWARM-135'
Browse files Browse the repository at this point in the history
  • Loading branch information
EvgenyGri committed Dec 28, 2023
2 parents fa6909e + 217f3e7 commit b0cec0b
Show file tree
Hide file tree
Showing 9 changed files with 180 additions and 84 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/testing.yml
Expand Up @@ -19,7 +19,7 @@ jobs:

- uses: actions/setup-go@v2
with:
go-version: 1.18
go-version: 1.21

- name: Check deps
run: make go-deps
Expand Down
12 changes: 6 additions & 6 deletions .golangci.yaml
@@ -1,8 +1,8 @@
# More info on config here: https://golangci-lint.run/usage/configuration/#config-file
run:
timeout: 59s
timeout: 100s
issues-exit-code: 1
tests: true
tests: false
skip-dirs:
- bin
- vendor
Expand All @@ -13,7 +13,7 @@ run:
- \.pb\.goclay\.go$


go: '1.18'
go: '1.20'

output:
format: colored-line-number
Expand All @@ -38,9 +38,9 @@ linters:
- unparam
- govet
- errcheck
- deadcode
- structcheck
- varcheck
#- deadcode
#- structcheck
#- varcheck
- ineffassign
- typecheck
- dupl
Expand Down
40 changes: 40 additions & 0 deletions client/grpc/metagata-interceptors.go
@@ -0,0 +1,40 @@
package grpc

import (
"context"

"github.com/H-BF/corlib/pkg/conventions"
"google.golang.org/grpc"
"google.golang.org/grpc/metadata"
)

// AddMetaToOutgoingUnaryInterceptor - specifies fixed headers for every rpc as kv array
func AddMetaToOutgoingUnaryInterceptor(kv ...string) grpc.UnaryClientInterceptor {
return func(ctx context.Context, method string, req, reply any, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error {
if len(kv) != 0 {
ctx = metadata.AppendToOutgoingContext(ctx, kv...)
}
return invoker(ctx, method, req, reply, cc, opts...)
}
}

// AddMetaToOutgoingStreamInterceptor - specifies fixed headers for every rpc as kv array
func AddMetaToOutgoingStreamInterceptor(kv ...string) grpc.StreamClientInterceptor {
return func(ctx context.Context, desc *grpc.StreamDesc, cc *grpc.ClientConn, method string, streamer grpc.Streamer, opts ...grpc.CallOption) (grpc.ClientStream, error) {
ctx = metadata.AppendToOutgoingContext(ctx, kv...)
return streamer(ctx, desc, cc, method, opts...)
}
}

// HostNamePropagator add host name into outgoing metadata
type HostNamePropagator string

// ClientUnary unary client interceptor
func (h HostNamePropagator) ClientUnary() grpc.UnaryClientInterceptor {
return AddMetaToOutgoingUnaryInterceptor(conventions.HostNameHeader, string(h))
}

// ClientStream stream client interceptor
func (h HostNamePropagator) ClientStream() grpc.StreamClientInterceptor {
return AddMetaToOutgoingStreamInterceptor(conventions.HostNameHeader, string(h))
}
2 changes: 1 addition & 1 deletion go.mod
@@ -1,6 +1,6 @@
module github.com/H-BF/corlib

go 1.18
go 1.20

require (
github.com/cenkalti/backoff/v4 v4.1.3
Expand Down
74 changes: 55 additions & 19 deletions pkg/conventions/medatada-and-headers.go
Expand Up @@ -4,17 +4,21 @@ import (
"context"
"strings"

"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
"google.golang.org/grpc/metadata"
)

const (
//SysHeaderPrefix common of system GRPC metadata and HTTP headers
SysHeaderPrefix = "x-sbr-"
SysHeaderPrefix = "x-sys-"
)

const (
//UserAgentHeader web requests
// UserAgentHeader web requests
UserAgentHeader = "user-agent"

// HostNameHeader remote host name going from grpc-client
HostNameHeader = "host-name"
)

const (
Expand All @@ -28,18 +32,18 @@ const (
AppVersionHeader = SysHeaderPrefix + "app-ver"
)

//ClientName user agent extractor
// ClientName user agent extractor
var ClientName clientNameExtractor

//Incoming extracts user agent from incoming context
// Incoming extracts user agent from incoming context
func (a clientNameExtractor) Incoming(ctx context.Context, defVal string) string {
if ret, ok := a.extractClientName(ctx, a.mdIncoming); ok {
return ret
}
return defVal
}

//Outgoing extracts user agent from outgoing context
// Outgoing extracts user agent from outgoing context
func (a clientNameExtractor) Outgoing(ctx context.Context, defVal string) string {
if ret, ok := a.extractClientName(ctx, a.mdOutgoing); ok {
return ret
Expand All @@ -64,24 +68,56 @@ func (clientNameExtractor) mdOutgoing(ctx context.Context) metadata.MD {
}

func (clientNameExtractor) extractClientName(ctx context.Context, mdExtractor func(ctx context.Context) metadata.MD) (string, bool) {
var (
res string
ok bool
)
if md := mdExtractor(ctx); md != nil {
for _, k := range []string{AppNameHeader, UserAgentHeader} {
if v := md[k]; len(v) > 0 {
res, ok = v[0], true
break
ff := [...]func(metadata.MD, string) string{
GetAppName, GetUserAgent,
}
for _, f := range ff {
if v := f(md, ""); v != "" {
return v, true
}
}
}
const suffix = "grpc-go/"
if ok && len(res) > 0 {
n := strings.Index(res, suffix)
if n > 0 {
res = strings.TrimRight(res[:n], " ")
return "", false
}

// GetAppName -
func GetAppName(md metadata.MD, defVal string) string {
return getAnyFromMD(md, defVal, AppNameHeader)
}

// GetUserAgent -
func GetUserAgent(md metadata.MD, defVal string) string {
return getAnyFromMD(md, defVal, runtime.MetadataPrefix+UserAgentHeader, UserAgentHeader)
}

// GetHostName -
func GetHostName(md metadata.MD, defVal string) string {
return getAnyFromMD(md, defVal, HostNameHeader)
}

func getAnyFromMD(md metadata.MD, defVal string, keys ...string) string {
var s string
var k string
for _, k = range keys {
if data := md.Get(k); len(data) > 0 {
s = data[0]
break
}
}
return res, ok
if strings.HasSuffix(k, UserAgentHeader) {
s = removeGrpcGoPrefixAndVersion(s)
}
if s == "" {
return defVal
}
return s
}

func removeGrpcGoPrefixAndVersion(s string) string {
const suffix = "grpc-go/" //мерзотный суффикс
if n := strings.Index(s, suffix); n >= 0 {
return strings.TrimRight(s[:n], " ")
}
return s
}
22 changes: 11 additions & 11 deletions server/api-server-options.go
Expand Up @@ -11,7 +11,7 @@ import (
"google.golang.org/grpc/tap"
)

//WithDocs добавим сваггер доку
// WithDocs добавим сваггер доку
func WithDocs(docs *SwaggerSpec, anURLSuffix string) APIServerOption {
return serverOptApplier(func(srv *APIServer) error {
if srv.docs = docs; docs != nil {
Expand All @@ -23,7 +23,7 @@ func WithDocs(docs *SwaggerSpec, anURLSuffix string) APIServerOption {
})
}

//WithServices добавим service APIs к серверу
// WithServices добавим service APIs к серверу
func WithServices(services ...APIService) APIServerOption {
return serverOptApplier(func(srv *APIServer) error {
for _, s := range services {
Expand All @@ -35,55 +35,55 @@ func WithServices(services ...APIService) APIServerOption {
})
}

//WithGrpcServerOptions добавим GRPC опции
// WithGrpcServerOptions добавим GRPC опции
func WithGrpcServerOptions(options ...grpc.ServerOption) APIServerOption {
return serverOptApplier(func(srv *APIServer) error {
srv.grpcOptions = append(srv.grpcOptions, options...)
return nil
})
}

//WithGatewayOptions добавим GW-2-GRPC опции
// WithGatewayOptions добавим GW-2-GRPC опции
func WithGatewayOptions(options ...runtime.ServeMuxOption) APIServerOption {
return serverOptApplier(func(srv *APIServer) error {
srv.gatewayOptions = append(srv.gatewayOptions, options...)
return nil
})
}

//WithStatsHandlers добавим stats.Handler-ы
// WithStatsHandlers добавим stats.Handler-ы
func WithStatsHandlers(handlers ...stats.Handler) APIServerOption {
return serverOptApplier(func(srv *APIServer) error {
srv.grpcStatsHandlers = append(srv.grpcStatsHandlers, handlers...)
return nil
})
}

//WithTapInHandlers добавим tap.ServerInHandle-ы
// WithTapInHandlers добавим tap.ServerInHandle-ы
func WithTapInHandlers(handlers ...tap.ServerInHandle) APIServerOption {
return serverOptApplier(func(srv *APIServer) error {
srv.grpcTapHandlers = append(srv.grpcTapHandlers, handlers...)
return nil
})
}

//WithUnaryInterceptors добавим унарные перехвачики
// WithUnaryInterceptors добавим унарные перехвачики
func WithUnaryInterceptors(interceptors ...grpc.UnaryServerInterceptor) APIServerOption {
return serverOptApplier(func(srv *APIServer) error {
srv.grpcUnaryInterceptors = append(srv.grpcUnaryInterceptors, interceptors...)
return nil
})
}

//WithStreamInterceptors добавим стримовые перехватчики
// WithStreamInterceptors добавим стримовые перехватчики
func WithStreamInterceptors(interceptors ...grpc.StreamServerInterceptor) APIServerOption {
return serverOptApplier(func(srv *APIServer) error {
srv.grpcStreamInterceptors = append(srv.grpcStreamInterceptors, interceptors...)
return nil
})
}

//WithRecovery ...
// WithRecovery ...
func WithRecovery(recovery *interceptors.Recovery) APIServerOption {
return serverOptApplier(func(srv *APIServer) error {
srv.addDefInterceptors &= ^interceptors.DefRecovery
Expand All @@ -92,7 +92,7 @@ func WithRecovery(recovery *interceptors.Recovery) APIServerOption {
})
}

//SkipDefInterceptors ...
// SkipDefInterceptors ...
func SkipDefInterceptors(ids ...interceptors.DefInterceptor) APIServerOption {
return serverOptApplier(func(srv *APIServer) error {
for _, interceptorID := range ids {
Expand All @@ -110,7 +110,7 @@ func WithTracer(t GRPCTracer) APIServerOption {
})
}

//WithHttpHandler add HTTP handler for pattern
// WithHttpHandler add HTTP handler for pattern
func WithHttpHandler(pattern string, handler http.Handler) APIServerOption { //nolint:revive
return serverOptApplier(func(srv *APIServer) error {
pattern = "/" + strings.Trim(
Expand Down
14 changes: 12 additions & 2 deletions server/api-server-run-assistant.go
Expand Up @@ -94,8 +94,11 @@ func (ass *runAPIServersAssistant) constructProxyConn(ctx context.Context, ep *p
ret, err := grpc.DialContext(
ctx,
endpointAddr,
grpc.WithUserAgent("grpc-api-gw"),
grpc.WithTransportCredentials(insecure.NewCredentials()),
grpc.WithUnaryInterceptor(grpc_retry.UnaryClientInterceptor(opts...)),
grpc.WithChainUnaryInterceptor(
grpc_retry.UnaryClientInterceptor(opts...),
),
)
if err == nil {
rt.SetFinalizer(ret, func(o *grpc.ClientConn) {
Expand Down Expand Up @@ -136,9 +139,16 @@ func (ass *runAPIServersAssistant) construct(runner *runAPIServersOptions) error
for k, values := range h {
doSet := len(k) >= len(conventions.SysHeaderPrefix) &&
strings.EqualFold(k[:n], conventions.SysHeaderPrefix)
/*//TODO: Remove this
if !doSet {
doSet = strings.EqualFold(k, conventions.UserAgentHeader)
headers := [...]string{
conventions.UserAgentHeader, conventions.HostNameHeader,
}
for i := 0; !doSet && i < len(headers); i++ {
doSet = strings.EqualFold(k, headers[i])
}
}
*/
if doSet {
md.Set(k, values...)
}
Expand Down

0 comments on commit b0cec0b

Please sign in to comment.