Further consolidate the libraries
This commit is contained in:
		
							
								
								
									
										211
									
								
								api/handler/registry/registry.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										211
									
								
								api/handler/registry/registry.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,211 @@ | ||||
| // Package registry is a go-micro/registry handler | ||||
| package registry | ||||
|  | ||||
| import ( | ||||
| 	"encoding/json" | ||||
| 	"io/ioutil" | ||||
| 	"net/http" | ||||
| 	"strconv" | ||||
| 	"time" | ||||
|  | ||||
| 	"github.com/gorilla/websocket" | ||||
| 	"github.com/micro/go-micro/api/handler" | ||||
| 	"github.com/micro/go-micro/registry" | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	Handler = "registry" | ||||
|  | ||||
| 	pingTime      = (readDeadline * 9) / 10 | ||||
| 	readLimit     = 16384 | ||||
| 	readDeadline  = 60 * time.Second | ||||
| 	writeDeadline = 10 * time.Second | ||||
| ) | ||||
|  | ||||
| type registryHandler struct { | ||||
| 	opts handler.Options | ||||
| 	reg  registry.Registry | ||||
| } | ||||
|  | ||||
| func (rh *registryHandler) add(w http.ResponseWriter, r *http.Request) { | ||||
| 	r.ParseForm() | ||||
| 	b, err := ioutil.ReadAll(r.Body) | ||||
| 	if err != nil { | ||||
| 		http.Error(w, err.Error(), 500) | ||||
| 		return | ||||
| 	} | ||||
| 	defer r.Body.Close() | ||||
|  | ||||
| 	var opts []registry.RegisterOption | ||||
|  | ||||
| 	// parse ttl | ||||
| 	if ttl := r.Form.Get("ttl"); len(ttl) > 0 { | ||||
| 		d, err := time.ParseDuration(ttl) | ||||
| 		if err == nil { | ||||
| 			opts = append(opts, registry.RegisterTTL(d)) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	var service *registry.Service | ||||
| 	err = json.Unmarshal(b, &service) | ||||
| 	if err != nil { | ||||
| 		http.Error(w, err.Error(), 500) | ||||
| 		return | ||||
| 	} | ||||
| 	err = rh.reg.Register(service, opts...) | ||||
| 	if err != nil { | ||||
| 		http.Error(w, err.Error(), 500) | ||||
| 		return | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (rh *registryHandler) del(w http.ResponseWriter, r *http.Request) { | ||||
| 	r.ParseForm() | ||||
| 	b, err := ioutil.ReadAll(r.Body) | ||||
| 	if err != nil { | ||||
| 		http.Error(w, err.Error(), 500) | ||||
| 		return | ||||
| 	} | ||||
| 	defer r.Body.Close() | ||||
|  | ||||
| 	var service *registry.Service | ||||
| 	err = json.Unmarshal(b, &service) | ||||
| 	if err != nil { | ||||
| 		http.Error(w, err.Error(), 500) | ||||
| 		return | ||||
| 	} | ||||
| 	err = rh.reg.Deregister(service) | ||||
| 	if err != nil { | ||||
| 		http.Error(w, err.Error(), 500) | ||||
| 		return | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (rh *registryHandler) get(w http.ResponseWriter, r *http.Request) { | ||||
| 	r.ParseForm() | ||||
| 	service := r.Form.Get("service") | ||||
|  | ||||
| 	var s []*registry.Service | ||||
| 	var err error | ||||
|  | ||||
| 	if len(service) == 0 { | ||||
| 		// | ||||
| 		upgrade := r.Header.Get("Upgrade") | ||||
| 		connect := r.Header.Get("Connection") | ||||
|  | ||||
| 		// watch if websockets | ||||
| 		if upgrade == "websocket" && connect == "Upgrade" { | ||||
| 			rw, err := rh.reg.Watch() | ||||
| 			if err != nil { | ||||
| 				http.Error(w, err.Error(), 500) | ||||
| 				return | ||||
| 			} | ||||
| 			watch(rw, w, r) | ||||
| 			return | ||||
| 		} | ||||
|  | ||||
| 		// otherwise list services | ||||
| 		s, err = rh.reg.ListServices() | ||||
| 	} else { | ||||
| 		s, err = rh.reg.GetService(service) | ||||
| 	} | ||||
|  | ||||
| 	if err != nil { | ||||
| 		http.Error(w, err.Error(), 500) | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	if s == nil || (len(service) > 0 && (len(s) == 0 || len(s[0].Name) == 0)) { | ||||
| 		http.Error(w, "Service not found", 404) | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	b, err := json.Marshal(s) | ||||
| 	if err != nil { | ||||
| 		http.Error(w, err.Error(), 500) | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	w.Header().Set("Content-Type", "application/json") | ||||
| 	w.Header().Set("Content-Length", strconv.Itoa(len(b))) | ||||
| 	w.Write(b) | ||||
| } | ||||
|  | ||||
| func ping(ws *websocket.Conn, exit chan bool) { | ||||
| 	ticker := time.NewTicker(pingTime) | ||||
|  | ||||
| 	for { | ||||
| 		select { | ||||
| 		case <-ticker.C: | ||||
| 			ws.SetWriteDeadline(time.Now().Add(writeDeadline)) | ||||
| 			err := ws.WriteMessage(websocket.PingMessage, []byte{}) | ||||
| 			if err != nil { | ||||
| 				return | ||||
| 			} | ||||
| 		case <-exit: | ||||
| 			return | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func watch(rw registry.Watcher, w http.ResponseWriter, r *http.Request) { | ||||
| 	upgrader := websocket.Upgrader{ | ||||
| 		ReadBufferSize:  1024, | ||||
| 		WriteBufferSize: 1024, | ||||
| 	} | ||||
|  | ||||
| 	ws, err := upgrader.Upgrade(w, r, nil) | ||||
| 	if err != nil { | ||||
| 		http.Error(w, err.Error(), 500) | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	// we need an exit chan | ||||
| 	exit := make(chan bool) | ||||
|  | ||||
| 	defer func() { | ||||
| 		close(exit) | ||||
| 	}() | ||||
|  | ||||
| 	// ping the socket | ||||
| 	go ping(ws, exit) | ||||
|  | ||||
| 	for { | ||||
| 		// get next result | ||||
| 		r, err := rw.Next() | ||||
| 		if err != nil { | ||||
| 			http.Error(w, err.Error(), 500) | ||||
| 			return | ||||
| 		} | ||||
|  | ||||
| 		// write to client | ||||
| 		ws.SetWriteDeadline(time.Now().Add(writeDeadline)) | ||||
| 		if err := ws.WriteJSON(r); err != nil { | ||||
| 			return | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (rh *registryHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { | ||||
| 	switch r.Method { | ||||
| 	case "GET": | ||||
| 		rh.get(w, r) | ||||
| 	case "POST": | ||||
| 		rh.add(w, r) | ||||
| 	case "DELETE": | ||||
| 		rh.del(w, r) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (rh *registryHandler) String() string { | ||||
| 	return "registry" | ||||
| } | ||||
|  | ||||
| func NewHandler(opts ...handler.Option) handler.Handler { | ||||
| 	options := handler.NewOptions(opts...) | ||||
|  | ||||
| 	return ®istryHandler{ | ||||
| 		opts: options, | ||||
| 		reg:  options.Service.Client().Options().Registry, | ||||
| 	} | ||||
| } | ||||
		Reference in New Issue
	
	Block a user