func main() { // Create listener l, err := net.Listen("tcp", "localhost:10001") if err != nil { log.Fatal(err) } defer l.Close() // Create Config Source f := file.NewSource(config.SourceName("routes.json")) conf := config.NewConfig(config.WithSource(f)) // Create Router r := router.NewRouter(router.Config(conf)) // Setup Handler wr := r.Handler() h := wr(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { http.Error(w, "not found", 404) })) // Start Server if err := http.Serve(l, h); err != nil { log.Fatal(err) } }
func (r *router) Init(ctx *cli.Context) error { // TODO: Make this more configurable and add more sources var conf config.Config if c := ctx.String("config_source"); len(c) == 0 && r.opts.Config == nil { return errors.New("config source must be defined") } else if len(c) > 0 { var source config.Source switch c { case "platform": source = config.NewSource() case "file": fileName := DefaultFile parts := strings.Split(c, ":") if len(parts) > 1 { fileName = parts[1] } source = file.NewSource(config.SourceName(fileName)) default: return errors.New("Unknown config source " + c) } conf = config.NewConfig(config.WithSource(source)) } else { conf = r.opts.Config } go r.run(conf) return nil }
func main() { flag.Parse() // Write our first entry if err := writeFile(0); err != nil { fmt.Println(err) return } defer os.Remove(configFile) // Create a config instance config := config.NewConfig( // aggressive config polling config.PollInterval(time.Millisecond*500), // use file as a config source config.WithSource(file.NewSource(config.SourceName(configFile))), ) defer config.Close() // lets read the value while editing it a number of times for i := 0; i < 10; i++ { val := config.Get("key").String("default") fmt.Println("Got ", val) writeFile(i + 1) time.Sleep(time.Second) } // watch key that exists watch(config, "key") // watch key that does not exist watch(config, "foo") fmt.Println("Stopping config runner") }
func TestRouter(t *testing.T) { l, err := net.Listen("tcp", "127.0.0.1:0") if err != nil { t.Fatal(err) } defer l.Close() routes := []Route{ { Request: Request{ Method: "GET", Host: l.Addr().String(), Path: "/", }, Response: Response{ StatusCode: 302, Header: map[string]string{ "Location": "http://example.com", }, }, Weight: 1.0, }, { Request: Request{ Method: "POST", Host: l.Addr().String(), Path: "/bar", }, Response: Response{ StatusCode: 301, Header: map[string]string{ "Location": "http://foo.bar.com", }, }, Weight: 1.0, }, { Request: Request{ Method: "GET", Host: l.Addr().String(), Path: "/foobar", }, ProxyURL: URL{ Scheme: "http", Host: "www.foo.com", Path: "/", }, Weight: 1.0, Type: "proxy", }, } apiConfig := map[string]interface{}{ "api": map[string]interface{}{ "routes": routes, }, } b, _ := json.Marshal(apiConfig) m := memory.NewSource() m.Update(b) conf := config.NewConfig(config.WithSource(m)) r := NewRouter(Config(conf)) wr := r.Handler() h := wr(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { http.Error(w, "not found", 404) })) go http.Serve(l, h) ErrRedirect := errors.New("redirect") c := &http.Client{ CheckRedirect: func(req *http.Request, via []*http.Request) error { return ErrRedirect }, } for _, route := range routes { var rsp *http.Response var err error switch route.Request.Method { case "GET": rsp, err = c.Get("http://" + route.Request.Host + route.Request.Path) case "POST": rsp, err = c.Post("http://"+route.Request.Host+route.Request.Path, "application/json", bytes.NewBuffer(nil)) } if err != nil { urlErr, ok := err.(*url.Error) if ok && urlErr.Err == ErrRedirect { // skip } else { t.Fatal(err) } } if route.Type == "proxy" { if rsp.StatusCode >= 400 { t.Fatalf("Expected healthy response got %d", rsp.StatusCode) } continue } if rsp.StatusCode != route.Response.StatusCode { t.Fatalf("Expected code %d got %d", route.Response.StatusCode, rsp.StatusCode) } loc := rsp.Header.Get("Location") if loc != route.Response.Header["Location"] { t.Fatalf("Expected Location %s got %s", route.Response.Header["Location"], loc) } } }