Beispiel #1
0
// Proxy is a reverse proxy used by the micro web and api
func Proxy(ns string, ws bool) http.Handler {
	return &proxy{
		Namespace: ns,
		Selector: cache.NewSelector(
			selector.Registry((*cmd.DefaultOptions().Registry)),
		),
		re: regexp.MustCompile("^[a-zA-Z0-9]+$"),
		ws: ws,
	}
}
Beispiel #2
0
func (s *srv) proxy() http.Handler {
	sel := cache.NewSelector(
		selector.Registry((*cmd.DefaultOptions().Registry)),
	)

	director := func(r *http.Request) {
		kill := func() {
			r.URL.Host = ""
			r.URL.Path = ""
			r.URL.Scheme = ""
			r.Host = ""
			r.RequestURI = ""
		}

		parts := strings.Split(r.URL.Path, "/")
		if len(parts) < 2 {
			kill()
			return
		}
		if !re.MatchString(parts[1]) {
			kill()
			return
		}
		next, err := sel.Select(Namespace + "." + parts[1])
		if err != nil {
			kill()
			return
		}

		s, err := next()
		if err != nil {
			kill()
			return
		}

		r.Header.Set(BasePathHeader, "/"+parts[1])
		r.URL.Host = fmt.Sprintf("%s:%d", s.Address, s.Port)
		r.URL.Path = "/" + strings.Join(parts[2:], "/")
		r.URL.Scheme = "http"
		r.Host = r.URL.Host
	}

	return &proxy{
		Default:  &httputil.ReverseProxy{Director: director},
		Director: director,
	}
}
Beispiel #3
0
func TestWatcher(t *testing.T) {
	r := setupRegistry()
	c := cache.NewSelector(selector.Registry(r))

	// wait for watcher to get setup
	time.Sleep(time.Millisecond)

	// check that service is blank
	if _, err := c.Select("foo.service"); err != registry.ErrNotFound {
		log.Fatal("expected registry.ErrNotFound")
	}

	// setup svc
	svc1 := &registry.Service{Name: "foo.service", Version: "1"}
	register(r, "pod-1", svc1)
	time.Sleep(time.Millisecond)

	var wg sync.WaitGroup
	wg.Add(3)

	c.Select("foo.service", selector.WithFilter(func(svcs []*registry.Service) []*registry.Service {
		defer wg.Done()
		if !hasServices(svcs, []*registry.Service{svc1}) {
			t.Fatal("expected services to match")
		}
		return nil
	}))

	// setup svc
	svc2 := &registry.Service{Name: "foo.service", Version: "1"}
	register(r, "pod-2", svc2)
	time.Sleep(time.Millisecond)

	c.Select("foo.service", selector.WithFilter(func(svcs []*registry.Service) []*registry.Service {
		defer wg.Done()
		if !hasNodes(svcs[0].Nodes, []*registry.Node{svc1.Nodes[0], svc2.Nodes[0]}) {
			t.Fatal("expected to have same nodes")
		}
		return nil
	}))

	// deregister
	os.Setenv("HOSTNAME", "pod-1")
	r.Deregister(svc1)
	time.Sleep(time.Millisecond)

	c.Select("foo.service", selector.WithFilter(func(svcs []*registry.Service) []*registry.Service {

		defer wg.Done()
		if !hasServices(svcs, []*registry.Service{svc2}) {
			t.Fatal("expected services to match")
		}
		return nil
	}))

	// remove pods
	teardownRegistry()
	time.Sleep(time.Millisecond)

	if _, err := c.Select("foo.service"); err != registry.ErrNotFound {
		log.Fatal("expected registry.ErrNotFound")
	}

	out := make(chan bool)
	go func() {
		wg.Wait()
		close(out)
	}()

	select {
	case <-out:
		return
	case <-time.After(time.Second):
		t.Fatal("expected c.Select() to be called 3 times")
	}

}
Beispiel #4
0
func NewSelector(opts ...selector.Option) selector.Selector {
	return cache.NewSelector(opts...)
}