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,
			))
	}
}
Exemple #2
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{}))
}
Exemple #3
0
func (r *Trie) toMap(segment string, m map[route.Uri]*route.Pool) map[route.Uri]*route.Pool {
	if r.Pool != nil {
		m[route.Uri(segment)] = r.Pool
	}

	for _, child := range r.ChildNodes {
		var newseg string
		if len(segment) == 0 {
			newseg = segment + child.Segment
		} else {
			newseg = segment + "/" + child.Segment
		}
		child.toMap(newseg, m)
	}

	return m
}
Exemple #4
0
func (p *proxy) lookup(request *http.Request) *route.Pool {
	requestPath := request.URL.EscapedPath()

	uri := route.Uri(hostWithoutPort(request) + requestPath)
	appInstanceHeader := request.Header.Get(router_http.CfAppInstance)
	if appInstanceHeader != "" {
		appId, appIndex, err := router_http.ValidateCfAppInstance(appInstanceHeader)

		if err != nil {
			p.logger.Error("invalid-app-instance-header", err)
			return nil
		} else {
			return p.registry.LookupWithInstance(uri, appId, appIndex)
		}
	}

	return p.registry.Lookup(uri)
}
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)
	}
}
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,
			))
	}
}
Exemple #7
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)

})
				err = natsClient.Publish("router.register", data)
				Expect(err).ToNot(HaveOccurred())

				Consistently(registry.RegisterCallCount).Should(BeZero())
			})
		})
	})

	Context("when a route is unregistered through NATS", func() {
		BeforeEach(func() {
			process = ifrit.Invoke(sub)
			Eventually(process.Ready()).Should(BeClosed())
		})

		It("does not race against registrations", func() {
			racingURI := route.Uri("test3.example.com")
			racingMsg := mbus.RegistryMessage{
				Host:                 "host",
				App:                  "app",
				RouteServiceURL:      "https://url.example.com",
				PrivateInstanceID:    "id",
				PrivateInstanceIndex: "index",
				Port:                 1111,
				StaleThresholdInSeconds: 120,
				Uris: []route.Uri{racingURI},
				Tags: map[string]string{"key": "value"},
			}

			racingData, err := json.Marshal(racingMsg)
			Expect(err).NotTo(HaveOccurred())
			*response[1].TTL = 1
			*response[2].TTL = 1
		})

		It("updates the route registry", func() {
			client.RoutesReturns(response, nil)

			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)
				Ip:                   conf.Ip,
				TraceKey:             conf.TraceKey,
				Registry:             r,
				Reporter:             test_helpers.NullVarz{},
				Logger:               logger,
				AccessLogger:         fakeAccessLogger,
				SecureCookies:        conf.SecureCookies,
				TLSConfig:            tlsConfig,
				RouteServiceEnabled:  conf.RouteServiceEnabled,
				RouteServiceTimeout:  conf.RouteServiceTimeout,
				Crypto:               crypto,
				CryptoPrev:           cryptoPrev,
				HealthCheckUserAgent: "HTTP-Monitor/1.1",
			})

			r.Register(route.Uri("some-app"), &route.Endpoint{})
		})

		Context("when backend fails to respond", func() {
			It("logs the error and associated endpoint", func() {
				body := []byte("some body")
				req := test_util.NewRequest("GET", "some-app", "/", bytes.NewReader(body))
				resp := httptest.NewRecorder()

				proxyObj.ServeHTTP(resp, req)

				Eventually(logger).Should(Say("error"))
				Eventually(logger).Should(Say("route-endpoint"))
			})
		})
Exemple #11
0
package route_test

import (
	"code.cloudfoundry.org/gorouter/route"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

var _ = Describe("URIs", func() {

	Context("RouteKey", func() {

		var key route.Uri

		It("creates a route key based on uri", func() {
			key = route.Uri("dora.app.com").RouteKey()
			Expect(key.String()).To(Equal("dora.app.com"))

			key = route.Uri("dora.app.com/").RouteKey()
			Expect(key.String()).To(Equal("dora.app.com"))

			key = route.Uri("dora.app.com/v1").RouteKey()
			Expect(key.String()).To(Equal("dora.app.com/v1"))

		})

		Context("has a context path", func() {

			It("creates route key with context path", func() {
				key = route.Uri("dora.app.com/v1").RouteKey()
				Expect(key.String()).To(Equal("dora.app.com/v1"))
				Expect(logger).ToNot(gbytes.Say(`prune.*"log_level":0.*foo.com/bar`))
			})
		})

		Context("when suspend pruning is triggered (i.e. nats offline)", func() {
			var totalRoutes int

			BeforeEach(func() {
				totalRoutes = 1000
				Expect(r.NumUris()).To(Equal(0))
				Expect(r.NumEndpoints()).To(Equal(0))

				// add endpoints
				for i := 0; i < totalRoutes; i++ {
					e := route.NewEndpoint("12345", "192.168.1.1", uint16(1024+i), "id1", "", nil, -1, "", modTag)
					r.Register(route.Uri(fmt.Sprintf("foo-%d", i)), e)
				}

				r.StartPruningCycle()
				r.SuspendPruning(func() bool { return true })
				time.Sleep(configObj.PruneStaleDropletsInterval + configObj.DropletStaleThreshold)
			})

			It("does not remove any routes", func() {
				Expect(r.NumUris()).To(Equal(totalRoutes))
				Expect(r.NumEndpoints()).To(Equal(totalRoutes))

				interval := configObj.PruneStaleDropletsInterval + 50*time.Millisecond
				Eventually(logger, interval).Should(gbytes.Say("prune-suspended"))

				Expect(r.NumUris()).To(Equal(totalRoutes))
Exemple #13
0
			})
			for _, e := range endpoints {
				pool.Remove(e)
			}
		}

		It("responds with a 502 BadGateway", func() {
			ln := registerHandler(r, "nil-endpoint", func(conn *test_util.HttpConn) {
				conn.CheckLine("GET / HTTP/1.1")
				resp := test_util.NewResponse(http.StatusOK)
				conn.WriteResponse(resp)
				conn.Close()
			})
			defer ln.Close()

			removeAllEndpoints(r.Lookup(route.Uri("nil-endpoint")))
			conn := dialProxy(proxyServer)

			req := test_util.NewRequest("GET", "nil-endpoint", "/", nil)
			conn.WriteRequest(req)

			b := make([]byte, 0, 0)
			buf := bytes.NewBuffer(b)
			log.SetOutput(buf)
			res, _ := conn.ReadResponse()
			log.SetOutput(os.Stderr)
			Expect(buf).NotTo(ContainSubstring("multiple response.WriteHeader calls"))
			Expect(res.StatusCode).To(Equal(http.StatusBadGateway))
		})

		It("does not capture routing response", func() {