예제 #1
0
func (r *RouteFetcher) deleteEndpoints(validRoutes []models.Route) {
	var diff []models.Route

	for _, curRoute := range r.endpoints {
		routeFound := false

		for _, validRoute := range validRoutes {
			if routeEquals(curRoute, validRoute) {
				routeFound = true
				break
			}
		}

		if !routeFound {
			diff = append(diff, curRoute)
		}
	}

	for _, aRoute := range diff {
		r.RouteRegistry.Unregister(
			route.Uri(aRoute.Route),
			route.NewEndpoint(
				aRoute.LogGuid,
				aRoute.IP,
				uint16(aRoute.Port),
				aRoute.LogGuid,
				"",
				nil,
				aRoute.GetTTL(),
				aRoute.RouteServiceUrl,
				aRoute.ModificationTag,
			))
	}
}
func loadBalanceFor(strategy string, b *testing.B) {

	pool := route.NewPool(2*time.Minute, "")
	total := 5
	endpoints := make([]*route.Endpoint, 0)
	for i := 0; i < total; i++ {
		ip := fmt.Sprintf("10.0.1.%d", i)
		e := route.NewEndpoint("", ip, 60000, "", "", nil, -1, "", models.ModificationTag{})
		endpoints = append(endpoints, e)
		pool.Put(e)
	}

	var lb route.EndpointIterator
	switch strategy {
	case "round-robin":
		lb = route.NewRoundRobin(pool, "")
	case "least-connection":
		lb = route.NewLeastConnection(pool, "")
	default:
		panic("invalid load balancing strategy")
	}

	for n := 0; n < b.N; n++ {
		loadBalance(lb)
	}
}
예제 #3
0
func registerAddr(reg *registry.RouteRegistry, path string, routeServiceUrl string, addr net.Addr, instanceId, instanceIndex, appId string) {
	host, portStr, err := net.SplitHostPort(addr.String())
	Expect(err).NotTo(HaveOccurred())

	port, err := strconv.Atoi(portStr)
	Expect(err).NotTo(HaveOccurred())
	reg.Register(route.Uri(path), route.NewEndpoint(appId, host, uint16(port), instanceId, instanceIndex, nil, -1, routeServiceUrl, models.ModificationTag{}))
}
예제 #4
0
func (rm *RegistryMessage) makeEndpoint() *route.Endpoint {
	return route.NewEndpoint(
		rm.App,
		rm.Host,
		rm.Port,
		rm.PrivateInstanceID,
		rm.PrivateInstanceIndex,
		rm.Tags,
		rm.StaleThresholdInSeconds,
		rm.RouteServiceURL,
		models.ModificationTag{})
}
예제 #5
0
func (r *RouteFetcher) HandleEvent(e routing_api.Event) {
	eventRoute := e.Route
	uri := route.Uri(eventRoute.Route)
	endpoint := route.NewEndpoint(
		eventRoute.LogGuid,
		eventRoute.IP,
		uint16(eventRoute.Port),
		eventRoute.LogGuid,
		"",
		nil,
		eventRoute.GetTTL(),
		eventRoute.RouteServiceUrl,
		eventRoute.ModificationTag)
	switch e.Action {
	case "Delete":
		r.RouteRegistry.Unregister(uri, endpoint)
	case "Upsert":
		r.RouteRegistry.Register(uri, endpoint)
	}
}
예제 #6
0
func (r *RouteFetcher) refreshEndpoints(validRoutes []models.Route) {
	r.deleteEndpoints(validRoutes)

	r.endpoints = validRoutes

	for _, aRoute := range r.endpoints {
		r.RouteRegistry.Register(
			route.Uri(aRoute.Route),
			route.NewEndpoint(
				aRoute.LogGuid,
				aRoute.IP,
				uint16(aRoute.Port),
				aRoute.LogGuid,
				"",
				nil,
				aRoute.GetTTL(),
				aRoute.RouteServiceUrl,
				aRoute.ModificationTag,
			))
	}
}
func CreateAccessLogRecord() *schema.AccessLogRecord {
	u, err := url.Parse("http://foo.bar:1234/quz?wat")
	if err != nil {
		panic(err)
	}

	req := &http.Request{
		Method:     "GET",
		URL:        u,
		Proto:      "HTTP/1.1",
		Header:     make(http.Header),
		Host:       "foo.bar",
		RemoteAddr: "1.2.3.4:5678",
	}

	req.Header.Set("Referer", "referer")
	req.Header.Set("User-Agent", "user-agent")

	res := &http.Response{
		StatusCode: http.StatusOK,
	}

	b := route.NewEndpoint("my_awesome_id", "127.0.0.1", 4567, "", "", nil, -1, "", models.ModificationTag{})

	r := schema.AccessLogRecord{
		Request:       req,
		StatusCode:    res.StatusCode,
		RouteEndpoint: b,
		StartedAt:     time.Unix(10, 100000000),
		FirstByteAt:   time.Unix(10, 200000000),
		FinishedAt:    time.Unix(10, 300000000),
		BodyBytesSent: 42,
	}

	return &r
}
예제 #8
0
		r.Insert("/foo/bar/baz", p1)
		r.Insert("/foo/bar", p2)

		Expect(r.PoolCount()).To(Equal(2))
	})

	Describe(".PruneDeadLeaves", func() {
		It("removes dead leaves", func() {
			segments := make([]string, 0)
			count := 0
			f := func(r *container.Trie) {
				segments = append(segments, r.Segment)
				count += 1
			}

			e1 := route.NewEndpoint("", "192.168.1.1", 1234, "", "", nil, -1, "", modTag)
			e2 := route.NewEndpoint("", "192.168.1.1", 4321, "", "", nil, -1, "", modTag)
			p1 := route.NewPool(42, "")
			p2 := route.NewPool(42, "")
			p3 := route.NewPool(42, "")
			p4 := route.NewPool(42, "")
			p1.Put(e1)
			p2.Put(e2)
			r.Insert("/foo", p1)
			r.Insert("/foo/bar/baz", p2)
			r.Insert("/zoo", p3)
			r.Insert("/foo/bar/zak", p4)

			r.EachNodeWithPool(f)
			Expect(segments).To(ConsistOf("foo", "baz", "zak", "zoo"))
			Expect(count).To(Equal(4))
예제 #9
0
var _ = Describe("AccessLogRecord", func() {
	Measure("Register", func(b Benchmarker) {
		logger := lagertest.NewTestLogger("test")
		c := config.DefaultConfig()
		r := registry.NewRouteRegistry(logger, c, new(fakes.FakeRouteRegistryReporter))

		accesslog, err := access_log.CreateRunningAccessLogger(logger, c)
		Expect(err).ToNot(HaveOccurred())

		proxy.NewProxy(proxy.ProxyArgs{
			EndpointTimeout: c.EndpointTimeout,
			Ip:              c.Ip,
			TraceKey:        c.TraceKey,
			Registry:        r,
			Reporter:        varz.NewVarz(r),
			AccessLogger:    accesslog,
		})

		b.Time("RegisterTime", func() {
			for i := 0; i < 1000; i++ {
				str := strconv.Itoa(i)
				r.Register(
					route.Uri("bench.vcap.me."+str),
					route.NewEndpoint("", "localhost", uint16(i), "", "", nil, -1, "", models.ModificationTag{}),
				)
			}
		})
	}, 10)

})
예제 #10
0
			err := fetcher.FetchRoutes()
			Expect(err).ToNot(HaveOccurred())

			Expect(registry.RegisterCallCount()).To(Equal(3))

			for i := 0; i < 3; i++ {
				expectedRoute := response[i]
				uri, endpoint := registry.RegisterArgsForCall(i)
				Expect(uri).To(Equal(route.Uri(expectedRoute.Route)))
				Expect(endpoint).To(Equal(
					route.NewEndpoint(expectedRoute.LogGuid,
						expectedRoute.IP, uint16(expectedRoute.Port),
						expectedRoute.LogGuid,
						"",
						nil,
						*expectedRoute.TTL,
						expectedRoute.RouteServiceUrl,
						expectedRoute.ModificationTag,
					)))
			}
		})

		It("uses cache when fetching token from UAA", func() {
			client.RoutesReturns(response, nil)

			err := fetcher.FetchRoutes()
			Expect(err).ToNot(HaveOccurred())
			Expect(uaaClient.FetchTokenCallCount()).To(Equal(1))
			Expect(uaaClient.FetchTokenArgsForCall(0)).To(Equal(false))
		})
예제 #11
0
				Expect(iter.Next()).To(BeNil())
			})
		})

		Context("when pool has endpoints", func() {
			var (
				endpoints []*route.Endpoint
				total     int
			)

			BeforeEach(func() {
				total = 5
				endpoints = make([]*route.Endpoint, 0)
				for i := 0; i < total; i++ {
					ip := fmt.Sprintf("10.0.1.%d", i)
					e := route.NewEndpoint("", ip, 60000, "", "", nil, -1, "", models.ModificationTag{})
					endpoints = append(endpoints, e)
					pool.Put(e)
				}
				// 10.0.1.0:6000
				// 10.0.1.1:6000
				// 10.0.1.2:6000
				// 10.0.1.3:6000
				// 10.0.1.4:6000
			})

			Context("when all endpoints have no statistics", func() {
				It("selects a random endpoint", func() {
					iter := route.NewLeastConnection(pool, "")
					n := iter.Next()
					Expect(n).NotTo(BeNil())
예제 #12
0
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

var _ = Describe("RoundRobin", func() {
	var pool *route.Pool
	var modTag models.ModificationTag

	BeforeEach(func() {
		pool = route.NewPool(2*time.Minute, "")
		modTag = models.ModificationTag{}
	})

	Describe("Next", func() {
		It("performs round-robin through the endpoints", func() {
			e1 := route.NewEndpoint("", "1.2.3.4", 5678, "", "", nil, -1, "", modTag)
			e2 := route.NewEndpoint("", "5.6.7.8", 1234, "", "", nil, -1, "", modTag)
			e3 := route.NewEndpoint("", "1.2.7.8", 1234, "", "", nil, -1, "", modTag)
			endpoints := []*route.Endpoint{e1, e2, e3}

			for _, e := range endpoints {
				pool.Put(e)
			}

			counts := make([]int, len(endpoints))

			iter := route.NewRoundRobin(pool, "")

			loops := 50
			for i := 0; i < len(endpoints)*loops; i += 1 {
				n := iter.Next()
예제 #13
0
	var modTag models.ModificationTag

	BeforeEach(func() {

		logger = lagertest.NewTestLogger("test")
		configObj = config.DefaultConfig()
		configObj.PruneStaleDropletsInterval = 50 * time.Millisecond
		configObj.DropletStaleThreshold = 24 * time.Millisecond

		reporter = new(fakes.FakeRouteRegistryReporter)

		r = NewRouteRegistry(logger, configObj, reporter)
		modTag = models.ModificationTag{}
		fooEndpoint = route.NewEndpoint("12345", "192.168.1.1", 1234,
			"id1", "0",
			map[string]string{
				"runtime":   "ruby18",
				"framework": "sinatra",
			}, -1, "", modTag)

		barEndpoint = route.NewEndpoint("54321", "192.168.1.2", 4321,
			"id2", "0", map[string]string{
				"runtime":   "javascript",
				"framework": "node",
			}, -1, "https://my-rs.com", modTag)

		bar2Endpoint = route.NewEndpoint("54321", "192.168.1.3", 1234,
			"id3", "0", map[string]string{
				"runtime":   "javascript",
				"framework": "node",
			}, -1, "", modTag)
	})
	var fakeReporter2 *fakes.FakeProxyReporter
	var composite reporter.ProxyReporter

	var req *http.Request
	var endpoint *route.Endpoint
	var response *http.Response
	var responseTime time.Time
	var responseDuration time.Duration

	BeforeEach(func() {
		fakeReporter1 = new(fakes.FakeProxyReporter)
		fakeReporter2 = new(fakes.FakeProxyReporter)

		composite = metrics.NewCompositeReporter(fakeReporter1, fakeReporter2)
		req, _ = http.NewRequest("GET", "https://example.com", nil)
		endpoint = route.NewEndpoint("someId", "host", 2222, "privateId", "2", map[string]string{}, 30, "", models.ModificationTag{})
		response = &http.Response{StatusCode: 200}
		responseTime = time.Now()
		responseDuration = time.Second
	})

	It("forwards CaptureBadRequest to both reporters", func() {
		composite.CaptureBadRequest(req)

		Expect(fakeReporter1.CaptureBadRequestCallCount()).To(Equal(1))
		Expect(fakeReporter2.CaptureBadRequestCallCount()).To(Equal(1))

		Expect(fakeReporter1.CaptureBadRequestArgsForCall(0)).To(Equal(req))
		Expect(fakeReporter2.CaptureBadRequestArgsForCall(0)).To(Equal(req))
	})
				Expect(fakeLogSender.GetLogs()[0].Message).To(MatchRegexp("^.*foo.bar.*\n"))
				Expect(fakeLogSender.GetLogs()[0].SourceType).To(Equal("RTR"))
				Expect(fakeLogSender.GetLogs()[0].SourceInstance).To(Equal("42"))
				Expect(fakeLogSender.GetLogs()[0].MessageType).To(Equal("OUT"))

				accessLogger.Stop()
			})

			It("a record with no app id is not logged to dropsonde", func() {

				fakeLogSender := fake.NewFakeLogSender()
				logs.Initialize(fakeLogSender)

				accessLogger := NewFileAndLoggregatorAccessLogger(logger, "43")

				routeEndpoint := route.NewEndpoint("", "127.0.0.1", 4567, "", "", nil, -1, "", models.ModificationTag{})

				accessLogRecord := CreateAccessLogRecord()
				accessLogRecord.RouteEndpoint = routeEndpoint
				accessLogger.Log(*accessLogRecord)
				go accessLogger.Run()

				Consistently(fakeLogSender.GetLogs).Should(HaveLen(0))

				accessLogger.Stop()
			})

		})

		Context("created with access log file", func() {
			It("writes to the log file and Stdout", func() {
	"code.cloudfoundry.org/gorouter/route"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"

	"net/http"
	"net/url"
	"time"
)

var _ = Describe("AccessLogRecord", func() {
	var (
		endpoint *route.Endpoint
		record   *schema.AccessLogRecord
	)
	BeforeEach(func() {
		endpoint = route.NewEndpoint("FakeApplicationId", "1.2.3.4", 1234, "", "3", nil, 0, "", models.ModificationTag{})
		record = &schema.AccessLogRecord{
			Request: &http.Request{
				Host:   "FakeRequestHost",
				Method: "FakeRequestMethod",
				Proto:  "FakeRequestProto",
				URL: &url.URL{
					Opaque: "http://example.com/request",
				},
				Header: http.Header{
					"Referer":                       []string{"FakeReferer"},
					"User-Agent":                    []string{"FakeUserAgent"},
					"X-Forwarded-For":               []string{"FakeProxy1, FakeProxy2"},
					"X-Forwarded-Proto":             []string{"FakeOriginalRequestProto"},
					router_http.VcapRequestIdHeader: []string{"abc-123-xyz-pdq"},
				},
예제 #17
0
	BeforeEach(func() {
		pool = route.NewPool(2*time.Minute, "")
		modTag = models.ModificationTag{}
	})

	Context("Put", func() {
		It("adds endpoints", func() {
			endpoint := &route.Endpoint{}

			b := pool.Put(endpoint)
			Expect(b).To(BeTrue())
		})

		It("handles duplicate endpoints", func() {
			endpoint := route.NewEndpoint("", "1.2.3.4", 5678, "", "", nil, 1, "", modTag)
			pool.Put(endpoint)
			pool.MarkUpdated(time.Now().Add(-(10 * time.Minute)))

			b := pool.Put(endpoint)
			Expect(b).To(BeTrue())

			prunedEndpoints := pool.PruneEndpoints(time.Second)
			Expect(prunedEndpoints).To(BeEmpty())
		})

		It("handles equivalent (duplicate) endpoints", func() {
			endpoint1 := route.NewEndpoint("", "1.2.3.4", 5678, "", "", nil, -1, "", modTag)
			endpoint2 := route.NewEndpoint("", "1.2.3.4", 5678, "", "", nil, -1, "", modTag)

			pool.Put(endpoint1)
예제 #18
0
	})

	It("reports seconds since last registry update", func() {
		Registry.Register("foo", &route.Endpoint{})

		time.Sleep(10 * time.Millisecond)

		timeSince := findValue(Varz, "ms_since_last_registry_update").(float64)
		Expect(timeSince).To(BeNumerically("<", 1000))
		Expect(timeSince).To(BeNumerically(">=", 10))
	})

	It("has urls", func() {
		Expect(findValue(Varz, "urls")).To(Equal(float64(0)))

		var fooReg = route.NewEndpoint("12345", "192.168.1.1", 1234, "", "", map[string]string{}, -1, "", models.ModificationTag{})

		// Add a route
		Registry.Register("foo.vcap.me", fooReg)
		Registry.Register("fooo.vcap.me", fooReg)

		Expect(findValue(Varz, "urls")).To(Equal(float64(2)))
	})

	It("updates bad requests", func() {
		r := http.Request{}

		Varz.CaptureBadRequest(&r)
		Expect(findValue(Varz, "bad_requests")).To(Equal(float64(1)))

		Varz.CaptureBadRequest(&r)