gitee.com/liuxuezhan/go-micro-v1.18.0@v1.0.0/network/service/handler/handler.go (about) 1 // Package handler implements network RPC handler 2 package handler 3 4 import ( 5 "context" 6 7 "gitee.com/liuxuezhan/go-micro-v1.18.0/errors" 8 "gitee.com/liuxuezhan/go-micro-v1.18.0/network" 9 pbNet "gitee.com/liuxuezhan/go-micro-v1.18.0/network/proto" 10 "gitee.com/liuxuezhan/go-micro-v1.18.0/router" 11 pbRtr "gitee.com/liuxuezhan/go-micro-v1.18.0/router/proto" 12 "gitee.com/liuxuezhan/go-micro-v1.18.0/util/log" 13 ) 14 15 // Network implements network handler 16 type Network struct { 17 Network network.Network 18 } 19 20 func flatten(n network.Node, visited map[string]bool) []network.Node { 21 // if node is nil runaway 22 if n == nil { 23 return nil 24 } 25 26 // set visisted 27 if visited == nil { 28 visited = make(map[string]bool) 29 } 30 31 // create new list of nodes 32 //nolint:prealloc 33 var nodes []network.Node 34 35 // check if already visited 36 if !visited[n.Id()] { 37 // append the current node 38 nodes = append(nodes, n) 39 } 40 41 // set to visited 42 visited[n.Id()] = true 43 44 // visit the list of peers 45 for _, node := range n.Peers() { 46 nodes = append(nodes, flatten(node, visited)...) 47 } 48 49 return nodes 50 } 51 52 func (n *Network) Connect(ctx context.Context, req *pbNet.ConnectRequest, resp *pbNet.ConnectResponse) error { 53 if len(req.Nodes) == 0 { 54 return nil 55 } 56 57 // get list of existing nodes 58 nodes := n.Network.Options().Nodes 59 60 // generate a node map 61 nodeMap := make(map[string]bool) 62 63 for _, node := range nodes { 64 nodeMap[node] = true 65 } 66 67 for _, node := range req.Nodes { 68 // TODO: we may have been provided a network only 69 // so process anad resolve node.Network 70 if len(node.Address) == 0 { 71 continue 72 } 73 74 // already exists 75 if _, ok := nodeMap[node.Address]; ok { 76 continue 77 } 78 79 nodeMap[node.Address] = true 80 nodes = append(nodes, node.Address) 81 } 82 83 log.Infof("Network.Connect setting peers: %v", nodes) 84 85 // reinitialise the peers 86 n.Network.Init( 87 network.Nodes(nodes...), 88 ) 89 90 // call the connect method 91 n.Network.Connect() 92 93 return nil 94 } 95 96 // Nodes returns the list of nodes 97 func (n *Network) Nodes(ctx context.Context, req *pbNet.NodesRequest, resp *pbNet.NodesResponse) error { 98 // root node 99 nodes := map[string]network.Node{} 100 101 // get peers encoded into protobuf 102 peers := flatten(n.Network, nil) 103 104 // walk all the peers 105 for _, peer := range peers { 106 if peer == nil { 107 continue 108 } 109 if _, ok := nodes[peer.Id()]; ok { 110 continue 111 } 112 113 // add to visited list 114 nodes[n.Network.Id()] = peer 115 116 resp.Nodes = append(resp.Nodes, &pbNet.Node{ 117 Id: peer.Id(), 118 Address: peer.Address(), 119 }) 120 } 121 122 return nil 123 } 124 125 // Graph returns the network graph from this root node 126 func (n *Network) Graph(ctx context.Context, req *pbNet.GraphRequest, resp *pbNet.GraphResponse) error { 127 depth := uint(req.Depth) 128 if depth <= 0 || depth > network.MaxDepth { 129 depth = network.MaxDepth 130 } 131 132 // get peers encoded into protobuf 133 peers := network.PeersToProto(n.Network, depth) 134 135 // set the root node 136 resp.Root = peers 137 138 return nil 139 } 140 141 // Routes returns a list of routing table routes 142 func (n *Network) Routes(ctx context.Context, req *pbNet.RoutesRequest, resp *pbNet.RoutesResponse) error { 143 // build query 144 145 var qOpts []router.QueryOption 146 147 if q := req.Query; q != nil { 148 if len(q.Service) > 0 { 149 qOpts = append(qOpts, router.QueryService(q.Service)) 150 } 151 if len(q.Address) > 0 { 152 qOpts = append(qOpts, router.QueryAddress(q.Address)) 153 } 154 if len(q.Gateway) > 0 { 155 qOpts = append(qOpts, router.QueryGateway(q.Gateway)) 156 } 157 if len(q.Router) > 0 { 158 qOpts = append(qOpts, router.QueryRouter(q.Router)) 159 } 160 if len(q.Network) > 0 { 161 qOpts = append(qOpts, router.QueryNetwork(q.Network)) 162 } 163 } 164 165 routes, err := n.Network.Options().Router.Table().Query(qOpts...) 166 if err != nil { 167 return errors.InternalServerError("go.micro.network", "failed to list routes: %s", err) 168 } 169 170 respRoutes := make([]*pbRtr.Route, 0, len(routes)) 171 for _, route := range routes { 172 respRoute := &pbRtr.Route{ 173 Service: route.Service, 174 Address: route.Address, 175 Gateway: route.Gateway, 176 Network: route.Network, 177 Router: route.Router, 178 Link: route.Link, 179 Metric: int64(route.Metric), 180 } 181 respRoutes = append(respRoutes, respRoute) 182 } 183 184 resp.Routes = respRoutes 185 186 return nil 187 } 188 189 // Services returns a list of services based on the routing table 190 func (n *Network) Services(ctx context.Context, req *pbNet.ServicesRequest, resp *pbNet.ServicesResponse) error { 191 routes, err := n.Network.Options().Router.Table().List() 192 if err != nil { 193 return errors.InternalServerError("go.micro.network", "failed to list services: %s", err) 194 } 195 196 services := make(map[string]bool) 197 198 for _, route := range routes { 199 if _, ok := services[route.Service]; ok { 200 continue 201 } 202 services[route.Service] = true 203 resp.Services = append(resp.Services, route.Service) 204 } 205 206 return nil 207 }