// makeTopologyList returns a handler that yields an APITopologyList. func makeTopologyList(rep xfer.Reporter) func(w http.ResponseWriter, r *http.Request) { return func(w http.ResponseWriter, r *http.Request) { var ( rpt = rep.Report() topologies = []APITopologyDesc{} ) for name, def := range topologyRegistry { if def.parent != "" { continue // subtopology, don't show at top level } subTopologies := []APITopologyDesc{} for subName, subDef := range topologyRegistry { if subDef.parent == name { subTopologies = append(subTopologies, APITopologyDesc{ Name: subDef.human, URL: "/api/topology/" + subName, Stats: stats(subDef.renderer.Render(rpt)), }) } } topologies = append(topologies, APITopologyDesc{ Name: def.human, URL: "/api/topology/" + name, SubTopologies: subTopologies, Stats: stats(def.renderer.Render(rpt)), }) } respondWith(w, http.StatusOK, topologies) } }
// Individual edges. func handleEdge(rep xfer.Reporter, t topologyView, w http.ResponseWriter, r *http.Request) { var ( vars = mux.Vars(r) localID = vars["local"] remoteID = vars["remote"] rpt = rep.Report() metadata = t.renderer.EdgeMetadata(rpt, localID, remoteID) ) respondWith(w, http.StatusOK, APIEdge{Metadata: metadata}) }
// Individual nodes. func handleNode(rep xfer.Reporter, t topologyView, w http.ResponseWriter, r *http.Request) { var ( vars = mux.Vars(r) nodeID = vars["id"] rpt = rep.Report() node, ok = t.renderer.Render(rep.Report())[nodeID] ) if !ok { http.NotFound(w, r) return } respondWith(w, http.StatusOK, APINode{Node: render.MakeDetailedNode(rpt, node)}) }
// makeOriginHostHandler makes the /api/origin/* handler. func makeOriginHostHandler(rep xfer.Reporter) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { var ( vars = mux.Vars(r) nodeID = vars["id"] ) origin, ok := getOriginHost(rep.Report().Host, nodeID) if !ok { http.NotFound(w, r) return } respondWith(w, http.StatusOK, origin) } }
func handleWebsocket( w http.ResponseWriter, r *http.Request, rep xfer.Reporter, t topologyView, loop time.Duration, ) { conn, err := upgrader.Upgrade(w, r, nil) if err != nil { // log.Println("Upgrade:", err) return } defer conn.Close() quit := make(chan struct{}) go func(c *websocket.Conn) { for { // just discard everything the browser sends if _, _, err := c.NextReader(); err != nil { close(quit) break } } }(conn) var ( previousTopo render.RenderableNodes tick = time.Tick(loop) ) for { newTopo := t.renderer.Render(rep.Report()) diff := render.TopoDiff(previousTopo, newTopo) previousTopo = newTopo if err := conn.SetWriteDeadline(time.Now().Add(websocketTimeout)); err != nil { return } if err := conn.WriteJSON(diff); err != nil { return } select { case <-quit: return case <-tick: } } }
// makeTopologyList returns a handler that yields an APITopologyList. func makeTopologyList(rep xfer.Reporter) func(w http.ResponseWriter, r *http.Request) { return func(w http.ResponseWriter, r *http.Request) { var ( rpt = rep.Report() topologies = []APITopologyDesc{} ) for name, def := range topologyRegistry { // Don't show sub-topologies at the top level. if def.parent != "" { continue } decorateTopologyForRequest(r, &def) // Collect all sub-topologies of this one, depth=1 only. subTopologies := []APITopologyDesc{} for subName, subDef := range topologyRegistry { if subDef.parent == name { decorateTopologyForRequest(r, &subDef) subTopologies = append(subTopologies, APITopologyDesc{ Name: subDef.human, URL: "/api/topology/" + subName, Options: makeTopologyOptions(subDef), Stats: stats(subDef.renderer, rpt), }) } } // Append. topologies = append(topologies, APITopologyDesc{ Name: def.human, URL: "/api/topology/" + name, SubTopologies: subTopologies, Options: makeTopologyOptions(def), Stats: stats(def.renderer, rpt), }) } respondWith(w, http.StatusOK, topologies) } }
// Full topology. func handleTopology(rep xfer.Reporter, t topologyView, w http.ResponseWriter, r *http.Request) { respondWith(w, http.StatusOK, APITopology{ Nodes: t.renderer.Render(rep.Report()), }) }
// Raw report handler func makeRawReportHandler(rep xfer.Reporter) func(http.ResponseWriter, *http.Request) { return func(w http.ResponseWriter, r *http.Request) { // r.ParseForm() respondWith(w, http.StatusOK, rep.Report()) } }