From 1d12bb4f4c22ecd39638bcff85646cdc2caddfe4 Mon Sep 17 00:00:00 2001 From: Alexander Nicke Date: Fri, 18 Oct 2024 10:52:47 +0200 Subject: [PATCH] feat: implement support for per-route options This commit adds the Options field to the RegistryMessage and Route struct. Required for route-emitter to forward the per-route-options. Co-authored-by: Tamara Boehm See: https://github.com/cloudfoundry/community/issues/909 --- routehandlers/handler_test.go | 1 + routingtable/endpoint.go | 2 ++ routingtable/registry_message.go | 3 ++ routingtable/registry_message_test.go | 40 +++++++++++++++++++++++++++ routingtable/routingtable.go | 1 + 5 files changed, 47 insertions(+) diff --git a/routehandlers/handler_test.go b/routehandlers/handler_test.go index 5ca7846..3ec55f2 100644 --- a/routehandlers/handler_test.go +++ b/routehandlers/handler_test.go @@ -1076,6 +1076,7 @@ var _ = Describe("Handler", func() { Hostnames: []string{hostname1}, Port: 8080, RouteServiceUrl: "https://rs.example.com", + Options: json.RawMessage(`{"lb_algo":"least-connection"}`), }, }.RoutingInfo() diff --git a/routingtable/endpoint.go b/routingtable/endpoint.go index 95fab5a..d312c2e 100644 --- a/routingtable/endpoint.go +++ b/routingtable/endpoint.go @@ -1,6 +1,7 @@ package routingtable import ( + "encoding/json" "fmt" "code.cloudfoundry.org/bbs/models" @@ -141,6 +142,7 @@ type Route struct { LogGUID string Protocol string MetricTags map[string]*models.MetricTagValue + Options json.RawMessage } type routeHash struct { diff --git a/routingtable/registry_message.go b/routingtable/registry_message.go index b6a77d2..9c15c05 100644 --- a/routingtable/registry_message.go +++ b/routingtable/registry_message.go @@ -1,6 +1,7 @@ package routingtable import ( + "encoding/json" "fmt" "strconv" @@ -22,6 +23,7 @@ type RegistryMessage struct { EndpointUpdatedAtNs int64 `json:"endpoint_updated_at_ns,omitempty" hash:"ignore"` Tags map[string]string `json:"tags,omitempty" hash:"ignore"` AvailabilityZone string `json:"availability_zone,omitempty" hash:"ignore"` + Options json.RawMessage `json:"options,omitempty" hash:"ignore"` } func RegistryMessageFor(endpoint Endpoint, route Route, emitEndpointUpdatedAt bool) RegistryMessage { @@ -50,6 +52,7 @@ func RegistryMessageFor(endpoint Endpoint, route Route, emitEndpointUpdatedAt bo PrivateInstanceIndex: index, ServerCertDomainSAN: endpoint.InstanceGUID, RouteServiceUrl: route.RouteServiceUrl, + Options: route.Options, } } diff --git a/routingtable/registry_message_test.go b/routingtable/registry_message_test.go index 1bf428a..aeec82c 100644 --- a/routingtable/registry_message_test.go +++ b/routingtable/registry_message_test.go @@ -120,6 +120,34 @@ var _ = Describe("RegistryMessage", func() { Expect(message).To(Equal(expectedMessage)) }) }) + + Context("when a route option is provided", func() { + BeforeEach(func() { + expectedMessage.Options = json.RawMessage(`{"lb_algo":"least-connection"}`) + expectedJSON = `{ + "host": "1.1.1.1", + "port": 61001, + "uris": ["host-1.example.com"], + "app" : "app-guid", + "private_instance_id": "instance-guid", + "server_cert_domain_san": "instance-guid", + "private_instance_index": "0", + "route_service_url": "https://hello.com", + "endpoint_updated_at_ns": 1000, + "tags": {"component":"route-emitter", "doo": "0", "foo": "bar", "goo": "instance-guid"}, + "availability_zone": "some-zone", + "options": {"lb_algo":"least-connection"} + }` + }) + + It("correctly marshals the route option", func() { + message := routingtable.RegistryMessage{} + + err := json.Unmarshal([]byte(expectedJSON), &message) + Expect(err).NotTo(HaveOccurred()) + Expect(message).To(Equal(expectedMessage)) + }) + }) }) Describe("RegistryMessageFor", func() { @@ -182,6 +210,18 @@ var _ = Describe("RegistryMessage", func() { Expect(message).To(Equal(expectedMessage)) }) }) + + Context("when route options are provided", func() { + BeforeEach(func() { + route.Options = json.RawMessage(`{"lb_algo":"least-connection"}`) + expectedMessage.Options = json.RawMessage(`{"lb_algo":"least-connection"}`) + }) + + It("creates a valid message when route options are provided", func() { + message := routingtable.RegistryMessageFor(endpoint, route, true) + Expect(message).To(Equal(expectedMessage)) + }) + }) }) Describe("InternalAddressRegistryMessageFor", func() { diff --git a/routingtable/routingtable.go b/routingtable/routingtable.go index 1360ee4..ecd50b8 100644 --- a/routingtable/routingtable.go +++ b/routingtable/routingtable.go @@ -444,6 +444,7 @@ func httpRoutesFrom(lrp *models.DesiredLRP) map[RoutingKey][]routeMapping { IsolationSegment: route.IsolationSegment, MetricTags: lrp.MetricTags, Protocol: route.Protocol, + Options: route.Options, } routes = append(routes, route) }