From 75ec78c232405ab016d45175c79a79e02775379b Mon Sep 17 00:00:00 2001 From: Ivan Kozlovic Date: Thu, 24 Oct 2019 16:40:38 -0600 Subject: [PATCH] [FIXED] Explicit gateway not using discovered URLs If cluster A configures a gateway to cluster B, the server on A tries to connect to that server URL. If there is no server on B at that address, but a server on B with different address connects to server on cluster A, that server should be able to create its outbound connection in response. That was not the case because the configured URLs were snapshot before the loop of trying to connect. When accepting an inbound connection and updating the array, this new URL was not being used. The issue is only if the server on A had no outbound connection at that time. Signed-off-by: Ivan Kozlovic --- server/gateway.go | 7 +++++-- server/gateway_test.go | 28 ++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/server/gateway.go b/server/gateway.go index 603269b6..6343fcc7 100644 --- a/server/gateway.go +++ b/server/gateway.go @@ -580,7 +580,6 @@ func (s *Server) solicitGateway(cfg *gatewayCfg, firstConnect bool) { var ( opts = s.getOpts() isImplicit = cfg.isImplicit() - urls = cfg.getURLs() attempts int typeStr string ) @@ -593,7 +592,11 @@ func (s *Server) solicitGateway(cfg *gatewayCfg, firstConnect bool) { const connFmt = "Connecting to %s gateway %q (%s) at %s (attempt %v)" const connErrFmt = "Error connecting to %s gateway %q (%s) at %s (attempt %v): %v" - for s.isRunning() && len(urls) > 0 { + for s.isRunning() { + urls := cfg.getURLs() + if len(urls) == 0 { + break + } attempts++ report := s.shouldReportConnectErr(firstConnect, attempts) // Iteration is random diff --git a/server/gateway_test.go b/server/gateway_test.go index aaafa20f..0002f519 100644 --- a/server/gateway_test.go +++ b/server/gateway_test.go @@ -1098,6 +1098,34 @@ func TestGatewayURLsFromClusterSentInINFO(t *testing.T) { } } +func TestGatewayUseUpdatedURLs(t *testing.T) { + // For this test, we have cluster B with an explicit gateway to cluster A + // on a given URL. Then we create cluster A with a gateway to B with server B's + // GW url, and we expect server B to ultimately create an outbound GW connection + // to server A (with the URL it will get from server A connecting to it). + + ob := testGatewayOptionsFromToWithURLs(t, "B", "A", []string{"nats://127.0.0.1:1234"}) + sb := runGatewayServer(ob) + defer sb.Shutdown() + + // Add a delay before starting server A to make sure that server B start + // initiating the connection to A on inexistant server at :1234. + time.Sleep(100 * time.Millisecond) + + oa := testGatewayOptionsFromToWithServers(t, "A", "B", sb) + sa := runGatewayServer(oa) + defer sa.Shutdown() + + // sa should have no problem creating outbound connection to sb + waitForOutboundGateways(t, sa, 1, time.Second) + + // Make sure that since sb learns about sa's GW URL, it can successfully + // connect to it. + waitForOutboundGateways(t, sb, 1, 3*time.Second) + waitForInboundGateways(t, sb, 1, time.Second) + waitForInboundGateways(t, sa, 1, time.Second) +} + func TestGatewayAutoDiscovery(t *testing.T) { o4 := testDefaultOptionsForGateway("D") s4 := runGatewayServer(o4)