gitee.com/liuxuezhan/go-micro-v1.18.0@v1.0.0/router/handler/router.go (about) 1 package handler 2 3 import ( 4 "context" 5 "io" 6 "time" 7 8 "gitee.com/liuxuezhan/go-micro-v1.18.0/errors" 9 "gitee.com/liuxuezhan/go-micro-v1.18.0/router" 10 pb "gitee.com/liuxuezhan/go-micro-v1.18.0/router/proto" 11 ) 12 13 // Router implements router handler 14 type Router struct { 15 Router router.Router 16 } 17 18 // Lookup looks up routes in the routing table and returns them 19 func (r *Router) Lookup(ctx context.Context, req *pb.LookupRequest, resp *pb.LookupResponse) error { 20 routes, err := r.Router.Lookup(router.QueryService(req.Query.Service)) 21 if err != nil { 22 return errors.InternalServerError("go.micro.router", "failed to lookup routes: %v", err) 23 } 24 25 respRoutes := make([]*pb.Route, 0, len(routes)) 26 for _, route := range routes { 27 respRoute := &pb.Route{ 28 Service: route.Service, 29 Address: route.Address, 30 Gateway: route.Gateway, 31 Network: route.Network, 32 Router: route.Router, 33 Link: route.Link, 34 Metric: route.Metric, 35 } 36 respRoutes = append(respRoutes, respRoute) 37 } 38 39 resp.Routes = respRoutes 40 41 return nil 42 } 43 44 // Solicit triggers full routing table advertisement 45 func (r *Router) Solicit(ctx context.Context, req *pb.Request, resp *pb.Response) error { 46 if err := r.Router.Solicit(); err != nil { 47 return err 48 } 49 50 return nil 51 } 52 53 // Advertise streams router advertisements 54 func (r *Router) Advertise(ctx context.Context, req *pb.Request, stream pb.Router_AdvertiseStream) error { 55 advertChan, err := r.Router.Advertise() 56 if err != nil { 57 return errors.InternalServerError("go.micro.router", "failed to get adverts: %v", err) 58 } 59 60 for advert := range advertChan { 61 var events []*pb.Event 62 for _, event := range advert.Events { 63 route := &pb.Route{ 64 Service: event.Route.Service, 65 Address: event.Route.Address, 66 Gateway: event.Route.Gateway, 67 Network: event.Route.Network, 68 Router: event.Route.Router, 69 Link: event.Route.Link, 70 Metric: event.Route.Metric, 71 } 72 e := &pb.Event{ 73 Type: pb.EventType(event.Type), 74 Timestamp: event.Timestamp.UnixNano(), 75 Route: route, 76 } 77 events = append(events, e) 78 } 79 80 advert := &pb.Advert{ 81 Id: advert.Id, 82 Type: pb.AdvertType(advert.Type), 83 Timestamp: advert.Timestamp.UnixNano(), 84 Events: events, 85 } 86 87 // send the advert 88 err := stream.Send(advert) 89 if err == io.EOF { 90 return nil 91 } 92 if err != nil { 93 return errors.InternalServerError("go.micro.router", "error sending message %v", err) 94 } 95 } 96 97 return nil 98 } 99 100 // Process processes advertisements 101 func (r *Router) Process(ctx context.Context, req *pb.Advert, rsp *pb.ProcessResponse) error { 102 events := make([]*router.Event, len(req.Events)) 103 for i, event := range req.Events { 104 route := router.Route{ 105 Service: event.Route.Service, 106 Address: event.Route.Address, 107 Gateway: event.Route.Gateway, 108 Network: event.Route.Network, 109 Router: event.Route.Router, 110 Link: event.Route.Link, 111 Metric: event.Route.Metric, 112 } 113 114 events[i] = &router.Event{ 115 Type: router.EventType(event.Type), 116 Timestamp: time.Unix(0, event.Timestamp), 117 Route: route, 118 } 119 } 120 121 advert := &router.Advert{ 122 Id: req.Id, 123 Type: router.AdvertType(req.Type), 124 Timestamp: time.Unix(0, req.Timestamp), 125 TTL: time.Duration(req.Ttl), 126 Events: events, 127 } 128 129 if err := r.Router.Process(advert); err != nil { 130 return errors.InternalServerError("go.micro.router", "error publishing advert: %v", err) 131 } 132 133 return nil 134 } 135 136 // Status returns router status 137 func (r *Router) Status(ctx context.Context, req *pb.Request, rsp *pb.StatusResponse) error { 138 status := r.Router.Status() 139 140 rsp.Status = &pb.Status{ 141 Code: status.Code.String(), 142 } 143 144 if status.Error != nil { 145 rsp.Status.Error = status.Error.Error() 146 } 147 148 return nil 149 } 150 151 // Watch streans routing table events 152 func (r *Router) Watch(ctx context.Context, req *pb.WatchRequest, stream pb.Router_WatchStream) error { 153 watcher, err := r.Router.Watch() 154 if err != nil { 155 return errors.InternalServerError("go.micro.router", "failed creating event watcher: %v", err) 156 } 157 158 defer stream.Close() 159 160 for { 161 event, err := watcher.Next() 162 if err == router.ErrWatcherStopped { 163 return errors.InternalServerError("go.micro.router", "watcher stopped") 164 } 165 166 if err != nil { 167 return errors.InternalServerError("go.micro.router", "error watching events: %v", err) 168 } 169 170 route := &pb.Route{ 171 Service: event.Route.Service, 172 Address: event.Route.Address, 173 Gateway: event.Route.Gateway, 174 Network: event.Route.Network, 175 Router: event.Route.Router, 176 Link: event.Route.Link, 177 Metric: event.Route.Metric, 178 } 179 180 tableEvent := &pb.Event{ 181 Type: pb.EventType(event.Type), 182 Timestamp: event.Timestamp.UnixNano(), 183 Route: route, 184 } 185 186 if err := stream.Send(tableEvent); err != nil { 187 return err 188 } 189 } 190 }