github.com/tickoalcantara12/micro/v3@v3.0.0-20221007104245-9d75b9bcbab9/service/network/server/server.go (about)

     1  package server
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"os"
     7  	"strings"
     8  	"time"
     9  
    10  	"github.com/tickoalcantara12/micro/v3/service"
    11  	"github.com/tickoalcantara12/micro/v3/service/client"
    12  	log "github.com/tickoalcantara12/micro/v3/service/logger"
    13  	"github.com/tickoalcantara12/micro/v3/service/network"
    14  	"github.com/tickoalcantara12/micro/v3/service/network/handler"
    15  	"github.com/tickoalcantara12/micro/v3/service/network/transport"
    16  	"github.com/tickoalcantara12/micro/v3/service/network/transport/grpc"
    17  	"github.com/tickoalcantara12/micro/v3/service/network/tunnel"
    18  	tmucp "github.com/tickoalcantara12/micro/v3/service/network/tunnel/mucp"
    19  	"github.com/tickoalcantara12/micro/v3/service/proxy"
    20  	grpcProxy "github.com/tickoalcantara12/micro/v3/service/proxy/grpc"
    21  	mucpProxy "github.com/tickoalcantara12/micro/v3/service/proxy/mucp"
    22  	"github.com/tickoalcantara12/micro/v3/service/router"
    23  	"github.com/tickoalcantara12/micro/v3/service/server"
    24  	mucpServer "github.com/tickoalcantara12/micro/v3/service/server/mucp"
    25  	"github.com/tickoalcantara12/micro/v3/util/helper"
    26  	"github.com/tickoalcantara12/micro/v3/util/muxer"
    27  	"github.com/urfave/cli/v2"
    28  )
    29  
    30  var (
    31  	// name of the network service
    32  	name = "network"
    33  	// name of the micro network
    34  	networkName = "micro"
    35  	// address is the network address
    36  	address = ":8443"
    37  	// peerAddress is the address the network peers on
    38  	peerAddress = ":8085"
    39  	// set the advertise address
    40  	advertise = ""
    41  	// the tunnel token
    42  	token = "micro"
    43  
    44  	// Flags specific to the network
    45  	Flags = []cli.Flag{
    46  		&cli.StringFlag{
    47  			Name:    "address",
    48  			Usage:   "Set the address of the network service",
    49  			EnvVars: []string{"MICRO_NETWORK_ADDRESS"},
    50  		},
    51  		&cli.StringFlag{
    52  			Name:    "advertise",
    53  			Usage:   "Set the micro network address to advertise",
    54  			EnvVars: []string{"MICRO_NETWORK_ADVERTISE"},
    55  		},
    56  		&cli.StringFlag{
    57  			Name:    "gateway",
    58  			Usage:   "Set the default gateway",
    59  			EnvVars: []string{"MICRO_NETWORK_GATEWAY"},
    60  		},
    61  		&cli.StringFlag{
    62  			Name:    "network",
    63  			Usage:   "Set the micro network name: micro",
    64  			EnvVars: []string{"MICRO_NETWORK"},
    65  		},
    66  		&cli.StringFlag{
    67  			Name:    "nodes",
    68  			Usage:   "Set the micro network nodes to connect to. This can be a comma separated list.",
    69  			EnvVars: []string{"MICRO_NETWORK_NODES"},
    70  		},
    71  		&cli.StringFlag{
    72  			Name:    "token",
    73  			Usage:   "Set the micro network token for authentication",
    74  			EnvVars: []string{"MICRO_NETWORK_TOKEN"},
    75  		},
    76  	}
    77  )
    78  
    79  // Run runs the micro server
    80  func Run(ctx *cli.Context) error {
    81  	if len(ctx.String("server_name")) > 0 {
    82  		name = ctx.String("server_name")
    83  	}
    84  	if len(ctx.String("address")) > 0 {
    85  		address = ctx.String("address")
    86  	}
    87  	if len(ctx.String("peer_address")) > 0 {
    88  		peerAddress = ctx.String("peer_address")
    89  	}
    90  	if len(ctx.String("advertise")) > 0 {
    91  		advertise = ctx.String("advertise")
    92  	}
    93  	if len(ctx.String("network")) > 0 {
    94  		networkName = ctx.String("network")
    95  	}
    96  	if len(ctx.String("token")) > 0 {
    97  		token = ctx.String("token")
    98  	}
    99  
   100  	var nodes []string
   101  	if len(ctx.String("nodes")) > 0 {
   102  		nodes = strings.Split(ctx.String("nodes"), ",")
   103  	}
   104  
   105  	// Initialise the local service
   106  	service := service.New(
   107  		service.Name(name),
   108  		service.Address(address),
   109  	)
   110  
   111  	// create a tunnel
   112  	tunOpts := []tunnel.Option{
   113  		tunnel.Address(peerAddress),
   114  		tunnel.Token(token),
   115  	}
   116  
   117  	if ctx.Bool("enable_tls") {
   118  		config, err := helper.TLSConfig(ctx)
   119  		if err != nil {
   120  			fmt.Println(err.Error())
   121  			return err
   122  		}
   123  		config.InsecureSkipVerify = true
   124  
   125  		tunOpts = append(tunOpts, tunnel.Transport(
   126  			grpc.NewTransport(transport.TLSConfig(config)),
   127  		))
   128  	}
   129  
   130  	gateway := ctx.String("gateway")
   131  	tun := tmucp.NewTunnel(tunOpts...)
   132  	id := service.Server().Options().Id
   133  
   134  	// increase the client retries
   135  	client.DefaultClient.Init(
   136  		client.Retries(3),
   137  	)
   138  
   139  	// local tunnel router
   140  	rtr := router.DefaultRouter
   141  
   142  	rtr.Init(
   143  		router.Network(networkName),
   144  		router.Id(id),
   145  		router.Gateway(gateway),
   146  		router.Cache(),
   147  	)
   148  
   149  	// initialise network vals
   150  	network.DefaultNetwork.Init(
   151  		network.Id(id),
   152  		network.Name(networkName),
   153  		network.Address(peerAddress),
   154  		network.Advertise(advertise),
   155  		network.Nodes(nodes...),
   156  		network.Tunnel(tun),
   157  		network.Router(rtr),
   158  	)
   159  
   160  	netService := network.DefaultNetwork
   161  
   162  	// local proxy using grpc
   163  	// TODO: reenable after PR
   164  	localProxy := grpcProxy.NewProxy(
   165  		proxy.WithRouter(rtr),
   166  		proxy.WithClient(service.Client()),
   167  	)
   168  
   169  	// network proxy
   170  	// used by the network nodes to cluster
   171  	// and share routes or route through
   172  	// each other
   173  	networkProxy := mucpProxy.NewProxy(
   174  		proxy.WithRouter(rtr),
   175  		proxy.WithClient(service.Client()),
   176  		proxy.WithLink("network", netService.Client()),
   177  	)
   178  
   179  	// create a handler
   180  	h := mucpServer.DefaultRouter.NewHandler(
   181  		&handler.Network{Network: netService},
   182  	)
   183  
   184  	// register the handler
   185  	mucpServer.DefaultRouter.Handle(h)
   186  
   187  	// local mux
   188  	localMux := muxer.New(name, localProxy)
   189  
   190  	// network mux
   191  	networkMux := muxer.New(name, networkProxy)
   192  
   193  	// init the local grpc server
   194  	service.Server().Init(
   195  		server.WithRouter(localMux),
   196  	)
   197  
   198  	// set network server to proxy
   199  	netService.Server().Init(
   200  		server.WithRouter(networkMux),
   201  	)
   202  
   203  	// connect network
   204  	if err := netService.Connect(); err != nil {
   205  		log.Fatalf("Network failed to connect: %v", err)
   206  	}
   207  
   208  	// netClose hard exits if we have problems
   209  	netClose := func(net network.Network) error {
   210  		errChan := make(chan error, 1)
   211  
   212  		go func() {
   213  			errChan <- net.Close()
   214  		}()
   215  
   216  		select {
   217  		case err := <-errChan:
   218  			return err
   219  		case <-time.After(time.Second):
   220  			return errors.New("Network timeout closing")
   221  		}
   222  	}
   223  
   224  	log.Infof("Network [%s] listening on %s", networkName, peerAddress)
   225  
   226  	if err := service.Run(); err != nil {
   227  		log.Errorf("Network %s failed: %v", networkName, err)
   228  		netClose(netService)
   229  		os.Exit(1)
   230  	}
   231  
   232  	// close the network
   233  	netClose(netService)
   234  
   235  	return nil
   236  }