github.com/gofunct/common@v0.0.0-20190131174352-fd058c7fbf22/pkg/transport/config/config.go (about)

     1  package config
     2  
     3  import (
     4  	"crypto/tls"
     5  	"github.com/gofunct/common/pkg/transport/api"
     6  	"github.com/gofunct/common/pkg/transport/middleware"
     7  	"net"
     8  	"net/http"
     9  	"os"
    10  	"path/filepath"
    11  	pkg_runtime "runtime"
    12  	"time"
    13  
    14  	"github.com/grpc-ecosystem/go-grpc-middleware"
    15  	"github.com/grpc-ecosystem/grpc-gateway/runtime"
    16  	"github.com/pkg/errors"
    17  	"google.golang.org/grpc"
    18  )
    19  
    20  // Config contains configurations of gRPC and Gateway server.
    21  type Config struct {
    22  	GrpcAddr                        *Address
    23  	GrpcInternalAddr                *Address
    24  	GatewayAddr                     *Address
    25  	Servers                         []api.Server
    26  	GrpcServerUnaryInterceptors     []grpc.UnaryServerInterceptor
    27  	GrpcServerStreamInterceptors    []grpc.StreamServerInterceptor
    28  	GatewayServerUnaryInterceptors  []grpc.UnaryClientInterceptor
    29  	GatewayServerStreamInterceptors []grpc.StreamClientInterceptor
    30  	GrpcServerOption                []grpc.ServerOption
    31  	GatewayDialOption               []grpc.DialOption
    32  	GatewayMuxOptions               []runtime.ServeMuxOption
    33  	GatewayServerConfig             *HTTPServerConfig
    34  	MaxConcurrentStreams            uint32
    35  	GatewayServerMiddlewares        []middleware.HTTPServerMiddleware
    36  }
    37  
    38  func CreateDefaultConfig() *Config {
    39  	config := &Config{
    40  		GrpcInternalAddr: &Address{
    41  			Network: "unix",
    42  			Addr:    "tmp/server.sock",
    43  		},
    44  		GatewayAddr: &Address{
    45  			Network: "tcp",
    46  			Addr:    ":3000",
    47  		},
    48  		GatewayServerConfig: &HTTPServerConfig{
    49  			ReadTimeout:  8 * time.Second,
    50  			WriteTimeout: 8 * time.Second,
    51  			IdleTimeout:  2 * time.Minute,
    52  		},
    53  		MaxConcurrentStreams: 1000,
    54  	}
    55  	if pkg_runtime.GOOS == "windows" {
    56  		config.GrpcInternalAddr = &Address{
    57  			Network: "tcp",
    58  			Addr:    ":5050",
    59  		}
    60  	}
    61  	return config
    62  }
    63  
    64  // Address represents a network end point address.
    65  type Address struct {
    66  	Network string
    67  	Addr    string
    68  }
    69  
    70  func (a *Address) CreateListener() (net.Listener, error) {
    71  	if a.Network == "unix" {
    72  		dir := filepath.Dir(a.Addr)
    73  		f, err := os.Stat(dir)
    74  		if err != nil {
    75  			if err = os.MkdirAll(dir, 0755); err != nil {
    76  				return nil, errors.Wrap(err, "failed to create the directory")
    77  			}
    78  		} else if !f.IsDir() {
    79  			return nil, errors.Errorf("file %q already exists", dir)
    80  		}
    81  	}
    82  	lis, err := net.Listen(a.Network, a.Addr)
    83  	if err != nil {
    84  		return nil, errors.Wrapf(err, "failed to listen %s %s", a.Network, a.Addr)
    85  	}
    86  	return lis, nil
    87  }
    88  
    89  type HTTPServerConfig struct {
    90  	TLSConfig         *tls.Config
    91  	ReadTimeout       time.Duration
    92  	ReadHeaderTimeout time.Duration
    93  	WriteTimeout      time.Duration
    94  	IdleTimeout       time.Duration
    95  	MaxHeaderBytes    int
    96  	TLSNextProto      map[string]func(*http.Server, *tls.Conn, http.Handler)
    97  	ConnState         func(net.Conn, http.ConnState)
    98  }
    99  
   100  func (c *HTTPServerConfig) ApplyTo(s *http.Server) {
   101  	s.TLSConfig = c.TLSConfig
   102  	s.ReadTimeout = c.ReadTimeout
   103  	s.ReadHeaderTimeout = c.ReadHeaderTimeout
   104  	s.WriteTimeout = c.WriteTimeout
   105  	s.IdleTimeout = c.IdleTimeout
   106  	s.MaxHeaderBytes = c.MaxHeaderBytes
   107  	s.TLSNextProto = c.TLSNextProto
   108  	s.ConnState = c.ConnState
   109  }
   110  
   111  func (c *Config) ServerOptions() []grpc.ServerOption {
   112  	return append(
   113  		[]grpc.ServerOption{
   114  			grpc_middleware.WithUnaryServerChain(c.GrpcServerUnaryInterceptors...),
   115  			grpc_middleware.WithStreamServerChain(c.GrpcServerStreamInterceptors...),
   116  			grpc.MaxConcurrentStreams(c.MaxConcurrentStreams),
   117  		},
   118  		c.GrpcServerOption...,
   119  	)
   120  }
   121  
   122  func (c *Config) ClientOptions() []grpc.DialOption {
   123  	return append(
   124  		[]grpc.DialOption{
   125  			grpc.WithInsecure(),
   126  			grpc.WithDialer(func(a string, t time.Duration) (net.Conn, error) {
   127  				return net.Dial(c.GrpcInternalAddr.Network, a)
   128  			}),
   129  			grpc.WithUnaryInterceptor(
   130  				grpc_middleware.ChainUnaryClient(c.GatewayServerUnaryInterceptors...),
   131  			),
   132  			grpc.WithStreamInterceptor(
   133  				grpc_middleware.ChainStreamClient(c.GatewayServerStreamInterceptors...),
   134  			),
   135  		},
   136  		c.GatewayDialOption...,
   137  	)
   138  }