get.pme.sh/pnats@v0.0.0-20240304004023-26bb5a137ed0/server/gateway_test.go (about)

     1  // Copyright 2018-2020 The NATS Authors
     2  // Licensed under the Apache License, Version 2.0 (the "License");
     3  // you may not use this file except in compliance with the License.
     4  // You may obtain a copy of the License at
     5  //
     6  // http://www.apache.org/licenses/LICENSE-2.0
     7  //
     8  // Unless required by applicable law or agreed to in writing, software
     9  // distributed under the License is distributed on an "AS IS" BASIS,
    10  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    11  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package server
    15  
    16  import (
    17  	"bufio"
    18  	"bytes"
    19  	"context"
    20  	"crypto/tls"
    21  	"encoding/json"
    22  	"fmt"
    23  	"net"
    24  	"net/url"
    25  	"runtime"
    26  	"strconv"
    27  	"strings"
    28  	"sync"
    29  	"sync/atomic"
    30  	"testing"
    31  	"time"
    32  
    33  	"get.pme.sh/pnats/logger"
    34  	"github.com/nats-io/nats.go"
    35  )
    36  
    37  func init() {
    38  	gatewayConnectDelay = 15 * time.Millisecond
    39  	gatewayReconnectDelay = 15 * time.Millisecond
    40  }
    41  
    42  // Wait for the expected number of outbound gateways, or fails.
    43  func waitForOutboundGateways(t *testing.T, s *Server, expected int, timeout time.Duration) {
    44  	t.Helper()
    45  	if timeout < 2*time.Second {
    46  		timeout = 2 * time.Second
    47  	}
    48  	checkFor(t, timeout, 15*time.Millisecond, func() error {
    49  		if n := s.numOutboundGateways(); n != expected {
    50  			return fmt.Errorf("Expected %v outbound gateway(s), got %v", expected, n)
    51  		}
    52  		return nil
    53  	})
    54  }
    55  
    56  // Wait for the expected number of inbound gateways, or fails.
    57  func waitForInboundGateways(t *testing.T, s *Server, expected int, timeout time.Duration) {
    58  	t.Helper()
    59  	if timeout < 2*time.Second {
    60  		timeout = 2 * time.Second
    61  	}
    62  	checkFor(t, timeout, 15*time.Millisecond, func() error {
    63  		if n := s.numInboundGateways(); n != expected {
    64  			return fmt.Errorf("Expected %v inbound gateway(s), got %v", expected, n)
    65  		}
    66  		return nil
    67  	})
    68  }
    69  
    70  func waitForGatewayFailedConnect(t *testing.T, s *Server, gwName string, expectFailure bool, timeout time.Duration) {
    71  	t.Helper()
    72  	checkFor(t, timeout, 15*time.Millisecond, func() error {
    73  		var c int
    74  		cfg := s.getRemoteGateway(gwName)
    75  		if cfg != nil {
    76  			c = cfg.getConnAttempts()
    77  		}
    78  		if expectFailure && c <= 1 {
    79  			return fmt.Errorf("Expected several attempts to connect, got %v", c)
    80  		} else if !expectFailure && c > 1 {
    81  			return fmt.Errorf("Expected single attempt to connect, got %v", c)
    82  		}
    83  		return nil
    84  	})
    85  }
    86  
    87  func checkForRegisteredQSubInterest(t *testing.T, s *Server, gwName, acc, subj string, expected int, timeout time.Duration) {
    88  	t.Helper()
    89  	checkFor(t, timeout, 15*time.Millisecond, func() error {
    90  		count := 0
    91  		c := s.getOutboundGatewayConnection(gwName)
    92  		ei, _ := c.gw.outsim.Load(acc)
    93  		if ei != nil {
    94  			sl := ei.(*outsie).sl
    95  			r := sl.Match(subj)
    96  			for _, qsubs := range r.qsubs {
    97  				count += len(qsubs)
    98  			}
    99  		}
   100  		if count == expected {
   101  			return nil
   102  		}
   103  		return fmt.Errorf("Expected %v qsubs in sublist, got %v", expected, count)
   104  	})
   105  }
   106  
   107  func checkForSubjectNoInterest(t *testing.T, c *client, account, subject string, expectNoInterest bool, timeout time.Duration) {
   108  	t.Helper()
   109  	checkFor(t, timeout, 15*time.Millisecond, func() error {
   110  		ei, _ := c.gw.outsim.Load(account)
   111  		if ei == nil {
   112  			return fmt.Errorf("Did not receive subject no-interest")
   113  		}
   114  		e := ei.(*outsie)
   115  		e.RLock()
   116  		_, inMap := e.ni[subject]
   117  		e.RUnlock()
   118  		if expectNoInterest {
   119  			if inMap {
   120  				return nil
   121  			}
   122  			return fmt.Errorf("Did not receive subject no-interest on %q", subject)
   123  		}
   124  		if inMap {
   125  			return fmt.Errorf("No-interest on subject %q was not cleared", subject)
   126  		}
   127  		return nil
   128  	})
   129  }
   130  
   131  func checkForAccountNoInterest(t *testing.T, c *client, account string, expectedNoInterest bool, timeout time.Duration) {
   132  	t.Helper()
   133  	checkFor(t, timeout, 15*time.Millisecond, func() error {
   134  		ei, ok := c.gw.outsim.Load(account)
   135  		if !ok && expectedNoInterest {
   136  			return fmt.Errorf("No-interest for account %q not yet registered", account)
   137  		} else if ok && !expectedNoInterest {
   138  			return fmt.Errorf("Account %q should not have a no-interest", account)
   139  		}
   140  		if ei != nil {
   141  			return fmt.Errorf("Account %q should have a global no-interest, not subject no-interest", account)
   142  		}
   143  		return nil
   144  	})
   145  }
   146  
   147  func checkGWInterestOnlyMode(t *testing.T, s *Server, outboundGWName, accName string) {
   148  	t.Helper()
   149  	checkGWInterestOnlyModeOrNotPresent(t, s, outboundGWName, accName, false)
   150  }
   151  
   152  func checkGWInterestOnlyModeOrNotPresent(t *testing.T, s *Server, outboundGWName, accName string, notPresentOk bool) {
   153  	t.Helper()
   154  	checkFor(t, 2*time.Second, 15*time.Millisecond, func() error {
   155  		gwc := s.getOutboundGatewayConnection(outboundGWName)
   156  		if gwc == nil {
   157  			return fmt.Errorf("No outbound gateway connection %q for server %v", outboundGWName, s)
   158  		}
   159  		gwc.mu.Lock()
   160  		defer gwc.mu.Unlock()
   161  		out, ok := gwc.gw.outsim.Load(accName)
   162  		if !ok {
   163  			if notPresentOk {
   164  				return nil
   165  			} else {
   166  				return fmt.Errorf("Server %v - outbound gateway connection %q: no account %q found in map",
   167  					s, outboundGWName, accName)
   168  			}
   169  		}
   170  		if out == nil {
   171  			return fmt.Errorf("Server %v - outbound gateway connection %q: interest map not found for account %q",
   172  				s, outboundGWName, accName)
   173  		}
   174  		e := out.(*outsie)
   175  		e.RLock()
   176  		defer e.RUnlock()
   177  		if e.mode != InterestOnly {
   178  			return fmt.Errorf(
   179  				"Server %v - outbound gateway connection %q: account %q mode shoule be InterestOnly but is %v",
   180  				s, outboundGWName, accName, e.mode)
   181  		}
   182  		return nil
   183  	})
   184  }
   185  
   186  func checkGWInterestOnlyModeInterestOn(t *testing.T, s *Server, outboundGWName, accName, subject string) {
   187  	t.Helper()
   188  	checkFor(t, 2*time.Second, 15*time.Millisecond, func() error {
   189  		c := s.getOutboundGatewayConnection(outboundGWName)
   190  		outsiei, _ := c.gw.outsim.Load(accName)
   191  		if outsiei == nil {
   192  			return fmt.Errorf("Server %s - outbound gateway connection %q: no map entry found for account %q",
   193  				s, outboundGWName, accName)
   194  		}
   195  		outsie := outsiei.(*outsie)
   196  		r := outsie.sl.Match(subject)
   197  		if len(r.psubs) == 0 {
   198  			return fmt.Errorf("Server %s - outbound gateway connection %q - account %q: no subject interest for %q",
   199  				s, outboundGWName, accName, subject)
   200  		}
   201  		return nil
   202  	})
   203  }
   204  
   205  func waitCh(t *testing.T, ch chan bool, errTxt string) {
   206  	t.Helper()
   207  	select {
   208  	case <-ch:
   209  		return
   210  	case <-time.After(5 * time.Second):
   211  		t.Fatalf(errTxt)
   212  	}
   213  }
   214  
   215  var noOpErrHandler = func(_ *nats.Conn, _ *nats.Subscription, _ error) {}
   216  
   217  func natsConnect(t testing.TB, url string, options ...nats.Option) *nats.Conn {
   218  	t.Helper()
   219  	opts := nats.GetDefaultOptions()
   220  	for _, opt := range options {
   221  		if err := opt(&opts); err != nil {
   222  			t.Fatalf("Error applying client option: %v", err)
   223  		}
   224  	}
   225  	nc, err := nats.Connect(url, options...)
   226  	if err != nil {
   227  		t.Fatalf("Error on connect: %v", err)
   228  	}
   229  	if opts.AsyncErrorCB == nil {
   230  		// Set this up to not pollute the logs when running tests.
   231  		nc.SetErrorHandler(noOpErrHandler)
   232  	}
   233  
   234  	return nc
   235  }
   236  
   237  func natsSub(t *testing.T, nc *nats.Conn, subj string, cb nats.MsgHandler) *nats.Subscription {
   238  	t.Helper()
   239  	sub, err := nc.Subscribe(subj, cb)
   240  	if err != nil {
   241  		t.Fatalf("Error on subscribe: %v", err)
   242  	}
   243  	return sub
   244  }
   245  
   246  func natsSubSync(t *testing.T, nc *nats.Conn, subj string) *nats.Subscription {
   247  	t.Helper()
   248  	sub, err := nc.SubscribeSync(subj)
   249  	if err != nil {
   250  		t.Fatalf("Error on subscribe: %v", err)
   251  	}
   252  	return sub
   253  }
   254  
   255  func natsNexMsg(t *testing.T, sub *nats.Subscription, timeout time.Duration) *nats.Msg {
   256  	t.Helper()
   257  	msg, err := sub.NextMsg(timeout)
   258  	if err != nil {
   259  		t.Fatalf("Failed getting next message: %v", err)
   260  	}
   261  	return msg
   262  }
   263  
   264  func natsQueueSub(t *testing.T, nc *nats.Conn, subj, queue string, cb nats.MsgHandler) *nats.Subscription {
   265  	t.Helper()
   266  	sub, err := nc.QueueSubscribe(subj, queue, cb)
   267  	if err != nil {
   268  		t.Fatalf("Error on subscribe: %v", err)
   269  	}
   270  	return sub
   271  }
   272  
   273  func natsQueueSubSync(t *testing.T, nc *nats.Conn, subj, queue string) *nats.Subscription {
   274  	t.Helper()
   275  	sub, err := nc.QueueSubscribeSync(subj, queue)
   276  	if err != nil {
   277  		t.Fatalf("Error on subscribe: %v", err)
   278  	}
   279  	return sub
   280  }
   281  
   282  func natsFlush(t *testing.T, nc *nats.Conn) {
   283  	t.Helper()
   284  	if err := nc.Flush(); err != nil {
   285  		t.Fatalf("Error on flush: %v", err)
   286  	}
   287  }
   288  
   289  func natsPub(t testing.TB, nc *nats.Conn, subj string, payload []byte) {
   290  	t.Helper()
   291  	if err := nc.Publish(subj, payload); err != nil {
   292  		t.Fatalf("Error on publish: %v", err)
   293  	}
   294  }
   295  
   296  func natsPubReq(t *testing.T, nc *nats.Conn, subj, reply string, payload []byte) {
   297  	t.Helper()
   298  	if err := nc.PublishRequest(subj, reply, payload); err != nil {
   299  		t.Fatalf("Error on publish: %v", err)
   300  	}
   301  }
   302  
   303  func natsUnsub(t *testing.T, sub *nats.Subscription) {
   304  	t.Helper()
   305  	if err := sub.Unsubscribe(); err != nil {
   306  		t.Fatalf("Error on unsubscribe: %v", err)
   307  	}
   308  }
   309  
   310  func testDefaultOptionsForGateway(name string) *Options {
   311  	o := DefaultOptions()
   312  	o.NoSystemAccount = true
   313  	o.Cluster.Name = name
   314  	o.Gateway.Name = name
   315  	o.Gateway.Host = "127.0.0.1"
   316  	o.Gateway.Port = -1
   317  	o.gatewaysSolicitDelay = 15 * time.Millisecond
   318  	return o
   319  }
   320  
   321  func runGatewayServer(o *Options) *Server {
   322  	s := RunServer(o)
   323  	s.SetLogger(&DummyLogger{}, true, true)
   324  	return s
   325  }
   326  
   327  func testGatewayOptionsFromToWithServers(t *testing.T, org, dst string, servers ...*Server) *Options {
   328  	t.Helper()
   329  	o := testDefaultOptionsForGateway(org)
   330  	gw := &RemoteGatewayOpts{Name: dst}
   331  	for _, s := range servers {
   332  		us := fmt.Sprintf("nats://127.0.0.1:%d", s.GatewayAddr().Port)
   333  		u, err := url.Parse(us)
   334  		if err != nil {
   335  			t.Fatalf("Error parsing url: %v", err)
   336  		}
   337  		gw.URLs = append(gw.URLs, u)
   338  	}
   339  	o.Gateway.Gateways = append(o.Gateway.Gateways, gw)
   340  	return o
   341  }
   342  
   343  func testAddGatewayURLs(t *testing.T, o *Options, dst string, urls []string) {
   344  	t.Helper()
   345  	gw := &RemoteGatewayOpts{Name: dst}
   346  	for _, us := range urls {
   347  		u, err := url.Parse(us)
   348  		if err != nil {
   349  			t.Fatalf("Error parsing url: %v", err)
   350  		}
   351  		gw.URLs = append(gw.URLs, u)
   352  	}
   353  	o.Gateway.Gateways = append(o.Gateway.Gateways, gw)
   354  }
   355  
   356  func testGatewayOptionsFromToWithURLs(t *testing.T, org, dst string, urls []string) *Options {
   357  	o := testDefaultOptionsForGateway(org)
   358  	testAddGatewayURLs(t, o, dst, urls)
   359  	return o
   360  }
   361  
   362  func testGatewayOptionsWithTLS(t *testing.T, name string) *Options {
   363  	t.Helper()
   364  	o := testDefaultOptionsForGateway(name)
   365  	var (
   366  		tc  = &TLSConfigOpts{}
   367  		err error
   368  	)
   369  	if name == "A" {
   370  		tc.CertFile = "../test/configs/certs/srva-cert.pem"
   371  		tc.KeyFile = "../test/configs/certs/srva-key.pem"
   372  	} else {
   373  		tc.CertFile = "../test/configs/certs/srvb-cert.pem"
   374  		tc.KeyFile = "../test/configs/certs/srvb-key.pem"
   375  	}
   376  	tc.CaFile = "../test/configs/certs/ca.pem"
   377  	o.Gateway.TLSConfig, err = GenTLSConfig(tc)
   378  	if err != nil {
   379  		t.Fatalf("Error generating TLS config: %v", err)
   380  	}
   381  	o.Gateway.TLSConfig.ClientAuth = tls.RequireAndVerifyClientCert
   382  	o.Gateway.TLSConfig.RootCAs = o.Gateway.TLSConfig.ClientCAs
   383  	o.Gateway.TLSTimeout = 2.0
   384  	return o
   385  }
   386  
   387  func testGatewayOptionsFromToWithTLS(t *testing.T, org, dst string, urls []string) *Options {
   388  	o := testGatewayOptionsWithTLS(t, org)
   389  	testAddGatewayURLs(t, o, dst, urls)
   390  	return o
   391  }
   392  
   393  func TestGatewayBasic(t *testing.T) {
   394  	o2 := testDefaultOptionsForGateway("B")
   395  	o2.Gateway.ConnectRetries = 0
   396  	s2 := runGatewayServer(o2)
   397  	defer s2.Shutdown()
   398  
   399  	o1 := testGatewayOptionsFromToWithServers(t, "A", "B", s2)
   400  	s1 := runGatewayServer(o1)
   401  	defer s1.Shutdown()
   402  
   403  	// s1 should have an outbound gateway to s2.
   404  	waitForOutboundGateways(t, s1, 1, time.Second)
   405  	// s2 should have an inbound gateway
   406  	waitForInboundGateways(t, s2, 1, time.Second)
   407  	// and an outbound too
   408  	waitForOutboundGateways(t, s2, 1, time.Second)
   409  
   410  	// Stop s2 server
   411  	s2.Shutdown()
   412  
   413  	// gateway should go away
   414  	waitForOutboundGateways(t, s1, 0, time.Second)
   415  	waitForInboundGateways(t, s1, 0, time.Second)
   416  
   417  	// Restart server
   418  	s2 = runGatewayServer(o2)
   419  	defer s2.Shutdown()
   420  
   421  	// gateway should reconnect
   422  	waitForOutboundGateways(t, s1, 1, 2*time.Second)
   423  	waitForOutboundGateways(t, s2, 1, 2*time.Second)
   424  	waitForInboundGateways(t, s1, 1, 2*time.Second)
   425  	waitForInboundGateways(t, s2, 1, 2*time.Second)
   426  
   427  	// Shutdown s1, remove the gateway from A to B and restart.
   428  	s1.Shutdown()
   429  	// When s2 detects the connection is closed, it will attempt
   430  	// to reconnect once (even if the route is implicit).
   431  	// We need to wait more than a dial timeout to make sure
   432  	// s1 does not restart too quickly and s2 can actually reconnect.
   433  	time.Sleep(DEFAULT_ROUTE_DIAL + 250*time.Millisecond)
   434  	// Restart s1 without gateway to B.
   435  	o1.Gateway.Gateways = nil
   436  	s1 = runGatewayServer(o1)
   437  	defer s1.Shutdown()
   438  
   439  	// s1 should not have any outbound nor inbound
   440  	waitForOutboundGateways(t, s1, 0, 2*time.Second)
   441  	waitForInboundGateways(t, s1, 0, 2*time.Second)
   442  
   443  	// Same for s2
   444  	waitForOutboundGateways(t, s2, 0, 2*time.Second)
   445  	waitForInboundGateways(t, s2, 0, 2*time.Second)
   446  
   447  	// Verify that s2 no longer has A gateway in its list
   448  	checkFor(t, time.Second, 15*time.Millisecond, func() error {
   449  		if s2.getRemoteGateway("A") != nil {
   450  			return fmt.Errorf("Gateway A should have been removed from s2")
   451  		}
   452  		return nil
   453  	})
   454  }
   455  
   456  func TestGatewayIgnoreSelfReference(t *testing.T) {
   457  	o := testDefaultOptionsForGateway("A")
   458  	// To create a reference to itself before running the server
   459  	// it means that we have to assign an explicit port
   460  	o.Gateway.Port = 5222
   461  	o.gatewaysSolicitDelay = 0
   462  	u, _ := url.Parse(fmt.Sprintf("nats://%s:%d", o.Gateway.Host, o.Gateway.Port))
   463  	cfg := &RemoteGatewayOpts{
   464  		Name: "A",
   465  		URLs: []*url.URL{u},
   466  	}
   467  	o.Gateway.Gateways = append(o.Gateway.Gateways, cfg)
   468  	o.NoSystemAccount = true
   469  	s := runGatewayServer(o)
   470  	defer s.Shutdown()
   471  
   472  	// Wait a bit to make sure that there is no attempt to connect.
   473  	time.Sleep(20 * time.Millisecond)
   474  
   475  	// No outbound connection expected, and no attempt to connect.
   476  	if s.getRemoteGateway("A") != nil {
   477  		t.Fatalf("Should not have a remote gateway config for A")
   478  	}
   479  	if s.getOutboundGatewayConnection("A") != nil {
   480  		t.Fatalf("Should not have a gateway connection to A")
   481  	}
   482  	s.Shutdown()
   483  
   484  	// Now try with config files and include
   485  	s1, _ := RunServerWithConfig("configs/gwa.conf")
   486  	defer s1.Shutdown()
   487  
   488  	s2, _ := RunServerWithConfig("configs/gwb.conf")
   489  	defer s2.Shutdown()
   490  
   491  	waitForOutboundGateways(t, s1, 1, 2*time.Second)
   492  	waitForOutboundGateways(t, s2, 1, 2*time.Second)
   493  	waitForInboundGateways(t, s1, 1, 2*time.Second)
   494  	waitForInboundGateways(t, s2, 1, 2*time.Second)
   495  
   496  	if s1.getRemoteGateway("A") != nil {
   497  		t.Fatalf("Should not have a remote gateway config for A")
   498  	}
   499  	if s1.getOutboundGatewayConnection("A") != nil {
   500  		t.Fatalf("Should not have a gateway connection to A")
   501  	}
   502  	if s2.getRemoteGateway("B") != nil {
   503  		t.Fatalf("Should not have a remote gateway config for B")
   504  	}
   505  	if s2.getOutboundGatewayConnection("B") != nil {
   506  		t.Fatalf("Should not have a gateway connection to B")
   507  	}
   508  }
   509  
   510  func TestGatewayHeaderInfo(t *testing.T) {
   511  	o := testDefaultOptionsForGateway("A")
   512  	s := runGatewayServer(o)
   513  	defer s.Shutdown()
   514  
   515  	gwconn, err := net.Dial("tcp", fmt.Sprintf("%s:%d", o.Gateway.Host, o.Gateway.Port))
   516  	if err != nil {
   517  		t.Fatalf("Error dialing server: %v\n", err)
   518  	}
   519  	defer gwconn.Close()
   520  	client := bufio.NewReaderSize(gwconn, maxBufSize)
   521  	l, err := client.ReadString('\n')
   522  	if err != nil {
   523  		t.Fatalf("Error receiving info from server: %v\n", err)
   524  	}
   525  	var info serverInfo
   526  	if err = json.Unmarshal([]byte(l[5:]), &info); err != nil {
   527  		t.Fatalf("Could not parse INFO json: %v\n", err)
   528  	}
   529  	if !info.Headers {
   530  		t.Fatalf("Expected by default for header support to be enabled")
   531  	}
   532  
   533  	s.Shutdown()
   534  	gwconn.Close()
   535  
   536  	// Now turn headers off.
   537  	o.NoHeaderSupport = true
   538  	s = runGatewayServer(o)
   539  	defer s.Shutdown()
   540  
   541  	gwconn, err = net.Dial("tcp", fmt.Sprintf("%s:%d", o.Gateway.Host, o.Gateway.Port))
   542  	if err != nil {
   543  		t.Fatalf("Error dialing server: %v\n", err)
   544  	}
   545  	defer gwconn.Close()
   546  	client = bufio.NewReaderSize(gwconn, maxBufSize)
   547  	l, err = client.ReadString('\n')
   548  	if err != nil {
   549  		t.Fatalf("Error receiving info from server: %v\n", err)
   550  	}
   551  	if err = json.Unmarshal([]byte(l[5:]), &info); err != nil {
   552  		t.Fatalf("Could not parse INFO json: %v\n", err)
   553  	}
   554  	if info.Headers {
   555  		t.Fatalf("Expected header support to be disabled")
   556  	}
   557  }
   558  
   559  func TestGatewayHeaderSupport(t *testing.T) {
   560  	o2 := testDefaultOptionsForGateway("B")
   561  	o2.Gateway.ConnectRetries = 0
   562  	s2 := runGatewayServer(o2)
   563  	defer s2.Shutdown()
   564  
   565  	o1 := testGatewayOptionsFromToWithServers(t, "A", "B", s2)
   566  	s1 := runGatewayServer(o1)
   567  	defer s1.Shutdown()
   568  
   569  	// s1 should have an outbound gateway to s2.
   570  	waitForOutboundGateways(t, s1, 1, time.Second)
   571  	// and an inbound too
   572  	waitForInboundGateways(t, s1, 1, time.Second)
   573  	// s2 should have an inbound gateway
   574  	waitForInboundGateways(t, s2, 1, time.Second)
   575  	// and an outbound too
   576  	waitForOutboundGateways(t, s2, 1, time.Second)
   577  
   578  	c, cr, _ := newClientForServer(s1)
   579  	defer c.close()
   580  
   581  	connect := "CONNECT {\"headers\":true}"
   582  	subOp := "SUB foo 1"
   583  	pingOp := "PING\r\n"
   584  	cmd := strings.Join([]string{connect, subOp, pingOp}, "\r\n")
   585  	c.parseAsync(cmd)
   586  	if _, err := cr.ReadString('\n'); err != nil {
   587  		t.Fatalf("Error receiving msg from server: %v\n", err)
   588  	}
   589  
   590  	// Wait for interest to be registered on s2
   591  	checkGWInterestOnlyModeInterestOn(t, s2, "A", globalAccountName, "foo")
   592  
   593  	b, _, _ := newClientForServer(s2)
   594  	defer b.close()
   595  
   596  	pubOp := "HPUB foo 12 14\r\nName:Derek\r\nOK\r\n"
   597  	cmd = strings.Join([]string{connect, pubOp}, "\r\n")
   598  	b.parseAsync(cmd)
   599  
   600  	l, err := cr.ReadString('\n')
   601  	if err != nil {
   602  		t.Fatalf("Error receiving msg from server: %v\n", err)
   603  	}
   604  
   605  	am := hmsgPat.FindAllStringSubmatch(l, -1)
   606  	if len(am) == 0 {
   607  		t.Fatalf("Did not get a match for %q", l)
   608  	}
   609  	matches := am[0]
   610  	if len(matches) != 7 {
   611  		t.Fatalf("Did not get correct # matches: %d vs %d\n", len(matches), 7)
   612  	}
   613  	if matches[SUB_INDEX] != "foo" {
   614  		t.Fatalf("Did not get correct subject: '%s'\n", matches[SUB_INDEX])
   615  	}
   616  	if matches[SID_INDEX] != "1" {
   617  		t.Fatalf("Did not get correct sid: '%s'\n", matches[SID_INDEX])
   618  	}
   619  	if matches[HDR_INDEX] != "12" {
   620  		t.Fatalf("Did not get correct msg length: '%s'\n", matches[HDR_INDEX])
   621  	}
   622  	if matches[TLEN_INDEX] != "14" {
   623  		t.Fatalf("Did not get correct msg length: '%s'\n", matches[TLEN_INDEX])
   624  	}
   625  	checkPayload(cr, []byte("Name:Derek\r\nOK\r\n"), t)
   626  }
   627  
   628  func TestGatewayHeaderDeliverStrippedMsg(t *testing.T) {
   629  	o2 := testDefaultOptionsForGateway("B")
   630  	o2.Gateway.ConnectRetries = 0
   631  	s2 := runGatewayServer(o2)
   632  	defer s2.Shutdown()
   633  
   634  	o1 := testGatewayOptionsFromToWithServers(t, "A", "B", s2)
   635  	o1.NoHeaderSupport = true
   636  	s1 := runGatewayServer(o1)
   637  	defer s1.Shutdown()
   638  
   639  	// s1 should have an outbound gateway to s2.
   640  	waitForOutboundGateways(t, s1, 1, time.Second)
   641  	// and an inbound too
   642  	waitForInboundGateways(t, s1, 1, time.Second)
   643  	// s2 should have an inbound gateway
   644  	waitForInboundGateways(t, s2, 1, time.Second)
   645  	// and an outbound too
   646  	waitForOutboundGateways(t, s2, 1, time.Second)
   647  
   648  	c, cr, _ := newClientForServer(s1)
   649  	defer c.close()
   650  
   651  	connect := "CONNECT {\"headers\":true}"
   652  	subOp := "SUB foo 1"
   653  	pingOp := "PING\r\n"
   654  	cmd := strings.Join([]string{connect, subOp, pingOp}, "\r\n")
   655  	c.parseAsync(cmd)
   656  	if _, err := cr.ReadString('\n'); err != nil {
   657  		t.Fatalf("Error receiving msg from server: %v\n", err)
   658  	}
   659  
   660  	// Wait for interest to be registered on s2
   661  	checkGWInterestOnlyModeInterestOn(t, s2, "A", globalAccountName, "foo")
   662  
   663  	b, _, _ := newClientForServer(s2)
   664  	defer b.close()
   665  
   666  	pubOp := "HPUB foo 12 14\r\nName:Derek\r\nOK\r\n"
   667  	cmd = strings.Join([]string{connect, pubOp}, "\r\n")
   668  	b.parseAsync(cmd)
   669  
   670  	l, err := cr.ReadString('\n')
   671  	if err != nil {
   672  		t.Fatalf("Error receiving msg from server: %v\n", err)
   673  	}
   674  	am := smsgPat.FindAllStringSubmatch(l, -1)
   675  	if len(am) == 0 {
   676  		t.Fatalf("Did not get a correct match for %q", l)
   677  	}
   678  	matches := am[0]
   679  	if len(matches) != 6 {
   680  		t.Fatalf("Did not get correct # matches: %d vs %d\n", len(matches), 6)
   681  	}
   682  	if matches[SUB_INDEX] != "foo" {
   683  		t.Fatalf("Did not get correct subject: '%s'\n", matches[SUB_INDEX])
   684  	}
   685  	if matches[SID_INDEX] != "1" {
   686  		t.Fatalf("Did not get correct sid: '%s'\n", matches[SID_INDEX])
   687  	}
   688  	if matches[LEN_INDEX] != "2" {
   689  		t.Fatalf("Did not get correct msg length: '%s'\n", matches[LEN_INDEX])
   690  	}
   691  	checkPayload(cr, []byte("OK\r\n"), t)
   692  	if cr.Buffered() != 0 {
   693  		t.Fatalf("Expected no extra bytes to be buffered, got %d", cr.Buffered())
   694  	}
   695  }
   696  
   697  func TestGatewaySolicitDelay(t *testing.T) {
   698  	o2 := testDefaultOptionsForGateway("B")
   699  	s2 := runGatewayServer(o2)
   700  	defer s2.Shutdown()
   701  
   702  	o1 := testGatewayOptionsFromToWithServers(t, "A", "B", s2)
   703  	// Set the solicit delay to 0. This tests that server will use its
   704  	// default value, currently set at 1 sec.
   705  	o1.gatewaysSolicitDelay = 0
   706  	start := time.Now()
   707  	s1 := runGatewayServer(o1)
   708  	defer s1.Shutdown()
   709  
   710  	// After 500ms, check outbound gateway. Should not be there.
   711  	time.Sleep(500 * time.Millisecond)
   712  	if time.Since(start) < defaultSolicitGatewaysDelay {
   713  		if s1.numOutboundGateways() > 0 {
   714  			t.Fatalf("The outbound gateway was initiated sooner than expected (%v)", time.Since(start))
   715  		}
   716  	}
   717  	// Ultimately, s1 should have an outbound gateway to s2.
   718  	waitForOutboundGateways(t, s1, 1, 2*time.Second)
   719  	// s2 should have an inbound gateway
   720  	waitForInboundGateways(t, s2, 1, 2*time.Second)
   721  
   722  	s1.Shutdown()
   723  	// Make sure that server can be shutdown while waiting
   724  	// for that initial solicit delay
   725  	o1.gatewaysSolicitDelay = 2 * time.Second
   726  	s1 = runGatewayServer(o1)
   727  	start = time.Now()
   728  	s1.Shutdown()
   729  	if dur := time.Since(start); dur >= 2*time.Second {
   730  		t.Fatalf("Looks like shutdown was delayed: %v", dur)
   731  	}
   732  }
   733  
   734  func TestGatewaySolicitDelayWithImplicitOutbounds(t *testing.T) {
   735  	// Cause a situation where A connects to B, and because of
   736  	// delay of solicit gateways set on B, we want to make sure
   737  	// that B does not end-up with 2 connections to A.
   738  	o2 := testDefaultOptionsForGateway("B")
   739  	o2.gatewaysSolicitDelay = 500 * time.Millisecond
   740  	s2 := runGatewayServer(o2)
   741  	defer s2.Shutdown()
   742  
   743  	o1 := testGatewayOptionsFromToWithServers(t, "A", "B", s2)
   744  	s1 := runGatewayServer(o1)
   745  	defer s1.Shutdown()
   746  
   747  	// s1 should have an outbound and inbound gateway to s2.
   748  	waitForOutboundGateways(t, s1, 1, 2*time.Second)
   749  	// s2 should have an inbound gateway
   750  	waitForInboundGateways(t, s2, 1, 2*time.Second)
   751  	// Wait for more than s2 solicit delay
   752  	time.Sleep(750 * time.Millisecond)
   753  	// The way we store outbound (map key'ed by gw name), we would
   754  	// not know if we had created 2 (since the newer would replace
   755  	// the older in the map). But if a second connection was made,
   756  	// then s1 would have 2 inbounds. So check it has only 1.
   757  	waitForInboundGateways(t, s1, 1, time.Second)
   758  }
   759  
   760  type slowResolver struct {
   761  	inLookupCh chan struct{}
   762  	releaseCh  chan struct{}
   763  }
   764  
   765  func (r *slowResolver) LookupHost(ctx context.Context, h string) ([]string, error) {
   766  	if r.inLookupCh != nil {
   767  		select {
   768  		case r.inLookupCh <- struct{}{}:
   769  		default:
   770  		}
   771  		<-r.releaseCh
   772  	} else {
   773  		time.Sleep(500 * time.Millisecond)
   774  	}
   775  	return []string{h}, nil
   776  }
   777  
   778  func TestGatewaySolicitShutdown(t *testing.T) {
   779  	var urls []string
   780  	for i := 0; i < 5; i++ {
   781  		u := fmt.Sprintf("nats://localhost:%d", 1234+i)
   782  		urls = append(urls, u)
   783  	}
   784  	o1 := testGatewayOptionsFromToWithURLs(t, "A", "B", urls)
   785  	o1.Gateway.resolver = &slowResolver{}
   786  	s1 := runGatewayServer(o1)
   787  	defer s1.Shutdown()
   788  
   789  	time.Sleep(o1.gatewaysSolicitDelay + 10*time.Millisecond)
   790  
   791  	start := time.Now()
   792  	s1.Shutdown()
   793  	if dur := time.Since(start); dur > 1200*time.Millisecond {
   794  		t.Fatalf("Took too long to shutdown: %v", dur)
   795  	}
   796  }
   797  
   798  func testFatalErrorOnStart(t *testing.T, o *Options, errTxt string) {
   799  	t.Helper()
   800  	s := New(o)
   801  	defer s.Shutdown()
   802  	l := &captureFatalLogger{fatalCh: make(chan string, 1)}
   803  	s.SetLogger(l, false, false)
   804  	wg := sync.WaitGroup{}
   805  	wg.Add(1)
   806  	go func() {
   807  		s.Start()
   808  		wg.Done()
   809  	}()
   810  	select {
   811  	case e := <-l.fatalCh:
   812  		if !strings.Contains(e, errTxt) {
   813  			t.Fatalf("Error should contain %q, got %s", errTxt, e)
   814  		}
   815  	case <-time.After(time.Second):
   816  		t.Fatal("Should have got a fatal error")
   817  	}
   818  	s.Shutdown()
   819  	wg.Wait()
   820  }
   821  
   822  func TestGatewayListenError(t *testing.T) {
   823  	o2 := testDefaultOptionsForGateway("B")
   824  	s2 := runGatewayServer(o2)
   825  	defer s2.Shutdown()
   826  
   827  	o1 := testDefaultOptionsForGateway("A")
   828  	o1.Gateway.Port = s2.GatewayAddr().Port
   829  	testFatalErrorOnStart(t, o1, "listening on")
   830  }
   831  
   832  func TestGatewayWithListenToAny(t *testing.T) {
   833  	confB1 := createConfFile(t, []byte(`
   834  		listen: "127.0.0.1:-1"
   835  		cluster {
   836  			listen: "127.0.0.1:-1"
   837  		}
   838  		gateway {
   839  			name: "B"
   840  			listen: "0.0.0.0:-1"
   841  		}
   842  	`))
   843  	sb1, ob1 := RunServerWithConfig(confB1)
   844  	defer sb1.Shutdown()
   845  
   846  	confB2 := createConfFile(t, []byte(fmt.Sprintf(`
   847  		listen: "127.0.0.1:-1"
   848  		cluster {
   849  			listen: "127.0.0.1:-1"
   850  			routes: ["%s"]
   851  		}
   852  		gateway {
   853  			name: "B"
   854  			listen: "0.0.0.0:-1"
   855  		}
   856  	`, fmt.Sprintf("nats://127.0.0.1:%d", sb1.ClusterAddr().Port))))
   857  	sb2, ob2 := RunServerWithConfig(confB2)
   858  	defer sb2.Shutdown()
   859  
   860  	checkClusterFormed(t, sb1, sb2)
   861  
   862  	confA := createConfFile(t, []byte(fmt.Sprintf(`
   863  		listen: "127.0.0.1:-1"
   864  		cluster {
   865  			listen: "127.0.0.1:-1"
   866  		}
   867  		gateway {
   868  			name: "A"
   869  			listen: "0.0.0.0:-1"
   870  			gateways [
   871  				{
   872  					name: "B"
   873  					urls: ["%s", "%s"]
   874  				}
   875  			]
   876  		}
   877  	`, fmt.Sprintf("nats://127.0.0.1:%d", ob1.Gateway.Port), fmt.Sprintf("nats://127.0.0.1:%d", ob2.Gateway.Port))))
   878  	oa := LoadConfig(confA)
   879  	oa.gatewaysSolicitDelay = 15 * time.Millisecond
   880  	sa := runGatewayServer(oa)
   881  	defer sa.Shutdown()
   882  
   883  	waitForOutboundGateways(t, sa, 1, time.Second)
   884  	waitForOutboundGateways(t, sb1, 1, time.Second)
   885  	waitForOutboundGateways(t, sb2, 1, time.Second)
   886  	waitForInboundGateways(t, sa, 2, time.Second)
   887  
   888  	checkAll := func(t *testing.T) {
   889  		t.Helper()
   890  		checkURL := func(t *testing.T, s *Server) {
   891  			t.Helper()
   892  			url := s.getGatewayURL()
   893  			if strings.HasPrefix(url, "0.0.0.0") {
   894  				t.Fatalf("URL still references 0.0.0.0")
   895  			}
   896  			s.gateway.RLock()
   897  			for url := range s.gateway.URLs {
   898  				if strings.HasPrefix(url, "0.0.0.0") {
   899  					s.gateway.RUnlock()
   900  					t.Fatalf("URL still references 0.0.0.0")
   901  				}
   902  			}
   903  			s.gateway.RUnlock()
   904  
   905  			var cfg *gatewayCfg
   906  			if s.getGatewayName() == "A" {
   907  				cfg = s.getRemoteGateway("B")
   908  			} else {
   909  				cfg = s.getRemoteGateway("A")
   910  			}
   911  			urls := cfg.getURLs()
   912  			for _, url := range urls {
   913  				if strings.HasPrefix(url.Host, "0.0.0.0") {
   914  					t.Fatalf("URL still references 0.0.0.0")
   915  				}
   916  			}
   917  		}
   918  		checkURL(t, sb1)
   919  		checkURL(t, sb2)
   920  		checkURL(t, sa)
   921  	}
   922  	checkAll(t)
   923  	// Perform a reload and ensure that nothing has changed
   924  	servers := []*Server{sb1, sb2, sa}
   925  	for _, s := range servers {
   926  		if err := s.Reload(); err != nil {
   927  			t.Fatalf("Error on reload: %v", err)
   928  		}
   929  		checkAll(t)
   930  	}
   931  }
   932  
   933  func TestGatewayAdvertise(t *testing.T) {
   934  	o3 := testDefaultOptionsForGateway("C")
   935  	s3 := runGatewayServer(o3)
   936  	defer s3.Shutdown()
   937  
   938  	o2 := testDefaultOptionsForGateway("B")
   939  	s2 := runGatewayServer(o2)
   940  	defer s2.Shutdown()
   941  
   942  	o1 := testGatewayOptionsFromToWithServers(t, "A", "B", s2)
   943  	// Set the advertise so that this points to C
   944  	o1.Gateway.Advertise = fmt.Sprintf("127.0.0.1:%d", s3.GatewayAddr().Port)
   945  	s1 := runGatewayServer(o1)
   946  	defer s1.Shutdown()
   947  
   948  	// We should have outbound from s1 to s2
   949  	waitForOutboundGateways(t, s1, 1, time.Second)
   950  	// But no inbound from s2
   951  	waitForInboundGateways(t, s1, 0, time.Second)
   952  
   953  	// And since B tries to connect to A but reaches C, it should fail to connect,
   954  	// and without connect retries, stop trying. So no outbound for s2, and no
   955  	// inbound/outbound for s3.
   956  	waitForInboundGateways(t, s2, 1, time.Second)
   957  	waitForOutboundGateways(t, s2, 0, time.Second)
   958  	waitForInboundGateways(t, s3, 0, time.Second)
   959  	waitForOutboundGateways(t, s3, 0, time.Second)
   960  }
   961  
   962  func TestGatewayAdvertiseErr(t *testing.T) {
   963  	o1 := testDefaultOptionsForGateway("A")
   964  	o1.Gateway.Advertise = "wrong:address"
   965  	testFatalErrorOnStart(t, o1, "Gateway.Advertise")
   966  }
   967  
   968  func TestGatewayAuth(t *testing.T) {
   969  	o2 := testDefaultOptionsForGateway("B")
   970  	o2.Gateway.Username = "me"
   971  	o2.Gateway.Password = "pwd"
   972  	s2 := runGatewayServer(o2)
   973  	defer s2.Shutdown()
   974  
   975  	o1 := testGatewayOptionsFromToWithURLs(t, "A", "B", []string{fmt.Sprintf("nats://me:pwd@127.0.0.1:%d", s2.GatewayAddr().Port)})
   976  	s1 := runGatewayServer(o1)
   977  	defer s1.Shutdown()
   978  
   979  	// s1 should have an outbound gateway to s2.
   980  	waitForOutboundGateways(t, s1, 1, time.Second)
   981  	// s2 should have an inbound gateway
   982  	waitForInboundGateways(t, s2, 1, time.Second)
   983  
   984  	s2.Shutdown()
   985  	s1.Shutdown()
   986  
   987  	o2.Gateway.Username = "me"
   988  	o2.Gateway.Password = "wrong"
   989  	s2 = runGatewayServer(o2)
   990  	defer s2.Shutdown()
   991  
   992  	s1 = runGatewayServer(o1)
   993  	defer s1.Shutdown()
   994  
   995  	// Connection should fail...
   996  	waitForGatewayFailedConnect(t, s1, "B", true, 2*time.Second)
   997  
   998  	s2.Shutdown()
   999  	s1.Shutdown()
  1000  	o2.Gateway.Username = "wrong"
  1001  	o2.Gateway.Password = "pwd"
  1002  	s2 = runGatewayServer(o2)
  1003  	defer s2.Shutdown()
  1004  
  1005  	s1 = runGatewayServer(o1)
  1006  	defer s1.Shutdown()
  1007  
  1008  	// Connection should fail...
  1009  	waitForGatewayFailedConnect(t, s1, "B", true, 2*time.Second)
  1010  }
  1011  
  1012  func TestGatewayTLS(t *testing.T) {
  1013  	o2 := testGatewayOptionsWithTLS(t, "B")
  1014  	s2 := runGatewayServer(o2)
  1015  	defer s2.Shutdown()
  1016  
  1017  	o1 := testGatewayOptionsFromToWithTLS(t, "A", "B", []string{fmt.Sprintf("nats://127.0.0.1:%d", s2.GatewayAddr().Port)})
  1018  	s1 := runGatewayServer(o1)
  1019  	defer s1.Shutdown()
  1020  
  1021  	// s1 should have an outbound gateway to s2.
  1022  	waitForOutboundGateways(t, s1, 1, time.Second)
  1023  	// s2 should have an inbound gateway
  1024  	waitForInboundGateways(t, s2, 1, time.Second)
  1025  	// and vice-versa
  1026  	waitForOutboundGateways(t, s2, 1, time.Second)
  1027  	waitForInboundGateways(t, s1, 1, time.Second)
  1028  
  1029  	// Stop s2 server
  1030  	s2.Shutdown()
  1031  
  1032  	// gateway should go away
  1033  	waitForOutboundGateways(t, s1, 0, time.Second)
  1034  	waitForInboundGateways(t, s1, 0, time.Second)
  1035  	waitForOutboundGateways(t, s2, 0, time.Second)
  1036  	waitForInboundGateways(t, s2, 0, time.Second)
  1037  
  1038  	// Restart server
  1039  	s2 = runGatewayServer(o2)
  1040  	defer s2.Shutdown()
  1041  
  1042  	// gateway should reconnect
  1043  	waitForOutboundGateways(t, s1, 1, 2*time.Second)
  1044  	waitForOutboundGateways(t, s2, 1, 2*time.Second)
  1045  	waitForInboundGateways(t, s1, 1, 2*time.Second)
  1046  	waitForInboundGateways(t, s2, 1, 2*time.Second)
  1047  
  1048  	s1.Shutdown()
  1049  	// Wait for s2 to lose connections to s1.
  1050  	waitForOutboundGateways(t, s2, 0, 2*time.Second)
  1051  	waitForInboundGateways(t, s2, 0, 2*time.Second)
  1052  
  1053  	// Make an explicit TLS config for remote gateway config "B"
  1054  	// on cluster A.
  1055  	o1.Gateway.Gateways[0].TLSConfig = o1.Gateway.TLSConfig.Clone()
  1056  	u, _ := url.Parse(fmt.Sprintf("tls://localhost:%d", s2.GatewayAddr().Port))
  1057  	o1.Gateway.Gateways[0].URLs = []*url.URL{u}
  1058  	// Make the TLSTimeout so small that it should fail to connect.
  1059  	smallTimeout := 0.00000001
  1060  	o1.Gateway.Gateways[0].TLSTimeout = smallTimeout
  1061  	s1 = runGatewayServer(o1)
  1062  	defer s1.Shutdown()
  1063  
  1064  	// Check that s1 reports connection failures
  1065  	waitForGatewayFailedConnect(t, s1, "B", true, 2*time.Second)
  1066  
  1067  	// Check that TLSConfig from s1's remote "B" is based on
  1068  	// what we have configured.
  1069  	cfg := s1.getRemoteGateway("B")
  1070  	cfg.RLock()
  1071  	tlsName := cfg.tlsName
  1072  	timeout := cfg.TLSTimeout
  1073  	cfg.RUnlock()
  1074  	if tlsName != "localhost" {
  1075  		t.Fatalf("Expected server name to be localhost, got %v", tlsName)
  1076  	}
  1077  	if timeout != smallTimeout {
  1078  		t.Fatalf("Expected tls timeout to be %v, got %v", smallTimeout, timeout)
  1079  	}
  1080  	s1.Shutdown()
  1081  	// Wait for s2 to lose connections to s1.
  1082  	waitForOutboundGateways(t, s2, 0, 2*time.Second)
  1083  	waitForInboundGateways(t, s2, 0, 2*time.Second)
  1084  
  1085  	// Remove explicit TLSTimeout from gateway "B" and check that
  1086  	// we use the A's spec one.
  1087  	o1.Gateway.Gateways[0].TLSTimeout = 0
  1088  	s1 = runGatewayServer(o1)
  1089  	defer s1.Shutdown()
  1090  
  1091  	waitForOutboundGateways(t, s1, 1, 2*time.Second)
  1092  	waitForOutboundGateways(t, s2, 1, 2*time.Second)
  1093  	waitForInboundGateways(t, s1, 1, 2*time.Second)
  1094  	waitForInboundGateways(t, s2, 1, 2*time.Second)
  1095  
  1096  	cfg = s1.getRemoteGateway("B")
  1097  	cfg.RLock()
  1098  	timeout = cfg.TLSTimeout
  1099  	cfg.RUnlock()
  1100  	if timeout != o1.Gateway.TLSTimeout {
  1101  		t.Fatalf("Expected tls timeout to be %v, got %v", o1.Gateway.TLSTimeout, timeout)
  1102  	}
  1103  }
  1104  
  1105  func TestGatewayTLSErrors(t *testing.T) {
  1106  	o2 := testDefaultOptionsForGateway("B")
  1107  	s2 := runGatewayServer(o2)
  1108  	defer s2.Shutdown()
  1109  
  1110  	o1 := testGatewayOptionsFromToWithTLS(t, "A", "B", []string{fmt.Sprintf("nats://127.0.0.1:%d", s2.ClusterAddr().Port)})
  1111  	s1 := runGatewayServer(o1)
  1112  	defer s1.Shutdown()
  1113  
  1114  	// Expect s1 to have a failed to connect count > 0
  1115  	waitForGatewayFailedConnect(t, s1, "B", true, 2*time.Second)
  1116  }
  1117  
  1118  func TestGatewayServerNameInTLSConfig(t *testing.T) {
  1119  	o2 := testDefaultOptionsForGateway("B")
  1120  	var (
  1121  		tc  = &TLSConfigOpts{}
  1122  		err error
  1123  	)
  1124  	tc.CertFile = "../test/configs/certs/server-noip.pem"
  1125  	tc.KeyFile = "../test/configs/certs/server-key-noip.pem"
  1126  	tc.CaFile = "../test/configs/certs/ca.pem"
  1127  	o2.Gateway.TLSConfig, err = GenTLSConfig(tc)
  1128  	if err != nil {
  1129  		t.Fatalf("Error generating TLS config: %v", err)
  1130  	}
  1131  	o2.Gateway.TLSConfig.ClientAuth = tls.RequireAndVerifyClientCert
  1132  	o2.Gateway.TLSConfig.RootCAs = o2.Gateway.TLSConfig.ClientCAs
  1133  	o2.Gateway.TLSTimeout = 2.0
  1134  	s2 := runGatewayServer(o2)
  1135  	defer s2.Shutdown()
  1136  
  1137  	o1 := testGatewayOptionsFromToWithTLS(t, "A", "B", []string{fmt.Sprintf("nats://127.0.0.1:%d", s2.GatewayAddr().Port)})
  1138  	s1 := runGatewayServer(o1)
  1139  	defer s1.Shutdown()
  1140  
  1141  	// s1 should fail to connect since we don't have proper expected hostname.
  1142  	waitForGatewayFailedConnect(t, s1, "B", true, 2*time.Second)
  1143  
  1144  	// Now set server name, and it should work.
  1145  	s1.Shutdown()
  1146  	o1.Gateway.TLSConfig.ServerName = "localhost"
  1147  	s1 = runGatewayServer(o1)
  1148  	defer s1.Shutdown()
  1149  
  1150  	waitForOutboundGateways(t, s1, 1, 2*time.Second)
  1151  }
  1152  
  1153  func TestGatewayWrongDestination(t *testing.T) {
  1154  	// Start a server with a gateway named "C"
  1155  	o2 := testDefaultOptionsForGateway("C")
  1156  	s2 := runGatewayServer(o2)
  1157  	defer s2.Shutdown()
  1158  
  1159  	// Configure a gateway to "B", but since we are connecting to "C"...
  1160  	o1 := testGatewayOptionsFromToWithServers(t, "A", "B", s2)
  1161  	s1 := runGatewayServer(o1)
  1162  	defer s1.Shutdown()
  1163  
  1164  	// we should not be able to connect.
  1165  	waitForGatewayFailedConnect(t, s1, "B", true, time.Second)
  1166  
  1167  	// Shutdown s2 and fix the gateway name.
  1168  	// s1 should then connect ok and failed connect should be cleared.
  1169  	s2.Shutdown()
  1170  
  1171  	// Reset the conn attempts
  1172  	cfg := s1.getRemoteGateway("B")
  1173  	cfg.resetConnAttempts()
  1174  
  1175  	o2.Gateway.Name = "B"
  1176  	o2.Cluster.Name = "B"
  1177  	s2 = runGatewayServer(o2)
  1178  	defer s2.Shutdown()
  1179  
  1180  	// At some point, the number of failed connect count should be reset to 0.
  1181  	waitForGatewayFailedConnect(t, s1, "B", false, 2*time.Second)
  1182  }
  1183  
  1184  func TestGatewayConnectToWrongPort(t *testing.T) {
  1185  	o2 := testDefaultOptionsForGateway("B")
  1186  	s2 := runGatewayServer(o2)
  1187  	defer s2.Shutdown()
  1188  
  1189  	// Configure a gateway to "B", but connect to the wrong port
  1190  	urls := []string{fmt.Sprintf("nats://127.0.0.1:%d", s2.Addr().(*net.TCPAddr).Port)}
  1191  	o1 := testGatewayOptionsFromToWithURLs(t, "A", "B", urls)
  1192  	s1 := runGatewayServer(o1)
  1193  	defer s1.Shutdown()
  1194  
  1195  	// we should not be able to connect.
  1196  	waitForGatewayFailedConnect(t, s1, "B", true, time.Second)
  1197  
  1198  	s1.Shutdown()
  1199  
  1200  	// Repeat with route port
  1201  	urls = []string{fmt.Sprintf("nats://127.0.0.1:%d", s2.ClusterAddr().Port)}
  1202  	o1 = testGatewayOptionsFromToWithURLs(t, "A", "B", urls)
  1203  	s1 = runGatewayServer(o1)
  1204  	defer s1.Shutdown()
  1205  
  1206  	// we should not be able to connect.
  1207  	waitForGatewayFailedConnect(t, s1, "B", true, time.Second)
  1208  
  1209  	s1.Shutdown()
  1210  
  1211  	// Now have a client connect to s2's gateway port.
  1212  	nc, err := nats.Connect(fmt.Sprintf("nats://127.0.0.1:%d", s2.GatewayAddr().Port))
  1213  	if err == nil {
  1214  		nc.Close()
  1215  		t.Fatal("Expected error, got none")
  1216  	}
  1217  }
  1218  
  1219  func TestGatewayCreateImplicit(t *testing.T) {
  1220  	// Create a regular cluster of 2 servers
  1221  	o2 := testDefaultOptionsForGateway("B")
  1222  	s2 := runGatewayServer(o2)
  1223  	defer s2.Shutdown()
  1224  
  1225  	o3 := testDefaultOptionsForGateway("B")
  1226  	o3.Routes = RoutesFromStr(fmt.Sprintf("nats://127.0.0.1:%d", s2.ClusterAddr().Port))
  1227  	s3 := runGatewayServer(o3)
  1228  	defer s3.Shutdown()
  1229  
  1230  	checkClusterFormed(t, s2, s3)
  1231  
  1232  	// Now start s1 that creates a Gateway connection to s2 or s3
  1233  	o1 := testGatewayOptionsFromToWithServers(t, "A", "B", s2, s3)
  1234  	s1 := runGatewayServer(o1)
  1235  	defer s1.Shutdown()
  1236  
  1237  	// We should have an outbound gateway connection on ALL servers.
  1238  	waitForOutboundGateways(t, s1, 1, 2*time.Second)
  1239  	waitForOutboundGateways(t, s2, 1, 2*time.Second)
  1240  	waitForOutboundGateways(t, s3, 1, 2*time.Second)
  1241  
  1242  	// Server s1 must have 2 inbound ones
  1243  	waitForInboundGateways(t, s1, 2, 2*time.Second)
  1244  
  1245  	// However, s1 may have created the outbound to s2 or s3. It is possible that
  1246  	// either s2 or s3 does not an inbound connection.
  1247  	s2Inbound := s2.numInboundGateways()
  1248  	s3Inbound := s3.numInboundGateways()
  1249  	if (s2Inbound == 1 && s3Inbound != 0) || (s3Inbound == 1 && s2Inbound != 0) {
  1250  		t.Fatalf("Unexpected inbound for s2/s3: %v/%v", s2Inbound, s3Inbound)
  1251  	}
  1252  }
  1253  
  1254  func TestGatewayCreateImplicitOnNewRoute(t *testing.T) {
  1255  	// Start with only 2 clusters of 1 server each
  1256  	o2 := testDefaultOptionsForGateway("B")
  1257  	s2 := runGatewayServer(o2)
  1258  	defer s2.Shutdown()
  1259  
  1260  	// Now start s1 that creates a Gateway connection to s2
  1261  	o1 := testGatewayOptionsFromToWithServers(t, "A", "B", s2)
  1262  	s1 := runGatewayServer(o1)
  1263  	defer s1.Shutdown()
  1264  
  1265  	// Check outbounds
  1266  	waitForOutboundGateways(t, s1, 1, 2*time.Second)
  1267  	waitForOutboundGateways(t, s2, 1, 2*time.Second)
  1268  
  1269  	// Now add a server to cluster B
  1270  	o3 := testDefaultOptionsForGateway("B")
  1271  	o3.Routes = RoutesFromStr(fmt.Sprintf("nats://127.0.0.1:%d", s2.ClusterAddr().Port))
  1272  	s3 := runGatewayServer(o3)
  1273  	defer s3.Shutdown()
  1274  
  1275  	// Wait for cluster between s2/s3 to form
  1276  	checkClusterFormed(t, s2, s3)
  1277  
  1278  	// s3 should have been notified about existence of A and create its gateway to A.
  1279  	waitForOutboundGateways(t, s1, 1, 2*time.Second)
  1280  	waitForOutboundGateways(t, s2, 1, 2*time.Second)
  1281  	waitForOutboundGateways(t, s3, 1, 2*time.Second)
  1282  }
  1283  
  1284  func TestGatewayImplicitReconnect(t *testing.T) {
  1285  	o2 := testDefaultOptionsForGateway("B")
  1286  	o2.Gateway.ConnectRetries = 5
  1287  	s2 := runGatewayServer(o2)
  1288  	defer s2.Shutdown()
  1289  
  1290  	o1 := testGatewayOptionsFromToWithServers(t, "A", "B", s2)
  1291  	s1 := runGatewayServer(o1)
  1292  	defer s1.Shutdown()
  1293  
  1294  	// s1 should have an outbound gateway to s2.
  1295  	waitForOutboundGateways(t, s1, 1, time.Second)
  1296  	// s2 should have an inbound gateway
  1297  	waitForInboundGateways(t, s2, 1, time.Second)
  1298  	// It will have also created an implicit outbound connection to s1.
  1299  	// We need to wait for that implicit outbound connection to be made
  1300  	// to show that it will try to reconnect when we stop/restart s1
  1301  	// (without config to connect to B).
  1302  	waitForOutboundGateways(t, s2, 1, time.Second)
  1303  
  1304  	// Shutdown s1, remove the gateway from A to B and restart.
  1305  	s1.Shutdown()
  1306  	o1.Gateway.Gateways = o1.Gateway.Gateways[:0]
  1307  	s1 = runGatewayServer(o1)
  1308  	defer s1.Shutdown()
  1309  
  1310  	// s1 should have both outbound and inbound to s2
  1311  	waitForOutboundGateways(t, s1, 1, 2*time.Second)
  1312  	waitForInboundGateways(t, s1, 1, 2*time.Second)
  1313  
  1314  	// Same for s2
  1315  	waitForOutboundGateways(t, s2, 1, 2*time.Second)
  1316  	waitForInboundGateways(t, s2, 1, 2*time.Second)
  1317  
  1318  	// Verify that s2 still has "A" in its gateway config
  1319  	if s2.getRemoteGateway("A") == nil {
  1320  		t.Fatal("Gateway A should be in s2")
  1321  	}
  1322  }
  1323  
  1324  func TestGatewayImplicitReconnectRace(t *testing.T) {
  1325  	ob := testDefaultOptionsForGateway("B")
  1326  	resolver := &slowResolver{
  1327  		inLookupCh: make(chan struct{}, 1),
  1328  		releaseCh:  make(chan struct{}),
  1329  	}
  1330  	ob.Gateway.resolver = resolver
  1331  	sb := runGatewayServer(ob)
  1332  	defer sb.Shutdown()
  1333  
  1334  	oa1 := testGatewayOptionsFromToWithServers(t, "A", "B", sb)
  1335  	sa1 := runGatewayServer(oa1)
  1336  	defer sa1.Shutdown()
  1337  
  1338  	// Wait for the proper connections
  1339  	waitForOutboundGateways(t, sa1, 1, time.Second)
  1340  	waitForOutboundGateways(t, sb, 1, time.Second)
  1341  	waitForInboundGateways(t, sa1, 1, time.Second)
  1342  	waitForInboundGateways(t, sb, 1, time.Second)
  1343  
  1344  	// On sb, change the URL to sa1 so that it is a name, instead of an IP,
  1345  	// so that we hit the slow resolver.
  1346  	cfg := sb.getRemoteGateway("A")
  1347  	cfg.updateURLs([]string{fmt.Sprintf("localhost:%d", sa1.GatewayAddr().Port)})
  1348  
  1349  	// Shutdown sa1 now...
  1350  	sa1.Shutdown()
  1351  
  1352  	// Wait to be notified that B has detected the connection close
  1353  	// and it is trying to resolve the host during the reconnect.
  1354  	<-resolver.inLookupCh
  1355  
  1356  	// Start a new "A" server (sa2).
  1357  	oa2 := testGatewayOptionsFromToWithServers(t, "A", "B", sb)
  1358  	sa2 := runGatewayServer(oa2)
  1359  	defer sa2.Shutdown()
  1360  
  1361  	// Make sure we have our outbound to sb registered on sa2 and inbound
  1362  	// from sa2 on sb before releasing the resolver.
  1363  	waitForOutboundGateways(t, sa2, 1, 2*time.Second)
  1364  	waitForInboundGateways(t, sb, 1, 2*time.Second)
  1365  
  1366  	// Now release the resolver and ensure we have all connections.
  1367  	close(resolver.releaseCh)
  1368  
  1369  	waitForOutboundGateways(t, sb, 1, 2*time.Second)
  1370  	waitForInboundGateways(t, sa2, 1, 2*time.Second)
  1371  }
  1372  
  1373  type gwReconnAttemptLogger struct {
  1374  	DummyLogger
  1375  	errCh chan string
  1376  }
  1377  
  1378  func (l *gwReconnAttemptLogger) Errorf(format string, v ...interface{}) {
  1379  	msg := fmt.Sprintf(format, v...)
  1380  	if strings.Contains(msg, `Error connecting to implicit gateway "A"`) {
  1381  		select {
  1382  		case l.errCh <- msg:
  1383  		default:
  1384  		}
  1385  	}
  1386  }
  1387  
  1388  func TestGatewayImplicitReconnectHonorConnectRetries(t *testing.T) {
  1389  	ob := testDefaultOptionsForGateway("B")
  1390  	ob.ReconnectErrorReports = 1
  1391  	ob.Gateway.ConnectRetries = 2
  1392  	sb := runGatewayServer(ob)
  1393  	defer sb.Shutdown()
  1394  
  1395  	l := &gwReconnAttemptLogger{errCh: make(chan string, 3)}
  1396  	sb.SetLogger(l, true, false)
  1397  
  1398  	oa := testGatewayOptionsFromToWithServers(t, "A", "B", sb)
  1399  	sa := runGatewayServer(oa)
  1400  	defer sa.Shutdown()
  1401  
  1402  	// Wait for the proper connections
  1403  	waitForOutboundGateways(t, sa, 1, time.Second)
  1404  	waitForOutboundGateways(t, sb, 1, time.Second)
  1405  	waitForInboundGateways(t, sa, 1, time.Second)
  1406  	waitForInboundGateways(t, sb, 1, time.Second)
  1407  
  1408  	// Now have C connect to B.
  1409  	oc := testGatewayOptionsFromToWithServers(t, "C", "B", sb)
  1410  	sc := runGatewayServer(oc)
  1411  	defer sc.Shutdown()
  1412  
  1413  	// Wait for the proper connections
  1414  	waitForOutboundGateways(t, sa, 2, time.Second)
  1415  	waitForOutboundGateways(t, sb, 2, time.Second)
  1416  	waitForOutboundGateways(t, sc, 2, time.Second)
  1417  	waitForInboundGateways(t, sa, 2, time.Second)
  1418  	waitForInboundGateways(t, sb, 2, time.Second)
  1419  	waitForInboundGateways(t, sc, 2, time.Second)
  1420  
  1421  	// Shutdown sa now...
  1422  	sa.Shutdown()
  1423  
  1424  	// B will try to reconnect to A 3 times (we stop after attempts > ConnectRetries)
  1425  	timeout := time.NewTimer(time.Second)
  1426  	for i := 0; i < 3; i++ {
  1427  		select {
  1428  		case <-l.errCh:
  1429  			// OK
  1430  		case <-timeout.C:
  1431  			t.Fatal("Did not get debug trace about reconnect")
  1432  		}
  1433  	}
  1434  	// If we get 1 more, we have an issue!
  1435  	select {
  1436  	case e := <-l.errCh:
  1437  		t.Fatalf("Should not have attempted to reconnect: %q", e)
  1438  	case <-time.After(250 * time.Millisecond):
  1439  		// OK!
  1440  	}
  1441  
  1442  	waitForOutboundGateways(t, sb, 1, 2*time.Second)
  1443  	waitForInboundGateways(t, sb, 1, 2*time.Second)
  1444  	waitForOutboundGateways(t, sc, 1, 2*time.Second)
  1445  	waitForInboundGateways(t, sc, 1, 2*time.Second)
  1446  }
  1447  
  1448  func TestGatewayURLsFromClusterSentInINFO(t *testing.T) {
  1449  	o2 := testDefaultOptionsForGateway("B")
  1450  	s2 := runGatewayServer(o2)
  1451  	defer s2.Shutdown()
  1452  
  1453  	o3 := testDefaultOptionsForGateway("B")
  1454  	o3.Routes = RoutesFromStr(fmt.Sprintf("nats://127.0.0.1:%d", s2.ClusterAddr().Port))
  1455  	s3 := runGatewayServer(o3)
  1456  	defer s3.Shutdown()
  1457  
  1458  	checkClusterFormed(t, s2, s3)
  1459  
  1460  	// Now start s1 that creates a Gateway connection to s2
  1461  	o1 := testGatewayOptionsFromToWithServers(t, "A", "B", s2)
  1462  	s1 := runGatewayServer(o1)
  1463  	defer s1.Shutdown()
  1464  
  1465  	// Make sure we have proper outbound/inbound
  1466  	waitForOutboundGateways(t, s1, 1, time.Second)
  1467  	waitForOutboundGateways(t, s2, 1, time.Second)
  1468  	waitForOutboundGateways(t, s3, 1, time.Second)
  1469  
  1470  	// Although s1 connected to s2 and knew only about s2, it should have
  1471  	// received the list of gateway URLs in the B cluster. So if we shutdown
  1472  	// server s2, it should be able to reconnect to s3.
  1473  	s2.Shutdown()
  1474  	// Wait for s3 to register that there s2 is gone.
  1475  	checkNumRoutes(t, s3, 0)
  1476  	// s1 should have reconnected to s3 because it learned about it
  1477  	// when connecting earlier to s2.
  1478  	waitForOutboundGateways(t, s1, 1, 2*time.Second)
  1479  	// Also make sure that the gateway's urls map has 2 urls.
  1480  	gw := s1.getRemoteGateway("B")
  1481  	if gw == nil {
  1482  		t.Fatal("Did not find gateway B")
  1483  	}
  1484  	gw.RLock()
  1485  	l := len(gw.urls)
  1486  	gw.RUnlock()
  1487  	if l != 2 {
  1488  		t.Fatalf("S1 should have 2 urls, got %v", l)
  1489  	}
  1490  }
  1491  
  1492  func TestGatewayUseUpdatedURLs(t *testing.T) {
  1493  	// For this test, we have cluster B with an explicit gateway to cluster A
  1494  	// on a given URL. Then we create cluster A with a gateway to B with server B's
  1495  	// GW url, and we expect server B to ultimately create an outbound GW connection
  1496  	// to server A (with the URL it will get from server A connecting to it).
  1497  
  1498  	ob := testGatewayOptionsFromToWithURLs(t, "B", "A", []string{"nats://127.0.0.1:1234"})
  1499  	sb := runGatewayServer(ob)
  1500  	defer sb.Shutdown()
  1501  
  1502  	// Add a delay before starting server A to make sure that server B start
  1503  	// initiating the connection to A on inexistant server at :1234.
  1504  	time.Sleep(100 * time.Millisecond)
  1505  
  1506  	oa := testGatewayOptionsFromToWithServers(t, "A", "B", sb)
  1507  	sa := runGatewayServer(oa)
  1508  	defer sa.Shutdown()
  1509  
  1510  	// sa should have no problem creating outbound connection to sb
  1511  	waitForOutboundGateways(t, sa, 1, time.Second)
  1512  
  1513  	// Make sure that since sb learns about sa's GW URL, it can successfully
  1514  	// connect to it.
  1515  	waitForOutboundGateways(t, sb, 1, 3*time.Second)
  1516  	waitForInboundGateways(t, sb, 1, time.Second)
  1517  	waitForInboundGateways(t, sa, 1, time.Second)
  1518  }
  1519  
  1520  func TestGatewayAutoDiscovery(t *testing.T) {
  1521  	o4 := testDefaultOptionsForGateway("D")
  1522  	s4 := runGatewayServer(o4)
  1523  	defer s4.Shutdown()
  1524  
  1525  	o3 := testGatewayOptionsFromToWithServers(t, "C", "D", s4)
  1526  	s3 := runGatewayServer(o3)
  1527  	defer s3.Shutdown()
  1528  
  1529  	o2 := testGatewayOptionsFromToWithServers(t, "B", "C", s3)
  1530  	s2 := runGatewayServer(o2)
  1531  	defer s2.Shutdown()
  1532  
  1533  	o1 := testGatewayOptionsFromToWithServers(t, "A", "B", s2)
  1534  	s1 := runGatewayServer(o1)
  1535  	defer s1.Shutdown()
  1536  
  1537  	// Each server should have 3 outbound gateway connections.
  1538  	waitForOutboundGateways(t, s1, 3, 2*time.Second)
  1539  	waitForOutboundGateways(t, s2, 3, 2*time.Second)
  1540  	waitForOutboundGateways(t, s3, 3, 2*time.Second)
  1541  	waitForOutboundGateways(t, s4, 3, 2*time.Second)
  1542  
  1543  	s1.Shutdown()
  1544  	s2.Shutdown()
  1545  	s3.Shutdown()
  1546  	s4.Shutdown()
  1547  
  1548  	o2 = testDefaultOptionsForGateway("B")
  1549  	s2 = runGatewayServer(o2)
  1550  	defer s2.Shutdown()
  1551  
  1552  	o4 = testGatewayOptionsFromToWithServers(t, "D", "B", s2)
  1553  	s4 = runGatewayServer(o4)
  1554  	defer s4.Shutdown()
  1555  
  1556  	o3 = testGatewayOptionsFromToWithServers(t, "C", "B", s2)
  1557  	s3 = runGatewayServer(o3)
  1558  	defer s3.Shutdown()
  1559  
  1560  	o1 = testGatewayOptionsFromToWithServers(t, "A", "B", s2)
  1561  	s1 = runGatewayServer(o1)
  1562  	defer s1.Shutdown()
  1563  
  1564  	// Each server should have 3 outbound gateway connections.
  1565  	waitForOutboundGateways(t, s1, 3, 2*time.Second)
  1566  	waitForOutboundGateways(t, s2, 3, 2*time.Second)
  1567  	waitForOutboundGateways(t, s3, 3, 2*time.Second)
  1568  	waitForOutboundGateways(t, s4, 3, 2*time.Second)
  1569  
  1570  	s1.Shutdown()
  1571  	s2.Shutdown()
  1572  	s3.Shutdown()
  1573  	s4.Shutdown()
  1574  
  1575  	o1 = testDefaultOptionsForGateway("A")
  1576  	s1 = runGatewayServer(o1)
  1577  	defer s1.Shutdown()
  1578  
  1579  	o2 = testDefaultOptionsForGateway("A")
  1580  	o2.Routes = RoutesFromStr(fmt.Sprintf("nats://127.0.0.1:%d", s1.ClusterAddr().Port))
  1581  	s2 = runGatewayServer(o2)
  1582  	defer s2.Shutdown()
  1583  
  1584  	o3 = testDefaultOptionsForGateway("A")
  1585  	o3.Routes = RoutesFromStr(fmt.Sprintf("nats://127.0.0.1:%d", s1.ClusterAddr().Port))
  1586  	s3 = runGatewayServer(o3)
  1587  	defer s3.Shutdown()
  1588  
  1589  	checkClusterFormed(t, s1, s2, s3)
  1590  
  1591  	o4 = testGatewayOptionsFromToWithServers(t, "B", "A", s1)
  1592  	s4 = runGatewayServer(o4)
  1593  	defer s4.Shutdown()
  1594  
  1595  	waitForOutboundGateways(t, s1, 1, 2*time.Second)
  1596  	waitForOutboundGateways(t, s2, 1, 2*time.Second)
  1597  	waitForOutboundGateways(t, s3, 1, 2*time.Second)
  1598  	waitForOutboundGateways(t, s4, 1, 2*time.Second)
  1599  	waitForInboundGateways(t, s4, 3, 2*time.Second)
  1600  
  1601  	o5 := testGatewayOptionsFromToWithServers(t, "C", "B", s4)
  1602  	s5 := runGatewayServer(o5)
  1603  	defer s5.Shutdown()
  1604  
  1605  	waitForOutboundGateways(t, s1, 2, 2*time.Second)
  1606  	waitForOutboundGateways(t, s2, 2, 2*time.Second)
  1607  	waitForOutboundGateways(t, s3, 2, 2*time.Second)
  1608  	waitForOutboundGateways(t, s4, 2, 2*time.Second)
  1609  	waitForInboundGateways(t, s4, 4, 2*time.Second)
  1610  	waitForOutboundGateways(t, s5, 2, 2*time.Second)
  1611  	waitForInboundGateways(t, s5, 4, 2*time.Second)
  1612  }
  1613  
  1614  func TestGatewayRejectUnknown(t *testing.T) {
  1615  	o2 := testDefaultOptionsForGateway("B")
  1616  	s2 := runGatewayServer(o2)
  1617  	defer s2.Shutdown()
  1618  
  1619  	// Create a gateway from A to B, but configure B to reject non configured ones.
  1620  	o1 := testGatewayOptionsFromToWithServers(t, "A", "B", s2)
  1621  	o1.Gateway.RejectUnknown = true
  1622  	s1 := runGatewayServer(o1)
  1623  	defer s1.Shutdown()
  1624  
  1625  	// Wait for outbound/inbound to be created.
  1626  	waitForOutboundGateways(t, s1, 1, time.Second)
  1627  	waitForOutboundGateways(t, s2, 1, time.Second)
  1628  	waitForInboundGateways(t, s1, 1, time.Second)
  1629  	waitForInboundGateways(t, s2, 1, time.Second)
  1630  
  1631  	// Create gateway C to B. B will tell C to connect to A,
  1632  	// which A should reject.
  1633  	o3 := testGatewayOptionsFromToWithServers(t, "C", "B", s2)
  1634  	s3 := runGatewayServer(o3)
  1635  	defer s3.Shutdown()
  1636  
  1637  	// s3 should have outbound to B, but not to A
  1638  	waitForOutboundGateways(t, s3, 1, time.Second)
  1639  	// s2 should have 2 inbounds (one from s1 one from s3)
  1640  	waitForInboundGateways(t, s2, 2, time.Second)
  1641  
  1642  	// s1 should have single outbound/inbound with s2.
  1643  	waitForOutboundGateways(t, s1, 1, time.Second)
  1644  	waitForInboundGateways(t, s1, 1, time.Second)
  1645  
  1646  	// It should not have a registered remote gateway with C (s3)
  1647  	if s1.getOutboundGatewayConnection("C") != nil {
  1648  		t.Fatalf("A should not have outbound gateway to C")
  1649  	}
  1650  	if s1.getRemoteGateway("C") != nil {
  1651  		t.Fatalf("A should not have a registered remote gateway to C")
  1652  	}
  1653  
  1654  	// Restart s1 and this time, B will tell A to connect to C.
  1655  	// But A will not even attempt that since it does not have
  1656  	// C configured.
  1657  	s1.Shutdown()
  1658  	waitForOutboundGateways(t, s2, 1, time.Second)
  1659  	waitForInboundGateways(t, s2, 1, time.Second)
  1660  	s1 = runGatewayServer(o1)
  1661  	defer s1.Shutdown()
  1662  	waitForOutboundGateways(t, s2, 2, time.Second)
  1663  	waitForInboundGateways(t, s2, 2, time.Second)
  1664  	waitForOutboundGateways(t, s1, 1, time.Second)
  1665  	waitForInboundGateways(t, s1, 1, time.Second)
  1666  	waitForOutboundGateways(t, s3, 1, time.Second)
  1667  	waitForInboundGateways(t, s3, 1, time.Second)
  1668  	// It should not have a registered remote gateway with C (s3)
  1669  	if s1.getOutboundGatewayConnection("C") != nil {
  1670  		t.Fatalf("A should not have outbound gateway to C")
  1671  	}
  1672  	if s1.getRemoteGateway("C") != nil {
  1673  		t.Fatalf("A should not have a registered remote gateway to C")
  1674  	}
  1675  }
  1676  
  1677  func TestGatewayNoReconnectOnClose(t *testing.T) {
  1678  	o2 := testDefaultOptionsForGateway("B")
  1679  	s2 := runGatewayServer(o2)
  1680  	defer s2.Shutdown()
  1681  
  1682  	o1 := testGatewayOptionsFromToWithServers(t, "A", "B", s2)
  1683  	s1 := runGatewayServer(o1)
  1684  	defer s1.Shutdown()
  1685  
  1686  	waitForOutboundGateways(t, s1, 1, time.Second)
  1687  	waitForOutboundGateways(t, s2, 1, time.Second)
  1688  
  1689  	// Shutdown s1, and check that there is no attempt to reconnect.
  1690  	s1.Shutdown()
  1691  	time.Sleep(250 * time.Millisecond)
  1692  	waitForOutboundGateways(t, s1, 0, time.Second)
  1693  	waitForOutboundGateways(t, s2, 0, time.Second)
  1694  	waitForInboundGateways(t, s2, 0, time.Second)
  1695  }
  1696  
  1697  func TestGatewayDontSendSubInterest(t *testing.T) {
  1698  	o2 := testDefaultOptionsForGateway("B")
  1699  	s2 := runGatewayServer(o2)
  1700  	defer s2.Shutdown()
  1701  
  1702  	o1 := testGatewayOptionsFromToWithServers(t, "A", "B", s2)
  1703  	s1 := runGatewayServer(o1)
  1704  	defer s1.Shutdown()
  1705  
  1706  	waitForOutboundGateways(t, s1, 1, time.Second)
  1707  	waitForOutboundGateways(t, s2, 1, time.Second)
  1708  
  1709  	s2Url := fmt.Sprintf("nats://127.0.0.1:%d", o2.Port)
  1710  	subnc := natsConnect(t, s2Url)
  1711  	defer subnc.Close()
  1712  	natsSub(t, subnc, "foo", func(_ *nats.Msg) {})
  1713  	natsFlush(t, subnc)
  1714  
  1715  	checkExpectedSubs(t, 1, s2)
  1716  	// Subscription should not be sent to s1
  1717  	checkExpectedSubs(t, 0, s1)
  1718  
  1719  	// Restart s1
  1720  	s1.Shutdown()
  1721  	s1 = runGatewayServer(o1)
  1722  	defer s1.Shutdown()
  1723  	waitForOutboundGateways(t, s1, 1, time.Second)
  1724  	waitForOutboundGateways(t, s2, 1, time.Second)
  1725  
  1726  	checkExpectedSubs(t, 1, s2)
  1727  	checkExpectedSubs(t, 0, s1)
  1728  }
  1729  
  1730  func setAccountUserPassInOptions(o *Options, accName, username, password string) {
  1731  	acc := NewAccount(accName)
  1732  	o.Accounts = append(o.Accounts, acc)
  1733  	o.Users = append(o.Users, &User{Username: username, Password: password, Account: acc})
  1734  }
  1735  
  1736  func TestGatewayAccountInterest(t *testing.T) {
  1737  	GatewayDoNotForceInterestOnlyMode(true)
  1738  	defer GatewayDoNotForceInterestOnlyMode(false)
  1739  
  1740  	o2 := testDefaultOptionsForGateway("B")
  1741  	// Add users to cause s2 to require auth. Will add an account with user later.
  1742  	o2.Users = append([]*User(nil), &User{Username: "test", Password: "pwd"})
  1743  	s2 := runGatewayServer(o2)
  1744  	defer s2.Shutdown()
  1745  
  1746  	o1 := testGatewayOptionsFromToWithServers(t, "A", "B", s2)
  1747  	setAccountUserPassInOptions(o1, "$foo", "ivan", "password")
  1748  	s1 := runGatewayServer(o1)
  1749  	defer s1.Shutdown()
  1750  
  1751  	// Make this server initiate connection to A, so it is faster
  1752  	// when restarting it at the end of this test.
  1753  	o3 := testGatewayOptionsFromToWithServers(t, "C", "A", s1)
  1754  	setAccountUserPassInOptions(o3, "$foo", "ivan", "password")
  1755  	s3 := runGatewayServer(o3)
  1756  	defer s3.Shutdown()
  1757  
  1758  	waitForOutboundGateways(t, s1, 2, time.Second)
  1759  	waitForOutboundGateways(t, s2, 2, time.Second)
  1760  	waitForOutboundGateways(t, s3, 2, time.Second)
  1761  
  1762  	s1Url := fmt.Sprintf("nats://ivan:password@127.0.0.1:%d", o1.Port)
  1763  	nc := natsConnect(t, s1Url)
  1764  	defer nc.Close()
  1765  	natsPub(t, nc, "foo", []byte("hello"))
  1766  	natsFlush(t, nc)
  1767  
  1768  	// On first send, the message should be sent.
  1769  	checkCount := func(t *testing.T, c *client, expected int) {
  1770  		t.Helper()
  1771  		c.mu.Lock()
  1772  		out := c.outMsgs
  1773  		c.mu.Unlock()
  1774  		if int(out) != expected {
  1775  			t.Fatalf("Expected %d message(s) to be sent over, got %v", expected, out)
  1776  		}
  1777  	}
  1778  	gwcb := s1.getOutboundGatewayConnection("B")
  1779  	checkCount(t, gwcb, 1)
  1780  	gwcc := s1.getOutboundGatewayConnection("C")
  1781  	checkCount(t, gwcc, 1)
  1782  
  1783  	// S2 and S3 should have sent a protocol indicating no account interest.
  1784  	checkForAccountNoInterest(t, gwcb, "$foo", true, 2*time.Second)
  1785  	checkForAccountNoInterest(t, gwcc, "$foo", true, 2*time.Second)
  1786  	// Second send should not go to B nor C.
  1787  	natsPub(t, nc, "foo", []byte("hello"))
  1788  	natsFlush(t, nc)
  1789  	checkCount(t, gwcb, 1)
  1790  	checkCount(t, gwcc, 1)
  1791  
  1792  	// Add account to S2 and a client, this should clear the no-interest
  1793  	// for that account.
  1794  	s2FooAcc, err := s2.RegisterAccount("$foo")
  1795  	if err != nil {
  1796  		t.Fatalf("Error registering account: %v", err)
  1797  	}
  1798  	s2.mu.Lock()
  1799  	s2.users["ivan"] = &User{Account: s2FooAcc, Username: "ivan", Password: "password"}
  1800  	s2.mu.Unlock()
  1801  	s2Url := fmt.Sprintf("nats://ivan:password@127.0.0.1:%d", o2.Port)
  1802  	ncS2 := natsConnect(t, s2Url)
  1803  	defer ncS2.Close()
  1804  	// Any subscription should cause s2 to send an A+
  1805  	natsSubSync(t, ncS2, "asub")
  1806  	// Wait for the A+
  1807  	checkForAccountNoInterest(t, gwcb, "$foo", false, 2*time.Second)
  1808  
  1809  	// Now publish a message that should go to B
  1810  	natsPub(t, nc, "foo", []byte("hello"))
  1811  	natsFlush(t, nc)
  1812  	checkCount(t, gwcb, 2)
  1813  	// Still won't go to C since there is no sub interest
  1814  	checkCount(t, gwcc, 1)
  1815  
  1816  	// We should have received a subject no interest for foo
  1817  	checkForSubjectNoInterest(t, gwcb, "$foo", "foo", true, 2*time.Second)
  1818  
  1819  	// Now if we close the client, which removed the sole subscription,
  1820  	// and publish to a new subject, we should then get an A-
  1821  	ncS2.Close()
  1822  	// Wait a bit...
  1823  	time.Sleep(20 * time.Millisecond)
  1824  	// Publish on new subject
  1825  	natsPub(t, nc, "bar", []byte("hello"))
  1826  	natsFlush(t, nc)
  1827  	// It should go out to B...
  1828  	checkCount(t, gwcb, 3)
  1829  	// But then we should get a A-
  1830  	checkForAccountNoInterest(t, gwcb, "$foo", true, 2*time.Second)
  1831  
  1832  	// Restart C and that should reset the no-interest
  1833  	s3.Shutdown()
  1834  	s3 = runGatewayServer(o3)
  1835  	defer s3.Shutdown()
  1836  
  1837  	waitForOutboundGateways(t, s1, 2, 2*time.Second)
  1838  	waitForOutboundGateways(t, s2, 2, 2*time.Second)
  1839  	waitForOutboundGateways(t, s3, 2, 2*time.Second)
  1840  
  1841  	// First refresh gwcc
  1842  	gwcc = s1.getOutboundGatewayConnection("C")
  1843  	// Verify that it's count is 0
  1844  	checkCount(t, gwcc, 0)
  1845  	// Publish and now...
  1846  	natsPub(t, nc, "foo", []byte("hello"))
  1847  	natsFlush(t, nc)
  1848  	// it should not go to B (no sub interest)
  1849  	checkCount(t, gwcb, 3)
  1850  	// but will go to C
  1851  	checkCount(t, gwcc, 1)
  1852  }
  1853  
  1854  func TestGatewayAccountUnsub(t *testing.T) {
  1855  	ob := testDefaultOptionsForGateway("B")
  1856  	sb := runGatewayServer(ob)
  1857  	defer sb.Shutdown()
  1858  
  1859  	oa := testGatewayOptionsFromToWithServers(t, "A", "B", sb)
  1860  	sa := runGatewayServer(oa)
  1861  	defer sa.Shutdown()
  1862  
  1863  	waitForOutboundGateways(t, sa, 1, time.Second)
  1864  	waitForOutboundGateways(t, sb, 1, time.Second)
  1865  	waitForInboundGateways(t, sa, 1, time.Second)
  1866  	waitForInboundGateways(t, sb, 1, time.Second)
  1867  
  1868  	// Connect on B
  1869  	ncb := natsConnect(t, fmt.Sprintf("nats://%s:%d", ob.Host, ob.Port))
  1870  	defer ncb.Close()
  1871  	// Create subscription
  1872  	natsSub(t, ncb, "foo", func(m *nats.Msg) {
  1873  		ncb.Publish(m.Reply, []byte("reply"))
  1874  	})
  1875  	natsFlush(t, ncb)
  1876  
  1877  	// Connect on A
  1878  	nca := natsConnect(t, fmt.Sprintf("nats://%s:%d", oa.Host, oa.Port))
  1879  	defer nca.Close()
  1880  	// Send a request
  1881  	if _, err := nca.Request("foo", []byte("req"), time.Second); err != nil {
  1882  		t.Fatalf("Error getting reply: %v", err)
  1883  	}
  1884  
  1885  	// Now close connection on B
  1886  	ncb.Close()
  1887  
  1888  	// Publish lots of messages on "foo" from A.
  1889  	// We should receive an A- shortly and the number
  1890  	// of outbound messages from A to B should not be
  1891  	// close to the number of messages sent here.
  1892  	total := 5000
  1893  	for i := 0; i < total; i++ {
  1894  		natsPub(t, nca, "foo", []byte("hello"))
  1895  		// Try to slow down things a bit to give a chance
  1896  		// to srvB to send the A- and to srvA to be able
  1897  		// to process it, which will then suppress the sends.
  1898  		if i%100 == 0 {
  1899  			natsFlush(t, nca)
  1900  		}
  1901  	}
  1902  	natsFlush(t, nca)
  1903  
  1904  	c := sa.getOutboundGatewayConnection("B")
  1905  	c.mu.Lock()
  1906  	out := c.outMsgs
  1907  	c.mu.Unlock()
  1908  
  1909  	if out >= int64(80*total)/100 {
  1910  		t.Fatalf("Unexpected number of messages sent from A to B: %v", out)
  1911  	}
  1912  }
  1913  
  1914  func TestGatewaySubjectInterest(t *testing.T) {
  1915  	GatewayDoNotForceInterestOnlyMode(true)
  1916  	defer GatewayDoNotForceInterestOnlyMode(false)
  1917  
  1918  	o1 := testDefaultOptionsForGateway("A")
  1919  	setAccountUserPassInOptions(o1, "$foo", "ivan", "password")
  1920  	s1 := runGatewayServer(o1)
  1921  	defer s1.Shutdown()
  1922  
  1923  	o2 := testGatewayOptionsFromToWithServers(t, "B", "A", s1)
  1924  	setAccountUserPassInOptions(o2, "$foo", "ivan", "password")
  1925  	s2 := runGatewayServer(o2)
  1926  	defer s2.Shutdown()
  1927  
  1928  	waitForOutboundGateways(t, s1, 1, time.Second)
  1929  	waitForOutboundGateways(t, s2, 1, time.Second)
  1930  
  1931  	// We will create a subscription that we are not testing so
  1932  	// that we don't get an A- in this test.
  1933  	s2Url := fmt.Sprintf("nats://ivan:password@127.0.0.1:%d", o2.Port)
  1934  	ncb := natsConnect(t, s2Url)
  1935  	defer ncb.Close()
  1936  	natsSubSync(t, ncb, "not.used")
  1937  	checkExpectedSubs(t, 1, s2)
  1938  
  1939  	s1Url := fmt.Sprintf("nats://ivan:password@127.0.0.1:%d", o1.Port)
  1940  	nc := natsConnect(t, s1Url)
  1941  	defer nc.Close()
  1942  	natsPub(t, nc, "foo", []byte("hello"))
  1943  	natsFlush(t, nc)
  1944  
  1945  	// On first send, the message should be sent.
  1946  	checkCount := func(t *testing.T, c *client, expected int) {
  1947  		t.Helper()
  1948  		c.mu.Lock()
  1949  		out := c.outMsgs
  1950  		c.mu.Unlock()
  1951  		if int(out) != expected {
  1952  			t.Fatalf("Expected %d message(s) to be sent over, got %v", expected, out)
  1953  		}
  1954  	}
  1955  	gwcb := s1.getOutboundGatewayConnection("B")
  1956  	checkCount(t, gwcb, 1)
  1957  
  1958  	// S2 should have sent a protocol indicating no subject interest.
  1959  	checkNoInterest := func(t *testing.T, subject string, expectedNoInterest bool) {
  1960  		t.Helper()
  1961  		checkForSubjectNoInterest(t, gwcb, "$foo", subject, expectedNoInterest, 2*time.Second)
  1962  	}
  1963  	checkNoInterest(t, "foo", true)
  1964  	// Second send should not go through to B
  1965  	natsPub(t, nc, "foo", []byte("hello"))
  1966  	natsFlush(t, nc)
  1967  	checkCount(t, gwcb, 1)
  1968  
  1969  	// Now create subscription interest on B (s2)
  1970  	ch := make(chan bool, 1)
  1971  	sub := natsSub(t, ncb, "foo", func(_ *nats.Msg) {
  1972  		ch <- true
  1973  	})
  1974  	natsFlush(t, ncb)
  1975  	checkExpectedSubs(t, 2, s2)
  1976  	checkExpectedSubs(t, 0, s1)
  1977  
  1978  	// This should clear the no interest for this subject
  1979  	checkNoInterest(t, "foo", false)
  1980  	// Third send should go to B
  1981  	natsPub(t, nc, "foo", []byte("hello"))
  1982  	natsFlush(t, nc)
  1983  	checkCount(t, gwcb, 2)
  1984  
  1985  	// Make sure message is received
  1986  	waitCh(t, ch, "Did not get our message")
  1987  	// Now unsubscribe, there won't be an UNSUB sent to the gateway.
  1988  	natsUnsub(t, sub)
  1989  	natsFlush(t, ncb)
  1990  	checkExpectedSubs(t, 1, s2)
  1991  	checkExpectedSubs(t, 0, s1)
  1992  
  1993  	// So now sending a message should go over, but then we should get an RS-
  1994  	natsPub(t, nc, "foo", []byte("hello"))
  1995  	natsFlush(t, nc)
  1996  	checkCount(t, gwcb, 3)
  1997  
  1998  	checkNoInterest(t, "foo", true)
  1999  
  2000  	// Send one more time and now it should not go to B
  2001  	natsPub(t, nc, "foo", []byte("hello"))
  2002  	natsFlush(t, nc)
  2003  	checkCount(t, gwcb, 3)
  2004  
  2005  	// Send on bar, message should go over.
  2006  	natsPub(t, nc, "bar", []byte("hello"))
  2007  	natsFlush(t, nc)
  2008  	checkCount(t, gwcb, 4)
  2009  
  2010  	// But now we should have receives an RS- on bar.
  2011  	checkNoInterest(t, "bar", true)
  2012  
  2013  	// Check that wildcards are supported. Create a subscription on '*' on B.
  2014  	// This should clear the no-interest on both "foo" and "bar"
  2015  	natsSub(t, ncb, "*", func(_ *nats.Msg) {})
  2016  	natsFlush(t, ncb)
  2017  	checkExpectedSubs(t, 2, s2)
  2018  	checkExpectedSubs(t, 0, s1)
  2019  	checkNoInterest(t, "foo", false)
  2020  	checkNoInterest(t, "bar", false)
  2021  	// Publish on message on foo and one on bar and they should go.
  2022  	natsPub(t, nc, "foo", []byte("hello"))
  2023  	natsPub(t, nc, "bar", []byte("hello"))
  2024  	natsFlush(t, nc)
  2025  	checkCount(t, gwcb, 6)
  2026  
  2027  	// Restart B and that should clear everything on A
  2028  	ncb.Close()
  2029  	s2.Shutdown()
  2030  	s2 = runGatewayServer(o2)
  2031  	defer s2.Shutdown()
  2032  
  2033  	waitForOutboundGateways(t, s1, 1, time.Second)
  2034  	waitForOutboundGateways(t, s2, 1, time.Second)
  2035  
  2036  	ncb = natsConnect(t, s2Url)
  2037  	defer ncb.Close()
  2038  	natsSubSync(t, ncb, "not.used")
  2039  	checkExpectedSubs(t, 1, s2)
  2040  
  2041  	gwcb = s1.getOutboundGatewayConnection("B")
  2042  	checkCount(t, gwcb, 0)
  2043  	natsPub(t, nc, "foo", []byte("hello"))
  2044  	natsFlush(t, nc)
  2045  	checkCount(t, gwcb, 1)
  2046  
  2047  	checkNoInterest(t, "foo", true)
  2048  
  2049  	natsPub(t, nc, "foo", []byte("hello"))
  2050  	natsFlush(t, nc)
  2051  	checkCount(t, gwcb, 1)
  2052  
  2053  	// Add a node to B cluster and subscribe there.
  2054  	// We want to ensure that the no-interest is cleared
  2055  	// when s2 receives remote SUB from s2bis
  2056  	o2bis := testGatewayOptionsFromToWithServers(t, "B", "A", s1)
  2057  	setAccountUserPassInOptions(o2bis, "$foo", "ivan", "password")
  2058  	o2bis.Routes = RoutesFromStr(fmt.Sprintf("nats://127.0.0.1:%d", s2.ClusterAddr().Port))
  2059  	s2bis := runGatewayServer(o2bis)
  2060  	defer s2bis.Shutdown()
  2061  
  2062  	checkClusterFormed(t, s2, s2bis)
  2063  
  2064  	// Make sure all outbound gateway connections are setup
  2065  	waitForOutboundGateways(t, s1, 1, time.Second)
  2066  	waitForOutboundGateways(t, s2, 1, time.Second)
  2067  	waitForOutboundGateways(t, s2bis, 1, time.Second)
  2068  
  2069  	// A should have 2 inbound
  2070  	waitForInboundGateways(t, s1, 2, time.Second)
  2071  
  2072  	// Create sub on s2bis
  2073  	ncb2bis := natsConnect(t, fmt.Sprintf("nats://ivan:password@127.0.0.1:%d", o2bis.Port))
  2074  	defer ncb2bis.Close()
  2075  	natsSub(t, ncb2bis, "foo", func(_ *nats.Msg) {})
  2076  	natsFlush(t, ncb2bis)
  2077  
  2078  	// Wait for subscriptions to be registered locally on s2bis and remotely on s2
  2079  	checkExpectedSubs(t, 2, s2, s2bis)
  2080  
  2081  	// Check that subject no-interest on A was cleared.
  2082  	checkNoInterest(t, "foo", false)
  2083  
  2084  	// Now publish. Remember, s1 has outbound gateway to s2, and s2 does not
  2085  	// have a local subscription and has previously sent a no-interest on "foo".
  2086  	// We check that this has been cleared due to the interest on s2bis.
  2087  	natsPub(t, nc, "foo", []byte("hello"))
  2088  	natsFlush(t, nc)
  2089  	checkCount(t, gwcb, 2)
  2090  }
  2091  
  2092  func TestGatewayDoesntSendBackToItself(t *testing.T) {
  2093  	o2 := testDefaultOptionsForGateway("B")
  2094  	s2 := runGatewayServer(o2)
  2095  	defer s2.Shutdown()
  2096  
  2097  	o1 := testGatewayOptionsFromToWithServers(t, "A", "B", s2)
  2098  	s1 := runGatewayServer(o1)
  2099  	defer s1.Shutdown()
  2100  
  2101  	waitForOutboundGateways(t, s1, 1, time.Second)
  2102  	waitForOutboundGateways(t, s2, 1, time.Second)
  2103  
  2104  	s2Url := fmt.Sprintf("nats://127.0.0.1:%d", o2.Port)
  2105  	nc2 := natsConnect(t, s2Url)
  2106  	defer nc2.Close()
  2107  
  2108  	count := int32(0)
  2109  	cb := func(_ *nats.Msg) {
  2110  		atomic.AddInt32(&count, 1)
  2111  	}
  2112  	natsSub(t, nc2, "foo", cb)
  2113  	natsFlush(t, nc2)
  2114  
  2115  	s1Url := fmt.Sprintf("nats://127.0.0.1:%d", o1.Port)
  2116  	nc1 := natsConnect(t, s1Url)
  2117  	defer nc1.Close()
  2118  
  2119  	natsSub(t, nc1, "foo", cb)
  2120  	natsFlush(t, nc1)
  2121  
  2122  	// Now send 1 message. If there is a cycle, after few ms we
  2123  	// should have tons of messages...
  2124  	natsPub(t, nc1, "foo", []byte("cycle"))
  2125  	natsFlush(t, nc1)
  2126  	time.Sleep(100 * time.Millisecond)
  2127  	if c := atomic.LoadInt32(&count); c != 2 {
  2128  		t.Fatalf("Expected only 2 messages, got %v", c)
  2129  	}
  2130  }
  2131  
  2132  func TestGatewayOrderedOutbounds(t *testing.T) {
  2133  	o2 := testDefaultOptionsForGateway("B")
  2134  	s2 := runGatewayServer(o2)
  2135  	defer s2.Shutdown()
  2136  
  2137  	o1 := testGatewayOptionsFromToWithServers(t, "A", "B", s2)
  2138  	s1 := runGatewayServer(o1)
  2139  	defer s1.Shutdown()
  2140  
  2141  	o3 := testGatewayOptionsFromToWithServers(t, "C", "B", s2)
  2142  	s3 := runGatewayServer(o3)
  2143  	defer s3.Shutdown()
  2144  
  2145  	waitForOutboundGateways(t, s1, 2, time.Second)
  2146  	waitForOutboundGateways(t, s2, 2, time.Second)
  2147  	waitForOutboundGateways(t, s3, 2, time.Second)
  2148  
  2149  	gws := make([]*client, 0, 2)
  2150  	s2.getOutboundGatewayConnections(&gws)
  2151  
  2152  	// RTTs are expected to be initially 0. So update RTT of first
  2153  	// in the array so that its value is no longer 0, this should
  2154  	// cause order to be flipped.
  2155  	c := gws[0]
  2156  	c.mu.Lock()
  2157  	c.sendPing()
  2158  	c.mu.Unlock()
  2159  
  2160  	// Wait a tiny but
  2161  	time.Sleep(15 * time.Millisecond)
  2162  	// Get the ordering again.
  2163  	gws = gws[:0]
  2164  	s2.getOutboundGatewayConnections(&gws)
  2165  	// Verify order is correct.
  2166  	fRTT := gws[0].getRTTValue()
  2167  	sRTT := gws[1].getRTTValue()
  2168  	if fRTT > sRTT {
  2169  		t.Fatalf("Wrong ordering: %v, %v", fRTT, sRTT)
  2170  	}
  2171  
  2172  	// What is the first in the array?
  2173  	gws[0].mu.Lock()
  2174  	gwName := gws[0].gw.name
  2175  	gws[0].mu.Unlock()
  2176  	if gwName == "A" {
  2177  		s1.Shutdown()
  2178  	} else {
  2179  		s3.Shutdown()
  2180  	}
  2181  	waitForOutboundGateways(t, s2, 1, time.Second)
  2182  	gws = gws[:0]
  2183  	s2.getOutboundGatewayConnections(&gws)
  2184  	if len(gws) != 1 {
  2185  		t.Fatalf("Expected size of outo to be 1, got %v", len(gws))
  2186  	}
  2187  	gws[0].mu.Lock()
  2188  	name := gws[0].gw.name
  2189  	gws[0].mu.Unlock()
  2190  	if gwName == name {
  2191  		t.Fatalf("Gateway %q should have been removed", gwName)
  2192  	}
  2193  	// Stop the remaining gateway
  2194  	if gwName == "A" {
  2195  		s3.Shutdown()
  2196  	} else {
  2197  		s1.Shutdown()
  2198  	}
  2199  	waitForOutboundGateways(t, s2, 0, time.Second)
  2200  	gws = gws[:0]
  2201  	s2.getOutboundGatewayConnections(&gws)
  2202  	if len(gws) != 0 {
  2203  		t.Fatalf("Expected size of outo to be 0, got %v", len(gws))
  2204  	}
  2205  }
  2206  
  2207  func TestGatewayQueueSub(t *testing.T) {
  2208  	o2 := testDefaultOptionsForGateway("B")
  2209  	s2 := runGatewayServer(o2)
  2210  	defer s2.Shutdown()
  2211  
  2212  	o1 := testGatewayOptionsFromToWithServers(t, "A", "B", s2)
  2213  	s1 := runGatewayServer(o1)
  2214  	defer s1.Shutdown()
  2215  
  2216  	waitForOutboundGateways(t, s1, 1, time.Second)
  2217  	waitForOutboundGateways(t, s2, 1, time.Second)
  2218  
  2219  	sBUrl := fmt.Sprintf("nats://127.0.0.1:%d", o2.Port)
  2220  	ncB := natsConnect(t, sBUrl)
  2221  	defer ncB.Close()
  2222  
  2223  	count2 := int32(0)
  2224  	cb2 := func(_ *nats.Msg) {
  2225  		atomic.AddInt32(&count2, 1)
  2226  	}
  2227  	qsubOnB := natsQueueSub(t, ncB, "foo", "bar", cb2)
  2228  	natsFlush(t, ncB)
  2229  
  2230  	sAUrl := fmt.Sprintf("nats://127.0.0.1:%d", o1.Port)
  2231  	ncA := natsConnect(t, sAUrl)
  2232  	defer ncA.Close()
  2233  
  2234  	count1 := int32(0)
  2235  	cb1 := func(_ *nats.Msg) {
  2236  		atomic.AddInt32(&count1, 1)
  2237  	}
  2238  	qsubOnA := natsQueueSub(t, ncA, "foo", "bar", cb1)
  2239  	natsFlush(t, ncA)
  2240  
  2241  	// Make sure subs are registered on each server
  2242  	checkExpectedSubs(t, 1, s1, s2)
  2243  	checkForRegisteredQSubInterest(t, s1, "B", globalAccountName, "foo", 1, time.Second)
  2244  	checkForRegisteredQSubInterest(t, s2, "A", globalAccountName, "foo", 1, time.Second)
  2245  
  2246  	total := 100
  2247  	send := func(t *testing.T, nc *nats.Conn) {
  2248  		t.Helper()
  2249  		for i := 0; i < total; i++ {
  2250  			// Alternate with adding a reply
  2251  			if i%2 == 0 {
  2252  				natsPubReq(t, nc, "foo", "reply", []byte("msg"))
  2253  			} else {
  2254  				natsPub(t, nc, "foo", []byte("msg"))
  2255  			}
  2256  		}
  2257  		natsFlush(t, nc)
  2258  	}
  2259  	// Send from client connecting to S1 (cluster A)
  2260  	send(t, ncA)
  2261  
  2262  	check := func(t *testing.T, count *int32, expected int) {
  2263  		t.Helper()
  2264  		checkFor(t, 2*time.Second, 15*time.Millisecond, func() error {
  2265  			if n := int(atomic.LoadInt32(count)); n != expected {
  2266  				return fmt.Errorf("Expected to get %v messages, got %v", expected, n)
  2267  			}
  2268  			return nil
  2269  		})
  2270  	}
  2271  	// Check that all messages stay on S1 (cluster A)
  2272  	check(t, &count1, total)
  2273  	check(t, &count2, 0)
  2274  
  2275  	// Now send from the other side
  2276  	send(t, ncB)
  2277  	check(t, &count1, total)
  2278  	check(t, &count2, total)
  2279  
  2280  	// Reset counters
  2281  	atomic.StoreInt32(&count1, 0)
  2282  	atomic.StoreInt32(&count2, 0)
  2283  
  2284  	// Add different queue group and make sure that messages are received
  2285  	count3 := int32(0)
  2286  	cb3 := func(_ *nats.Msg) {
  2287  		atomic.AddInt32(&count3, 1)
  2288  	}
  2289  	batQSub := natsQueueSub(t, ncB, "foo", "bat", cb3)
  2290  	natsFlush(t, ncB)
  2291  	checkExpectedSubs(t, 2, s2)
  2292  
  2293  	checkForRegisteredQSubInterest(t, s1, "B", globalAccountName, "foo", 2, time.Second)
  2294  
  2295  	send(t, ncA)
  2296  	check(t, &count1, total)
  2297  	check(t, &count2, 0)
  2298  	check(t, &count3, total)
  2299  
  2300  	// Reset counters
  2301  	atomic.StoreInt32(&count1, 0)
  2302  	atomic.StoreInt32(&count2, 0)
  2303  	atomic.StoreInt32(&count3, 0)
  2304  
  2305  	natsUnsub(t, batQSub)
  2306  	natsFlush(t, ncB)
  2307  	checkExpectedSubs(t, 1, s2)
  2308  
  2309  	checkForRegisteredQSubInterest(t, s1, "B", globalAccountName, "foo", 1, time.Second)
  2310  
  2311  	// Stop qsub on A, and send messages to A, they should
  2312  	// be routed to B.
  2313  	qsubOnA.Unsubscribe()
  2314  	checkExpectedSubs(t, 0, s1)
  2315  	send(t, ncA)
  2316  	check(t, &count1, 0)
  2317  	check(t, &count2, total)
  2318  
  2319  	// Reset counters
  2320  	atomic.StoreInt32(&count1, 0)
  2321  	atomic.StoreInt32(&count2, 0)
  2322  
  2323  	// Create a C gateway now
  2324  	o3 := testGatewayOptionsFromToWithServers(t, "C", "B", s2)
  2325  	s3 := runGatewayServer(o3)
  2326  	defer s3.Shutdown()
  2327  
  2328  	waitForOutboundGateways(t, s1, 2, time.Second)
  2329  	waitForOutboundGateways(t, s2, 2, time.Second)
  2330  	waitForOutboundGateways(t, s3, 2, time.Second)
  2331  
  2332  	waitForInboundGateways(t, s1, 2, time.Second)
  2333  	waitForInboundGateways(t, s2, 2, time.Second)
  2334  	waitForInboundGateways(t, s3, 2, time.Second)
  2335  
  2336  	// Create another qsub "bar"
  2337  	sCUrl := fmt.Sprintf("nats://127.0.0.1:%d", o3.Port)
  2338  	ncC := natsConnect(t, sCUrl)
  2339  	defer ncC.Close()
  2340  	// Associate this with count1 (since A qsub is no longer running)
  2341  	natsQueueSub(t, ncC, "foo", "bar", cb1)
  2342  	natsFlush(t, ncC)
  2343  	checkExpectedSubs(t, 1, s3)
  2344  	checkForRegisteredQSubInterest(t, s1, "C", globalAccountName, "foo", 1, time.Second)
  2345  	checkForRegisteredQSubInterest(t, s2, "C", globalAccountName, "foo", 1, time.Second)
  2346  
  2347  	// Artificially bump the RTT from A to C so that
  2348  	// the code should favor sending to B.
  2349  	gwcC := s1.getOutboundGatewayConnection("C")
  2350  	gwcC.mu.Lock()
  2351  	gwcC.rtt = 10 * time.Second
  2352  	gwcC.mu.Unlock()
  2353  	s1.gateway.orderOutboundConnections()
  2354  
  2355  	send(t, ncA)
  2356  	check(t, &count1, 0)
  2357  	check(t, &count2, total)
  2358  
  2359  	// Add a new group on s3 that should receive all messages
  2360  	natsQueueSub(t, ncC, "foo", "baz", cb3)
  2361  	natsFlush(t, ncC)
  2362  	checkExpectedSubs(t, 2, s3)
  2363  	checkForRegisteredQSubInterest(t, s1, "C", globalAccountName, "foo", 2, time.Second)
  2364  	checkForRegisteredQSubInterest(t, s2, "C", globalAccountName, "foo", 2, time.Second)
  2365  
  2366  	// Reset counters
  2367  	atomic.StoreInt32(&count1, 0)
  2368  	atomic.StoreInt32(&count2, 0)
  2369  
  2370  	// Make the RTTs equal
  2371  	gwcC.mu.Lock()
  2372  	gwcC.rtt = time.Second
  2373  	gwcC.mu.Unlock()
  2374  
  2375  	gwcB := s1.getOutboundGatewayConnection("B")
  2376  	gwcB.mu.Lock()
  2377  	gwcB.rtt = time.Second
  2378  	gwcB.mu.Unlock()
  2379  
  2380  	s1.gateway.Lock()
  2381  	s1.gateway.orderOutboundConnectionsLocked()
  2382  	destName := s1.gateway.outo[0].gw.name
  2383  	s1.gateway.Unlock()
  2384  
  2385  	send(t, ncA)
  2386  	// Group baz should receive all messages
  2387  	check(t, &count3, total)
  2388  
  2389  	// Ordering is normally re-evaluated when processing PONGs,
  2390  	// but rest of the time order will remain the same.
  2391  	// Since RTT are equal, messages will go to the first
  2392  	// GW in the array.
  2393  	if destName == "B" {
  2394  		check(t, &count2, total)
  2395  	} else if destName == "C" && int(atomic.LoadInt32(&count2)) != total {
  2396  		check(t, &count1, total)
  2397  	}
  2398  
  2399  	// Unsubscribe qsub on B and C should receive
  2400  	// all messages on count1 and count3.
  2401  	qsubOnB.Unsubscribe()
  2402  	checkExpectedSubs(t, 0, s2)
  2403  
  2404  	// gwcB should have the qsubs interest map empty now.
  2405  	checkFor(t, 2*time.Second, 15*time.Millisecond, func() error {
  2406  		ei, _ := gwcB.gw.outsim.Load(globalAccountName)
  2407  		if ei != nil {
  2408  			sl := ei.(*outsie).sl
  2409  			if sl.Count() == 0 {
  2410  				return nil
  2411  			}
  2412  		}
  2413  		return fmt.Errorf("Qsub interest for account should have been removed")
  2414  	})
  2415  
  2416  	// Reset counters
  2417  	atomic.StoreInt32(&count1, 0)
  2418  	atomic.StoreInt32(&count2, 0)
  2419  	atomic.StoreInt32(&count3, 0)
  2420  
  2421  	send(t, ncA)
  2422  	check(t, &count1, total)
  2423  	check(t, &count3, total)
  2424  }
  2425  
  2426  func TestGatewayTotalQSubs(t *testing.T) {
  2427  	ob1 := testDefaultOptionsForGateway("B")
  2428  	sb1 := runGatewayServer(ob1)
  2429  	defer sb1.Shutdown()
  2430  
  2431  	ob2 := testDefaultOptionsForGateway("B")
  2432  	ob2.Routes = RoutesFromStr(fmt.Sprintf("nats://127.0.0.1:%d", sb1.ClusterAddr().Port))
  2433  	sb2 := runGatewayServer(ob2)
  2434  	defer sb2.Shutdown()
  2435  
  2436  	checkClusterFormed(t, sb1, sb2)
  2437  
  2438  	sb1URL := fmt.Sprintf("nats://%s:%d", ob1.Host, ob1.Port)
  2439  	ncb1 := natsConnect(t, sb1URL, nats.ReconnectWait(50*time.Millisecond))
  2440  	defer ncb1.Close()
  2441  
  2442  	sb2URL := fmt.Sprintf("nats://%s:%d", ob2.Host, ob2.Port)
  2443  	ncb2 := natsConnect(t, sb2URL, nats.ReconnectWait(50*time.Millisecond))
  2444  	defer ncb2.Close()
  2445  
  2446  	oa := testGatewayOptionsFromToWithServers(t, "A", "B", sb1)
  2447  	sa := runGatewayServer(oa)
  2448  	defer sa.Shutdown()
  2449  
  2450  	waitForOutboundGateways(t, sa, 1, 2*time.Second)
  2451  	waitForOutboundGateways(t, sb1, 1, 2*time.Second)
  2452  	waitForOutboundGateways(t, sb2, 1, 2*time.Second)
  2453  	waitForInboundGateways(t, sa, 2, 2*time.Second)
  2454  	waitForInboundGateways(t, sb1, 1, 2*time.Second)
  2455  
  2456  	checkTotalQSubs := func(t *testing.T, s *Server, expected int) {
  2457  		t.Helper()
  2458  		checkFor(t, time.Second, 15*time.Millisecond, func() error {
  2459  			if n := int(atomic.LoadInt64(&s.gateway.totalQSubs)); n != expected {
  2460  				return fmt.Errorf("Expected TotalQSubs to be %v, got %v", expected, n)
  2461  			}
  2462  			return nil
  2463  		})
  2464  	}
  2465  
  2466  	cb := func(_ *nats.Msg) {}
  2467  
  2468  	natsQueueSub(t, ncb1, "foo", "bar", cb)
  2469  	checkTotalQSubs(t, sa, 1)
  2470  	qsub2 := natsQueueSub(t, ncb1, "foo", "baz", cb)
  2471  	checkTotalQSubs(t, sa, 2)
  2472  	qsub3 := natsQueueSub(t, ncb1, "foo", "baz", cb)
  2473  	checkTotalQSubs(t, sa, 2)
  2474  
  2475  	// Shutdown sb1, there should be a failover from clients
  2476  	// to sb2. sb2 will then send the queue subs to sa.
  2477  	sb1.Shutdown()
  2478  
  2479  	checkClientsCount(t, sb2, 2)
  2480  	checkExpectedSubs(t, 3, sb2)
  2481  
  2482  	waitForOutboundGateways(t, sa, 1, 2*time.Second)
  2483  	waitForOutboundGateways(t, sb2, 1, 2*time.Second)
  2484  	waitForInboundGateways(t, sa, 1, 2*time.Second)
  2485  	waitForInboundGateways(t, sb2, 1, 2*time.Second)
  2486  
  2487  	// When sb1 is shutdown, the total qsubs on sa should fall
  2488  	// down to 0, but will be updated as soon as sa and sb2
  2489  	// connect to each other. So instead we will verify by
  2490  	// making sure that the count is 2 instead of 4 if there
  2491  	// was a bug.
  2492  	// (note that there are 2 qsubs on same group, so only
  2493  	// 1 RS+ would have been sent for that group)
  2494  	checkTotalQSubs(t, sa, 2)
  2495  
  2496  	// Restart sb1
  2497  	sb1 = runGatewayServer(ob1)
  2498  	defer sb1.Shutdown()
  2499  
  2500  	checkClusterFormed(t, sb1, sb2)
  2501  
  2502  	waitForOutboundGateways(t, sa, 1, 2*time.Second)
  2503  	waitForOutboundGateways(t, sb1, 1, 2*time.Second)
  2504  	waitForOutboundGateways(t, sb2, 1, 2*time.Second)
  2505  	waitForInboundGateways(t, sa, 2, 2*time.Second)
  2506  	waitForInboundGateways(t, sb1, 0, 2*time.Second)
  2507  	waitForInboundGateways(t, sb2, 1, 2*time.Second)
  2508  
  2509  	// Now start unsubscribing. Start with one of the duplicate
  2510  	// and check that count stays same.
  2511  	natsUnsub(t, qsub3)
  2512  	checkTotalQSubs(t, sa, 2)
  2513  	// Now the other, which would cause an RS-
  2514  	natsUnsub(t, qsub2)
  2515  	checkTotalQSubs(t, sa, 1)
  2516  	// Now test that if connections are closed, things are updated
  2517  	// properly.
  2518  	ncb1.Close()
  2519  	ncb2.Close()
  2520  	checkTotalQSubs(t, sa, 0)
  2521  }
  2522  
  2523  func TestGatewaySendQSubsOnGatewayConnect(t *testing.T) {
  2524  	o2 := testDefaultOptionsForGateway("B")
  2525  	s2 := runGatewayServer(o2)
  2526  	defer s2.Shutdown()
  2527  
  2528  	s2Url := fmt.Sprintf("nats://127.0.0.1:%d", o2.Port)
  2529  	subnc := natsConnect(t, s2Url)
  2530  	defer subnc.Close()
  2531  
  2532  	ch := make(chan bool, 1)
  2533  	cb := func(_ *nats.Msg) {
  2534  		ch <- true
  2535  	}
  2536  	natsQueueSub(t, subnc, "foo", "bar", cb)
  2537  	natsFlush(t, subnc)
  2538  
  2539  	// Now start s1 that creates a gateway to s2
  2540  	o1 := testGatewayOptionsFromToWithServers(t, "A", "B", s2)
  2541  	s1 := runGatewayServer(o1)
  2542  	defer s1.Shutdown()
  2543  
  2544  	waitForOutboundGateways(t, s1, 1, time.Second)
  2545  	waitForOutboundGateways(t, s2, 1, time.Second)
  2546  
  2547  	checkForRegisteredQSubInterest(t, s1, "B", globalAccountName, "foo", 1, time.Second)
  2548  
  2549  	// Publish from s1, message should be received on s2.
  2550  	pubnc := natsConnect(t, fmt.Sprintf("nats://127.0.0.1:%d", o1.Port))
  2551  	defer pubnc.Close()
  2552  	// Publish 1 message
  2553  	natsPub(t, pubnc, "foo", []byte("hello"))
  2554  	waitCh(t, ch, "Did not get out message")
  2555  	pubnc.Close()
  2556  
  2557  	s1.Shutdown()
  2558  	s1 = runGatewayServer(o1)
  2559  	defer s1.Shutdown()
  2560  
  2561  	waitForOutboundGateways(t, s1, 1, time.Second)
  2562  	waitForOutboundGateways(t, s2, 1, time.Second)
  2563  
  2564  	checkForRegisteredQSubInterest(t, s1, "B", globalAccountName, "foo", 1, time.Second)
  2565  
  2566  	pubnc = natsConnect(t, fmt.Sprintf("nats://127.0.0.1:%d", o1.Port))
  2567  	defer pubnc.Close()
  2568  	// Publish 1 message
  2569  	natsPub(t, pubnc, "foo", []byte("hello"))
  2570  	waitCh(t, ch, "Did not get out message")
  2571  }
  2572  
  2573  func TestGatewaySendRemoteQSubs(t *testing.T) {
  2574  	GatewayDoNotForceInterestOnlyMode(true)
  2575  	defer GatewayDoNotForceInterestOnlyMode(false)
  2576  
  2577  	ob1 := testDefaultOptionsForGateway("B")
  2578  	sb1 := runGatewayServer(ob1)
  2579  	defer sb1.Shutdown()
  2580  
  2581  	ob2 := testDefaultOptionsForGateway("B")
  2582  	ob2.Routes = RoutesFromStr(fmt.Sprintf("nats://%s:%d", ob1.Cluster.Host, ob1.Cluster.Port))
  2583  	sb2 := runGatewayServer(ob2)
  2584  	defer sb2.Shutdown()
  2585  
  2586  	checkClusterFormed(t, sb1, sb2)
  2587  
  2588  	sbURL := fmt.Sprintf("nats://127.0.0.1:%d", ob2.Port)
  2589  	subnc := natsConnect(t, sbURL)
  2590  	defer subnc.Close()
  2591  
  2592  	ch := make(chan bool, 1)
  2593  	cb := func(_ *nats.Msg) {
  2594  		ch <- true
  2595  	}
  2596  	qsub1 := natsQueueSub(t, subnc, "foo", "bar", cb)
  2597  	qsub2 := natsQueueSub(t, subnc, "foo", "bar", cb)
  2598  	natsFlush(t, subnc)
  2599  
  2600  	// There will be 2 local qsubs on the sb2 server where the client is connected
  2601  	checkExpectedSubs(t, 2, sb2)
  2602  	// But only 1 remote on sb1
  2603  	checkExpectedSubs(t, 1, sb1)
  2604  
  2605  	// Now start s1 that creates a gateway to sb1 (the one that does not have the local QSub)
  2606  	oa := testGatewayOptionsFromToWithServers(t, "A", "B", sb1)
  2607  	sa := runGatewayServer(oa)
  2608  	defer sa.Shutdown()
  2609  
  2610  	waitForOutboundGateways(t, sa, 1, time.Second)
  2611  	waitForOutboundGateways(t, sb1, 1, time.Second)
  2612  	waitForOutboundGateways(t, sb2, 1, time.Second)
  2613  
  2614  	checkForRegisteredQSubInterest(t, sa, "B", globalAccountName, "foo", 1, time.Second)
  2615  
  2616  	// Publish from s1, message should be received on s2.
  2617  	saURL := fmt.Sprintf("nats://127.0.0.1:%d", oa.Port)
  2618  	pubnc := natsConnect(t, saURL)
  2619  	defer pubnc.Close()
  2620  	// Publish 1 message
  2621  	natsPub(t, pubnc, "foo", []byte("hello"))
  2622  	natsFlush(t, pubnc)
  2623  	waitCh(t, ch, "Did not get out message")
  2624  
  2625  	// Note that since cluster B has no plain sub, an "RS- $G foo" will have been sent.
  2626  	// Wait for the no interest to be received by A
  2627  	checkFor(t, time.Second, 15*time.Millisecond, func() error {
  2628  		gw := sa.getOutboundGatewayConnection("B").gw
  2629  		ei, _ := gw.outsim.Load(globalAccountName)
  2630  		if ei != nil {
  2631  			e := ei.(*outsie)
  2632  			e.RLock()
  2633  			defer e.RUnlock()
  2634  			if _, inMap := e.ni["foo"]; inMap {
  2635  				return nil
  2636  			}
  2637  		}
  2638  		return fmt.Errorf("No-interest still not registered")
  2639  	})
  2640  
  2641  	// Unsubscribe 1 qsub
  2642  	natsUnsub(t, qsub1)
  2643  	natsFlush(t, subnc)
  2644  	// There should be only 1 local qsub on sb2 now, and the remote should still exist on sb1
  2645  	checkExpectedSubs(t, 1, sb1, sb2)
  2646  
  2647  	// Publish 1 message
  2648  	natsPub(t, pubnc, "foo", []byte("hello"))
  2649  	natsFlush(t, pubnc)
  2650  	waitCh(t, ch, "Did not get out message")
  2651  
  2652  	// Unsubscribe the remaining
  2653  	natsUnsub(t, qsub2)
  2654  	natsFlush(t, subnc)
  2655  
  2656  	// No more subs now on both sb1 and sb2
  2657  	checkExpectedSubs(t, 0, sb1, sb2)
  2658  
  2659  	// Server sb1 should not have qsub in its sub interest map
  2660  	checkFor(t, time.Second, 15*time.Millisecond, func() error {
  2661  		var entry *sitally
  2662  		var err error
  2663  		sb1.gateway.pasi.Lock()
  2664  		asim := sb1.gateway.pasi.m[globalAccountName]
  2665  		if asim != nil {
  2666  			entry = asim["foo bar"]
  2667  		}
  2668  		if entry != nil {
  2669  			err = fmt.Errorf("Map should not have an entry, got %#v", entry)
  2670  		}
  2671  		sb1.gateway.pasi.Unlock()
  2672  		return err
  2673  	})
  2674  
  2675  	// Let's wait for A to receive the unsubscribe
  2676  	checkFor(t, time.Second, 15*time.Millisecond, func() error {
  2677  		gw := sa.getOutboundGatewayConnection("B").gw
  2678  		ei, _ := gw.outsim.Load(globalAccountName)
  2679  		if ei != nil {
  2680  			sl := ei.(*outsie).sl
  2681  			if sl.Count() == 0 {
  2682  				return nil
  2683  			}
  2684  		}
  2685  		return fmt.Errorf("Interest still present")
  2686  	})
  2687  
  2688  	// Now send a message, it won't be sent because A received an RS-
  2689  	// on the first published message since there was no plain sub interest.
  2690  	natsPub(t, pubnc, "foo", []byte("hello"))
  2691  	natsFlush(t, pubnc)
  2692  
  2693  	// Get the gateway connection from A (sa) to B (sb1)
  2694  	gw := sa.getOutboundGatewayConnection("B")
  2695  	gw.mu.Lock()
  2696  	out := gw.outMsgs
  2697  	gw.mu.Unlock()
  2698  	if out != 2 {
  2699  		t.Fatalf("Expected 2 out messages, got %v", out)
  2700  	}
  2701  
  2702  	// Restart A
  2703  	pubnc.Close()
  2704  	sa.Shutdown()
  2705  	sa = runGatewayServer(oa)
  2706  	defer sa.Shutdown()
  2707  
  2708  	waitForOutboundGateways(t, sa, 1, time.Second)
  2709  
  2710  	// Check qsubs interest should be empty
  2711  	checkFor(t, time.Second, 15*time.Millisecond, func() error {
  2712  		gw := sa.getOutboundGatewayConnection("B").gw
  2713  		if ei, _ := gw.outsim.Load(globalAccountName); ei == nil {
  2714  			return nil
  2715  		}
  2716  		return fmt.Errorf("Interest still present")
  2717  	})
  2718  }
  2719  
  2720  func TestGatewayComplexSetup(t *testing.T) {
  2721  	doLog := false
  2722  
  2723  	// This test will have the following setup:
  2724  	// --- means route connection
  2725  	// === means gateway connection
  2726  	// [o] is outbound
  2727  	// [i] is inbound
  2728  	// Each server as an outbound connection to the other cluster.
  2729  	// It may have 0 or more inbound connection(s).
  2730  	//
  2731  	//  Cluster A		Cluster B
  2732  	//   sa1 [o]===========>[i]
  2733  	//    |  [i]<===========[o]
  2734  	//    |            		sb1 ------- sb2
  2735  	//    |					[i]			[o]
  2736  	//   sa2 [o]=============^   		 ||
  2737  	//		 [i]<========================||
  2738  	ob1 := testDefaultOptionsForGateway("B")
  2739  	sb1 := runGatewayServer(ob1)
  2740  	defer sb1.Shutdown()
  2741  	if doLog {
  2742  		sb1.SetLogger(logger.NewTestLogger("[B1] - ", true), true, true)
  2743  	}
  2744  
  2745  	oa1 := testGatewayOptionsFromToWithServers(t, "A", "B", sb1)
  2746  	sa1 := runGatewayServer(oa1)
  2747  	defer sa1.Shutdown()
  2748  	if doLog {
  2749  		sa1.SetLogger(logger.NewTestLogger("[A1] - ", true), true, true)
  2750  	}
  2751  
  2752  	waitForOutboundGateways(t, sa1, 1, time.Second)
  2753  	waitForOutboundGateways(t, sb1, 1, time.Second)
  2754  
  2755  	waitForInboundGateways(t, sa1, 1, time.Second)
  2756  	waitForInboundGateways(t, sb1, 1, time.Second)
  2757  
  2758  	oa2 := testGatewayOptionsFromToWithServers(t, "A", "B", sb1)
  2759  	oa2.Routes = RoutesFromStr(fmt.Sprintf("nats://127.0.0.1:%d", sa1.ClusterAddr().Port))
  2760  	sa2 := runGatewayServer(oa2)
  2761  	defer sa2.Shutdown()
  2762  	if doLog {
  2763  		sa2.SetLogger(logger.NewTestLogger("[A2] - ", true), true, true)
  2764  	}
  2765  
  2766  	checkClusterFormed(t, sa1, sa2)
  2767  
  2768  	waitForOutboundGateways(t, sa2, 1, time.Second)
  2769  	waitForInboundGateways(t, sb1, 2, time.Second)
  2770  
  2771  	ob2 := testGatewayOptionsFromToWithServers(t, "B", "A", sa2)
  2772  	ob2.Routes = RoutesFromStr(fmt.Sprintf("nats://127.0.0.1:%d", sb1.ClusterAddr().Port))
  2773  	var sb2 *Server
  2774  	for {
  2775  		sb2 = runGatewayServer(ob2)
  2776  		defer sb2.Shutdown()
  2777  
  2778  		checkClusterFormed(t, sb1, sb2)
  2779  
  2780  		waitForOutboundGateways(t, sb2, 1, time.Second)
  2781  		waitForInboundGateways(t, sb2, 0, time.Second)
  2782  		// For this test, we want the outbound to be to sa2, so if we don't have that,
  2783  		// restart sb2 until we get lucky.
  2784  		time.Sleep(100 * time.Millisecond)
  2785  		if sa2.numInboundGateways() == 0 {
  2786  			sb2.Shutdown()
  2787  			sb2 = nil
  2788  		} else {
  2789  			break
  2790  		}
  2791  	}
  2792  	if doLog {
  2793  		sb2.SetLogger(logger.NewTestLogger("[B2] - ", true), true, true)
  2794  	}
  2795  
  2796  	ch := make(chan bool, 1)
  2797  	cb := func(_ *nats.Msg) {
  2798  		ch <- true
  2799  	}
  2800  
  2801  	// Create a subscription on sa1 and sa2.
  2802  	ncsa1 := natsConnect(t, fmt.Sprintf("nats://127.0.0.1:%d", oa1.Port))
  2803  	defer ncsa1.Close()
  2804  	sub1 := natsSub(t, ncsa1, "foo", cb)
  2805  	natsFlush(t, ncsa1)
  2806  
  2807  	ncsa2 := natsConnect(t, fmt.Sprintf("nats://127.0.0.1:%d", oa2.Port))
  2808  	defer ncsa2.Close()
  2809  	sub2 := natsSub(t, ncsa2, "foo", cb)
  2810  	natsFlush(t, ncsa2)
  2811  
  2812  	// sa1 will have 1 local, one remote (from sa2), same for sa2.
  2813  	checkExpectedSubs(t, 2, sa1, sa2)
  2814  
  2815  	// Connect to sb2 and send 1 message
  2816  	ncsb2 := natsConnect(t, fmt.Sprintf("nats://127.0.0.1:%d", ob2.Port))
  2817  	defer ncsb2.Close()
  2818  	natsPub(t, ncsb2, "foo", []byte("hello"))
  2819  	natsFlush(t, ncsb2)
  2820  
  2821  	for i := 0; i < 2; i++ {
  2822  		waitCh(t, ch, "Did not get our message")
  2823  	}
  2824  
  2825  	// Unsubscribe sub2, and send 1, should still get it.
  2826  	natsUnsub(t, sub2)
  2827  	natsFlush(t, ncsa2)
  2828  	natsPub(t, ncsb2, "foo", []byte("hello"))
  2829  	natsFlush(t, ncsb2)
  2830  	waitCh(t, ch, "Did not get our message")
  2831  
  2832  	// Unsubscribe sub1, all server's sublist should be empty
  2833  	sub1.Unsubscribe()
  2834  	natsFlush(t, ncsa1)
  2835  
  2836  	checkExpectedSubs(t, 0, sa1, sa2, sb1, sb2)
  2837  
  2838  	// Create queue subs
  2839  	total := 100
  2840  	c1 := int32(0)
  2841  	c2 := int32(0)
  2842  	c3 := int32(0)
  2843  	tc := int32(0)
  2844  	natsQueueSub(t, ncsa1, "foo", "bar", func(_ *nats.Msg) {
  2845  		atomic.AddInt32(&c1, 1)
  2846  		if c := atomic.AddInt32(&tc, 1); int(c) == total {
  2847  			ch <- true
  2848  		}
  2849  	})
  2850  	natsFlush(t, ncsa1)
  2851  	natsQueueSub(t, ncsa2, "foo", "bar", func(_ *nats.Msg) {
  2852  		atomic.AddInt32(&c2, 1)
  2853  		if c := atomic.AddInt32(&tc, 1); int(c) == total {
  2854  			ch <- true
  2855  		}
  2856  	})
  2857  	natsFlush(t, ncsa2)
  2858  	checkExpectedSubs(t, 2, sa1, sa2)
  2859  
  2860  	qsubOnB2 := natsQueueSub(t, ncsb2, "foo", "bar", func(_ *nats.Msg) {
  2861  		atomic.AddInt32(&c3, 1)
  2862  		if c := atomic.AddInt32(&tc, 1); int(c) == total {
  2863  			ch <- true
  2864  		}
  2865  	})
  2866  	natsFlush(t, ncsb2)
  2867  	checkExpectedSubs(t, 1, sb2)
  2868  
  2869  	checkForRegisteredQSubInterest(t, sb1, "A", globalAccountName, "foo", 1, time.Second)
  2870  
  2871  	// Publish all messages. The queue sub on cluster B should receive all
  2872  	// messages.
  2873  	for i := 0; i < total; i++ {
  2874  		natsPub(t, ncsb2, "foo", []byte("msg"))
  2875  	}
  2876  	natsFlush(t, ncsb2)
  2877  
  2878  	waitCh(t, ch, "Did not get all our queue messages")
  2879  	if n := int(atomic.LoadInt32(&c1)); n != 0 {
  2880  		t.Fatalf("No message should have been received by qsub1, got %v", n)
  2881  	}
  2882  	if n := int(atomic.LoadInt32(&c2)); n != 0 {
  2883  		t.Fatalf("No message should have been received by qsub2, got %v", n)
  2884  	}
  2885  	if n := int(atomic.LoadInt32(&c3)); n != total {
  2886  		t.Fatalf("All messages should have been delivered to qsub on B, got %v", n)
  2887  	}
  2888  
  2889  	// Reset counters
  2890  	atomic.StoreInt32(&c1, 0)
  2891  	atomic.StoreInt32(&c2, 0)
  2892  	atomic.StoreInt32(&c3, 0)
  2893  	atomic.StoreInt32(&tc, 0)
  2894  
  2895  	// Now send from cluster A, messages should be distributed to qsubs on A.
  2896  	for i := 0; i < total; i++ {
  2897  		natsPub(t, ncsa1, "foo", []byte("msg"))
  2898  	}
  2899  	natsFlush(t, ncsa1)
  2900  
  2901  	expectedLow := int(float32(total/2) * 0.6)
  2902  	expectedHigh := int(float32(total/2) * 1.4)
  2903  	checkCount := func(t *testing.T, count *int32) {
  2904  		t.Helper()
  2905  		c := int(atomic.LoadInt32(count))
  2906  		if c < expectedLow || c > expectedHigh {
  2907  			t.Fatalf("Expected value to be between %v/%v, got %v", expectedLow, expectedHigh, c)
  2908  		}
  2909  	}
  2910  	waitCh(t, ch, "Did not get all our queue messages")
  2911  	checkCount(t, &c1)
  2912  	checkCount(t, &c2)
  2913  
  2914  	// Now unsubscribe sub on B and reset counters
  2915  	natsUnsub(t, qsubOnB2)
  2916  	checkExpectedSubs(t, 0, sb2)
  2917  	atomic.StoreInt32(&c1, 0)
  2918  	atomic.StoreInt32(&c2, 0)
  2919  	atomic.StoreInt32(&c3, 0)
  2920  	atomic.StoreInt32(&tc, 0)
  2921  	// Publish from cluster B, messages should be delivered to cluster A.
  2922  	for i := 0; i < total; i++ {
  2923  		natsPub(t, ncsb2, "foo", []byte("msg"))
  2924  	}
  2925  	natsFlush(t, ncsb2)
  2926  
  2927  	waitCh(t, ch, "Did not get all our queue messages")
  2928  	if n := int(atomic.LoadInt32(&c3)); n != 0 {
  2929  		t.Fatalf("There should not have been messages on unsubscribed sub, got %v", n)
  2930  	}
  2931  	checkCount(t, &c1)
  2932  	checkCount(t, &c2)
  2933  }
  2934  
  2935  func TestGatewayMsgSentOnlyOnce(t *testing.T) {
  2936  	o2 := testDefaultOptionsForGateway("B")
  2937  	s2 := runGatewayServer(o2)
  2938  	defer s2.Shutdown()
  2939  
  2940  	o1 := testGatewayOptionsFromToWithServers(t, "A", "B", s2)
  2941  	s1 := runGatewayServer(o1)
  2942  	defer s1.Shutdown()
  2943  
  2944  	waitForOutboundGateways(t, s1, 1, time.Second)
  2945  	waitForOutboundGateways(t, s2, 1, time.Second)
  2946  
  2947  	s2Url := fmt.Sprintf("nats://127.0.0.1:%d", o2.Port)
  2948  	nc2 := natsConnect(t, s2Url)
  2949  	defer nc2.Close()
  2950  
  2951  	s1Url := fmt.Sprintf("nats://127.0.0.1:%d", o1.Port)
  2952  	nc1 := natsConnect(t, s1Url)
  2953  	defer nc1.Close()
  2954  
  2955  	ch := make(chan bool, 1)
  2956  	count := int32(0)
  2957  	expected := int32(4)
  2958  	cb := func(_ *nats.Msg) {
  2959  		if c := atomic.AddInt32(&count, 1); c == expected {
  2960  			ch <- true
  2961  		}
  2962  	}
  2963  
  2964  	// On s1, create 2 plain subs, 2 queue members for group
  2965  	// "bar" and 1 for group "baz".
  2966  	natsSub(t, nc1, ">", cb)
  2967  	natsSub(t, nc1, "foo", cb)
  2968  	natsQueueSub(t, nc1, "foo", "bar", cb)
  2969  	natsQueueSub(t, nc1, "foo", "bar", cb)
  2970  	natsQueueSub(t, nc1, "foo", "baz", cb)
  2971  	natsFlush(t, nc1)
  2972  
  2973  	// Ensure subs registered in S1
  2974  	checkExpectedSubs(t, 5, s1)
  2975  
  2976  	// Also need to wait for qsubs to be registered on s2.
  2977  	checkForRegisteredQSubInterest(t, s2, "A", globalAccountName, "foo", 2, time.Second)
  2978  
  2979  	// From s2, send 1 message, s1 should receive 1 only,
  2980  	// and total we should get the callback notified 4 times.
  2981  	natsPub(t, nc2, "foo", []byte("hello"))
  2982  	natsFlush(t, nc2)
  2983  
  2984  	waitCh(t, ch, "Did not get our messages")
  2985  	// Verifiy that count is still 4
  2986  	if c := atomic.LoadInt32(&count); c != expected {
  2987  		t.Fatalf("Expected %v messages, got %v", expected, c)
  2988  	}
  2989  	// Check s2 outbound connection stats. It should say that it
  2990  	// sent only 1 message.
  2991  	c := s2.getOutboundGatewayConnection("A")
  2992  	if c == nil {
  2993  		t.Fatalf("S2 outbound gateway not found")
  2994  	}
  2995  	c.mu.Lock()
  2996  	out := c.outMsgs
  2997  	c.mu.Unlock()
  2998  	if out != 1 {
  2999  		t.Fatalf("Expected s2's outbound gateway to have sent a single message, got %v", out)
  3000  	}
  3001  	// Now check s1's inbound gateway
  3002  	s1.gateway.RLock()
  3003  	c = nil
  3004  	for _, ci := range s1.gateway.in {
  3005  		c = ci
  3006  		break
  3007  	}
  3008  	s1.gateway.RUnlock()
  3009  	if c == nil {
  3010  		t.Fatalf("S1 inbound gateway not found")
  3011  	}
  3012  	if in := atomic.LoadInt64(&c.inMsgs); in != 1 {
  3013  		t.Fatalf("Expected s1's inbound gateway to have received a single message, got %v", in)
  3014  	}
  3015  }
  3016  
  3017  type checkErrorLogger struct {
  3018  	DummyLogger
  3019  	checkErrorStr string
  3020  	gotError      bool
  3021  }
  3022  
  3023  func (l *checkErrorLogger) Errorf(format string, args ...interface{}) {
  3024  	l.DummyLogger.Errorf(format, args...)
  3025  	l.Lock()
  3026  	if strings.Contains(l.Msg, l.checkErrorStr) {
  3027  		l.gotError = true
  3028  	}
  3029  	l.Unlock()
  3030  }
  3031  
  3032  func TestGatewayRoutedServerWithoutGatewayConfigured(t *testing.T) {
  3033  	o2 := testDefaultOptionsForGateway("B")
  3034  	s2 := runGatewayServer(o2)
  3035  	defer s2.Shutdown()
  3036  
  3037  	o1 := testGatewayOptionsFromToWithServers(t, "A", "B", s2)
  3038  	s1 := runGatewayServer(o1)
  3039  	defer s1.Shutdown()
  3040  
  3041  	waitForOutboundGateways(t, s1, 1, time.Second)
  3042  	waitForOutboundGateways(t, s2, 1, time.Second)
  3043  
  3044  	o3 := DefaultOptions()
  3045  	o3.NoSystemAccount = true
  3046  	o3.Cluster.Name = "B"
  3047  	o3.Routes = RoutesFromStr(fmt.Sprintf("nats://127.0.0.1:%d", s2.ClusterAddr().Port))
  3048  	s3 := New(o3)
  3049  	defer s3.Shutdown()
  3050  	l := &checkErrorLogger{checkErrorStr: "not configured"}
  3051  	s3.SetLogger(l, true, true)
  3052  	wg := sync.WaitGroup{}
  3053  	wg.Add(1)
  3054  	go func() {
  3055  		s3.Start()
  3056  		wg.Done()
  3057  	}()
  3058  
  3059  	checkClusterFormed(t, s2, s3)
  3060  
  3061  	// Check that server s3 does not panic when being notified
  3062  	// about the A gateway, but report an error.
  3063  	deadline := time.Now().Add(2 * time.Second)
  3064  	gotIt := false
  3065  	for time.Now().Before(deadline) {
  3066  		l.Lock()
  3067  		gotIt = l.gotError
  3068  		l.Unlock()
  3069  		if gotIt {
  3070  			break
  3071  		}
  3072  		time.Sleep(15 * time.Millisecond)
  3073  	}
  3074  	if !gotIt {
  3075  		t.Fatalf("Should have reported error about gateway not configured")
  3076  	}
  3077  
  3078  	s3.Shutdown()
  3079  	wg.Wait()
  3080  }
  3081  
  3082  func TestGatewaySendsToNonLocalSubs(t *testing.T) {
  3083  	ob1 := testDefaultOptionsForGateway("B")
  3084  	sb1 := runGatewayServer(ob1)
  3085  	defer sb1.Shutdown()
  3086  
  3087  	oa1 := testGatewayOptionsFromToWithServers(t, "A", "B", sb1)
  3088  	sa1 := runGatewayServer(oa1)
  3089  	defer sa1.Shutdown()
  3090  
  3091  	waitForOutboundGateways(t, sa1, 1, time.Second)
  3092  	waitForOutboundGateways(t, sb1, 1, time.Second)
  3093  
  3094  	waitForInboundGateways(t, sa1, 1, time.Second)
  3095  	waitForInboundGateways(t, sb1, 1, time.Second)
  3096  
  3097  	oa2 := testGatewayOptionsFromToWithServers(t, "A", "B", sb1)
  3098  	oa2.Routes = RoutesFromStr(fmt.Sprintf("nats://127.0.0.1:%d", sa1.ClusterAddr().Port))
  3099  	sa2 := runGatewayServer(oa2)
  3100  	defer sa2.Shutdown()
  3101  
  3102  	checkClusterFormed(t, sa1, sa2)
  3103  
  3104  	waitForOutboundGateways(t, sa2, 1, time.Second)
  3105  	waitForInboundGateways(t, sb1, 2, time.Second)
  3106  
  3107  	ch := make(chan bool, 1)
  3108  	// Create an interest of sa2
  3109  	ncSub := natsConnect(t, fmt.Sprintf("nats://127.0.0.1:%d", oa2.Port))
  3110  	defer ncSub.Close()
  3111  	natsSub(t, ncSub, "foo", func(_ *nats.Msg) { ch <- true })
  3112  	natsFlush(t, ncSub)
  3113  	checkExpectedSubs(t, 1, sa1, sa2)
  3114  
  3115  	// Produce a message from sb1, make sure it can be received.
  3116  	ncPub := natsConnect(t, fmt.Sprintf("nats://127.0.0.1:%d", ob1.Port))
  3117  	defer ncPub.Close()
  3118  	natsPub(t, ncPub, "foo", []byte("hello"))
  3119  	waitCh(t, ch, "Did not get our message")
  3120  
  3121  	ncSub.Close()
  3122  	ncPub.Close()
  3123  	checkExpectedSubs(t, 0, sa1, sa2)
  3124  
  3125  	// Now create sb2 that has a route to sb1 and gateway connects to sa2.
  3126  	ob2 := testGatewayOptionsFromToWithServers(t, "B", "A", sa2)
  3127  	ob2.Routes = RoutesFromStr(fmt.Sprintf("nats://127.0.0.1:%d", sb1.ClusterAddr().Port))
  3128  	sb2 := runGatewayServer(ob2)
  3129  	defer sb2.Shutdown()
  3130  
  3131  	checkClusterFormed(t, sb1, sb2)
  3132  	waitForOutboundGateways(t, sb2, 1, time.Second)
  3133  
  3134  	ncSub = natsConnect(t, fmt.Sprintf("nats://127.0.0.1:%d", oa1.Port))
  3135  	defer ncSub.Close()
  3136  	natsSub(t, ncSub, "foo", func(_ *nats.Msg) { ch <- true })
  3137  	natsFlush(t, ncSub)
  3138  	checkExpectedSubs(t, 1, sa1, sa2)
  3139  
  3140  	ncPub = natsConnect(t, fmt.Sprintf("nats://127.0.0.1:%d", ob2.Port))
  3141  	defer ncPub.Close()
  3142  	natsPub(t, ncPub, "foo", []byte("hello"))
  3143  	waitCh(t, ch, "Did not get our message")
  3144  }
  3145  
  3146  func TestGatewayUnknownGatewayCommand(t *testing.T) {
  3147  	o1 := testDefaultOptionsForGateway("A")
  3148  	s1 := runGatewayServer(o1)
  3149  	defer s1.Shutdown()
  3150  
  3151  	l := &checkErrorLogger{checkErrorStr: "Unknown command"}
  3152  	s1.SetLogger(l, true, true)
  3153  
  3154  	o2 := testDefaultOptionsForGateway("A")
  3155  	o2.Routes = RoutesFromStr(fmt.Sprintf("nats://127.0.0.1:%d", s1.ClusterAddr().Port))
  3156  	s2 := runGatewayServer(o2)
  3157  	defer s2.Shutdown()
  3158  
  3159  	checkClusterFormed(t, s1, s2)
  3160  
  3161  	var route *client
  3162  	s2.mu.Lock()
  3163  	if r := getFirstRoute(s2); r != nil {
  3164  		route = r
  3165  	}
  3166  	s2.mu.Unlock()
  3167  
  3168  	route.mu.Lock()
  3169  	info := &Info{
  3170  		Gateway:    "B",
  3171  		GatewayCmd: 255,
  3172  	}
  3173  	b, _ := json.Marshal(info)
  3174  	route.enqueueProto([]byte(fmt.Sprintf(InfoProto, b)))
  3175  	route.mu.Unlock()
  3176  
  3177  	checkFor(t, time.Second, 15*time.Millisecond, func() error {
  3178  		l.Lock()
  3179  		gotIt := l.gotError
  3180  		l.Unlock()
  3181  		if gotIt {
  3182  			return nil
  3183  		}
  3184  		return fmt.Errorf("Did not get expected error")
  3185  	})
  3186  }
  3187  
  3188  func TestGatewayRandomIP(t *testing.T) {
  3189  	ob := testDefaultOptionsForGateway("B")
  3190  	sb := runGatewayServer(ob)
  3191  	defer sb.Shutdown()
  3192  
  3193  	oa := testGatewayOptionsFromToWithURLs(t, "A", "B",
  3194  		[]string{
  3195  			"nats://noport",
  3196  			fmt.Sprintf("nats://localhost:%d", sb.GatewayAddr().Port),
  3197  		})
  3198  	// Create a dummy resolver that returns error since we
  3199  	// don't provide any IP. The code should then use the configured
  3200  	// url (localhost:port) and try with that, which in this case
  3201  	// should work.
  3202  	oa.Gateway.resolver = &myDummyDNSResolver{}
  3203  	sa := runGatewayServer(oa)
  3204  	defer sa.Shutdown()
  3205  
  3206  	waitForOutboundGateways(t, sa, 1, 2*time.Second)
  3207  	waitForOutboundGateways(t, sb, 1, 2*time.Second)
  3208  }
  3209  
  3210  func TestGatewaySendQSubsBufSize(t *testing.T) {
  3211  	for _, test := range []struct {
  3212  		name    string
  3213  		bufSize int
  3214  	}{
  3215  		{
  3216  			name:    "Bufsize 45, more than one at a time",
  3217  			bufSize: 45,
  3218  		},
  3219  		{
  3220  			name:    "Bufsize 15, one at a time",
  3221  			bufSize: 15,
  3222  		},
  3223  		{
  3224  			name:    "Bufsize 0, default to maxBufSize, all at once",
  3225  			bufSize: 0,
  3226  		},
  3227  	} {
  3228  		t.Run(test.name, func(t *testing.T) {
  3229  
  3230  			o2 := testDefaultOptionsForGateway("B")
  3231  			o2.Gateway.sendQSubsBufSize = test.bufSize
  3232  			s2 := runGatewayServer(o2)
  3233  			defer s2.Shutdown()
  3234  
  3235  			s2Url := fmt.Sprintf("nats://%s:%d", o2.Host, o2.Port)
  3236  			nc := natsConnect(t, s2Url)
  3237  			defer nc.Close()
  3238  			natsQueueSub(t, nc, "foo", "bar", func(_ *nats.Msg) {})
  3239  			natsQueueSub(t, nc, "foo", "baz", func(_ *nats.Msg) {})
  3240  			natsQueueSub(t, nc, "foo", "bat", func(_ *nats.Msg) {})
  3241  			natsQueueSub(t, nc, "foo", "bax", func(_ *nats.Msg) {})
  3242  
  3243  			checkExpectedSubs(t, 4, s2)
  3244  
  3245  			o1 := testGatewayOptionsFromToWithServers(t, "A", "B", s2)
  3246  			s1 := runGatewayServer(o1)
  3247  			defer s1.Shutdown()
  3248  
  3249  			waitForOutboundGateways(t, s1, 1, time.Second)
  3250  			waitForOutboundGateways(t, s2, 1, time.Second)
  3251  
  3252  			checkForRegisteredQSubInterest(t, s1, "B", globalAccountName, "foo", 4, time.Second)
  3253  
  3254  			// Make sure we have the 4 we expected
  3255  			c := s1.getOutboundGatewayConnection("B")
  3256  			ei, _ := c.gw.outsim.Load(globalAccountName)
  3257  			if ei == nil {
  3258  				t.Fatalf("No interest found")
  3259  			}
  3260  			sl := ei.(*outsie).sl
  3261  			r := sl.Match("foo")
  3262  			if len(r.qsubs) != 4 {
  3263  				t.Fatalf("Expected 4 groups, got %v", len(r.qsubs))
  3264  			}
  3265  			var gotBar, gotBaz, gotBat, gotBax bool
  3266  			for _, qs := range r.qsubs {
  3267  				if len(qs) != 1 {
  3268  					t.Fatalf("Unexpected number of subs for group %s: %v", qs[0].queue, len(qs))
  3269  				}
  3270  				q := qs[0].queue
  3271  				switch string(q) {
  3272  				case "bar":
  3273  					gotBar = true
  3274  				case "baz":
  3275  					gotBaz = true
  3276  				case "bat":
  3277  					gotBat = true
  3278  				case "bax":
  3279  					gotBax = true
  3280  				default:
  3281  					t.Fatalf("Unexpected group name: %s", q)
  3282  				}
  3283  			}
  3284  			if !gotBar || !gotBaz || !gotBat || !gotBax {
  3285  				t.Fatalf("Did not get all we wanted: bar=%v baz=%v bat=%v bax=%v",
  3286  					gotBar, gotBaz, gotBat, gotBax)
  3287  			}
  3288  
  3289  			nc.Close()
  3290  			s1.Shutdown()
  3291  			s2.Shutdown()
  3292  
  3293  			waitForOutboundGateways(t, s1, 0, time.Second)
  3294  			waitForOutboundGateways(t, s2, 0, time.Second)
  3295  		})
  3296  	}
  3297  }
  3298  
  3299  func TestGatewayRaceBetweenPubAndSub(t *testing.T) {
  3300  	o2 := testDefaultOptionsForGateway("B")
  3301  	s2 := runGatewayServer(o2)
  3302  	defer s2.Shutdown()
  3303  
  3304  	o1 := testGatewayOptionsFromToWithServers(t, "A", "B", s2)
  3305  	s1 := runGatewayServer(o1)
  3306  	defer s1.Shutdown()
  3307  
  3308  	waitForOutboundGateways(t, s1, 1, time.Second)
  3309  	waitForOutboundGateways(t, s2, 1, time.Second)
  3310  
  3311  	s2Url := fmt.Sprintf("nats://127.0.0.1:%d", o2.Port)
  3312  	nc2 := natsConnect(t, s2Url)
  3313  	defer nc2.Close()
  3314  
  3315  	s1Url := fmt.Sprintf("nats://127.0.0.1:%d", o1.Port)
  3316  	var ncaa [5]*nats.Conn
  3317  	var nca = ncaa[:0]
  3318  	for i := 0; i < 5; i++ {
  3319  		nc := natsConnect(t, s1Url)
  3320  		defer nc.Close()
  3321  		nca = append(nca, nc)
  3322  	}
  3323  
  3324  	ch := make(chan bool, 1)
  3325  	wg := sync.WaitGroup{}
  3326  	wg.Add(5)
  3327  	for _, nc := range nca {
  3328  		nc := nc
  3329  		go func(n *nats.Conn) {
  3330  			defer wg.Done()
  3331  			for {
  3332  				n.Publish("foo", []byte("hello"))
  3333  				select {
  3334  				case <-ch:
  3335  					return
  3336  				default:
  3337  				}
  3338  			}
  3339  		}(nc)
  3340  	}
  3341  	time.Sleep(100 * time.Millisecond)
  3342  	natsQueueSub(t, nc2, "foo", "bar", func(m *nats.Msg) {
  3343  		natsUnsub(t, m.Sub)
  3344  		close(ch)
  3345  	})
  3346  	wg.Wait()
  3347  }
  3348  
  3349  // Returns the first (if any) of the inbound connections for this name.
  3350  func getInboundGatewayConnection(s *Server, name string) *client {
  3351  	var gwsa [4]*client
  3352  	var gws = gwsa[:0]
  3353  	s.getInboundGatewayConnections(&gws)
  3354  	if len(gws) > 0 {
  3355  		return gws[0]
  3356  	}
  3357  	return nil
  3358  }
  3359  
  3360  func TestGatewaySendAllSubs(t *testing.T) {
  3361  	GatewayDoNotForceInterestOnlyMode(true)
  3362  	defer GatewayDoNotForceInterestOnlyMode(false)
  3363  
  3364  	gatewayMaxRUnsubBeforeSwitch = 100
  3365  	defer func() { gatewayMaxRUnsubBeforeSwitch = defaultGatewayMaxRUnsubBeforeSwitch }()
  3366  
  3367  	ob := testDefaultOptionsForGateway("B")
  3368  	sb := runGatewayServer(ob)
  3369  	defer sb.Shutdown()
  3370  
  3371  	oa := testGatewayOptionsFromToWithServers(t, "A", "B", sb)
  3372  	sa := runGatewayServer(oa)
  3373  	defer sa.Shutdown()
  3374  
  3375  	oc := testGatewayOptionsFromToWithServers(t, "C", "B", sb)
  3376  	sc := runGatewayServer(oc)
  3377  	defer sc.Shutdown()
  3378  
  3379  	waitForOutboundGateways(t, sa, 2, time.Second)
  3380  	waitForOutboundGateways(t, sb, 2, time.Second)
  3381  	waitForOutboundGateways(t, sc, 2, time.Second)
  3382  	waitForInboundGateways(t, sa, 2, time.Second)
  3383  	waitForInboundGateways(t, sb, 2, time.Second)
  3384  	waitForInboundGateways(t, sc, 2, time.Second)
  3385  
  3386  	// On A, create a sub to register some interest
  3387  	aURL := fmt.Sprintf("nats://%s:%d", oa.Host, oa.Port)
  3388  	ncA := natsConnect(t, aURL)
  3389  	defer ncA.Close()
  3390  	natsSub(t, ncA, "sub.on.a.*", func(m *nats.Msg) {})
  3391  	natsFlush(t, ncA)
  3392  	checkExpectedSubs(t, 1, sa)
  3393  
  3394  	// On C, have some sub activity while it receives
  3395  	// unwanted messages and switches to interestOnly mode.
  3396  	cURL := fmt.Sprintf("nats://%s:%d", oc.Host, oc.Port)
  3397  	ncC := natsConnect(t, cURL)
  3398  	defer ncC.Close()
  3399  	wg := sync.WaitGroup{}
  3400  	wg.Add(2)
  3401  	done := make(chan bool)
  3402  	consCount := 0
  3403  	accsCount := 0
  3404  	go func() {
  3405  		defer wg.Done()
  3406  		for i := 0; ; i++ {
  3407  			// Create subs and qsubs on same subject
  3408  			natsSub(t, ncC, fmt.Sprintf("foo.%d", i+1), func(_ *nats.Msg) {})
  3409  			natsQueueSub(t, ncC, fmt.Sprintf("foo.%d", i+1), fmt.Sprintf("bar.%d", i+1), func(_ *nats.Msg) {})
  3410  			// Create psubs and qsubs on unique subjects
  3411  			natsSub(t, ncC, fmt.Sprintf("foox.%d", i+1), func(_ *nats.Msg) {})
  3412  			natsQueueSub(t, ncC, fmt.Sprintf("fooy.%d", i+1), fmt.Sprintf("bar.%d", i+1), func(_ *nats.Msg) {})
  3413  			consCount += 4
  3414  			// Register account
  3415  			sc.RegisterAccount(fmt.Sprintf("acc.%d", i+1))
  3416  			accsCount++
  3417  			select {
  3418  			case <-done:
  3419  				return
  3420  			case <-time.After(15 * time.Millisecond):
  3421  			}
  3422  		}
  3423  	}()
  3424  
  3425  	// From B publish on subjects for which C has an interest
  3426  	bURL := fmt.Sprintf("nats://%s:%d", ob.Host, ob.Port)
  3427  	ncB := natsConnect(t, bURL)
  3428  	defer ncB.Close()
  3429  
  3430  	go func() {
  3431  		defer wg.Done()
  3432  		time.Sleep(10 * time.Millisecond)
  3433  		for {
  3434  			for i := 0; i < 10; i++ {
  3435  				natsPub(t, ncB, fmt.Sprintf("foo.%d", i+1), []byte("hello"))
  3436  			}
  3437  			select {
  3438  			case <-done:
  3439  				return
  3440  			case <-time.After(5 * time.Millisecond):
  3441  			}
  3442  		}
  3443  	}()
  3444  
  3445  	// From B, send a lot of messages that A is interested in,
  3446  	// but not C.
  3447  	// TODO(ik): May need to change that if we change the threshold
  3448  	// for when the switch happens.
  3449  	total := 300
  3450  	for i := 0; i < total; i++ {
  3451  		if err := ncB.Publish(fmt.Sprintf("sub.on.a.%d", i), []byte("hi")); err != nil {
  3452  			t.Fatalf("Error waiting for reply: %v", err)
  3453  		}
  3454  	}
  3455  	close(done)
  3456  
  3457  	// Normally, C would receive a message for each req inbox and
  3458  	// would send and RS- on that to B, making both have an unbounded
  3459  	// growth of the no-interest map. But after a certain amount
  3460  	// of RS-, C will send all its sub for the given account and
  3461  	// instruct B to send only if there is explicit interest.
  3462  	checkFor(t, 2*time.Second, 50*time.Millisecond, func() error {
  3463  		// Check C inbound connection from B
  3464  		c := getInboundGatewayConnection(sc, "B")
  3465  		c.mu.Lock()
  3466  		var switchedMode bool
  3467  		e := c.gw.insim[globalAccountName]
  3468  		if e != nil {
  3469  			switchedMode = e.ni == nil && e.mode == InterestOnly
  3470  		}
  3471  		c.mu.Unlock()
  3472  		if !switchedMode {
  3473  			return fmt.Errorf("C has still not switched mode")
  3474  		}
  3475  		return nil
  3476  	})
  3477  	checkGWInterestOnlyMode(t, sb, "C", globalAccountName)
  3478  	wg.Wait()
  3479  
  3480  	// Check consCount and accsCount on C
  3481  	checkFor(t, 2*time.Second, 15*time.Millisecond, func() error {
  3482  		sc.gateway.pasi.Lock()
  3483  		scount := len(sc.gateway.pasi.m[globalAccountName])
  3484  		sc.gateway.pasi.Unlock()
  3485  		if scount != consCount {
  3486  			return fmt.Errorf("Expected %v consumers for global account, got %v", consCount, scount)
  3487  		}
  3488  		acount := sc.numAccounts()
  3489  		if acount != accsCount+1 {
  3490  			return fmt.Errorf("Expected %v accounts, got %v", accsCount+1, acount)
  3491  		}
  3492  		return nil
  3493  	})
  3494  
  3495  	// Also, after all that, if a sub is created on C, it should
  3496  	// be sent to B (but not A). Check that this is the case.
  3497  	// So first send from A on the subject that we are going to
  3498  	// use for this new sub.
  3499  	natsPub(t, ncA, "newsub", []byte("hello"))
  3500  	natsFlush(t, ncA)
  3501  	aOutboundToC := sa.getOutboundGatewayConnection("C")
  3502  	checkForSubjectNoInterest(t, aOutboundToC, globalAccountName, "newsub", true, 2*time.Second)
  3503  
  3504  	newSubSub := natsSub(t, ncC, "newsub", func(_ *nats.Msg) {})
  3505  	natsFlush(t, ncC)
  3506  	checkExpectedSubs(t, consCount+1)
  3507  	checkFor(t, time.Second, 15*time.Millisecond, func() error {
  3508  		c := sb.getOutboundGatewayConnection("C")
  3509  		ei, _ := c.gw.outsim.Load(globalAccountName)
  3510  		if ei != nil {
  3511  			sl := ei.(*outsie).sl
  3512  			r := sl.Match("newsub")
  3513  			if len(r.psubs) == 1 {
  3514  				return nil
  3515  			}
  3516  		}
  3517  		return fmt.Errorf("Newsub not registered on B")
  3518  	})
  3519  	checkForSubjectNoInterest(t, aOutboundToC, globalAccountName, "newsub", false, 2*time.Second)
  3520  
  3521  	natsUnsub(t, newSubSub)
  3522  	natsFlush(t, ncC)
  3523  	checkExpectedSubs(t, consCount)
  3524  	checkFor(t, time.Second, 15*time.Millisecond, func() error {
  3525  		c := sb.getOutboundGatewayConnection("C")
  3526  		ei, _ := c.gw.outsim.Load(globalAccountName)
  3527  		if ei != nil {
  3528  			sl := ei.(*outsie).sl
  3529  			r := sl.Match("newsub")
  3530  			if len(r.psubs) == 0 {
  3531  				return nil
  3532  			}
  3533  		}
  3534  		return fmt.Errorf("Newsub still registered on B")
  3535  	})
  3536  }
  3537  
  3538  func TestGatewaySendAllSubsBadProtocol(t *testing.T) {
  3539  	ob := testDefaultOptionsForGateway("B")
  3540  	sb := runGatewayServer(ob)
  3541  	defer sb.Shutdown()
  3542  
  3543  	oa := testGatewayOptionsFromToWithServers(t, "A", "B", sb)
  3544  	sa := runGatewayServer(oa)
  3545  	defer sa.Shutdown()
  3546  
  3547  	waitForOutboundGateways(t, sa, 1, time.Second)
  3548  	waitForOutboundGateways(t, sb, 1, time.Second)
  3549  	waitForInboundGateways(t, sa, 1, time.Second)
  3550  	waitForInboundGateways(t, sb, 1, time.Second)
  3551  
  3552  	// For this test, make sure to use inbound from A so
  3553  	// A will reconnect when we send bad proto that
  3554  	// causes connection to be closed.
  3555  	c := getInboundGatewayConnection(sa, "A")
  3556  	// Mock an invalid protocol (account name missing)
  3557  	info := &Info{
  3558  		Gateway:    "B",
  3559  		GatewayCmd: gatewayCmdAllSubsStart,
  3560  	}
  3561  	b, _ := json.Marshal(info)
  3562  	c.mu.Lock()
  3563  	c.enqueueProto([]byte(fmt.Sprintf("INFO %s\r\n", b)))
  3564  	c.mu.Unlock()
  3565  
  3566  	orgConn := c
  3567  	checkFor(t, 3*time.Second, 100*time.Millisecond, func() error {
  3568  		curConn := getInboundGatewayConnection(sa, "A")
  3569  		if orgConn == curConn {
  3570  			return fmt.Errorf("Not reconnected")
  3571  		}
  3572  		return nil
  3573  	})
  3574  
  3575  	waitForOutboundGateways(t, sa, 1, 2*time.Second)
  3576  	waitForOutboundGateways(t, sb, 1, 2*time.Second)
  3577  
  3578  	// Refresh
  3579  	c = nil
  3580  	checkFor(t, 3*time.Second, 15*time.Millisecond, func() error {
  3581  		c = getInboundGatewayConnection(sa, "A")
  3582  		if c == nil {
  3583  			return fmt.Errorf("Did not reconnect")
  3584  		}
  3585  		return nil
  3586  	})
  3587  	// Do correct start
  3588  	info.GatewayCmdPayload = []byte(globalAccountName)
  3589  	b, _ = json.Marshal(info)
  3590  	c.mu.Lock()
  3591  	c.enqueueProto([]byte(fmt.Sprintf("INFO %s\r\n", b)))
  3592  	c.mu.Unlock()
  3593  	// But incorrect end.
  3594  	info.GatewayCmd = gatewayCmdAllSubsComplete
  3595  	info.GatewayCmdPayload = nil
  3596  	b, _ = json.Marshal(info)
  3597  	c.mu.Lock()
  3598  	c.enqueueProto([]byte(fmt.Sprintf("INFO %s\r\n", b)))
  3599  	c.mu.Unlock()
  3600  
  3601  	orgConn = c
  3602  	checkFor(t, 3*time.Second, 100*time.Millisecond, func() error {
  3603  		curConn := getInboundGatewayConnection(sa, "A")
  3604  		if orgConn == curConn {
  3605  			return fmt.Errorf("Not reconnected")
  3606  		}
  3607  		return nil
  3608  	})
  3609  }
  3610  
  3611  func TestGatewayRaceOnClose(t *testing.T) {
  3612  	ob := testDefaultOptionsForGateway("B")
  3613  	sb := runGatewayServer(ob)
  3614  	defer sb.Shutdown()
  3615  
  3616  	oa := testGatewayOptionsFromToWithServers(t, "A", "B", sb)
  3617  	sa := runGatewayServer(oa)
  3618  	defer sa.Shutdown()
  3619  
  3620  	waitForOutboundGateways(t, sa, 1, time.Second)
  3621  	waitForOutboundGateways(t, sb, 1, time.Second)
  3622  	waitForInboundGateways(t, sa, 1, time.Second)
  3623  	waitForInboundGateways(t, sb, 1, time.Second)
  3624  
  3625  	bURL := fmt.Sprintf("nats://%s:%d", ob.Host, ob.Port)
  3626  	ncB := natsConnect(t, bURL, nats.NoReconnect())
  3627  	defer ncB.Close()
  3628  
  3629  	wg := sync.WaitGroup{}
  3630  	wg.Add(1)
  3631  	go func() {
  3632  		defer wg.Done()
  3633  		cb := func(_ *nats.Msg) {}
  3634  		for {
  3635  			// Expect failure at one point and just return.
  3636  			qsub, err := ncB.QueueSubscribe("foo", "bar", cb)
  3637  			if err != nil {
  3638  				return
  3639  			}
  3640  			if err := qsub.Unsubscribe(); err != nil {
  3641  				return
  3642  			}
  3643  		}
  3644  	}()
  3645  	// Wait a bit and kill B
  3646  	time.Sleep(200 * time.Millisecond)
  3647  	sb.Shutdown()
  3648  	wg.Wait()
  3649  }
  3650  
  3651  // Similar to TestNewRoutesServiceImport but with 2 GW servers instead
  3652  // of a cluster of 2 servers.
  3653  func TestGatewayServiceImport(t *testing.T) {
  3654  	GatewayDoNotForceInterestOnlyMode(true)
  3655  	defer GatewayDoNotForceInterestOnlyMode(false)
  3656  
  3657  	oa := testDefaultOptionsForGateway("A")
  3658  	setAccountUserPassInOptions(oa, "$foo", "clientA", "password")
  3659  	setAccountUserPassInOptions(oa, "$bar", "yyyyyyy", "password")
  3660  	sa := runGatewayServer(oa)
  3661  	defer sa.Shutdown()
  3662  
  3663  	ob := testGatewayOptionsFromToWithServers(t, "B", "A", sa)
  3664  	setAccountUserPassInOptions(ob, "$foo", "clientBFoo", "password")
  3665  	setAccountUserPassInOptions(ob, "$bar", "clientB", "password")
  3666  	sb := runGatewayServer(ob)
  3667  	defer sb.Shutdown()
  3668  
  3669  	waitForOutboundGateways(t, sa, 1, time.Second)
  3670  	waitForOutboundGateways(t, sb, 1, time.Second)
  3671  	waitForInboundGateways(t, sa, 1, time.Second)
  3672  	waitForInboundGateways(t, sb, 1, time.Second)
  3673  
  3674  	// Get accounts
  3675  	fooA, _ := sa.LookupAccount("$foo")
  3676  	barA, _ := sa.LookupAccount("$bar")
  3677  	fooB, _ := sb.LookupAccount("$foo")
  3678  	barB, _ := sb.LookupAccount("$bar")
  3679  
  3680  	// Add in the service export for the requests. Make it public.
  3681  	fooA.AddServiceExport("test.request", nil)
  3682  	fooB.AddServiceExport("test.request", nil)
  3683  
  3684  	// Add import abilities to server B's bar account from foo.
  3685  	if err := barB.AddServiceImport(fooB, "foo.request", "test.request"); err != nil {
  3686  		t.Fatalf("Error adding service import: %v", err)
  3687  	}
  3688  	// Same on A.
  3689  	if err := barA.AddServiceImport(fooA, "foo.request", "test.request"); err != nil {
  3690  		t.Fatalf("Error adding service import: %v", err)
  3691  	}
  3692  
  3693  	// clientA will be connected to srvA and be the service endpoint and responder.
  3694  	aURL := fmt.Sprintf("nats://clientA:password@127.0.0.1:%d", oa.Port)
  3695  	clientA := natsConnect(t, aURL)
  3696  	defer clientA.Close()
  3697  
  3698  	subA := natsSubSync(t, clientA, "test.request")
  3699  	natsFlush(t, clientA)
  3700  
  3701  	// Now setup client B on srvB who will do a sub from account $bar
  3702  	// that should map account $foo's foo subject.
  3703  	bURL := fmt.Sprintf("nats://clientB:password@127.0.0.1:%d", ob.Port)
  3704  	clientB := natsConnect(t, bURL)
  3705  	defer clientB.Close()
  3706  
  3707  	subB := natsSubSync(t, clientB, "reply")
  3708  	natsFlush(t, clientB)
  3709  
  3710  	for i := 1; i <= 2; i++ {
  3711  		// Send the request from clientB on foo.request,
  3712  		natsPubReq(t, clientB, "foo.request", "reply", []byte("hi"))
  3713  		natsFlush(t, clientB)
  3714  
  3715  		// Expect the request on A
  3716  		msg, err := subA.NextMsg(time.Second)
  3717  		if err != nil {
  3718  			t.Fatalf("subA failed to get request: %v", err)
  3719  		}
  3720  		if msg.Subject != "test.request" || string(msg.Data) != "hi" {
  3721  			t.Fatalf("Unexpected message: %v", msg)
  3722  		}
  3723  		if msg.Reply == "reply" {
  3724  			t.Fatalf("Expected randomized reply, but got original")
  3725  		}
  3726  
  3727  		// Check for duplicate message
  3728  		if msg, err := subA.NextMsg(250 * time.Millisecond); err != nats.ErrTimeout {
  3729  			t.Fatalf("Unexpected msg: %v", msg)
  3730  		}
  3731  
  3732  		// Send reply
  3733  		natsPub(t, clientA, msg.Reply, []byte("ok"))
  3734  		natsFlush(t, clientA)
  3735  
  3736  		msg, err = subB.NextMsg(time.Second)
  3737  		if err != nil {
  3738  			t.Fatalf("subB failed to get reply: %v", err)
  3739  		}
  3740  		if msg.Subject != "reply" || string(msg.Data) != "ok" {
  3741  			t.Fatalf("Unexpected message: %v", msg)
  3742  		}
  3743  
  3744  		// Check for duplicate message
  3745  		if msg, err := subB.NextMsg(250 * time.Millisecond); err != nats.ErrTimeout {
  3746  			t.Fatalf("Unexpected msg: %v", msg)
  3747  		}
  3748  
  3749  		expected := int64(i * 2)
  3750  		vz, _ := sa.Varz(nil)
  3751  		if vz.OutMsgs != expected {
  3752  			t.Fatalf("Expected %d outMsgs for A, got %v", expected, vz.OutMsgs)
  3753  		}
  3754  
  3755  		// For B, we expect it to send to gateway on the two subjects: test.request
  3756  		// and foo.request then send the reply to the client and optimistically
  3757  		// to the other gateway.
  3758  		if i == 1 {
  3759  			expected = 4
  3760  		} else {
  3761  			// The second time, one of the accounts will be suppressed and the reply going
  3762  			// back so we should only get 2 more messages.
  3763  			expected = 6
  3764  		}
  3765  		vz, _ = sb.Varz(nil)
  3766  		if vz.OutMsgs != expected {
  3767  			t.Fatalf("Expected %d outMsgs for B, got %v", expected, vz.OutMsgs)
  3768  		}
  3769  	}
  3770  
  3771  	checkFor(t, 2*time.Second, 15*time.Millisecond, func() error {
  3772  		if ts := fooA.TotalSubs(); ts != 1 {
  3773  			return fmt.Errorf("Expected one sub to be left on fooA, but got %d", ts)
  3774  		}
  3775  		return nil
  3776  	})
  3777  
  3778  	// Speed up exiration
  3779  	err := fooA.SetServiceExportResponseThreshold("test.request", 50*time.Millisecond)
  3780  	if err != nil {
  3781  		t.Fatalf("Error setting response threshold: %v", err)
  3782  	}
  3783  
  3784  	// Send 100 requests from clientB on foo.request,
  3785  	for i := 0; i < 100; i++ {
  3786  		natsPubReq(t, clientB, "foo.request", "reply", []byte("hi"))
  3787  	}
  3788  	natsFlush(t, clientB)
  3789  
  3790  	// Consume the requests, but don't reply to them...
  3791  	for i := 0; i < 100; i++ {
  3792  		if _, err := subA.NextMsg(time.Second); err != nil {
  3793  			t.Fatalf("subA did not receive request: %v", err)
  3794  		}
  3795  	}
  3796  
  3797  	// These reply subjects will be dangling off of $foo account on serverA.
  3798  	// Remove our service endpoint and wait for the dangling replies to go to zero.
  3799  	natsUnsub(t, subA)
  3800  	natsFlush(t, clientA)
  3801  
  3802  	checkFor(t, 2*time.Second, 10*time.Millisecond, func() error {
  3803  		if ts := fooA.TotalSubs(); ts != 0 {
  3804  			return fmt.Errorf("Number of subs is %d, should be zero", ts)
  3805  		}
  3806  		return nil
  3807  	})
  3808  
  3809  	// Repeat similar test but without the small TTL and verify
  3810  	// that if B is shutdown, the dangling subs for replies are
  3811  	// cleared from the account sublist.
  3812  	err = fooA.SetServiceExportResponseThreshold("test.request", 10*time.Second)
  3813  	if err != nil {
  3814  		t.Fatalf("Error setting response threshold: %v", err)
  3815  	}
  3816  
  3817  	subA = natsSubSync(t, clientA, "test.request")
  3818  	natsFlush(t, clientA)
  3819  
  3820  	// Send 100 requests from clientB on foo.request,
  3821  	for i := 0; i < 100; i++ {
  3822  		natsPubReq(t, clientB, "foo.request", "reply", []byte("hi"))
  3823  	}
  3824  	natsFlush(t, clientB)
  3825  
  3826  	// Consume the requests, but don't reply to them...
  3827  	for i := 0; i < 100; i++ {
  3828  		if _, err := subA.NextMsg(time.Second); err != nil {
  3829  			t.Fatalf("subA did not receive request: %v", err)
  3830  		}
  3831  	}
  3832  
  3833  	// Shutdown B
  3834  	clientB.Close()
  3835  	sb.Shutdown()
  3836  
  3837  	// Close our last sub
  3838  	natsUnsub(t, subA)
  3839  	natsFlush(t, clientA)
  3840  
  3841  	// Verify that they are gone before the 10 sec TTL
  3842  	checkFor(t, 2*time.Second, 10*time.Millisecond, func() error {
  3843  		if ts := fooA.TotalSubs(); ts != 0 {
  3844  			return fmt.Errorf("Number of subs is %d, should be zero", ts)
  3845  		}
  3846  		return nil
  3847  	})
  3848  
  3849  	// Check that this all work in interest-only mode
  3850  	sb = runGatewayServer(ob)
  3851  	defer sb.Shutdown()
  3852  
  3853  	fooB, _ = sb.LookupAccount("$foo")
  3854  	barB, _ = sb.LookupAccount("$bar")
  3855  
  3856  	// Add in the service export for the requests. Make it public.
  3857  	fooB.AddServiceExport("test.request", nil)
  3858  	// Add import abilities to server B's bar account from foo.
  3859  	if err := barB.AddServiceImport(fooB, "foo.request", "test.request"); err != nil {
  3860  		t.Fatalf("Error adding service import: %v", err)
  3861  	}
  3862  
  3863  	waitForOutboundGateways(t, sa, 1, 2*time.Second)
  3864  	waitForOutboundGateways(t, sb, 1, 2*time.Second)
  3865  	waitForInboundGateways(t, sa, 1, 2*time.Second)
  3866  	waitForInboundGateways(t, sb, 1, 2*time.Second)
  3867  
  3868  	// We need at least a subscription on A otherwise when publishing
  3869  	// to subjects with no interest we would simply get an A-
  3870  	natsSubSync(t, clientA, "not.used")
  3871  
  3872  	// Create a client on B that will use account $foo
  3873  	bURL = fmt.Sprintf("nats://clientBFoo:password@127.0.0.1:%d", ob.Port)
  3874  	clientB = natsConnect(t, bURL)
  3875  	defer clientB.Close()
  3876  
  3877  	// First flood with subjects that remote gw is not interested
  3878  	// so we switch to interest-only.
  3879  	for i := 0; i < 1100; i++ {
  3880  		natsPub(t, clientB, fmt.Sprintf("no.interest.%d", i), []byte("hello"))
  3881  	}
  3882  	natsFlush(t, clientB)
  3883  
  3884  	checkGWInterestOnlyMode(t, sb, "A", "$foo")
  3885  
  3886  	// Go back to clientB on $bar.
  3887  	clientB.Close()
  3888  	bURL = fmt.Sprintf("nats://clientB:password@127.0.0.1:%d", ob.Port)
  3889  	clientB = natsConnect(t, bURL)
  3890  	defer clientB.Close()
  3891  
  3892  	subA = natsSubSync(t, clientA, "test.request")
  3893  	natsFlush(t, clientA)
  3894  
  3895  	subB = natsSubSync(t, clientB, "reply")
  3896  	natsFlush(t, clientB)
  3897  
  3898  	// Sine it is interest-only, B should receive an interest
  3899  	// on $foo test.request
  3900  	checkGWInterestOnlyModeInterestOn(t, sb, "A", "$foo", "test.request")
  3901  
  3902  	// Send the request from clientB on foo.request,
  3903  	natsPubReq(t, clientB, "foo.request", "reply", []byte("hi"))
  3904  	natsFlush(t, clientB)
  3905  
  3906  	// Expect the request on A
  3907  	msg, err := subA.NextMsg(time.Second)
  3908  	if err != nil {
  3909  		t.Fatalf("subA failed to get request: %v", err)
  3910  	}
  3911  	if msg.Subject != "test.request" || string(msg.Data) != "hi" {
  3912  		t.Fatalf("Unexpected message: %v", msg)
  3913  	}
  3914  	if msg.Reply == "reply" {
  3915  		t.Fatalf("Expected randomized reply, but got original")
  3916  	}
  3917  
  3918  	// Check for duplicate message
  3919  	if msg, err := subA.NextMsg(100 * time.Millisecond); err != nats.ErrTimeout {
  3920  		t.Fatalf("Unexpected msg: %v", msg)
  3921  	}
  3922  
  3923  	// Send reply
  3924  	natsPub(t, clientA, msg.Reply, []byte("ok"))
  3925  	natsFlush(t, clientA)
  3926  
  3927  	msg, err = subB.NextMsg(time.Second)
  3928  	if err != nil {
  3929  		t.Fatalf("subB failed to get reply: %v", err)
  3930  	}
  3931  	if msg.Subject != "reply" || string(msg.Data) != "ok" {
  3932  		t.Fatalf("Unexpected message: %v", msg)
  3933  	}
  3934  
  3935  	// Check for duplicate message
  3936  	if msg, err := subB.NextMsg(100 * time.Millisecond); err != nats.ErrTimeout {
  3937  		t.Fatalf("Unexpected msg: %v", msg)
  3938  	}
  3939  }
  3940  
  3941  func TestGatewayServiceImportWithQueue(t *testing.T) {
  3942  	GatewayDoNotForceInterestOnlyMode(true)
  3943  	defer GatewayDoNotForceInterestOnlyMode(false)
  3944  
  3945  	oa := testDefaultOptionsForGateway("A")
  3946  	setAccountUserPassInOptions(oa, "$foo", "clientA", "password")
  3947  	setAccountUserPassInOptions(oa, "$bar", "yyyyyyy", "password")
  3948  	sa := runGatewayServer(oa)
  3949  	defer sa.Shutdown()
  3950  
  3951  	ob := testGatewayOptionsFromToWithServers(t, "B", "A", sa)
  3952  	setAccountUserPassInOptions(ob, "$foo", "clientBFoo", "password")
  3953  	setAccountUserPassInOptions(ob, "$bar", "clientB", "password")
  3954  	sb := runGatewayServer(ob)
  3955  	defer sb.Shutdown()
  3956  
  3957  	waitForOutboundGateways(t, sa, 1, time.Second)
  3958  	waitForOutboundGateways(t, sb, 1, time.Second)
  3959  	waitForInboundGateways(t, sa, 1, time.Second)
  3960  	waitForInboundGateways(t, sb, 1, time.Second)
  3961  
  3962  	// Get accounts
  3963  	fooA, _ := sa.LookupAccount("$foo")
  3964  	barA, _ := sa.LookupAccount("$bar")
  3965  	fooB, _ := sb.LookupAccount("$foo")
  3966  	barB, _ := sb.LookupAccount("$bar")
  3967  
  3968  	// Add in the service export for the requests. Make it public.
  3969  	fooA.AddServiceExport("test.request", nil)
  3970  	fooB.AddServiceExport("test.request", nil)
  3971  
  3972  	// Add import abilities to server B's bar account from foo.
  3973  	if err := barB.AddServiceImport(fooB, "foo.request", "test.request"); err != nil {
  3974  		t.Fatalf("Error adding service import: %v", err)
  3975  	}
  3976  	// Same on A.
  3977  	if err := barA.AddServiceImport(fooA, "foo.request", "test.request"); err != nil {
  3978  		t.Fatalf("Error adding service import: %v", err)
  3979  	}
  3980  
  3981  	// clientA will be connected to srvA and be the service endpoint and responder.
  3982  	aURL := fmt.Sprintf("nats://clientA:password@127.0.0.1:%d", oa.Port)
  3983  	clientA := natsConnect(t, aURL)
  3984  	defer clientA.Close()
  3985  
  3986  	subA := natsQueueSubSync(t, clientA, "test.request", "queue")
  3987  	natsFlush(t, clientA)
  3988  
  3989  	// Now setup client B on srvB who will do a sub from account $bar
  3990  	// that should map account $foo's foo subject.
  3991  	bURL := fmt.Sprintf("nats://clientB:password@127.0.0.1:%d", ob.Port)
  3992  	clientB := natsConnect(t, bURL)
  3993  	defer clientB.Close()
  3994  
  3995  	subB := natsQueueSubSync(t, clientB, "reply", "queue2")
  3996  	natsFlush(t, clientB)
  3997  
  3998  	// Wait for queue interest on test.request from A to be registered
  3999  	// on server B.
  4000  	checkForRegisteredQSubInterest(t, sb, "A", "$foo", "test.request", 1, time.Second)
  4001  
  4002  	for i := 0; i < 2; i++ {
  4003  		// Send the request from clientB on foo.request,
  4004  		natsPubReq(t, clientB, "foo.request", "reply", []byte("hi"))
  4005  		natsFlush(t, clientB)
  4006  
  4007  		// Expect the request on A
  4008  		msg, err := subA.NextMsg(time.Second)
  4009  		if err != nil {
  4010  			t.Fatalf("subA failed to get request: %v", err)
  4011  		}
  4012  		if msg.Subject != "test.request" || string(msg.Data) != "hi" {
  4013  			t.Fatalf("Unexpected message: %v", msg)
  4014  		}
  4015  		if msg.Reply == "reply" {
  4016  			t.Fatalf("Expected randomized reply, but got original")
  4017  		}
  4018  		// Check for duplicate message
  4019  		if msg, err := subA.NextMsg(100 * time.Millisecond); err != nats.ErrTimeout {
  4020  			t.Fatalf("Unexpected msg: %v", msg)
  4021  		}
  4022  
  4023  		// Send reply
  4024  		natsPub(t, clientA, msg.Reply, []byte("ok"))
  4025  		natsFlush(t, clientA)
  4026  
  4027  		msg, err = subB.NextMsg(time.Second)
  4028  		if err != nil {
  4029  			t.Fatalf("subB failed to get reply: %v", err)
  4030  		}
  4031  		if msg.Subject != "reply" || string(msg.Data) != "ok" {
  4032  			t.Fatalf("Unexpected message: %v", msg)
  4033  		}
  4034  		// Check for duplicate message
  4035  		if msg, err := subB.NextMsg(250 * time.Millisecond); err != nats.ErrTimeout {
  4036  			t.Fatalf("Unexpected msg: %v", msg)
  4037  		}
  4038  
  4039  		expected := int64((i + 1) * 2)
  4040  		vz, _ := sa.Varz(nil)
  4041  		if vz.OutMsgs != expected {
  4042  			t.Fatalf("Expected %d outMsgs for A, got %v", expected, vz.OutMsgs)
  4043  		}
  4044  
  4045  		// For B, we expect it to send to gateway on the two subjects: test.request
  4046  		// and foo.request then send the reply to the client and optimistically
  4047  		// to the other gateway.
  4048  		if i == 0 {
  4049  			expected = 4
  4050  		} else {
  4051  			// The second time, one of the accounts will be suppressed and the reply going
  4052  			// back so we should get only 2 more messages.
  4053  			expected = 6
  4054  		}
  4055  		vz, _ = sb.Varz(nil)
  4056  		if vz.OutMsgs != expected {
  4057  			t.Fatalf("Expected %d outMsgs for B, got %v", expected, vz.OutMsgs)
  4058  		}
  4059  	}
  4060  
  4061  	checkFor(t, 2*time.Second, 15*time.Millisecond, func() error {
  4062  		if ts := fooA.TotalSubs(); ts != 1 {
  4063  			return fmt.Errorf("Expected one sub to be left on fooA, but got %d", ts)
  4064  		}
  4065  		return nil
  4066  	})
  4067  
  4068  	// Speed up exiration
  4069  	err := fooA.SetServiceExportResponseThreshold("test.request", 10*time.Millisecond)
  4070  	if err != nil {
  4071  		t.Fatalf("Error setting response threshold: %v", err)
  4072  	}
  4073  
  4074  	// Send 100 requests from clientB on foo.request,
  4075  	for i := 0; i < 100; i++ {
  4076  		natsPubReq(t, clientB, "foo.request", "reply", []byte("hi"))
  4077  	}
  4078  	natsFlush(t, clientB)
  4079  
  4080  	// Consume the requests, but don't reply to them...
  4081  	for i := 0; i < 100; i++ {
  4082  		if _, err := subA.NextMsg(time.Second); err != nil {
  4083  			t.Fatalf("subA did not receive request: %v", err)
  4084  		}
  4085  	}
  4086  
  4087  	// These reply subjects will be dangling off of $foo account on serverA.
  4088  	// Remove our service endpoint and wait for the dangling replies to go to zero.
  4089  	natsUnsub(t, subA)
  4090  	natsFlush(t, clientA)
  4091  
  4092  	checkFor(t, 2*time.Second, 10*time.Millisecond, func() error {
  4093  		if ts := fooA.TotalSubs(); ts != 0 {
  4094  			return fmt.Errorf("Number of subs is %d, should be zero", ts)
  4095  		}
  4096  		return nil
  4097  	})
  4098  	checkForRegisteredQSubInterest(t, sb, "A", "$foo", "test.request", 0, time.Second)
  4099  
  4100  	// Repeat similar test but without the small TTL and verify
  4101  	// that if B is shutdown, the dangling subs for replies are
  4102  	// cleared from the account sublist.
  4103  	err = fooA.SetServiceExportResponseThreshold("test.request", 10*time.Second)
  4104  	if err != nil {
  4105  		t.Fatalf("Error setting response threshold: %v", err)
  4106  	}
  4107  
  4108  	subA = natsQueueSubSync(t, clientA, "test.request", "queue")
  4109  	natsFlush(t, clientA)
  4110  	checkForRegisteredQSubInterest(t, sb, "A", "$foo", "test.request", 1, time.Second)
  4111  
  4112  	// Send 100 requests from clientB on foo.request,
  4113  	for i := 0; i < 100; i++ {
  4114  		natsPubReq(t, clientB, "foo.request", "reply", []byte("hi"))
  4115  	}
  4116  	natsFlush(t, clientB)
  4117  
  4118  	// Consume the requests, but don't reply to them...
  4119  	for i := 0; i < 100; i++ {
  4120  		if _, err := subA.NextMsg(time.Second); err != nil {
  4121  			t.Fatalf("subA did not receive request %d: %v", i+1, err)
  4122  		}
  4123  	}
  4124  
  4125  	// Shutdown B
  4126  	clientB.Close()
  4127  	sb.Shutdown()
  4128  
  4129  	// Close our last sub
  4130  	natsUnsub(t, subA)
  4131  	natsFlush(t, clientA)
  4132  
  4133  	// Verify that they are gone before the 10 sec TTL
  4134  	checkFor(t, 2*time.Second, 10*time.Millisecond, func() error {
  4135  		if ts := fooA.TotalSubs(); ts != 0 {
  4136  			return fmt.Errorf("Number of subs is %d, should be zero", ts)
  4137  		}
  4138  		return nil
  4139  	})
  4140  
  4141  	// Check that this all work in interest-only mode
  4142  	sb = runGatewayServer(ob)
  4143  	defer sb.Shutdown()
  4144  
  4145  	fooB, _ = sb.LookupAccount("$foo")
  4146  	barB, _ = sb.LookupAccount("$bar")
  4147  
  4148  	// Add in the service export for the requests. Make it public.
  4149  	fooB.AddServiceExport("test.request", nil)
  4150  	// Add import abilities to server B's bar account from foo.
  4151  	if err := barB.AddServiceImport(fooB, "foo.request", "test.request"); err != nil {
  4152  		t.Fatalf("Error adding service import: %v", err)
  4153  	}
  4154  
  4155  	waitForOutboundGateways(t, sa, 1, 2*time.Second)
  4156  	waitForOutboundGateways(t, sb, 1, 2*time.Second)
  4157  	waitForInboundGateways(t, sa, 1, 2*time.Second)
  4158  	waitForInboundGateways(t, sb, 1, 2*time.Second)
  4159  
  4160  	// We need at least a subscription on A otherwise when publishing
  4161  	// to subjects with no interest we would simply get an A-
  4162  	natsSubSync(t, clientA, "not.used")
  4163  
  4164  	// Create a client on B that will use account $foo
  4165  	bURL = fmt.Sprintf("nats://clientBFoo:password@127.0.0.1:%d", ob.Port)
  4166  	clientB = natsConnect(t, bURL)
  4167  	defer clientB.Close()
  4168  
  4169  	// First flood with subjects that remote gw is not interested
  4170  	// so we switch to interest-only.
  4171  	for i := 0; i < 1100; i++ {
  4172  		natsPub(t, clientB, fmt.Sprintf("no.interest.%d", i), []byte("hello"))
  4173  	}
  4174  	natsFlush(t, clientB)
  4175  
  4176  	checkGWInterestOnlyMode(t, sb, "A", "$foo")
  4177  
  4178  	// Go back to clientB on $bar.
  4179  	clientB.Close()
  4180  	bURL = fmt.Sprintf("nats://clientB:password@127.0.0.1:%d", ob.Port)
  4181  	clientB = natsConnect(t, bURL)
  4182  	defer clientB.Close()
  4183  
  4184  	subA = natsSubSync(t, clientA, "test.request")
  4185  	natsFlush(t, clientA)
  4186  
  4187  	subB = natsSubSync(t, clientB, "reply")
  4188  	natsFlush(t, clientB)
  4189  
  4190  	// Sine it is interest-only, B should receive an interest
  4191  	// on $foo test.request
  4192  	checkGWInterestOnlyModeInterestOn(t, sb, "A", "$foo", "test.request")
  4193  
  4194  	// Send the request from clientB on foo.request,
  4195  	natsPubReq(t, clientB, "foo.request", "reply", []byte("hi"))
  4196  	natsFlush(t, clientB)
  4197  
  4198  	// Expect the request on A
  4199  	msg, err := subA.NextMsg(time.Second)
  4200  	if err != nil {
  4201  		t.Fatalf("subA failed to get request: %v", err)
  4202  	}
  4203  	if msg.Subject != "test.request" || string(msg.Data) != "hi" {
  4204  		t.Fatalf("Unexpected message: %v", msg)
  4205  	}
  4206  	if msg.Reply == "reply" {
  4207  		t.Fatalf("Expected randomized reply, but got original")
  4208  	}
  4209  
  4210  	// Check for duplicate message
  4211  	if msg, err := subA.NextMsg(100 * time.Millisecond); err != nats.ErrTimeout {
  4212  		t.Fatalf("Unexpected msg: %v", msg)
  4213  	}
  4214  
  4215  	// Send reply
  4216  	natsPub(t, clientA, msg.Reply, []byte("ok"))
  4217  	natsFlush(t, clientA)
  4218  
  4219  	msg, err = subB.NextMsg(time.Second)
  4220  	if err != nil {
  4221  		t.Fatalf("subB failed to get reply: %v", err)
  4222  	}
  4223  	if msg.Subject != "reply" || string(msg.Data) != "ok" {
  4224  		t.Fatalf("Unexpected message: %v", msg)
  4225  	}
  4226  
  4227  	// Check for duplicate message
  4228  	if msg, err := subB.NextMsg(100 * time.Millisecond); err != nats.ErrTimeout {
  4229  		t.Fatalf("Unexpected msg: %v", msg)
  4230  	}
  4231  }
  4232  
  4233  func ensureGWConnectTo(t *testing.T, s *Server, remoteGWName string, remoteGWServer *Server) {
  4234  	t.Helper()
  4235  	var good bool
  4236  	for i := 0; !good && (i < 3); i++ {
  4237  		checkFor(t, 2*time.Second, 15*time.Millisecond, func() error {
  4238  			if s.numOutboundGateways() == 0 {
  4239  				return fmt.Errorf("Still no gw outbound connection")
  4240  			}
  4241  			return nil
  4242  		})
  4243  		ogc := s.getOutboundGatewayConnection(remoteGWName)
  4244  		ogc.mu.Lock()
  4245  		name := ogc.opts.Name
  4246  		nc := ogc.nc
  4247  		ogc.mu.Unlock()
  4248  		if name != remoteGWServer.ID() {
  4249  			rg := s.getRemoteGateway(remoteGWName)
  4250  			goodURL := remoteGWServer.getGatewayURL()
  4251  			rg.Lock()
  4252  			for u := range rg.urls {
  4253  				if u != goodURL {
  4254  					delete(rg.urls, u)
  4255  				}
  4256  			}
  4257  			rg.Unlock()
  4258  			if nc != nil {
  4259  				nc.Close()
  4260  			}
  4261  		} else {
  4262  			good = true
  4263  		}
  4264  	}
  4265  	if !good {
  4266  		t.Fatalf("Could not ensure that server connects to remote gateway %q at URL %q",
  4267  			remoteGWName, remoteGWServer.getGatewayURL())
  4268  	}
  4269  }
  4270  
  4271  func TestGatewayServiceImportComplexSetup(t *testing.T) {
  4272  	// This test will have following setup:
  4273  	//
  4274  	//						     |- responder (subs  to "$foo test.request")
  4275  	//                           |            (sends to "$foo _R_.xxxx")
  4276  	//              route        v
  4277  	//   [A1]<----------------->[A2]
  4278  	//   ^  |^                    |
  4279  	//   |gw| \______gw________ gw|
  4280  	//   |  v                  \  v
  4281  	//   [B1]<----------------->[B2]
  4282  	//    ^         route
  4283  	//    |
  4284  	//    |_ requestor (sends "$bar foo.request reply")
  4285  	//
  4286  
  4287  	// Setup first A1 and B1 to ensure that they have GWs
  4288  	// connections as described above.
  4289  
  4290  	oa1 := testDefaultOptionsForGateway("A")
  4291  	setAccountUserPassInOptions(oa1, "$foo", "clientA", "password")
  4292  	setAccountUserPassInOptions(oa1, "$bar", "yyyyyyy", "password")
  4293  	sa1 := runGatewayServer(oa1)
  4294  	defer sa1.Shutdown()
  4295  
  4296  	ob1 := testGatewayOptionsFromToWithServers(t, "B", "A", sa1)
  4297  	setAccountUserPassInOptions(ob1, "$foo", "xxxxxxx", "password")
  4298  	setAccountUserPassInOptions(ob1, "$bar", "clientB", "password")
  4299  	sb1 := runGatewayServer(ob1)
  4300  	defer sb1.Shutdown()
  4301  
  4302  	waitForOutboundGateways(t, sa1, 1, time.Second)
  4303  	waitForOutboundGateways(t, sb1, 1, time.Second)
  4304  
  4305  	waitForInboundGateways(t, sa1, 1, time.Second)
  4306  	waitForInboundGateways(t, sb1, 1, time.Second)
  4307  
  4308  	ob2 := testGatewayOptionsFromToWithServers(t, "B", "A", sa1)
  4309  	ob2.Routes = RoutesFromStr(fmt.Sprintf("nats://127.0.0.1:%d", sb1.ClusterAddr().Port))
  4310  	setAccountUserPassInOptions(ob2, "$foo", "clientBFoo", "password")
  4311  	setAccountUserPassInOptions(ob2, "$bar", "clientB", "password")
  4312  	ob2.gatewaysSolicitDelay = time.Nanosecond // 0 would be default, so nano to connect asap
  4313  	sb2 := runGatewayServer(ob2)
  4314  	defer sb2.Shutdown()
  4315  
  4316  	waitForOutboundGateways(t, sa1, 1, time.Second)
  4317  	waitForOutboundGateways(t, sb1, 1, time.Second)
  4318  	waitForOutboundGateways(t, sb2, 1, 2*time.Second)
  4319  
  4320  	waitForInboundGateways(t, sa1, 2, time.Second)
  4321  	waitForInboundGateways(t, sb1, 1, time.Second)
  4322  	waitForInboundGateways(t, sb2, 0, time.Second)
  4323  
  4324  	oa2 := testGatewayOptionsFromToWithServers(t, "A", "B", sb2)
  4325  	oa2.Routes = RoutesFromStr(fmt.Sprintf("nats://127.0.0.1:%d", sa1.ClusterAddr().Port))
  4326  	setAccountUserPassInOptions(oa2, "$foo", "clientA", "password")
  4327  	setAccountUserPassInOptions(oa2, "$bar", "yyyyyyy", "password")
  4328  	oa2.gatewaysSolicitDelay = time.Nanosecond // 0 would be default, so nano to connect asap
  4329  	sa2 := runGatewayServer(oa2)
  4330  	defer sa2.Shutdown()
  4331  
  4332  	ensureGWConnectTo(t, sa2, "B", sb2)
  4333  
  4334  	checkClusterFormed(t, sa1, sa2)
  4335  	checkClusterFormed(t, sb1, sb2)
  4336  
  4337  	waitForOutboundGateways(t, sa1, 1, time.Second)
  4338  	waitForOutboundGateways(t, sb1, 1, time.Second)
  4339  	waitForOutboundGateways(t, sb2, 1, time.Second)
  4340  	waitForOutboundGateways(t, sa2, 1, 2*time.Second)
  4341  
  4342  	waitForInboundGateways(t, sa1, 2, time.Second)
  4343  	waitForInboundGateways(t, sb1, 1, time.Second)
  4344  	waitForInboundGateways(t, sb2, 1, 2*time.Second)
  4345  	waitForInboundGateways(t, sa2, 0, time.Second)
  4346  
  4347  	// Verification that we have what we wanted
  4348  	c := sa2.getOutboundGatewayConnection("B")
  4349  	if c == nil || c.opts.Name != sb2.ID() {
  4350  		t.Fatalf("A2 does not have outbound to B2")
  4351  	}
  4352  	c = getInboundGatewayConnection(sa2, "A")
  4353  	if c != nil {
  4354  		t.Fatalf("Bad setup")
  4355  	}
  4356  	c = sb2.getOutboundGatewayConnection("A")
  4357  	if c == nil || c.opts.Name != sa1.ID() {
  4358  		t.Fatalf("B2 does not have outbound to A1")
  4359  	}
  4360  	c = getInboundGatewayConnection(sb2, "B")
  4361  	if c == nil || c.opts.Name != sa2.ID() {
  4362  		t.Fatalf("Bad setup")
  4363  	}
  4364  
  4365  	// Ok, so now that we have proper setup, do actual test!
  4366  
  4367  	// Get accounts
  4368  	fooA1, _ := sa1.LookupAccount("$foo")
  4369  	barA1, _ := sa1.LookupAccount("$bar")
  4370  	fooA2, _ := sa2.LookupAccount("$foo")
  4371  	barA2, _ := sa2.LookupAccount("$bar")
  4372  
  4373  	fooB1, _ := sb1.LookupAccount("$foo")
  4374  	barB1, _ := sb1.LookupAccount("$bar")
  4375  	fooB2, _ := sb2.LookupAccount("$foo")
  4376  	barB2, _ := sb2.LookupAccount("$bar")
  4377  
  4378  	// Add in the service export for the requests. Make it public.
  4379  	fooA1.AddServiceExport("test.request", nil)
  4380  	fooA2.AddServiceExport("test.request", nil)
  4381  	fooB1.AddServiceExport("test.request", nil)
  4382  	fooB2.AddServiceExport("test.request", nil)
  4383  
  4384  	// Add import abilities to server B's bar account from foo.
  4385  	if err := barB1.AddServiceImport(fooB1, "foo.request", "test.request"); err != nil {
  4386  		t.Fatalf("Error adding service import: %v", err)
  4387  	}
  4388  	if err := barB2.AddServiceImport(fooB2, "foo.request", "test.request"); err != nil {
  4389  		t.Fatalf("Error adding service import: %v", err)
  4390  	}
  4391  	// Same on A.
  4392  	if err := barA1.AddServiceImport(fooA1, "foo.request", "test.request"); err != nil {
  4393  		t.Fatalf("Error adding service import: %v", err)
  4394  	}
  4395  	if err := barA2.AddServiceImport(fooA2, "foo.request", "test.request"); err != nil {
  4396  		t.Fatalf("Error adding service import: %v", err)
  4397  	}
  4398  
  4399  	// clientA will be connected to A2 and be the service endpoint and responder.
  4400  	a2URL := fmt.Sprintf("nats://clientA:password@127.0.0.1:%d", oa2.Port)
  4401  	clientA := natsConnect(t, a2URL)
  4402  	defer clientA.Close()
  4403  
  4404  	subA := natsSubSync(t, clientA, "test.request")
  4405  	natsFlush(t, clientA)
  4406  
  4407  	// Now setup client B on B1 who will do a sub from account $bar
  4408  	// that should map account $foo's foo subject.
  4409  	b1URL := fmt.Sprintf("nats://clientB:password@127.0.0.1:%d", ob1.Port)
  4410  	clientB := natsConnect(t, b1URL)
  4411  	defer clientB.Close()
  4412  
  4413  	subB := natsSubSync(t, clientB, "reply")
  4414  	natsFlush(t, clientB)
  4415  
  4416  	var msg *nats.Msg
  4417  	var err error
  4418  	for attempts := 1; attempts <= 2; attempts++ {
  4419  		// Send the request from clientB on foo.request,
  4420  		natsPubReq(t, clientB, "foo.request", "reply", []byte("hi"))
  4421  		natsFlush(t, clientB)
  4422  
  4423  		// Expect the request on A
  4424  		msg, err = subA.NextMsg(time.Second)
  4425  		if err != nil {
  4426  			if attempts == 1 {
  4427  				// Since we are in interestOnly mode, it is possible
  4428  				// that server B did not receive the subscription
  4429  				// interest yet, so try again.
  4430  				continue
  4431  			}
  4432  			t.Fatalf("subA failed to get request: %v", err)
  4433  		}
  4434  		if msg.Subject != "test.request" || string(msg.Data) != "hi" {
  4435  			t.Fatalf("Unexpected message: %v", msg)
  4436  		}
  4437  		if msg.Reply == "reply" {
  4438  			t.Fatalf("Expected randomized reply, but got original")
  4439  		}
  4440  	}
  4441  	// Make sure we don't receive a second copy
  4442  	if msg, err := subA.NextMsg(100 * time.Millisecond); err != nats.ErrTimeout {
  4443  		t.Fatalf("Received unexpected message: %v", msg)
  4444  	}
  4445  
  4446  	// Send reply
  4447  	natsPub(t, clientA, msg.Reply, []byte("ok"))
  4448  	natsFlush(t, clientA)
  4449  
  4450  	msg, err = subB.NextMsg(time.Second)
  4451  	if err != nil {
  4452  		t.Fatalf("subB failed to get reply: %v", err)
  4453  	}
  4454  	if msg.Subject != "reply" || string(msg.Data) != "ok" {
  4455  		t.Fatalf("Unexpected message: %v", msg)
  4456  	}
  4457  	// Make sure we don't receive a second copy
  4458  	if msg, err := subB.NextMsg(100 * time.Millisecond); err != nats.ErrTimeout {
  4459  		t.Fatalf("Received unexpected message: %v", msg)
  4460  	}
  4461  
  4462  	checkSubs := func(t *testing.T, acc *Account, srvName string, expected int) {
  4463  		t.Helper()
  4464  		checkFor(t, 2*time.Second, 10*time.Millisecond, func() error {
  4465  			if ts := acc.TotalSubs(); ts != expected {
  4466  				return fmt.Errorf("Number of subs is %d on acc=%s srv=%s, should be %v", ts, acc.Name, srvName, expected)
  4467  			}
  4468  			return nil
  4469  		})
  4470  	}
  4471  	checkSubs(t, fooA1, "A1", 1)
  4472  	checkSubs(t, barA1, "A1", 1)
  4473  	checkSubs(t, fooA2, "A2", 1)
  4474  	checkSubs(t, barA2, "A2", 1)
  4475  	checkSubs(t, fooB1, "B1", 1)
  4476  	checkSubs(t, barB1, "B1", 2)
  4477  	checkSubs(t, fooB2, "B2", 1)
  4478  	checkSubs(t, barB2, "B2", 2)
  4479  
  4480  	// Speed up exiration
  4481  	err = fooA2.SetServiceExportResponseThreshold("test.request", 10*time.Millisecond)
  4482  	if err != nil {
  4483  		t.Fatalf("Error setting response threshold: %v", err)
  4484  	}
  4485  	err = fooB1.SetServiceExportResponseThreshold("test.request", 10*time.Millisecond)
  4486  	if err != nil {
  4487  		t.Fatalf("Error setting response threshold: %v", err)
  4488  	}
  4489  
  4490  	// Send 100 requests from clientB on foo.request,
  4491  	for i := 0; i < 100; i++ {
  4492  		natsPubReq(t, clientB, "foo.request", "reply", []byte("hi"))
  4493  	}
  4494  	natsFlush(t, clientB)
  4495  
  4496  	// Consume the requests, but don't reply to them...
  4497  	for i := 0; i < 100; i++ {
  4498  		if _, err := subA.NextMsg(time.Second); err != nil {
  4499  			t.Fatalf("subA did not receive request: %v", err)
  4500  		}
  4501  	}
  4502  
  4503  	// Unsubsribe all and ensure counts go to 0.
  4504  	natsUnsub(t, subA)
  4505  	natsFlush(t, clientA)
  4506  	natsUnsub(t, subB)
  4507  	natsFlush(t, clientB)
  4508  
  4509  	// We should expire because ttl.
  4510  	checkFor(t, 2*time.Second, 10*time.Millisecond, func() error {
  4511  		if nr := len(fooA1.exports.responses); nr != 0 {
  4512  			return fmt.Errorf("Number of responses is %d", nr)
  4513  		}
  4514  		return nil
  4515  	})
  4516  
  4517  	checkSubs(t, fooA1, "A1", 0)
  4518  	checkSubs(t, fooA2, "A2", 0)
  4519  	checkSubs(t, fooB1, "B1", 1)
  4520  	checkSubs(t, fooB2, "B2", 1)
  4521  
  4522  	checkSubs(t, barA1, "A1", 1)
  4523  	checkSubs(t, barA2, "A2", 1)
  4524  	checkSubs(t, barB1, "B1", 1)
  4525  	checkSubs(t, barB2, "B2", 1)
  4526  
  4527  	// Check that this all work in interest-only mode.
  4528  
  4529  	// We need at least a subscription on B2 otherwise when publishing
  4530  	// to subjects with no interest we would simply get an A-
  4531  	b2URL := fmt.Sprintf("nats://clientBFoo:password@127.0.0.1:%d", ob2.Port)
  4532  	clientB2 := natsConnect(t, b2URL)
  4533  	defer clientB2.Close()
  4534  	natsSubSync(t, clientB2, "not.used")
  4535  	natsFlush(t, clientB2)
  4536  
  4537  	// Make A2 flood B2 with subjects that B2 is not interested in.
  4538  	for i := 0; i < 1100; i++ {
  4539  		natsPub(t, clientA, fmt.Sprintf("no.interest.%d", i), []byte("hello"))
  4540  	}
  4541  	natsFlush(t, clientA)
  4542  	// Wait for B2 to switch to interest-only
  4543  	checkGWInterestOnlyMode(t, sa2, "B", "$foo")
  4544  
  4545  	subA = natsSubSync(t, clientA, "test.request")
  4546  	natsFlush(t, clientA)
  4547  
  4548  	subB = natsSubSync(t, clientB, "reply")
  4549  	natsFlush(t, clientB)
  4550  
  4551  	for attempts := 1; attempts <= 2; attempts++ {
  4552  		// Send the request from clientB on foo.request,
  4553  		natsPubReq(t, clientB, "foo.request", "reply", []byte("hi"))
  4554  		natsFlush(t, clientB)
  4555  
  4556  		// Expect the request on A
  4557  		msg, err = subA.NextMsg(time.Second)
  4558  		if err != nil {
  4559  			if attempts == 1 {
  4560  				// Since we are in interestOnly mode, it is possible
  4561  				// that server B did not receive the subscription
  4562  				// interest yet, so try again.
  4563  				continue
  4564  			}
  4565  			t.Fatalf("subA failed to get request: %v", err)
  4566  		}
  4567  		if msg.Subject != "test.request" || string(msg.Data) != "hi" {
  4568  			t.Fatalf("Unexpected message: %v", msg)
  4569  		}
  4570  		if msg.Reply == "reply" {
  4571  			t.Fatalf("Expected randomized reply, but got original")
  4572  		}
  4573  	}
  4574  
  4575  	// Check for duplicate message
  4576  	if msg, err := subA.NextMsg(100 * time.Millisecond); err != nats.ErrTimeout {
  4577  		t.Fatalf("Unexpected msg: %v", msg)
  4578  	}
  4579  
  4580  	// Send reply
  4581  	natsPub(t, clientA, msg.Reply, []byte("ok"))
  4582  	natsFlush(t, clientA)
  4583  
  4584  	msg, err = subB.NextMsg(time.Second)
  4585  	if err != nil {
  4586  		t.Fatalf("subB failed to get reply: %v", err)
  4587  	}
  4588  	if msg.Subject != "reply" || string(msg.Data) != "ok" {
  4589  		t.Fatalf("Unexpected message: %v", msg)
  4590  	}
  4591  
  4592  	// Check for duplicate message
  4593  	if msg, err := subB.NextMsg(100 * time.Millisecond); err != nats.ErrTimeout {
  4594  		t.Fatalf("Unexpected msg: %v", msg)
  4595  	}
  4596  }
  4597  
  4598  func TestGatewayServiceExportWithWildcards(t *testing.T) {
  4599  	// This test will have following setup:
  4600  	//
  4601  	//						     |- responder
  4602  	//                           |
  4603  	//              route        v
  4604  	//   [A1]<----------------->[A2]
  4605  	//   ^  |^                    |
  4606  	//   |gw| \______gw________ gw|
  4607  	//   |  v                  \  v
  4608  	//   [B1]<----------------->[B2]
  4609  	//    ^         route
  4610  	//    |
  4611  	//    |_ requestor
  4612  	//
  4613  
  4614  	for _, test := range []struct {
  4615  		name   string
  4616  		public bool
  4617  	}{
  4618  		{
  4619  			name:   "public",
  4620  			public: true,
  4621  		},
  4622  		{
  4623  			name:   "private",
  4624  			public: false,
  4625  		},
  4626  	} {
  4627  		t.Run(test.name, func(t *testing.T) {
  4628  
  4629  			// Setup first A1 and B1 to ensure that they have GWs
  4630  			// connections as described above.
  4631  
  4632  			oa1 := testDefaultOptionsForGateway("A")
  4633  			setAccountUserPassInOptions(oa1, "$foo", "clientA", "password")
  4634  			setAccountUserPassInOptions(oa1, "$bar", "yyyyyyy", "password")
  4635  			sa1 := runGatewayServer(oa1)
  4636  			defer sa1.Shutdown()
  4637  
  4638  			ob1 := testGatewayOptionsFromToWithServers(t, "B", "A", sa1)
  4639  			setAccountUserPassInOptions(ob1, "$foo", "xxxxxxx", "password")
  4640  			setAccountUserPassInOptions(ob1, "$bar", "clientB", "password")
  4641  			sb1 := runGatewayServer(ob1)
  4642  			defer sb1.Shutdown()
  4643  
  4644  			waitForOutboundGateways(t, sa1, 1, time.Second)
  4645  			waitForOutboundGateways(t, sb1, 1, time.Second)
  4646  
  4647  			waitForInboundGateways(t, sa1, 1, time.Second)
  4648  			waitForInboundGateways(t, sb1, 1, time.Second)
  4649  
  4650  			ob2 := testGatewayOptionsFromToWithServers(t, "B", "A", sa1)
  4651  			ob2.Routes = RoutesFromStr(fmt.Sprintf("nats://127.0.0.1:%d", sb1.ClusterAddr().Port))
  4652  			setAccountUserPassInOptions(ob2, "$foo", "clientBFoo", "password")
  4653  			setAccountUserPassInOptions(ob2, "$bar", "clientB", "password")
  4654  			ob2.gatewaysSolicitDelay = time.Nanosecond // 0 would be default, so nano to connect asap
  4655  			sb2 := runGatewayServer(ob2)
  4656  			defer sb2.Shutdown()
  4657  
  4658  			waitForOutboundGateways(t, sa1, 1, time.Second)
  4659  			waitForOutboundGateways(t, sb1, 1, time.Second)
  4660  			waitForOutboundGateways(t, sb2, 1, 2*time.Second)
  4661  
  4662  			waitForInboundGateways(t, sa1, 2, time.Second)
  4663  			waitForInboundGateways(t, sb1, 1, time.Second)
  4664  			waitForInboundGateways(t, sb2, 0, time.Second)
  4665  
  4666  			oa2 := testGatewayOptionsFromToWithServers(t, "A", "B", sb2)
  4667  			oa2.Routes = RoutesFromStr(fmt.Sprintf("nats://127.0.0.1:%d", sa1.ClusterAddr().Port))
  4668  			setAccountUserPassInOptions(oa2, "$foo", "clientA", "password")
  4669  			setAccountUserPassInOptions(oa2, "$bar", "yyyyyyy", "password")
  4670  			oa2.gatewaysSolicitDelay = time.Nanosecond // 0 would be default, so nano to connect asap
  4671  			sa2 := runGatewayServer(oa2)
  4672  			defer sa2.Shutdown()
  4673  
  4674  			ensureGWConnectTo(t, sa2, "B", sb2)
  4675  
  4676  			checkClusterFormed(t, sa1, sa2)
  4677  			checkClusterFormed(t, sb1, sb2)
  4678  
  4679  			waitForOutboundGateways(t, sa1, 1, time.Second)
  4680  			waitForOutboundGateways(t, sb1, 1, time.Second)
  4681  			waitForOutboundGateways(t, sb2, 1, time.Second)
  4682  			waitForOutboundGateways(t, sa2, 1, 2*time.Second)
  4683  
  4684  			waitForInboundGateways(t, sa1, 2, time.Second)
  4685  			waitForInboundGateways(t, sb1, 1, time.Second)
  4686  			waitForInboundGateways(t, sb2, 1, 2*time.Second)
  4687  			waitForInboundGateways(t, sa2, 0, time.Second)
  4688  
  4689  			// Verification that we have what we wanted
  4690  			c := sa2.getOutboundGatewayConnection("B")
  4691  			if c == nil || c.opts.Name != sb2.ID() {
  4692  				t.Fatalf("A2 does not have outbound to B2")
  4693  			}
  4694  			c = getInboundGatewayConnection(sa2, "A")
  4695  			if c != nil {
  4696  				t.Fatalf("Bad setup")
  4697  			}
  4698  			c = sb2.getOutboundGatewayConnection("A")
  4699  			if c == nil || c.opts.Name != sa1.ID() {
  4700  				t.Fatalf("B2 does not have outbound to A1")
  4701  			}
  4702  			c = getInboundGatewayConnection(sb2, "B")
  4703  			if c == nil || c.opts.Name != sa2.ID() {
  4704  				t.Fatalf("Bad setup")
  4705  			}
  4706  
  4707  			// Ok, so now that we have proper setup, do actual test!
  4708  
  4709  			// Get accounts
  4710  			fooA1, _ := sa1.LookupAccount("$foo")
  4711  			barA1, _ := sa1.LookupAccount("$bar")
  4712  			fooA2, _ := sa2.LookupAccount("$foo")
  4713  			barA2, _ := sa2.LookupAccount("$bar")
  4714  
  4715  			fooB1, _ := sb1.LookupAccount("$foo")
  4716  			barB1, _ := sb1.LookupAccount("$bar")
  4717  			fooB2, _ := sb2.LookupAccount("$foo")
  4718  			barB2, _ := sb2.LookupAccount("$bar")
  4719  
  4720  			var accs []*Account
  4721  			// Add in the service export for the requests.
  4722  			if !test.public {
  4723  				accs = []*Account{barA1}
  4724  			}
  4725  			fooA1.AddServiceExport("ngs.update.*", accs)
  4726  			if !test.public {
  4727  				accs = []*Account{barA2}
  4728  			}
  4729  			fooA2.AddServiceExport("ngs.update.*", accs)
  4730  			if !test.public {
  4731  				accs = []*Account{barB1}
  4732  			}
  4733  			fooB1.AddServiceExport("ngs.update.*", accs)
  4734  			if !test.public {
  4735  				accs = []*Account{barB2}
  4736  			}
  4737  			fooB2.AddServiceExport("ngs.update.*", accs)
  4738  
  4739  			// Add import abilities to server B's bar account from foo.
  4740  			if err := barB1.AddServiceImport(fooB1, "ngs.update", "ngs.update.$bar"); err != nil {
  4741  				t.Fatalf("Error adding service import: %v", err)
  4742  			}
  4743  			if err := barB2.AddServiceImport(fooB2, "ngs.update", "ngs.update.$bar"); err != nil {
  4744  				t.Fatalf("Error adding service import: %v", err)
  4745  			}
  4746  			// Same on A.
  4747  			if err := barA1.AddServiceImport(fooA1, "ngs.update", "ngs.update.$bar"); err != nil {
  4748  				t.Fatalf("Error adding service import: %v", err)
  4749  			}
  4750  			if err := barA2.AddServiceImport(fooA2, "ngs.update", "ngs.update.$bar"); err != nil {
  4751  				t.Fatalf("Error adding service import: %v", err)
  4752  			}
  4753  
  4754  			// clientA will be connected to A2 and be the service endpoint and responder.
  4755  			a2URL := fmt.Sprintf("nats://clientA:password@127.0.0.1:%d", oa2.Port)
  4756  			clientA := natsConnect(t, a2URL)
  4757  			defer clientA.Close()
  4758  
  4759  			subA := natsSubSync(t, clientA, "ngs.update.$bar")
  4760  			natsFlush(t, clientA)
  4761  
  4762  			// Now setup client B on B1 who will do a sub from account $bar
  4763  			// that should map account $foo's foo subject.
  4764  			b1URL := fmt.Sprintf("nats://clientB:password@127.0.0.1:%d", ob1.Port)
  4765  			clientB := natsConnect(t, b1URL)
  4766  			defer clientB.Close()
  4767  
  4768  			subB := natsSubSync(t, clientB, "reply")
  4769  			natsFlush(t, clientB)
  4770  
  4771  			var msg *nats.Msg
  4772  			var err error
  4773  			for attempts := 1; attempts <= 2; attempts++ {
  4774  				// Send the request from clientB on foo.request,
  4775  				natsPubReq(t, clientB, "ngs.update", "reply", []byte("hi"))
  4776  				natsFlush(t, clientB)
  4777  
  4778  				// Expect the request on A
  4779  				msg, err = subA.NextMsg(time.Second)
  4780  				if err != nil {
  4781  					if attempts == 1 {
  4782  						// Since we are in interestOnly mode, it is possible
  4783  						// that server B did not receive the subscription
  4784  						// interest yet, so try again.
  4785  						continue
  4786  					}
  4787  					t.Fatalf("subA failed to get request: %v", err)
  4788  				}
  4789  				if msg.Subject != "ngs.update.$bar" || string(msg.Data) != "hi" {
  4790  					t.Fatalf("Unexpected message: %v", msg)
  4791  				}
  4792  				if msg.Reply == "reply" {
  4793  					t.Fatalf("Expected randomized reply, but got original")
  4794  				}
  4795  			}
  4796  			// Make sure we don't receive a second copy
  4797  			if msg, err := subA.NextMsg(100 * time.Millisecond); err != nats.ErrTimeout {
  4798  				t.Fatalf("Received unexpected message: %v", msg)
  4799  			}
  4800  
  4801  			// Send reply
  4802  			natsPub(t, clientA, msg.Reply, []byte("ok"))
  4803  			natsFlush(t, clientA)
  4804  
  4805  			msg, err = subB.NextMsg(time.Second)
  4806  			if err != nil {
  4807  				t.Fatalf("subB failed to get reply: %v", err)
  4808  			}
  4809  			if msg.Subject != "reply" || string(msg.Data) != "ok" {
  4810  				t.Fatalf("Unexpected message: %v", msg)
  4811  			}
  4812  			// Make sure we don't receive a second copy
  4813  			if msg, err := subB.NextMsg(100 * time.Millisecond); err != nats.ErrTimeout {
  4814  				t.Fatalf("Received unexpected message: %v", msg)
  4815  			}
  4816  
  4817  			checkSubs := func(t *testing.T, acc *Account, srvName string, expected int) {
  4818  				t.Helper()
  4819  				checkFor(t, 2*time.Second, 10*time.Millisecond, func() error {
  4820  					if ts := acc.TotalSubs(); ts != expected {
  4821  						return fmt.Errorf("Number of subs is %d on acc=%s srv=%s, should be %v", ts, acc.Name, srvName, expected)
  4822  					}
  4823  					return nil
  4824  				})
  4825  			}
  4826  			checkSubs(t, fooA1, "A1", 1)
  4827  			checkSubs(t, barA1, "A1", 1)
  4828  			checkSubs(t, fooA2, "A2", 1)
  4829  			checkSubs(t, barA2, "A2", 1)
  4830  			checkSubs(t, fooB1, "B1", 1)
  4831  			checkSubs(t, barB1, "B1", 2)
  4832  			checkSubs(t, fooB2, "B2", 1)
  4833  			checkSubs(t, barB2, "B2", 2)
  4834  
  4835  			// Speed up exiration
  4836  			err = fooA1.SetServiceExportResponseThreshold("ngs.update.*", 10*time.Millisecond)
  4837  			if err != nil {
  4838  				t.Fatalf("Error setting response threshold: %v", err)
  4839  			}
  4840  			err = fooB1.SetServiceExportResponseThreshold("ngs.update.*", 10*time.Millisecond)
  4841  			if err != nil {
  4842  				t.Fatalf("Error setting response threshold: %v", err)
  4843  			}
  4844  
  4845  			// Send 100 requests from clientB on foo.request,
  4846  			for i := 0; i < 100; i++ {
  4847  				natsPubReq(t, clientB, "ngs.update", "reply", []byte("hi"))
  4848  			}
  4849  			natsFlush(t, clientB)
  4850  
  4851  			// Consume the requests, but don't reply to them...
  4852  			for i := 0; i < 100; i++ {
  4853  				if _, err := subA.NextMsg(time.Second); err != nil {
  4854  					t.Fatalf("subA did not receive request: %v", err)
  4855  				}
  4856  			}
  4857  
  4858  			// Unsubsribe all and ensure counts go to 0.
  4859  			natsUnsub(t, subA)
  4860  			natsFlush(t, clientA)
  4861  			natsUnsub(t, subB)
  4862  			natsFlush(t, clientB)
  4863  
  4864  			// We should expire because ttl.
  4865  			checkFor(t, 2*time.Second, 10*time.Millisecond, func() error {
  4866  				if nr := len(fooA1.exports.responses); nr != 0 {
  4867  					return fmt.Errorf("Number of responses is %d", nr)
  4868  				}
  4869  				return nil
  4870  			})
  4871  
  4872  			checkSubs(t, fooA1, "A1", 0)
  4873  			checkSubs(t, fooA2, "A2", 0)
  4874  			checkSubs(t, fooB1, "B1", 1)
  4875  			checkSubs(t, fooB2, "B2", 1)
  4876  
  4877  			checkSubs(t, barA1, "A1", 1)
  4878  			checkSubs(t, barA2, "A2", 1)
  4879  			checkSubs(t, barB1, "B1", 1)
  4880  			checkSubs(t, barB2, "B2", 1)
  4881  
  4882  			// Check that this all work in interest-only mode.
  4883  
  4884  			// We need at least a subscription on B2 otherwise when publishing
  4885  			// to subjects with no interest we would simply get an A-
  4886  			b2URL := fmt.Sprintf("nats://clientBFoo:password@127.0.0.1:%d", ob2.Port)
  4887  			clientB2 := natsConnect(t, b2URL)
  4888  			defer clientB2.Close()
  4889  			natsSubSync(t, clientB2, "not.used")
  4890  			natsFlush(t, clientB2)
  4891  
  4892  			// Make A2 flood B2 with subjects that B2 is not interested in.
  4893  			for i := 0; i < 1100; i++ {
  4894  				natsPub(t, clientA, fmt.Sprintf("no.interest.%d", i), []byte("hello"))
  4895  			}
  4896  			natsFlush(t, clientA)
  4897  
  4898  			// Wait for B2 to switch to interest-only
  4899  			checkGWInterestOnlyMode(t, sa2, "B", "$foo")
  4900  
  4901  			subA = natsSubSync(t, clientA, "ngs.update.*")
  4902  			natsFlush(t, clientA)
  4903  
  4904  			subB = natsSubSync(t, clientB, "reply")
  4905  			natsFlush(t, clientB)
  4906  
  4907  			for attempts := 1; attempts <= 2; attempts++ {
  4908  				// Send the request from clientB on foo.request,
  4909  				natsPubReq(t, clientB, "ngs.update", "reply", []byte("hi"))
  4910  				natsFlush(t, clientB)
  4911  
  4912  				// Expect the request on A
  4913  				msg, err = subA.NextMsg(time.Second)
  4914  				if err != nil {
  4915  					if attempts == 1 {
  4916  						// Since we are in interestOnly mode, it is possible
  4917  						// that server B did not receive the subscription
  4918  						// interest yet, so try again.
  4919  						continue
  4920  					}
  4921  					t.Fatalf("subA failed to get request: %v", err)
  4922  				}
  4923  				if msg.Subject != "ngs.update.$bar" || string(msg.Data) != "hi" {
  4924  					t.Fatalf("Unexpected message: %v", msg)
  4925  				}
  4926  				if msg.Reply == "reply" {
  4927  					t.Fatalf("Expected randomized reply, but got original")
  4928  				}
  4929  			}
  4930  
  4931  			// Check for duplicate message
  4932  			if msg, err := subA.NextMsg(100 * time.Millisecond); err != nats.ErrTimeout {
  4933  				t.Fatalf("Unexpected msg: %v", msg)
  4934  			}
  4935  
  4936  			// Send reply
  4937  			natsPub(t, clientA, msg.Reply, []byte("ok"))
  4938  			natsFlush(t, clientA)
  4939  
  4940  			msg, err = subB.NextMsg(time.Second)
  4941  			if err != nil {
  4942  				t.Fatalf("subB failed to get reply: %v", err)
  4943  			}
  4944  			if msg.Subject != "reply" || string(msg.Data) != "ok" {
  4945  				t.Fatalf("Unexpected message: %v", msg)
  4946  			}
  4947  
  4948  			// Check for duplicate message
  4949  			if msg, err := subB.NextMsg(100 * time.Millisecond); err != nats.ErrTimeout {
  4950  				t.Fatalf("Unexpected msg: %v", msg)
  4951  			}
  4952  		})
  4953  	}
  4954  }
  4955  
  4956  // NOTE: if this fails for you and says only has <10 outbound, make sure ulimit for open files > 256.
  4957  func TestGatewayMemUsage(t *testing.T) {
  4958  	// Try to clean up.
  4959  	runtime.GC()
  4960  	var m runtime.MemStats
  4961  	runtime.ReadMemStats(&m)
  4962  	pta := m.TotalAlloc
  4963  
  4964  	o := testDefaultOptionsForGateway("A")
  4965  	s := runGatewayServer(o)
  4966  	defer s.Shutdown()
  4967  
  4968  	var servers []*Server
  4969  	servers = append(servers, s)
  4970  
  4971  	numServers := 10
  4972  	for i := 0; i < numServers; i++ {
  4973  		rn := fmt.Sprintf("RG_%d", i+1)
  4974  		o := testGatewayOptionsFromToWithServers(t, rn, "A", s)
  4975  		s := runGatewayServer(o)
  4976  		defer s.Shutdown()
  4977  		servers = append(servers, s)
  4978  	}
  4979  
  4980  	// Each server should have an outbound
  4981  	for _, s := range servers {
  4982  		waitForOutboundGateways(t, s, numServers, 2*time.Second)
  4983  	}
  4984  	// The first started server should have numServers inbounds (since
  4985  	// they all connect to it).
  4986  	waitForInboundGateways(t, s, numServers, 2*time.Second)
  4987  
  4988  	// Calculate in MB what we are using now.
  4989  	const max = 50 * 1024 * 1024 // 50MB
  4990  	runtime.ReadMemStats(&m)
  4991  	used := m.TotalAlloc - pta
  4992  	if used > max {
  4993  		t.Fatalf("Cluster using too much memory, expect < 50MB, got %dMB", used/(1024*1024))
  4994  	}
  4995  
  4996  	for _, s := range servers {
  4997  		s.Shutdown()
  4998  	}
  4999  }
  5000  
  5001  func TestGatewayMapReplyOnlyForRecentSub(t *testing.T) {
  5002  	o2 := testDefaultOptionsForGateway("B")
  5003  	s2 := runGatewayServer(o2)
  5004  	defer s2.Shutdown()
  5005  
  5006  	o1 := testGatewayOptionsFromToWithServers(t, "A", "B", s2)
  5007  	s1 := runGatewayServer(o1)
  5008  	defer s1.Shutdown()
  5009  
  5010  	waitForOutboundGateways(t, s1, 1, time.Second)
  5011  	waitForOutboundGateways(t, s2, 1, time.Second)
  5012  
  5013  	// Change s1's recent sub expiration default value
  5014  	s1.mu.Lock()
  5015  	s1.gateway.pasi.Lock()
  5016  	s1.gateway.recSubExp = 100 * time.Millisecond
  5017  	s1.gateway.pasi.Unlock()
  5018  	s1.mu.Unlock()
  5019  
  5020  	// Setup a replier on s2
  5021  	nc2 := natsConnect(t, fmt.Sprintf("nats://%s:%d", o2.Host, o2.Port))
  5022  	defer nc2.Close()
  5023  	errCh := make(chan error, 1)
  5024  	natsSub(t, nc2, "foo", func(m *nats.Msg) {
  5025  		// Send reply regardless..
  5026  		nc2.Publish(m.Reply, []byte("reply"))
  5027  		// Check that reply given to application is not mapped.
  5028  		if !strings.HasPrefix(m.Reply, nats.InboxPrefix) {
  5029  			errCh <- fmt.Errorf("Reply expected to have normal inbox, got %v", m.Reply)
  5030  			return
  5031  		}
  5032  		errCh <- nil
  5033  	})
  5034  	natsFlush(t, nc2)
  5035  	checkExpectedSubs(t, 1, s2)
  5036  
  5037  	// Create requestor on s1
  5038  	nc1 := natsConnect(t, fmt.Sprintf("nats://%s:%d", o1.Host, o1.Port))
  5039  	defer nc1.Close()
  5040  	// Send first request, reply should be mapped
  5041  	nc1.Request("foo", []byte("msg1"), time.Second)
  5042  	// Wait more than the recent sub expiration (that we have set to 100ms)
  5043  	time.Sleep(200 * time.Millisecond)
  5044  	// Send second request (reply should not be mapped)
  5045  	nc1.Request("foo", []byte("msg2"), time.Second)
  5046  
  5047  	select {
  5048  	case e := <-errCh:
  5049  		if e != nil {
  5050  			t.Fatalf(e.Error())
  5051  		}
  5052  	case <-time.After(time.Second):
  5053  		t.Fatalf("Did not get replies")
  5054  	}
  5055  }
  5056  
  5057  type delayedWriteConn struct {
  5058  	sync.Mutex
  5059  	net.Conn
  5060  	bytes [][]byte
  5061  	delay bool
  5062  	wg    sync.WaitGroup
  5063  }
  5064  
  5065  func (c *delayedWriteConn) Write(b []byte) (int, error) {
  5066  	c.Lock()
  5067  	defer c.Unlock()
  5068  	if c.delay || len(c.bytes) > 0 {
  5069  		c.bytes = append(c.bytes, append([]byte(nil), b...))
  5070  		c.wg.Add(1)
  5071  		go func() {
  5072  			defer c.wg.Done()
  5073  			c.Lock()
  5074  			defer c.Unlock()
  5075  			if c.delay {
  5076  				c.Unlock()
  5077  				time.Sleep(100 * time.Millisecond)
  5078  				c.Lock()
  5079  			}
  5080  			if len(c.bytes) > 0 {
  5081  				b = c.bytes[0]
  5082  				c.bytes = c.bytes[1:]
  5083  				c.Conn.Write(b)
  5084  			}
  5085  		}()
  5086  		return len(b), nil
  5087  	}
  5088  	return c.Conn.Write(b)
  5089  }
  5090  
  5091  // This test uses a single account and makes sure that when
  5092  // a reply subject is prefixed with $GR it comes back to
  5093  // the origin cluster and delivered to proper reply subject
  5094  // there, but also to subscribers on that reply subject
  5095  // on the other cluster.
  5096  func TestGatewaySendReplyAcrossGateways(t *testing.T) {
  5097  	for _, test := range []struct {
  5098  		name     string
  5099  		poolSize int
  5100  		peracc   bool
  5101  	}{
  5102  		{"no pooling", -1, false},
  5103  		{"pooling", 5, false},
  5104  		{"per account", 0, true},
  5105  	} {
  5106  		t.Run(test.name, func(t *testing.T) {
  5107  			ob := testDefaultOptionsForGateway("B")
  5108  			ob.Accounts = []*Account{NewAccount("ACC")}
  5109  			ob.Users = []*User{{Username: "user", Password: "pwd", Account: ob.Accounts[0]}}
  5110  			sb := runGatewayServer(ob)
  5111  			defer sb.Shutdown()
  5112  
  5113  			oa1 := testGatewayOptionsFromToWithServers(t, "A", "B", sb)
  5114  			oa1.Cluster.PoolSize = test.poolSize
  5115  			if test.peracc {
  5116  				oa1.Cluster.PinnedAccounts = []string{"ACC"}
  5117  			}
  5118  			oa1.Accounts = []*Account{NewAccount("ACC")}
  5119  			oa1.Users = []*User{{Username: "user", Password: "pwd", Account: oa1.Accounts[0]}}
  5120  			sa1 := runGatewayServer(oa1)
  5121  			defer sa1.Shutdown()
  5122  
  5123  			waitForOutboundGateways(t, sb, 1, time.Second)
  5124  			waitForInboundGateways(t, sb, 1, time.Second)
  5125  			waitForOutboundGateways(t, sa1, 1, time.Second)
  5126  			waitForInboundGateways(t, sa1, 1, time.Second)
  5127  
  5128  			// Now start another server in cluster "A". This will allow us
  5129  			// to test the reply from cluster "B" coming back directly to
  5130  			// the server where the request originates, and indirectly through
  5131  			// route.
  5132  			oa2 := testGatewayOptionsFromToWithServers(t, "A", "B", sb)
  5133  			oa2.Cluster.PoolSize = test.poolSize
  5134  			if test.peracc {
  5135  				oa2.Cluster.PinnedAccounts = []string{"ACC"}
  5136  			}
  5137  			oa2.Accounts = []*Account{NewAccount("ACC")}
  5138  			oa2.Users = []*User{{Username: "user", Password: "pwd", Account: oa2.Accounts[0]}}
  5139  			oa2.Routes = RoutesFromStr(fmt.Sprintf("nats://%s:%d", oa1.Cluster.Host, oa1.Cluster.Port))
  5140  			sa2 := runGatewayServer(oa2)
  5141  			defer sa2.Shutdown()
  5142  
  5143  			waitForOutboundGateways(t, sa2, 1, time.Second)
  5144  			waitForInboundGateways(t, sb, 2, time.Second)
  5145  			checkClusterFormed(t, sa1, sa2)
  5146  
  5147  			replySubj := "bar"
  5148  
  5149  			// Setup a responder on sb
  5150  			ncb := natsConnect(t, fmt.Sprintf("nats://user:pwd@%s:%d", ob.Host, ob.Port))
  5151  			defer ncb.Close()
  5152  			natsSub(t, ncb, "foo", func(m *nats.Msg) {
  5153  				m.Respond([]byte("reply"))
  5154  			})
  5155  			// Set a subscription on the reply subject on sb
  5156  			subSB := natsSubSync(t, ncb, replySubj)
  5157  			natsFlush(t, ncb)
  5158  			checkExpectedSubs(t, 2, sb)
  5159  
  5160  			testReqReply := func(t *testing.T, host string, port int, createSubOnA bool) {
  5161  				t.Helper()
  5162  				nca := natsConnect(t, fmt.Sprintf("nats://user:pwd@%s:%d", host, port))
  5163  				defer nca.Close()
  5164  				if createSubOnA {
  5165  					subSA := natsSubSync(t, nca, replySubj)
  5166  					natsPubReq(t, nca, "foo", replySubj, []byte("hello"))
  5167  					natsNexMsg(t, subSA, time.Second)
  5168  					// Check for duplicates
  5169  					if _, err := subSA.NextMsg(50 * time.Millisecond); err == nil {
  5170  						t.Fatalf("Received duplicate message on subSA!")
  5171  					}
  5172  				} else {
  5173  					natsPubReq(t, nca, "foo", replySubj, []byte("hello"))
  5174  				}
  5175  				natsNexMsg(t, subSB, time.Second)
  5176  				// Check for duplicates
  5177  				if _, err := subSB.NextMsg(50 * time.Millisecond); err == nil {
  5178  					t.Fatalf("Received duplicate message on subSB!")
  5179  				}
  5180  			}
  5181  			// Create requestor on sa1 to check for direct reply from GW:
  5182  			testReqReply(t, oa1.Host, oa1.Port, true)
  5183  			// Wait for subscription to be gone...
  5184  			checkExpectedSubs(t, 0, sa1)
  5185  			// Now create requestor on sa2, it will receive reply through sa1.
  5186  			testReqReply(t, oa2.Host, oa2.Port, true)
  5187  			checkExpectedSubs(t, 0, sa1)
  5188  			checkExpectedSubs(t, 0, sa2)
  5189  
  5190  			// Now issue requests but without any interest in the requestor's
  5191  			// origin cluster and make sure the other cluster gets the reply.
  5192  			testReqReply(t, oa1.Host, oa1.Port, false)
  5193  			testReqReply(t, oa2.Host, oa2.Port, false)
  5194  
  5195  			// There is a possible race between sa2 sending the RS+ for the
  5196  			// subscription on the reply subject, and the GW reply making it
  5197  			// to sa1 before the RS+ is processed there.
  5198  			// We are going to force this race by making the route connection
  5199  			// block as needed.
  5200  
  5201  			acc, _ := sa2.LookupAccount("ACC")
  5202  			acc.mu.RLock()
  5203  			api := acc.routePoolIdx
  5204  			acc.mu.RUnlock()
  5205  
  5206  			var route *client
  5207  			sa2.mu.Lock()
  5208  			if test.peracc {
  5209  				if conns, ok := sa2.accRoutes["ACC"]; ok {
  5210  					for _, r := range conns {
  5211  						route = r
  5212  						break
  5213  					}
  5214  				}
  5215  			} else if test.poolSize > 0 {
  5216  				sa2.forEachRoute(func(r *client) {
  5217  					r.mu.Lock()
  5218  					if r.route.poolIdx == api {
  5219  						route = r
  5220  					}
  5221  					r.mu.Unlock()
  5222  				})
  5223  			} else if r := getFirstRoute(sa2); r != nil {
  5224  				route = r
  5225  			}
  5226  			sa2.mu.Unlock()
  5227  			route.mu.Lock()
  5228  			routeConn := &delayedWriteConn{
  5229  				Conn: route.nc,
  5230  				wg:   sync.WaitGroup{},
  5231  			}
  5232  			route.nc = routeConn
  5233  			route.mu.Unlock()
  5234  
  5235  			delayRoute := func() {
  5236  				routeConn.Lock()
  5237  				routeConn.delay = true
  5238  				routeConn.Unlock()
  5239  			}
  5240  			stopDelayRoute := func() {
  5241  				routeConn.Lock()
  5242  				routeConn.delay = false
  5243  				wg := &routeConn.wg
  5244  				routeConn.Unlock()
  5245  				wg.Wait()
  5246  			}
  5247  
  5248  			delayRoute()
  5249  			testReqReply(t, oa2.Host, oa2.Port, true)
  5250  			stopDelayRoute()
  5251  
  5252  			// Same test but now we have a local interest on the reply subject
  5253  			// on sa1 to make sure that interest there does not prevent sending
  5254  			// the RMSG to sa2, which is the origin of the request.
  5255  			checkExpectedSubs(t, 0, sa1)
  5256  			checkExpectedSubs(t, 0, sa2)
  5257  			nca1 := natsConnect(t, fmt.Sprintf("nats://user:pwd@%s:%d", oa1.Host, oa1.Port))
  5258  			defer nca1.Close()
  5259  			subSA1 := natsSubSync(t, nca1, replySubj)
  5260  			natsFlush(t, nca1)
  5261  			checkExpectedSubs(t, 1, sa1)
  5262  			checkExpectedSubs(t, 1, sa2)
  5263  
  5264  			delayRoute()
  5265  			testReqReply(t, oa2.Host, oa2.Port, true)
  5266  			stopDelayRoute()
  5267  
  5268  			natsNexMsg(t, subSA1, time.Second)
  5269  		})
  5270  	}
  5271  }
  5272  
  5273  // This test will have a requestor on cluster A and responder
  5274  // on cluster B, but when the responder sends the response,
  5275  // it will also have a reply subject to receive a response
  5276  // for the response.
  5277  func TestGatewayPingPongReplyAcrossGateways(t *testing.T) {
  5278  	ob := testDefaultOptionsForGateway("B")
  5279  	ob.Accounts = []*Account{NewAccount("ACC")}
  5280  	ob.Users = []*User{{Username: "user", Password: "pwd", Account: ob.Accounts[0]}}
  5281  	sb := runGatewayServer(ob)
  5282  	defer sb.Shutdown()
  5283  
  5284  	oa1 := testGatewayOptionsFromToWithServers(t, "A", "B", sb)
  5285  	oa1.Accounts = []*Account{NewAccount("ACC")}
  5286  	oa1.Users = []*User{{Username: "user", Password: "pwd", Account: oa1.Accounts[0]}}
  5287  	sa1 := runGatewayServer(oa1)
  5288  	defer sa1.Shutdown()
  5289  
  5290  	waitForOutboundGateways(t, sb, 1, time.Second)
  5291  	waitForInboundGateways(t, sb, 1, time.Second)
  5292  	waitForOutboundGateways(t, sa1, 1, time.Second)
  5293  	waitForInboundGateways(t, sa1, 1, time.Second)
  5294  
  5295  	// Now start another server in cluster "A". This will allow us
  5296  	// to test the reply from cluster "B" coming back directly to
  5297  	// the server where the request originates, and indirectly through
  5298  	// route.
  5299  	oa2 := testGatewayOptionsFromToWithServers(t, "A", "B", sb)
  5300  	oa2.Accounts = []*Account{NewAccount("ACC")}
  5301  	oa2.Users = []*User{{Username: "user", Password: "pwd", Account: oa2.Accounts[0]}}
  5302  	oa2.Routes = RoutesFromStr(fmt.Sprintf("nats://%s:%d", oa1.Cluster.Host, oa1.Cluster.Port))
  5303  	sa2 := runGatewayServer(oa2)
  5304  	defer sa2.Shutdown()
  5305  
  5306  	waitForOutboundGateways(t, sa2, 1, time.Second)
  5307  	waitForInboundGateways(t, sb, 2, time.Second)
  5308  	checkClusterFormed(t, sa1, sa2)
  5309  
  5310  	// Setup a responder on sb
  5311  	ncb := natsConnect(t, fmt.Sprintf("nats://user:pwd@%s:%d", ob.Host, ob.Port))
  5312  	defer ncb.Close()
  5313  	sbReplySubj := "sbreply"
  5314  	subSB := natsSubSync(t, ncb, sbReplySubj)
  5315  	natsSub(t, ncb, "foo", func(m *nats.Msg) {
  5316  		ncb.PublishRequest(m.Reply, sbReplySubj, []byte("sb reply"))
  5317  	})
  5318  	natsFlush(t, ncb)
  5319  	checkExpectedSubs(t, 2, sb)
  5320  
  5321  	testReqReply := func(t *testing.T, host string, port int) {
  5322  		t.Helper()
  5323  		nca := natsConnect(t, fmt.Sprintf("nats://user:pwd@%s:%d", host, port))
  5324  		defer nca.Close()
  5325  		msg, err := nca.Request("foo", []byte("sa request"), time.Second)
  5326  		if err != nil {
  5327  			t.Fatalf("Did not get response: %v", err)
  5328  		}
  5329  		// Check response from sb, it should have content "sb reply" and
  5330  		// reply subject should not have GW prefix
  5331  		if string(msg.Data) != "sb reply" || msg.Reply != sbReplySubj {
  5332  			t.Fatalf("Unexpected message from sb: %+v", msg)
  5333  		}
  5334  		// Now send our own reply:
  5335  		nca.Publish(msg.Reply, []byte("sa reply"))
  5336  		// And make sure that subS2 receives it...
  5337  		msg = natsNexMsg(t, subSB, time.Second)
  5338  		if string(msg.Data) != "sa reply" || msg.Reply != _EMPTY_ {
  5339  			t.Fatalf("Unexpected message from sa: %v", msg)
  5340  		}
  5341  	}
  5342  	// Create requestor on sa1 to check for direct reply from GW:
  5343  	testReqReply(t, oa1.Host, oa1.Port)
  5344  	// Now from sa2 to see reply coming from route (sa1)
  5345  	testReqReply(t, oa2.Host, oa2.Port)
  5346  }
  5347  
  5348  // Similar to TestGatewaySendReplyAcrossGateways, but this time
  5349  // with service import.
  5350  func TestGatewaySendReplyAcrossGatewaysServiceImport(t *testing.T) {
  5351  	ob := testDefaultOptionsForGateway("B")
  5352  	setAccountUserPassInOptions(ob, "$foo", "clientBFoo", "password")
  5353  	setAccountUserPassInOptions(ob, "$bar", "clientBBar", "password")
  5354  	sb := runGatewayServer(ob)
  5355  	defer sb.Shutdown()
  5356  
  5357  	oa1 := testGatewayOptionsFromToWithServers(t, "A", "B", sb)
  5358  	oa1.Cluster.PoolSize = 1
  5359  	setAccountUserPassInOptions(oa1, "$foo", "clientAFoo", "password")
  5360  	setAccountUserPassInOptions(oa1, "$bar", "clientABar", "password")
  5361  	sa1 := runGatewayServer(oa1)
  5362  	defer sa1.Shutdown()
  5363  
  5364  	waitForOutboundGateways(t, sb, 1, time.Second)
  5365  	waitForInboundGateways(t, sb, 1, time.Second)
  5366  	waitForOutboundGateways(t, sa1, 1, time.Second)
  5367  	waitForInboundGateways(t, sa1, 1, time.Second)
  5368  
  5369  	oa2 := testGatewayOptionsFromToWithServers(t, "A", "B", sb)
  5370  	oa2.Cluster.PoolSize = 1
  5371  	setAccountUserPassInOptions(oa2, "$foo", "clientAFoo", "password")
  5372  	setAccountUserPassInOptions(oa2, "$bar", "clientABar", "password")
  5373  	oa2.Routes = RoutesFromStr(fmt.Sprintf("nats://%s:%d", oa1.Cluster.Host, oa1.Cluster.Port))
  5374  	sa2 := runGatewayServer(oa2)
  5375  	defer sa2.Shutdown()
  5376  
  5377  	oa3 := testGatewayOptionsFromToWithServers(t, "A", "B", sb)
  5378  	oa3.Cluster.PoolSize = 1
  5379  	setAccountUserPassInOptions(oa3, "$foo", "clientAFoo", "password")
  5380  	setAccountUserPassInOptions(oa3, "$bar", "clientABar", "password")
  5381  	oa3.Routes = RoutesFromStr(fmt.Sprintf("nats://%s:%d", oa1.Cluster.Host, oa1.Cluster.Port))
  5382  	sa3 := runGatewayServer(oa3)
  5383  	defer sa3.Shutdown()
  5384  
  5385  	waitForOutboundGateways(t, sa2, 1, time.Second)
  5386  	waitForOutboundGateways(t, sa3, 1, time.Second)
  5387  	waitForInboundGateways(t, sb, 3, time.Second)
  5388  	checkClusterFormed(t, sa1, sa2, sa3)
  5389  
  5390  	// Setup account on B
  5391  	fooB, _ := sb.LookupAccount("$foo")
  5392  	// Add in the service export for the requests. Make it public.
  5393  	fooB.AddServiceExport("foo.request", nil)
  5394  
  5395  	// Setup accounts on sa1, sa2 and sa3
  5396  	setupAccsOnA := func(s *Server) {
  5397  		// Get accounts
  5398  		fooA, _ := s.LookupAccount("$foo")
  5399  		barA, _ := s.LookupAccount("$bar")
  5400  		// Add in the service export for the requests. Make it public.
  5401  		fooA.AddServiceExport("foo.request", nil)
  5402  		// Add import abilities to server A's bar account from foo.
  5403  		if err := barA.AddServiceImport(fooA, "bar.request", "foo.request"); err != nil {
  5404  			t.Fatalf("Error adding service import: %v", err)
  5405  		}
  5406  	}
  5407  	setupAccsOnA(sa1)
  5408  	setupAccsOnA(sa2)
  5409  	setupAccsOnA(sa3)
  5410  
  5411  	// clientB will be connected to sb and be the service endpoint and responder.
  5412  	bURL := fmt.Sprintf("nats://clientBFoo:password@127.0.0.1:%d", ob.Port)
  5413  	clientBFoo := natsConnect(t, bURL)
  5414  	defer clientBFoo.Close()
  5415  	subBFoo := natsSubSync(t, clientBFoo, "foo.request")
  5416  	natsFlush(t, clientBFoo)
  5417  
  5418  	// Create another client on B for account $bar that will listen to
  5419  	// the reply subject.
  5420  	bURL = fmt.Sprintf("nats://clientBBar:password@127.0.0.1:%d", ob.Port)
  5421  	clientBBar := natsConnect(t, bURL)
  5422  	defer clientBBar.Close()
  5423  	replySubj := "reply"
  5424  	subBReply := natsSubSync(t, clientBBar, replySubj)
  5425  	natsFlush(t, clientBBar)
  5426  
  5427  	testServiceImport := func(t *testing.T, host string, port int) {
  5428  		t.Helper()
  5429  		bURL := fmt.Sprintf("nats://clientABar:password@%s:%d", host, port)
  5430  		clientABar := natsConnect(t, bURL)
  5431  		defer clientABar.Close()
  5432  		subAReply := natsSubSync(t, clientABar, replySubj)
  5433  		natsFlush(t, clientABar)
  5434  
  5435  		// Send the request from clientA on bar.request, which
  5436  		// will be translated to foo.request and sent over.
  5437  		natsPubReq(t, clientABar, "bar.request", replySubj, []byte("hi"))
  5438  		natsFlush(t, clientABar)
  5439  
  5440  		// Expect the request to be received on subAFoo
  5441  		msg, err := subBFoo.NextMsg(time.Second)
  5442  		if err != nil {
  5443  			t.Fatalf("subBFoo failed to get request: %v", err)
  5444  		}
  5445  		if msg.Subject != "foo.request" || string(msg.Data) != "hi" {
  5446  			t.Fatalf("Unexpected message: %v", msg)
  5447  		}
  5448  		if msg.Reply == replySubj {
  5449  			t.Fatalf("Expected randomized reply, but got original")
  5450  		}
  5451  
  5452  		// Check for duplicate message
  5453  		if msg, err := subBFoo.NextMsg(100 * time.Millisecond); err != nats.ErrTimeout {
  5454  			t.Fatalf("Unexpected msg: %v", msg)
  5455  		}
  5456  
  5457  		// Send reply
  5458  		natsPub(t, clientBFoo, msg.Reply, []byte("ok-42"))
  5459  		natsFlush(t, clientBFoo)
  5460  
  5461  		// Now check that the subscription on the reply receives the message...
  5462  		checkReply := func(t *testing.T, sub *nats.Subscription) {
  5463  			t.Helper()
  5464  			msg, err = sub.NextMsg(time.Second)
  5465  			if err != nil {
  5466  				t.Fatalf("sub failed to get reply: %v", err)
  5467  			}
  5468  			if msg.Subject != replySubj || string(msg.Data) != "ok-42" {
  5469  				t.Fatalf("Unexpected message: %v", msg)
  5470  			}
  5471  		}
  5472  		// Check subscription on A (where the request originated)
  5473  		checkReply(t, subAReply)
  5474  		// And the subscription on B (where the responder is located)
  5475  		checkReply(t, subBReply)
  5476  	}
  5477  
  5478  	// We check the service import with GW working ok with either
  5479  	// direct connection between the responder's server to the
  5480  	// requestor's server and also through routes.
  5481  	testServiceImport(t, oa1.Host, oa1.Port)
  5482  	testServiceImport(t, oa2.Host, oa2.Port)
  5483  	// sa1 is the one receiving the reply from GW between B and A.
  5484  	// Check that the server routes directly to the the server
  5485  	// with the interest.
  5486  	checkRoute := func(t *testing.T, s *Server, expected int64) {
  5487  		t.Helper()
  5488  		s.mu.Lock()
  5489  		defer s.mu.Unlock()
  5490  		s.forEachRoute(func(r *client) {
  5491  			r.mu.Lock()
  5492  			if r.route.remoteID != sa1.ID() {
  5493  				r.mu.Unlock()
  5494  				return
  5495  			}
  5496  			inMsgs := atomic.LoadInt64(&r.inMsgs)
  5497  			r.mu.Unlock()
  5498  			if inMsgs != expected {
  5499  				t.Fatalf("Expected %v incoming msgs, got %v", expected, inMsgs)
  5500  			}
  5501  		})
  5502  	}
  5503  	// Wait a bit to make sure that we don't have a loop that
  5504  	// cause messages to be routed more than needed.
  5505  	time.Sleep(100 * time.Millisecond)
  5506  	checkRoute(t, sa2, 1)
  5507  	checkRoute(t, sa3, 0)
  5508  
  5509  	testServiceImport(t, oa3.Host, oa3.Port)
  5510  	// Wait a bit to make sure that we don't have a loop that
  5511  	// cause messages to be routed more than needed.
  5512  	time.Sleep(100 * time.Millisecond)
  5513  	checkRoute(t, sa2, 1)
  5514  	checkRoute(t, sa3, 1)
  5515  }
  5516  
  5517  func TestGatewayClientsDontReceiveMsgsOnGWPrefix(t *testing.T) {
  5518  	ob := testDefaultOptionsForGateway("B")
  5519  	sb := runGatewayServer(ob)
  5520  	defer sb.Shutdown()
  5521  
  5522  	oa := testGatewayOptionsFromToWithServers(t, "A", "B", sb)
  5523  	sa := runGatewayServer(oa)
  5524  	defer sa.Shutdown()
  5525  
  5526  	waitForOutboundGateways(t, sa, 1, time.Second)
  5527  	waitForInboundGateways(t, sa, 1, time.Second)
  5528  	waitForOutboundGateways(t, sb, 1, time.Second)
  5529  	waitForInboundGateways(t, sb, 1, time.Second)
  5530  
  5531  	// Setup a responder on sb
  5532  	ncb := natsConnect(t, fmt.Sprintf("nats://%s:%d", ob.Host, ob.Port))
  5533  	defer ncb.Close()
  5534  	natsSub(t, ncb, "foo", func(m *nats.Msg) {
  5535  		if strings.HasPrefix(m.Reply, gwReplyPrefix) {
  5536  			m.Respond([]byte(fmt.Sprintf("-ERR: received request with mapped reply subject %q", m.Reply)))
  5537  		} else {
  5538  			m.Respond([]byte("+OK: reply"))
  5539  		}
  5540  	})
  5541  	// And create a sub on ">" that should not get the $GR reply.
  5542  	subSB := natsSubSync(t, ncb, ">")
  5543  	natsFlush(t, ncb)
  5544  	checkExpectedSubs(t, 2, sb)
  5545  
  5546  	nca := natsConnect(t, fmt.Sprintf("nats://%s:%d", oa.Host, oa.Port))
  5547  	defer nca.Close()
  5548  	msg, err := nca.Request("foo", []byte("request"), time.Second)
  5549  	if err != nil {
  5550  		t.Fatalf("Did not get response: %v", err)
  5551  	}
  5552  	if string(msg.Data) != "+OK: reply" {
  5553  		t.Fatalf("Error from responder: %q", msg.Data)
  5554  	}
  5555  
  5556  	// subSB would have also received the request, so drop that one.
  5557  	msg = natsNexMsg(t, subSB, time.Second)
  5558  	if string(msg.Data) != "request" {
  5559  		t.Fatalf("Wrong request: %q", msg.Data)
  5560  	}
  5561  	// Once sa gets the direct reply, it should resend the reply
  5562  	// with normal subject. So subSB should get the message with
  5563  	// a subject that does not start with $GNR prefix.
  5564  	msg = natsNexMsg(t, subSB, time.Second)
  5565  	if string(msg.Data) != "+OK: reply" || strings.HasPrefix(msg.Subject, gwReplyPrefix) {
  5566  		t.Fatalf("Unexpected message from sa: %v", msg)
  5567  	}
  5568  	// Check no more message...
  5569  	if m, err := subSB.NextMsg(100 * time.Millisecond); m != nil || err == nil {
  5570  		t.Fatalf("Expected only 1 message, got %+v", m)
  5571  	}
  5572  }
  5573  
  5574  func TestGatewayNoAccInterestThenQSubThenRegularSub(t *testing.T) {
  5575  	GatewayDoNotForceInterestOnlyMode(true)
  5576  	defer GatewayDoNotForceInterestOnlyMode(false)
  5577  
  5578  	ob := testDefaultOptionsForGateway("B")
  5579  	sb := runGatewayServer(ob)
  5580  	defer sb.Shutdown()
  5581  
  5582  	oa := testGatewayOptionsFromToWithServers(t, "A", "B", sb)
  5583  	sa := runGatewayServer(oa)
  5584  	defer sa.Shutdown()
  5585  
  5586  	waitForOutboundGateways(t, sa, 1, time.Second)
  5587  	waitForInboundGateways(t, sa, 1, time.Second)
  5588  	waitForOutboundGateways(t, sb, 1, time.Second)
  5589  	waitForInboundGateways(t, sb, 1, time.Second)
  5590  
  5591  	// Connect on A and send a message
  5592  	ncA := natsConnect(t, fmt.Sprintf("nats://%s:%d", oa.Host, oa.Port))
  5593  	defer ncA.Close()
  5594  	natsPub(t, ncA, "foo", []byte("hello"))
  5595  	natsFlush(t, ncA)
  5596  
  5597  	// expect an A- on return
  5598  	gwb := sa.getOutboundGatewayConnection("B")
  5599  	checkForAccountNoInterest(t, gwb, globalAccountName, true, time.Second)
  5600  
  5601  	// Create a connection o B, and create a queue sub first
  5602  	ncB := natsConnect(t, fmt.Sprintf("nats://%s:%d", ob.Host, ob.Port))
  5603  	defer ncB.Close()
  5604  	qsub := natsQueueSubSync(t, ncB, "bar", "queue")
  5605  	natsFlush(t, ncB)
  5606  
  5607  	// A should have received a queue interest
  5608  	checkForRegisteredQSubInterest(t, sa, "B", globalAccountName, "bar", 1, time.Second)
  5609  
  5610  	// Now on B, create a regular sub
  5611  	sub := natsSubSync(t, ncB, "baz")
  5612  	natsFlush(t, ncB)
  5613  
  5614  	// From A now, produce a message on each subject and
  5615  	// expect both subs to receive their message.
  5616  	msgForQSub := []byte("msg_qsub")
  5617  	natsPub(t, ncA, "bar", msgForQSub)
  5618  	natsFlush(t, ncA)
  5619  
  5620  	if msg := natsNexMsg(t, qsub, time.Second); !bytes.Equal(msgForQSub, msg.Data) {
  5621  		t.Fatalf("Expected msg for queue sub to be %q, got %q", msgForQSub, msg.Data)
  5622  	}
  5623  
  5624  	// Publish for the regular sub
  5625  	msgForSub := []byte("msg_sub")
  5626  	natsPub(t, ncA, "baz", msgForSub)
  5627  	natsFlush(t, ncA)
  5628  
  5629  	if msg := natsNexMsg(t, sub, time.Second); !bytes.Equal(msgForSub, msg.Data) {
  5630  		t.Fatalf("Expected msg for sub to be %q, got %q", msgForSub, msg.Data)
  5631  	}
  5632  }
  5633  
  5634  // Similar to TestGatewayNoAccInterestThenQSubThenRegularSub but simulate
  5635  // older incorrect behavior.
  5636  func TestGatewayHandleUnexpectedASubUnsub(t *testing.T) {
  5637  	GatewayDoNotForceInterestOnlyMode(true)
  5638  	defer GatewayDoNotForceInterestOnlyMode(false)
  5639  
  5640  	ob := testDefaultOptionsForGateway("B")
  5641  	sb := runGatewayServer(ob)
  5642  	defer sb.Shutdown()
  5643  
  5644  	oa := testGatewayOptionsFromToWithServers(t, "A", "B", sb)
  5645  	sa := runGatewayServer(oa)
  5646  	defer sa.Shutdown()
  5647  
  5648  	waitForOutboundGateways(t, sa, 1, time.Second)
  5649  	waitForInboundGateways(t, sa, 1, time.Second)
  5650  	waitForOutboundGateways(t, sb, 1, time.Second)
  5651  	waitForInboundGateways(t, sb, 1, time.Second)
  5652  
  5653  	// Connect on A and send a message
  5654  	ncA := natsConnect(t, fmt.Sprintf("nats://%s:%d", oa.Host, oa.Port))
  5655  	defer ncA.Close()
  5656  	natsPub(t, ncA, "foo", []byte("hello"))
  5657  	natsFlush(t, ncA)
  5658  
  5659  	// expect an A- on return
  5660  	gwb := sa.getOutboundGatewayConnection("B")
  5661  	checkForAccountNoInterest(t, gwb, globalAccountName, true, time.Second)
  5662  
  5663  	// Create a connection o B, and create a queue sub first
  5664  	ncB := natsConnect(t, fmt.Sprintf("nats://%s:%d", ob.Host, ob.Port))
  5665  	defer ncB.Close()
  5666  	qsub := natsQueueSubSync(t, ncB, "bar", "queue")
  5667  	natsFlush(t, ncB)
  5668  
  5669  	// A should have received a queue interest
  5670  	checkForRegisteredQSubInterest(t, sa, "B", globalAccountName, "bar", 1, time.Second)
  5671  
  5672  	// Now on B, create a regular sub
  5673  	sub := natsSubSync(t, ncB, "baz")
  5674  	natsFlush(t, ncB)
  5675  	// and reproduce old, wrong, behavior that would have resulted in sending an A-
  5676  	gwA := getInboundGatewayConnection(sb, "A")
  5677  	gwA.mu.Lock()
  5678  	gwA.enqueueProto([]byte("A- $G\r\n"))
  5679  	gwA.mu.Unlock()
  5680  
  5681  	// From A now, produce a message on each subject and
  5682  	// expect both subs to receive their message.
  5683  	msgForQSub := []byte("msg_qsub")
  5684  	natsPub(t, ncA, "bar", msgForQSub)
  5685  	natsFlush(t, ncA)
  5686  
  5687  	if msg := natsNexMsg(t, qsub, time.Second); !bytes.Equal(msgForQSub, msg.Data) {
  5688  		t.Fatalf("Expected msg for queue sub to be %q, got %q", msgForQSub, msg.Data)
  5689  	}
  5690  
  5691  	// Publish for the regular sub
  5692  	msgForSub := []byte("msg_sub")
  5693  	natsPub(t, ncA, "baz", msgForSub)
  5694  	natsFlush(t, ncA)
  5695  
  5696  	if msg := natsNexMsg(t, sub, time.Second); !bytes.Equal(msgForSub, msg.Data) {
  5697  		t.Fatalf("Expected msg for sub to be %q, got %q", msgForSub, msg.Data)
  5698  	}
  5699  
  5700  	// Remove all subs on B.
  5701  	qsub.Unsubscribe()
  5702  	sub.Unsubscribe()
  5703  	ncB.Flush()
  5704  
  5705  	// Produce a message from A expect A-
  5706  	natsPub(t, ncA, "foo", []byte("hello"))
  5707  	natsFlush(t, ncA)
  5708  
  5709  	// expect an A- on return
  5710  	checkForAccountNoInterest(t, gwb, globalAccountName, true, time.Second)
  5711  
  5712  	// Simulate B sending another A-, on A account no interest should remain same.
  5713  	gwA.mu.Lock()
  5714  	gwA.enqueueProto([]byte("A- $G\r\n"))
  5715  	gwA.mu.Unlock()
  5716  
  5717  	checkForAccountNoInterest(t, gwb, globalAccountName, true, time.Second)
  5718  
  5719  	// Create a queue sub on B
  5720  	qsub = natsQueueSubSync(t, ncB, "bar", "queue")
  5721  	natsFlush(t, ncB)
  5722  
  5723  	checkForRegisteredQSubInterest(t, sa, "B", globalAccountName, "bar", 1, time.Second)
  5724  
  5725  	// Make B send an A+ and verify that we sitll have the registered qsub interest
  5726  	gwA.mu.Lock()
  5727  	gwA.enqueueProto([]byte("A+ $G\r\n"))
  5728  	gwA.mu.Unlock()
  5729  
  5730  	// Give a chance to A to possibly misbehave when receiving this proto
  5731  	time.Sleep(250 * time.Millisecond)
  5732  	// Now check interest is still there
  5733  	checkForRegisteredQSubInterest(t, sa, "B", globalAccountName, "bar", 1, time.Second)
  5734  
  5735  	qsub.Unsubscribe()
  5736  	natsFlush(t, ncB)
  5737  	checkForRegisteredQSubInterest(t, sa, "B", globalAccountName, "bar", 0, time.Second)
  5738  
  5739  	// Send A-, server A should set entry to nil
  5740  	gwA.mu.Lock()
  5741  	gwA.enqueueProto([]byte("A- $G\r\n"))
  5742  	gwA.mu.Unlock()
  5743  	checkForAccountNoInterest(t, gwb, globalAccountName, true, time.Second)
  5744  
  5745  	// Send A+ and entry should be removed since there is no longer reason to
  5746  	// keep the entry.
  5747  	gwA.mu.Lock()
  5748  	gwA.enqueueProto([]byte("A+ $G\r\n"))
  5749  	gwA.mu.Unlock()
  5750  	checkForAccountNoInterest(t, gwb, globalAccountName, false, time.Second)
  5751  
  5752  	// Last A+ should not change because account already removed from map.
  5753  	gwA.mu.Lock()
  5754  	gwA.enqueueProto([]byte("A+ $G\r\n"))
  5755  	gwA.mu.Unlock()
  5756  	checkForAccountNoInterest(t, gwb, globalAccountName, false, time.Second)
  5757  }
  5758  
  5759  type captureGWInterestSwitchLogger struct {
  5760  	DummyLogger
  5761  	imss []string
  5762  }
  5763  
  5764  func (l *captureGWInterestSwitchLogger) Debugf(format string, args ...interface{}) {
  5765  	l.Lock()
  5766  	msg := fmt.Sprintf(format, args...)
  5767  	if strings.Contains(msg, fmt.Sprintf("switching account %q to %s mode", globalAccountName, InterestOnly)) ||
  5768  		strings.Contains(msg, fmt.Sprintf("switching account %q to %s mode complete", globalAccountName, InterestOnly)) {
  5769  		l.imss = append(l.imss, msg)
  5770  	}
  5771  	l.Unlock()
  5772  }
  5773  
  5774  func TestGatewayLogAccountInterestModeSwitch(t *testing.T) {
  5775  	GatewayDoNotForceInterestOnlyMode(true)
  5776  	defer GatewayDoNotForceInterestOnlyMode(false)
  5777  
  5778  	ob := testDefaultOptionsForGateway("B")
  5779  	sb := runGatewayServer(ob)
  5780  	defer sb.Shutdown()
  5781  
  5782  	logB := &captureGWInterestSwitchLogger{}
  5783  	sb.SetLogger(logB, true, true)
  5784  
  5785  	oa := testGatewayOptionsFromToWithServers(t, "A", "B", sb)
  5786  	sa := runGatewayServer(oa)
  5787  	defer sa.Shutdown()
  5788  
  5789  	logA := &captureGWInterestSwitchLogger{}
  5790  	sa.SetLogger(logA, true, true)
  5791  
  5792  	waitForOutboundGateways(t, sa, 1, 2*time.Second)
  5793  	waitForInboundGateways(t, sa, 1, 2*time.Second)
  5794  	waitForOutboundGateways(t, sb, 1, 2*time.Second)
  5795  	waitForInboundGateways(t, sb, 1, 2*time.Second)
  5796  
  5797  	ncB := natsConnect(t, fmt.Sprintf("nats://127.0.0.1:%d", ob.Port))
  5798  	defer ncB.Close()
  5799  	natsSubSync(t, ncB, "foo")
  5800  	natsFlush(t, ncB)
  5801  
  5802  	ncA := natsConnect(t, fmt.Sprintf("nats://127.0.0.1:%d", oa.Port))
  5803  	defer ncA.Close()
  5804  	for i := 0; i < gatewayMaxRUnsubBeforeSwitch+10; i++ {
  5805  		subj := fmt.Sprintf("bar.%d", i)
  5806  		natsPub(t, ncA, subj, []byte("hello"))
  5807  	}
  5808  	natsFlush(t, ncA)
  5809  
  5810  	gwA := getInboundGatewayConnection(sb, "A")
  5811  	checkFor(t, 2*time.Second, 15*time.Millisecond, func() error {
  5812  		mode := Optimistic
  5813  		gwA.mu.Lock()
  5814  		e := gwA.gw.insim[globalAccountName]
  5815  		if e != nil {
  5816  			mode = e.mode
  5817  		}
  5818  		gwA.mu.Unlock()
  5819  		if mode != InterestOnly {
  5820  			return fmt.Errorf("not switched yet")
  5821  		}
  5822  		return nil
  5823  	})
  5824  
  5825  	checkGWInterestOnlyMode(t, sa, "B", globalAccountName)
  5826  
  5827  	checkLog := func(t *testing.T, l *captureGWInterestSwitchLogger) {
  5828  		t.Helper()
  5829  		l.Lock()
  5830  		logs := append([]string(nil), l.imss...)
  5831  		l.Unlock()
  5832  
  5833  		if len(logs) != 2 {
  5834  			t.Fatalf("Expected 2 logs about switching to interest-only, got %v", logs)
  5835  		}
  5836  		if !strings.Contains(logs[0], "switching account") {
  5837  			t.Fatalf("First log statement should have been about switching, got %v", logs[0])
  5838  		}
  5839  		if !strings.Contains(logs[1], "complete") {
  5840  			t.Fatalf("Second log statement should have been about having switched, got %v", logs[1])
  5841  		}
  5842  	}
  5843  	checkLog(t, logB)
  5844  	checkLog(t, logA)
  5845  
  5846  	// Clear log of server B
  5847  	logB.Lock()
  5848  	logB.imss = nil
  5849  	logB.Unlock()
  5850  
  5851  	// Force a switch on B to inbound gateway from A and make sure that it is
  5852  	// a no-op since this gateway connection has already been switched.
  5853  	sb.switchAccountToInterestMode(globalAccountName)
  5854  
  5855  	logB.Lock()
  5856  	didSwitch := len(logB.imss) > 0
  5857  	logB.Unlock()
  5858  	if didSwitch {
  5859  		t.Fatalf("Attempted to switch while it was already in interest mode only")
  5860  	}
  5861  }
  5862  
  5863  func TestGatewayAccountInterestModeSwitchOnlyOncePerAccount(t *testing.T) {
  5864  	GatewayDoNotForceInterestOnlyMode(true)
  5865  	defer GatewayDoNotForceInterestOnlyMode(false)
  5866  
  5867  	ob := testDefaultOptionsForGateway("B")
  5868  	sb := runGatewayServer(ob)
  5869  	defer sb.Shutdown()
  5870  
  5871  	logB := &captureGWInterestSwitchLogger{}
  5872  	sb.SetLogger(logB, true, true)
  5873  
  5874  	nc := natsConnect(t, sb.ClientURL())
  5875  	defer nc.Close()
  5876  	natsSubSync(t, nc, "foo")
  5877  	natsQueueSubSync(t, nc, "bar", "baz")
  5878  
  5879  	oa := testGatewayOptionsFromToWithServers(t, "A", "B", sb)
  5880  	sa := runGatewayServer(oa)
  5881  	defer sa.Shutdown()
  5882  
  5883  	waitForOutboundGateways(t, sa, 1, 2*time.Second)
  5884  	waitForInboundGateways(t, sa, 1, 2*time.Second)
  5885  	waitForOutboundGateways(t, sb, 1, 2*time.Second)
  5886  	waitForInboundGateways(t, sb, 1, 2*time.Second)
  5887  
  5888  	wg := sync.WaitGroup{}
  5889  	total := 20
  5890  	wg.Add(total)
  5891  	for i := 0; i < total; i++ {
  5892  		go func() {
  5893  			sb.switchAccountToInterestMode(globalAccountName)
  5894  			wg.Done()
  5895  		}()
  5896  	}
  5897  	wg.Wait()
  5898  	time.Sleep(50 * time.Millisecond)
  5899  	logB.Lock()
  5900  	nl := len(logB.imss)
  5901  	logB.Unlock()
  5902  	// There should be a trace for switching and when switch is complete
  5903  	if nl != 2 {
  5904  		t.Fatalf("Attempted to switch account too many times, number lines=%v", nl)
  5905  	}
  5906  }
  5907  
  5908  func TestGatewaySingleOutbound(t *testing.T) {
  5909  	l, err := natsListen("tcp", "127.0.0.1:0")
  5910  	if err != nil {
  5911  		t.Fatalf("Error on listen: %v", err)
  5912  	}
  5913  	defer l.Close()
  5914  	port := l.Addr().(*net.TCPAddr).Port
  5915  
  5916  	oa := testGatewayOptionsFromToWithTLS(t, "A", "B", []string{fmt.Sprintf("nats://127.0.0.1:%d", port)})
  5917  	oa.Gateway.TLSTimeout = 0.1
  5918  	sa := runGatewayServer(oa)
  5919  	defer sa.Shutdown()
  5920  
  5921  	// Wait a bit for reconnections
  5922  	time.Sleep(500 * time.Millisecond)
  5923  
  5924  	// Now prepare gateway B to take place of the bare listener.
  5925  	ob := testGatewayOptionsWithTLS(t, "B")
  5926  	// There is a risk that when stopping the listener and starting
  5927  	// the actual server, that port is being reused by some other process.
  5928  	ob.Gateway.Port = port
  5929  	l.Close()
  5930  	sb := runGatewayServer(ob)
  5931  	defer sb.Shutdown()
  5932  
  5933  	// To make sure that we don't fail, bump the TLSTimeout now.
  5934  	cfg := sa.getRemoteGateway("B")
  5935  	cfg.Lock()
  5936  	cfg.TLSTimeout = 2.0
  5937  	cfg.Unlock()
  5938  
  5939  	waitForOutboundGateways(t, sa, 1, time.Second)
  5940  	sa.gateway.Lock()
  5941  	lm := len(sa.gateway.out)
  5942  	sa.gateway.Unlock()
  5943  	if lm != 1 {
  5944  		t.Fatalf("Expected 1 outbound, got %v", lm)
  5945  	}
  5946  }
  5947  
  5948  func TestGatewayReplyMapTracking(t *testing.T) {
  5949  	// Increase the recSubExp value on servers so we have time
  5950  	// to check the replies mapping structures.
  5951  	subExp := 400 * time.Millisecond
  5952  	setRecSub := func(s *Server) {
  5953  		s.gateway.pasi.Lock()
  5954  		s.gateway.recSubExp = subExp
  5955  		s.gateway.pasi.Unlock()
  5956  	}
  5957  
  5958  	ob := testDefaultOptionsForGateway("B")
  5959  	sb := runGatewayServer(ob)
  5960  	defer sb.Shutdown()
  5961  	setRecSub(sb)
  5962  
  5963  	oa := testGatewayOptionsFromToWithServers(t, "A", "B", sb)
  5964  	sa := runGatewayServer(oa)
  5965  	defer sa.Shutdown()
  5966  	setRecSub(sa)
  5967  
  5968  	waitForOutboundGateways(t, sa, 1, 2*time.Second)
  5969  	waitForInboundGateways(t, sa, 1, 2*time.Second)
  5970  	waitForOutboundGateways(t, sb, 1, 2*time.Second)
  5971  	waitForInboundGateways(t, sb, 1, 2*time.Second)
  5972  
  5973  	ncb := natsConnect(t, sb.ClientURL())
  5974  	defer ncb.Close()
  5975  	count := 0
  5976  	total := 100
  5977  	ch := make(chan bool, 1)
  5978  	natsSub(t, ncb, "foo", func(m *nats.Msg) {
  5979  		m.Respond([]byte("reply"))
  5980  		if count++; count == total {
  5981  			ch <- true
  5982  		}
  5983  	})
  5984  	natsFlush(t, ncb)
  5985  
  5986  	var bc *client
  5987  	sb.mu.Lock()
  5988  	for _, c := range sb.clients {
  5989  		bc = c
  5990  		break
  5991  	}
  5992  	sb.mu.Unlock()
  5993  
  5994  	nca := natsConnect(t, sa.ClientURL())
  5995  	defer nca.Close()
  5996  
  5997  	replySub := natsSubSync(t, nca, "bar.>")
  5998  	for i := 0; i < total; i++ {
  5999  		nca.PublishRequest("foo", fmt.Sprintf("bar.%d", i), []byte("request"))
  6000  	}
  6001  
  6002  	waitCh(t, ch, "Did not receive all requests")
  6003  
  6004  	check := func(t *testing.T, expectedIndicator int32, expectLenMap int, expectedSrvMapEmpty bool) {
  6005  		t.Helper()
  6006  		bc.mu.Lock()
  6007  		mapIndicator := atomic.LoadInt32(&bc.gwReplyMapping.check)
  6008  		var lenMap int
  6009  		if bc.gwReplyMapping.mapping != nil {
  6010  			lenMap = len(bc.gwReplyMapping.mapping)
  6011  		}
  6012  		bc.mu.Unlock()
  6013  		if mapIndicator != expectedIndicator {
  6014  			t.Fatalf("Client should map indicator should be %v, got %v", expectedIndicator, mapIndicator)
  6015  		}
  6016  		if lenMap != expectLenMap {
  6017  			t.Fatalf("Client map should have %v entries, got %v", expectLenMap, lenMap)
  6018  		}
  6019  		srvMapEmpty := true
  6020  		sb.gwrm.m.Range(func(_, _ interface{}) bool {
  6021  			srvMapEmpty = false
  6022  			return false
  6023  		})
  6024  		if srvMapEmpty != expectedSrvMapEmpty {
  6025  			t.Fatalf("Expected server map to be empty=%v, got %v", expectedSrvMapEmpty, srvMapEmpty)
  6026  		}
  6027  	}
  6028  	// Check that indicator is set and that there "total" entries in the map
  6029  	// and that srv map is not empty
  6030  	check(t, 1, total, false)
  6031  
  6032  	// Receive all replies
  6033  	for i := 0; i < total; i++ {
  6034  		natsNexMsg(t, replySub, time.Second)
  6035  	}
  6036  
  6037  	// Wait until entries expire
  6038  	time.Sleep(2*subExp + 100*time.Millisecond)
  6039  
  6040  	// Now check again.
  6041  	check(t, 0, 0, true)
  6042  }
  6043  
  6044  func TestGatewayNoAccountUnsubWhenServiceReplyInUse(t *testing.T) {
  6045  	oa := testDefaultOptionsForGateway("A")
  6046  	setAccountUserPassInOptions(oa, "$foo", "clientFoo", "password")
  6047  	setAccountUserPassInOptions(oa, "$bar", "clientBar", "password")
  6048  	sa := runGatewayServer(oa)
  6049  	defer sa.Shutdown()
  6050  
  6051  	ob := testGatewayOptionsFromToWithServers(t, "B", "A", sa)
  6052  	setAccountUserPassInOptions(ob, "$foo", "clientFoo", "password")
  6053  	setAccountUserPassInOptions(ob, "$bar", "clientBar", "password")
  6054  	sb := runGatewayServer(ob)
  6055  	defer sb.Shutdown()
  6056  
  6057  	waitForOutboundGateways(t, sa, 1, time.Second)
  6058  	waitForOutboundGateways(t, sb, 1, time.Second)
  6059  	waitForInboundGateways(t, sa, 1, time.Second)
  6060  	waitForInboundGateways(t, sb, 1, time.Second)
  6061  
  6062  	// Get accounts
  6063  	fooA, _ := sa.LookupAccount("$foo")
  6064  	barA, _ := sa.LookupAccount("$bar")
  6065  	fooB, _ := sb.LookupAccount("$foo")
  6066  	barB, _ := sb.LookupAccount("$bar")
  6067  
  6068  	// Add in the service export for the requests. Make it public.
  6069  	fooA.AddServiceExport("test.request", nil)
  6070  	fooB.AddServiceExport("test.request", nil)
  6071  
  6072  	// Add import abilities to server B's bar account from foo.
  6073  	if err := barB.AddServiceImport(fooB, "foo.request", "test.request"); err != nil {
  6074  		t.Fatalf("Error adding service import: %v", err)
  6075  	}
  6076  	// Same on A.
  6077  	if err := barA.AddServiceImport(fooA, "foo.request", "test.request"); err != nil {
  6078  		t.Fatalf("Error adding service import: %v", err)
  6079  	}
  6080  
  6081  	// clientA will be connected to srvA and be the service endpoint and responder.
  6082  	aURL := fmt.Sprintf("nats://clientFoo:password@127.0.0.1:%d", oa.Port)
  6083  	clientA := natsConnect(t, aURL)
  6084  	defer clientA.Close()
  6085  
  6086  	natsSub(t, clientA, "test.request", func(m *nats.Msg) {
  6087  		m.Respond([]byte("reply"))
  6088  	})
  6089  	natsFlush(t, clientA)
  6090  
  6091  	// Now setup client B on srvB who will send the requests.
  6092  	bURL := fmt.Sprintf("nats://clientBar:password@127.0.0.1:%d", ob.Port)
  6093  	clientB := natsConnect(t, bURL)
  6094  	defer clientB.Close()
  6095  
  6096  	if _, err := clientB.Request("foo.request", []byte("request"), time.Second); err != nil {
  6097  		t.Fatalf("Did not get the reply: %v", err)
  6098  	}
  6099  
  6100  	quitCh := make(chan bool, 1)
  6101  	wg := sync.WaitGroup{}
  6102  	wg.Add(1)
  6103  	go func() {
  6104  		defer wg.Done()
  6105  
  6106  		for {
  6107  			select {
  6108  			case <-quitCh:
  6109  				return
  6110  			default:
  6111  				clientA.Publish("any.subject", []byte("any message"))
  6112  				time.Sleep(time.Millisecond)
  6113  			}
  6114  		}
  6115  	}()
  6116  	for i := 0; i < 1000; i++ {
  6117  		if _, err := clientB.Request("foo.request", []byte("request"), time.Second); err != nil {
  6118  			t.Fatalf("Did not get the reply: %v", err)
  6119  		}
  6120  	}
  6121  	close(quitCh)
  6122  	wg.Wait()
  6123  }
  6124  
  6125  func TestGatewayCloseTLSConnection(t *testing.T) {
  6126  	oa := testGatewayOptionsWithTLS(t, "A")
  6127  	oa.DisableShortFirstPing = true
  6128  	oa.Gateway.TLSConfig.ClientAuth = tls.NoClientCert
  6129  	oa.Gateway.TLSTimeout = 100
  6130  	sa := runGatewayServer(oa)
  6131  	defer sa.Shutdown()
  6132  
  6133  	ob1 := testGatewayOptionsFromToWithTLS(t, "B", "A", []string{fmt.Sprintf("nats://127.0.0.1:%d", sa.GatewayAddr().Port)})
  6134  	sb1 := runGatewayServer(ob1)
  6135  	defer sb1.Shutdown()
  6136  
  6137  	waitForOutboundGateways(t, sa, 1, 2*time.Second)
  6138  	waitForInboundGateways(t, sa, 1, 2*time.Second)
  6139  	waitForOutboundGateways(t, sb1, 1, 2*time.Second)
  6140  	waitForInboundGateways(t, sb1, 1, 2*time.Second)
  6141  
  6142  	endpoint := fmt.Sprintf("%s:%d", oa.Gateway.Host, oa.Gateway.Port)
  6143  	conn, err := net.DialTimeout("tcp", endpoint, 2*time.Second)
  6144  	if err != nil {
  6145  		t.Fatalf("Unexpected error on dial: %v", err)
  6146  	}
  6147  	defer conn.Close()
  6148  
  6149  	tlsConn := tls.Client(conn, &tls.Config{InsecureSkipVerify: true})
  6150  	defer tlsConn.Close()
  6151  	if err := tlsConn.Handshake(); err != nil {
  6152  		t.Fatalf("Unexpected error during handshake: %v", err)
  6153  	}
  6154  	connectOp := []byte("CONNECT {\"name\":\"serverID\",\"verbose\":false,\"pedantic\":false,\"tls_required\":true,\"gateway\":\"B\"}\r\n")
  6155  	if _, err := tlsConn.Write(connectOp); err != nil {
  6156  		t.Fatalf("Unexpected error writing CONNECT: %v", err)
  6157  	}
  6158  	infoOp := []byte("INFO {\"server_id\":\"serverID\",\"tls_required\":true,\"gateway\":\"B\",\"gateway_nrp\":true}\r\n")
  6159  	if _, err := tlsConn.Write(infoOp); err != nil {
  6160  		t.Fatalf("Unexpected error writing CONNECT: %v", err)
  6161  	}
  6162  	if _, err := tlsConn.Write([]byte("PING\r\n")); err != nil {
  6163  		t.Fatalf("Unexpected error writing PING: %v", err)
  6164  	}
  6165  
  6166  	// Get gw connection
  6167  	var gw *client
  6168  	checkFor(t, time.Second, 15*time.Millisecond, func() error {
  6169  		sa.gateway.RLock()
  6170  		for _, g := range sa.gateway.in {
  6171  			g.mu.Lock()
  6172  			if g.opts.Name == "serverID" {
  6173  				gw = g
  6174  			}
  6175  			g.mu.Unlock()
  6176  			break
  6177  		}
  6178  		sa.gateway.RUnlock()
  6179  		if gw == nil {
  6180  			return fmt.Errorf("No gw registered yet")
  6181  		}
  6182  		return nil
  6183  	})
  6184  	// Fill the buffer. We want to timeout on write so that nc.Close()
  6185  	// would block due to a write that cannot complete.
  6186  	buf := make([]byte, 64*1024)
  6187  	done := false
  6188  	for !done {
  6189  		gw.nc.SetWriteDeadline(time.Now().Add(time.Second))
  6190  		if _, err := gw.nc.Write(buf); err != nil {
  6191  			done = true
  6192  		}
  6193  		gw.nc.SetWriteDeadline(time.Time{})
  6194  	}
  6195  	ch := make(chan bool)
  6196  	go func() {
  6197  		select {
  6198  		case <-ch:
  6199  			return
  6200  		case <-time.After(3 * time.Second):
  6201  			fmt.Println("!!!! closeConnection is blocked, test will hang !!!")
  6202  			return
  6203  		}
  6204  	}()
  6205  	// Close the gateway
  6206  	gw.closeConnection(SlowConsumerWriteDeadline)
  6207  	ch <- true
  6208  }
  6209  
  6210  func TestGatewayNoCrashOnInvalidSubject(t *testing.T) {
  6211  	ob := testDefaultOptionsForGateway("B")
  6212  	sb := runGatewayServer(ob)
  6213  	defer sb.Shutdown()
  6214  
  6215  	oa := testGatewayOptionsFromToWithServers(t, "A", "B", sb)
  6216  	sa := runGatewayServer(oa)
  6217  	defer sa.Shutdown()
  6218  
  6219  	waitForOutboundGateways(t, sa, 1, 2*time.Second)
  6220  	waitForInboundGateways(t, sa, 1, 2*time.Second)
  6221  	waitForOutboundGateways(t, sb, 1, 2*time.Second)
  6222  	waitForInboundGateways(t, sb, 1, 2*time.Second)
  6223  
  6224  	ncB := natsConnect(t, sb.ClientURL())
  6225  	defer ncB.Close()
  6226  
  6227  	natsSubSync(t, ncB, "foo")
  6228  	natsFlush(t, ncB)
  6229  
  6230  	ncA := natsConnect(t, sa.ClientURL())
  6231  	defer ncA.Close()
  6232  
  6233  	// Send on an invalid subject. Since there is interest on B,
  6234  	// we will receive an RS- instead of A-
  6235  	natsPub(t, ncA, "bar..baz", []byte("bad subject"))
  6236  	natsFlush(t, ncA)
  6237  
  6238  	// Now create on B a sub on a wildcard subject
  6239  	sub := natsSubSync(t, ncB, "bar.*")
  6240  	natsFlush(t, ncB)
  6241  
  6242  	// Server should not have crashed...
  6243  	natsPub(t, ncA, "bar.baz", []byte("valid subject"))
  6244  	if _, err := sub.NextMsg(time.Second); err != nil {
  6245  		t.Fatalf("Error getting message: %v", err)
  6246  	}
  6247  }
  6248  
  6249  func TestGatewayUpdateURLsFromRemoteCluster(t *testing.T) {
  6250  	ob1 := testDefaultOptionsForGateway("B")
  6251  	sb1 := RunServer(ob1)
  6252  	defer sb1.Shutdown()
  6253  
  6254  	oa := testGatewayOptionsFromToWithServers(t, "A", "B", sb1)
  6255  	sa := RunServer(oa)
  6256  	defer sa.Shutdown()
  6257  
  6258  	waitForOutboundGateways(t, sa, 1, 2*time.Second)
  6259  	waitForOutboundGateways(t, sb1, 1, 2*time.Second)
  6260  
  6261  	// Add a server to cluster B.
  6262  	ob2 := testDefaultOptionsForGateway("B")
  6263  	ob2.Routes = RoutesFromStr(fmt.Sprintf("nats://127.0.0.1:%d", ob1.Cluster.Port))
  6264  	sb2 := RunServer(ob2)
  6265  	defer sb2.Shutdown()
  6266  
  6267  	checkClusterFormed(t, sb1, sb2)
  6268  	waitForOutboundGateways(t, sb2, 1, 2*time.Second)
  6269  	waitForInboundGateways(t, sa, 2, 2*time.Second)
  6270  
  6271  	pmap := make(map[int]string)
  6272  	pmap[ob1.Gateway.Port] = "B1"
  6273  	pmap[ob2.Gateway.Port] = "B2"
  6274  
  6275  	checkURLs := func(eurls map[string]string) {
  6276  		t.Helper()
  6277  		checkFor(t, 2*time.Second, 15*time.Millisecond, func() error {
  6278  			rg := sa.getRemoteGateway("B")
  6279  			urls := rg.getURLsAsStrings()
  6280  			for _, u := range urls {
  6281  				if _, ok := eurls[u]; !ok {
  6282  					_, sport, _ := net.SplitHostPort(u)
  6283  					port, _ := strconv.Atoi(sport)
  6284  					return fmt.Errorf("URL %q (%s) should not be in the list of urls (%q)", u, pmap[port], eurls)
  6285  				}
  6286  			}
  6287  			return nil
  6288  		})
  6289  	}
  6290  	expected := make(map[string]string)
  6291  	expected[fmt.Sprintf("127.0.0.1:%d", ob1.Gateway.Port)] = "B1"
  6292  	expected[fmt.Sprintf("127.0.0.1:%d", ob2.Gateway.Port)] = "B2"
  6293  	checkURLs(expected)
  6294  
  6295  	// Add another in cluster B
  6296  	ob3 := testDefaultOptionsForGateway("B")
  6297  	ob3.Routes = RoutesFromStr(fmt.Sprintf("nats://127.0.0.1:%d", ob1.Cluster.Port))
  6298  	sb3 := RunServer(ob3)
  6299  	defer sb3.Shutdown()
  6300  
  6301  	checkClusterFormed(t, sb1, sb2, sb3)
  6302  	waitForOutboundGateways(t, sb3, 1, 2*time.Second)
  6303  	waitForInboundGateways(t, sa, 3, 2*time.Second)
  6304  
  6305  	pmap[ob3.Gateway.Port] = "B3"
  6306  
  6307  	expected = make(map[string]string)
  6308  	expected[fmt.Sprintf("127.0.0.1:%d", ob1.Gateway.Port)] = "B1"
  6309  	expected[fmt.Sprintf("127.0.0.1:%d", ob2.Gateway.Port)] = "B2"
  6310  	expected[fmt.Sprintf("127.0.0.1:%d", ob3.Gateway.Port)] = "B3"
  6311  	checkURLs(expected)
  6312  
  6313  	// Now stop server SB2, which should cause SA to remove it from its list.
  6314  	sb2.Shutdown()
  6315  
  6316  	expected = make(map[string]string)
  6317  	expected[fmt.Sprintf("127.0.0.1:%d", ob1.Gateway.Port)] = "B1"
  6318  	expected[fmt.Sprintf("127.0.0.1:%d", ob3.Gateway.Port)] = "B3"
  6319  	checkURLs(expected)
  6320  }
  6321  
  6322  type capturePingConn struct {
  6323  	net.Conn
  6324  	ch chan struct{}
  6325  }
  6326  
  6327  func (c *capturePingConn) Write(b []byte) (int, error) {
  6328  	if bytes.Contains(b, []byte(pingProto)) {
  6329  		select {
  6330  		case c.ch <- struct{}{}:
  6331  		default:
  6332  		}
  6333  	}
  6334  	return c.Conn.Write(b)
  6335  }
  6336  
  6337  func TestGatewayPings(t *testing.T) {
  6338  	gatewayMaxPingInterval = 50 * time.Millisecond
  6339  	defer func() { gatewayMaxPingInterval = gwMaxPingInterval }()
  6340  
  6341  	ob := testDefaultOptionsForGateway("B")
  6342  	sb := RunServer(ob)
  6343  	defer sb.Shutdown()
  6344  
  6345  	oa := testGatewayOptionsFromToWithServers(t, "A", "B", sb)
  6346  	sa := RunServer(oa)
  6347  	defer sa.Shutdown()
  6348  
  6349  	waitForInboundGateways(t, sa, 1, 2*time.Second)
  6350  	waitForOutboundGateways(t, sa, 1, 2*time.Second)
  6351  	waitForInboundGateways(t, sb, 1, 2*time.Second)
  6352  	waitForOutboundGateways(t, sb, 1, 2*time.Second)
  6353  
  6354  	c := sa.getOutboundGatewayConnection("B")
  6355  	ch := make(chan struct{}, 1)
  6356  	c.mu.Lock()
  6357  	c.nc = &capturePingConn{c.nc, ch}
  6358  	c.mu.Unlock()
  6359  
  6360  	for i := 0; i < 5; i++ {
  6361  		select {
  6362  		case <-ch:
  6363  		case <-time.After(250 * time.Millisecond):
  6364  			t.Fatalf("Did not send PING")
  6365  		}
  6366  	}
  6367  }
  6368  
  6369  func TestGatewayTLSConfigReload(t *testing.T) {
  6370  	template := `
  6371  		listen: 127.0.0.1:-1
  6372  		gateway {
  6373  			name: "A"
  6374  			listen: "127.0.0.1:-1"
  6375  			tls {
  6376  				cert_file: "../test/configs/certs/server-cert.pem"
  6377  				key_file:  "../test/configs/certs/server-key.pem"
  6378  				%s
  6379  				timeout: 2
  6380  			}
  6381  		}
  6382  	`
  6383  	confA := createConfFile(t, []byte(fmt.Sprintf(template, "")))
  6384  
  6385  	srvA, optsA := RunServerWithConfig(confA)
  6386  	defer srvA.Shutdown()
  6387  
  6388  	optsB := testGatewayOptionsFromToWithTLS(t, "B", "A", []string{fmt.Sprintf("nats://127.0.0.1:%d", optsA.Gateway.Port)})
  6389  	srvB := runGatewayServer(optsB)
  6390  	defer srvB.Shutdown()
  6391  
  6392  	waitForGatewayFailedConnect(t, srvB, "A", true, time.Second)
  6393  
  6394  	reloadUpdateConfig(t, srvA, confA, fmt.Sprintf(template, `ca_file:   "../test/configs/certs/ca.pem"`))
  6395  
  6396  	waitForInboundGateways(t, srvA, 1, time.Second)
  6397  	waitForOutboundGateways(t, srvA, 1, time.Second)
  6398  	waitForInboundGateways(t, srvB, 1, time.Second)
  6399  	waitForOutboundGateways(t, srvB, 1, time.Second)
  6400  }
  6401  
  6402  func TestGatewayTLSConfigReloadForRemote(t *testing.T) {
  6403  	SetGatewaysSolicitDelay(5 * time.Millisecond)
  6404  	defer ResetGatewaysSolicitDelay()
  6405  
  6406  	optsA := testGatewayOptionsWithTLS(t, "A")
  6407  	srvA := runGatewayServer(optsA)
  6408  	defer srvA.Shutdown()
  6409  
  6410  	template := `
  6411  		listen: 127.0.0.1:-1
  6412  		gateway {
  6413  			name: "B"
  6414  			listen: "127.0.0.1:-1"
  6415  			tls {
  6416  				cert_file: "../test/configs/certs/server-cert.pem"
  6417  				key_file:  "../test/configs/certs/server-key.pem"
  6418  				ca_file:   "../test/configs/certs/ca.pem"
  6419  				timeout: 2
  6420  			}
  6421  			gateways [
  6422  				{
  6423  					name: "A"
  6424  					url: "nats://127.0.0.1:%d"
  6425  					tls {
  6426  						cert_file: "../test/configs/certs/server-cert.pem"
  6427  						key_file:  "../test/configs/certs/server-key.pem"
  6428  						%s
  6429  						timeout: 2
  6430  					}
  6431  				}
  6432  			]
  6433  		}
  6434  	`
  6435  	confB := createConfFile(t, []byte(fmt.Sprintf(template, optsA.Gateway.Port, "")))
  6436  
  6437  	srvB, _ := RunServerWithConfig(confB)
  6438  	defer srvB.Shutdown()
  6439  
  6440  	waitForGatewayFailedConnect(t, srvB, "A", true, time.Second)
  6441  
  6442  	reloadUpdateConfig(t, srvB, confB, fmt.Sprintf(template, optsA.Gateway.Port, `ca_file: "../test/configs/certs/ca.pem"`))
  6443  
  6444  	waitForInboundGateways(t, srvA, 1, time.Second)
  6445  	waitForOutboundGateways(t, srvA, 1, time.Second)
  6446  	waitForInboundGateways(t, srvB, 1, time.Second)
  6447  	waitForOutboundGateways(t, srvB, 1, time.Second)
  6448  }
  6449  
  6450  func TestGatewayAuthDiscovered(t *testing.T) {
  6451  	SetGatewaysSolicitDelay(5 * time.Millisecond)
  6452  	defer ResetGatewaysSolicitDelay()
  6453  
  6454  	confA := createConfFile(t, []byte(`
  6455  		listen: 127.0.0.1:-1
  6456  		gateway {
  6457  			name: "A"
  6458  			listen: 127.0.0.1:-1
  6459  			authorization: { user: gwuser, password: changeme }
  6460  		}
  6461  	`))
  6462  	srvA, optsA := RunServerWithConfig(confA)
  6463  	defer srvA.Shutdown()
  6464  
  6465  	confB := createConfFile(t, []byte(fmt.Sprintf(`
  6466  		listen: 127.0.0.1:-1
  6467  		gateway {
  6468  			name: "B"
  6469  			listen: 127.0.0.1:-1
  6470  			authorization: { user: gwuser, password: changeme }
  6471  			gateways: [
  6472  				{ name: A, url: nats://gwuser:changeme@127.0.0.1:%d }
  6473  			]
  6474  		}
  6475  	`, optsA.Gateway.Port)))
  6476  	srvB, _ := RunServerWithConfig(confB)
  6477  	defer srvB.Shutdown()
  6478  
  6479  	waitForInboundGateways(t, srvA, 1, time.Second)
  6480  	waitForOutboundGateways(t, srvA, 1, time.Second)
  6481  	waitForInboundGateways(t, srvB, 1, time.Second)
  6482  	waitForOutboundGateways(t, srvB, 1, time.Second)
  6483  }
  6484  
  6485  func TestTLSGatewaysCertificateImplicitAllowPass(t *testing.T) {
  6486  	testTLSGatewaysCertificateImplicitAllow(t, true)
  6487  }
  6488  
  6489  func TestTLSGatewaysCertificateImplicitAllowFail(t *testing.T) {
  6490  	testTLSGatewaysCertificateImplicitAllow(t, false)
  6491  }
  6492  
  6493  func testTLSGatewaysCertificateImplicitAllow(t *testing.T, pass bool) {
  6494  	// Base config for the servers
  6495  	cfg := createTempFile(t, "cfg")
  6496  	cfg.WriteString(fmt.Sprintf(`
  6497  		gateway {
  6498  		  tls {
  6499  			cert_file = "../test/configs/certs/tlsauth/server.pem"
  6500  			key_file = "../test/configs/certs/tlsauth/server-key.pem"
  6501  			ca_file = "../test/configs/certs/tlsauth/ca.pem"
  6502  			verify_cert_and_check_known_urls = true
  6503  			insecure = %t
  6504  			timeout = 1
  6505  		  }
  6506  		}
  6507  	`, !pass)) // set insecure to skip verification on the outgoing end
  6508  	if err := cfg.Sync(); err != nil {
  6509  		t.Fatal(err)
  6510  	}
  6511  	cfg.Close()
  6512  
  6513  	optsA := LoadConfig(cfg.Name())
  6514  	optsB := LoadConfig(cfg.Name())
  6515  
  6516  	urlA := "nats://localhost:9995"
  6517  	urlB := "nats://localhost:9996"
  6518  	if !pass {
  6519  		urlA = "nats://127.0.0.1:9995"
  6520  		urlB = "nats://127.0.0.1:9996"
  6521  	}
  6522  
  6523  	gwA, err := url.Parse(urlA)
  6524  	if err != nil {
  6525  		t.Fatal(err)
  6526  	}
  6527  	gwB, err := url.Parse(urlB)
  6528  	if err != nil {
  6529  		t.Fatal(err)
  6530  	}
  6531  
  6532  	optsA.Host = "127.0.0.1"
  6533  	optsA.Port = -1
  6534  	optsA.Gateway.Name = "A"
  6535  	optsA.Gateway.Port = 9995
  6536  	optsA.Gateway.resolver = &localhostResolver{}
  6537  
  6538  	optsB.Host = "127.0.0.1"
  6539  	optsB.Port = -1
  6540  	optsB.Gateway.Name = "B"
  6541  	optsB.Gateway.Port = 9996
  6542  	optsB.Gateway.resolver = &localhostResolver{}
  6543  
  6544  	gateways := make([]*RemoteGatewayOpts, 2)
  6545  	gateways[0] = &RemoteGatewayOpts{
  6546  		Name: optsA.Gateway.Name,
  6547  		URLs: []*url.URL{gwA},
  6548  	}
  6549  	gateways[1] = &RemoteGatewayOpts{
  6550  		Name: optsB.Gateway.Name,
  6551  		URLs: []*url.URL{gwB},
  6552  	}
  6553  
  6554  	optsA.Gateway.Gateways = gateways
  6555  	optsB.Gateway.Gateways = gateways
  6556  
  6557  	SetGatewaysSolicitDelay(100 * time.Millisecond)
  6558  	defer ResetGatewaysSolicitDelay()
  6559  
  6560  	srvA := RunServer(optsA)
  6561  	defer srvA.Shutdown()
  6562  
  6563  	srvB := RunServer(optsB)
  6564  	defer srvB.Shutdown()
  6565  
  6566  	if pass {
  6567  		waitForOutboundGateways(t, srvA, 1, 5*time.Second)
  6568  		waitForOutboundGateways(t, srvB, 1, 5*time.Second)
  6569  	} else {
  6570  		time.Sleep(1 * time.Second) // the fail case uses the IP, so a short wait is sufficient
  6571  		checkFor(t, 2*time.Second, 15*time.Millisecond, func() error {
  6572  			if srvA.NumOutboundGateways() != 0 || srvB.NumOutboundGateways() != 0 {
  6573  				return fmt.Errorf("No outbound gateway connection expected")
  6574  			}
  6575  			return nil
  6576  		})
  6577  	}
  6578  }
  6579  
  6580  func TestGatewayURLsNotRemovedOnDuplicateRoute(t *testing.T) {
  6581  	// For this test, we need to have servers in cluster B creating routes
  6582  	// to each other to help produce the "duplicate route" situation, so
  6583  	// we are forced to use deterministic ports.
  6584  	getEphemeralPort := func() int {
  6585  		t.Helper()
  6586  		l, err := net.Listen("tcp", "127.0.0.1:0")
  6587  		if err != nil {
  6588  			t.Fatalf("Error getting a port: %v", err)
  6589  		}
  6590  		p := l.Addr().(*net.TCPAddr).Port
  6591  		l.Close()
  6592  		return p
  6593  	}
  6594  	p1 := getEphemeralPort()
  6595  	p2 := getEphemeralPort()
  6596  	routeURLs := fmt.Sprintf("nats://127.0.0.1:%d,nats://127.0.0.1:%d", p1, p2)
  6597  
  6598  	ob1 := testDefaultOptionsForGateway("B")
  6599  	ob1.Cluster.Port = p1
  6600  	ob1.Routes = RoutesFromStr(routeURLs)
  6601  	sb1 := RunServer(ob1)
  6602  	defer sb1.Shutdown()
  6603  
  6604  	ob2 := testDefaultOptionsForGateway("B")
  6605  	ob2.Cluster.Port = p2
  6606  	ob2.Routes = RoutesFromStr(routeURLs)
  6607  	sb2 := RunServer(ob2)
  6608  	defer sb2.Shutdown()
  6609  
  6610  	checkClusterFormed(t, sb1, sb2)
  6611  
  6612  	oa := testGatewayOptionsFromToWithServers(t, "A", "B", sb1)
  6613  	sa := RunServer(oa)
  6614  	defer sa.Shutdown()
  6615  
  6616  	waitForOutboundGateways(t, sb1, 1, 2*time.Second)
  6617  	waitForOutboundGateways(t, sb2, 1, 2*time.Second)
  6618  	waitForOutboundGateways(t, sa, 1, 2*time.Second)
  6619  	waitForInboundGateways(t, sa, 2, 2*time.Second)
  6620  
  6621  	checkURLs := func(s *Server) {
  6622  		t.Helper()
  6623  		s.mu.Lock()
  6624  		urls := s.gateway.URLs.getAsStringSlice()
  6625  		s.mu.Unlock()
  6626  		if len(urls) != 2 {
  6627  			t.Fatalf("Expected 2 urls, got %v", urls)
  6628  		}
  6629  	}
  6630  	checkURLs(sb1)
  6631  	checkURLs(sb2)
  6632  
  6633  	// As for sa, we should have both sb1 and sb2 urls in its outbound urls map
  6634  	c := sa.getOutboundGatewayConnection("B")
  6635  	if c == nil {
  6636  		t.Fatal("No outound connection found!")
  6637  	}
  6638  	c.mu.Lock()
  6639  	urls := c.gw.cfg.urls
  6640  	c.mu.Unlock()
  6641  	if len(urls) != 2 {
  6642  		t.Fatalf("Expected 2 urls to B, got %v", urls)
  6643  	}
  6644  }
  6645  
  6646  func TestGatewayDuplicateServerName(t *testing.T) {
  6647  	// We will have 2 servers per cluster names "nats1" and "nats2", and have
  6648  	// the servers in the second cluster with the same name, but we will make
  6649  	// sure to connect "A/nats1" to "B/nats2" and "A/nats2" to "B/nats1" and
  6650  	// verify that we still discover the duplicate names.
  6651  	ob1 := testDefaultOptionsForGateway("B")
  6652  	ob1.ServerName = "nats1"
  6653  	sb1 := RunServer(ob1)
  6654  	defer sb1.Shutdown()
  6655  
  6656  	ob2 := testDefaultOptionsForGateway("B")
  6657  	ob2.ServerName = "nats2"
  6658  	ob2.Routes = RoutesFromStr(fmt.Sprintf("nats://127.0.0.1:%d", ob1.Cluster.Port))
  6659  	sb2 := RunServer(ob2)
  6660  	defer sb2.Shutdown()
  6661  
  6662  	checkClusterFormed(t, sb1, sb2)
  6663  
  6664  	oa1 := testGatewayOptionsFromToWithServers(t, "A", "B", sb2)
  6665  	oa1.ServerName = "nats1"
  6666  	// Needed later in the test
  6667  	oa1.Gateway.RejectUnknown = true
  6668  	sa1 := RunServer(oa1)
  6669  	defer sa1.Shutdown()
  6670  	sa1l := &captureErrorLogger{errCh: make(chan string, 100)}
  6671  	sa1.SetLogger(sa1l, false, false)
  6672  
  6673  	oa2 := testGatewayOptionsFromToWithServers(t, "A", "B", sb1)
  6674  	oa2.ServerName = "nats2"
  6675  	// Needed later in the test
  6676  	oa2.Gateway.RejectUnknown = true
  6677  	oa2.Routes = RoutesFromStr(fmt.Sprintf("nats://127.0.0.1:%d", oa1.Cluster.Port))
  6678  	sa2 := RunServer(oa2)
  6679  	defer sa2.Shutdown()
  6680  	sa2l := &captureErrorLogger{errCh: make(chan string, 100)}
  6681  	sa2.SetLogger(sa2l, false, false)
  6682  
  6683  	checkClusterFormed(t, sa1, sa2)
  6684  
  6685  	checkForDupError := func(errCh chan string) {
  6686  		t.Helper()
  6687  		timeout := time.NewTimer(time.Second)
  6688  		for done := false; !done; {
  6689  			select {
  6690  			case err := <-errCh:
  6691  				if strings.Contains(err, "server has a duplicate name") {
  6692  					done = true
  6693  				}
  6694  			case <-timeout.C:
  6695  				t.Fatal("Did not get error about servers in super-cluster with same name")
  6696  			}
  6697  		}
  6698  	}
  6699  
  6700  	// Since only servers from "A" have configured outbound to
  6701  	// cluster "B", only servers on "A" are expected to report error.
  6702  	for _, errCh := range []chan string{sa1l.errCh, sa2l.errCh} {
  6703  		checkForDupError(errCh)
  6704  	}
  6705  
  6706  	// So now we are going to fix names and wait for the super cluster to form.
  6707  	sa2.Shutdown()
  6708  	sa1.Shutdown()
  6709  
  6710  	// Drain the error channels
  6711  	for _, errCh := range []chan string{sa1l.errCh, sa2l.errCh} {
  6712  		for done := false; !done; {
  6713  			select {
  6714  			case <-errCh:
  6715  			default:
  6716  				done = true
  6717  			}
  6718  		}
  6719  	}
  6720  
  6721  	oa1.ServerName = "a_nats1"
  6722  	oa2.ServerName = "a_nats2"
  6723  	sa1 = RunServer(oa1)
  6724  	defer sa1.Shutdown()
  6725  	sa2 = RunServer(oa2)
  6726  	defer sa2.Shutdown()
  6727  
  6728  	checkClusterFormed(t, sa1, sa2)
  6729  
  6730  	waitForOutboundGateways(t, sa1, 1, 2*time.Second)
  6731  	waitForOutboundGateways(t, sa2, 1, 2*time.Second)
  6732  	waitForOutboundGateways(t, sb1, 1, 2*time.Second)
  6733  	waitForOutboundGateways(t, sb2, 1, 2*time.Second)
  6734  
  6735  	// Now add a server on cluster B (that does not have outbound
  6736  	// gateway connections explicitly defined) and use the name
  6737  	// of one of the cluster A's server. We should get an error.
  6738  	ob3 := testDefaultOptionsForGateway("B")
  6739  	ob3.ServerName = "a_nats2"
  6740  	ob3.Accounts = []*Account{NewAccount("sys")}
  6741  	ob3.Routes = RoutesFromStr(fmt.Sprintf("nats://127.0.0.1:%d", ob2.Cluster.Port))
  6742  	sb3 := RunServer(ob3)
  6743  	defer sb3.Shutdown()
  6744  	sb3l := &captureErrorLogger{errCh: make(chan string, 100)}
  6745  	sb3.SetLogger(sb3l, false, false)
  6746  
  6747  	checkClusterFormed(t, sb1, sb2, sb3)
  6748  
  6749  	// It should report the error when trying to create the GW connection
  6750  	checkForDupError(sb3l.errCh)
  6751  
  6752  	// Stop this node
  6753  	sb3.Shutdown()
  6754  	checkClusterFormed(t, sb1, sb2)
  6755  
  6756  	// Now create a GW "C" with a server that uses the same name than one of
  6757  	// the server on "A", say "a_nats2".
  6758  	// This server will connect to "B", and "B" will gossip "A" back to "C"
  6759  	// and "C" will then try to connect to "A", but "A" rejects unknown, so
  6760  	// connection will be refused. However, we want to make sure that the
  6761  	// duplicate server name is still detected.
  6762  	oc := testGatewayOptionsFromToWithServers(t, "C", "B", sb1)
  6763  	oc.ServerName = "a_nats2"
  6764  	oc.Accounts = []*Account{NewAccount("sys")}
  6765  	sc := RunServer(oc)
  6766  	defer sc.Shutdown()
  6767  	scl := &captureErrorLogger{errCh: make(chan string, 100)}
  6768  	sc.SetLogger(scl, false, false)
  6769  
  6770  	// It should report the error when trying to create the GW connection
  6771  	// to cluster "A"
  6772  	checkForDupError(scl.errCh)
  6773  }
  6774  
  6775  func TestGatewayNoPanicOnStartupWithMonitoring(t *testing.T) {
  6776  	o := testDefaultOptionsForGateway("B")
  6777  	o.HTTPHost = "127.0.0.1"
  6778  	o.HTTPPort = 8888
  6779  	s, err := NewServer(o)
  6780  	require_NoError(t, err)
  6781  
  6782  	wg := sync.WaitGroup{}
  6783  	wg.Add(1)
  6784  	go func() {
  6785  		defer wg.Done()
  6786  
  6787  		time.Sleep(50 * time.Millisecond)
  6788  		s.Start()
  6789  		s.WaitForShutdown()
  6790  	}()
  6791  
  6792  	for {
  6793  		g, err := s.Gatewayz(nil)
  6794  		if err != nil {
  6795  			continue
  6796  		}
  6797  		if g.Port != 0 && g.Port != s.GatewayAddr().Port {
  6798  			t.Fatalf("Unexpected port: %v vs %v", g.Port, s.GatewayAddr().Port)
  6799  		}
  6800  		break
  6801  	}
  6802  	s.Shutdown()
  6803  	wg.Wait()
  6804  }
  6805  
  6806  func TestGatewaySwitchToInterestOnlyModeImmediately(t *testing.T) {
  6807  	o2 := testDefaultOptionsForGateway("B")
  6808  	// Add users to cause s2 to require auth. Will add an account with user later.
  6809  	o2.Users = append([]*User(nil), &User{Username: "test", Password: "pwd"})
  6810  	s2 := runGatewayServer(o2)
  6811  	defer s2.Shutdown()
  6812  
  6813  	o1 := testGatewayOptionsFromToWithServers(t, "A", "B", s2)
  6814  	setAccountUserPassInOptions(o1, "$foo", "ivan", "password")
  6815  	s1 := runGatewayServer(o1)
  6816  	defer s1.Shutdown()
  6817  
  6818  	waitForOutboundGateways(t, s1, 1, time.Second)
  6819  	waitForOutboundGateways(t, s2, 1, time.Second)
  6820  
  6821  	s1Url := fmt.Sprintf("nats://ivan:password@127.0.0.1:%d", o1.Port)
  6822  	nc := natsConnect(t, s1Url)
  6823  	defer nc.Close()
  6824  	natsPub(t, nc, "foo", []byte("hello"))
  6825  	natsFlush(t, nc)
  6826  
  6827  	checkCount := func(t *testing.T, c *client, expected int) {
  6828  		t.Helper()
  6829  		c.mu.Lock()
  6830  		out := c.outMsgs
  6831  		c.mu.Unlock()
  6832  		if int(out) != expected {
  6833  			t.Fatalf("Expected %d message(s) to be sent over, got %v", expected, out)
  6834  		}
  6835  	}
  6836  	// No message should be sent
  6837  	gwcb := s1.getOutboundGatewayConnection("B")
  6838  	checkCount(t, gwcb, 0)
  6839  
  6840  	// Check that we are in interest-only mode, but in this case, since s2 does
  6841  	// have the account, we should have the account not even present in the map.
  6842  	checkGWInterestOnlyModeOrNotPresent(t, s1, "B", "$foo", true)
  6843  
  6844  	// Add account to S2 and a client.
  6845  	s2FooAcc, err := s2.RegisterAccount("$foo")
  6846  	if err != nil {
  6847  		t.Fatalf("Error registering account: %v", err)
  6848  	}
  6849  	s2.mu.Lock()
  6850  	s2.users["ivan"] = &User{Account: s2FooAcc, Username: "ivan", Password: "password"}
  6851  	s2.mu.Unlock()
  6852  	s2Url := fmt.Sprintf("nats://ivan:password@127.0.0.1:%d", o2.Port)
  6853  	ncS2 := natsConnect(t, s2Url)
  6854  	defer ncS2.Close()
  6855  	natsSubSync(t, ncS2, "asub")
  6856  	// This time we will have the account in the map and it will be interest-only
  6857  	checkGWInterestOnlyMode(t, s1, "B", "$foo")
  6858  
  6859  	// Now publish a message, still should not go because the sub is on "asub"
  6860  	natsPub(t, nc, "foo", []byte("hello"))
  6861  	natsFlush(t, nc)
  6862  	checkCount(t, gwcb, 0)
  6863  
  6864  	natsSubSync(t, ncS2, "foo")
  6865  	natsFlush(t, ncS2)
  6866  
  6867  	checkGWInterestOnlyModeInterestOn(t, s1, "B", "$foo", "foo")
  6868  
  6869  	// Publish on foo
  6870  	natsPub(t, nc, "foo", []byte("hello"))
  6871  	natsFlush(t, nc)
  6872  	checkCount(t, gwcb, 1)
  6873  }
  6874  
  6875  func TestGatewaySlowConsumer(t *testing.T) {
  6876  	gatewayMaxPingInterval = 50 * time.Millisecond
  6877  	defer func() { gatewayMaxPingInterval = gwMaxPingInterval }()
  6878  
  6879  	ob := testDefaultOptionsForGateway("B")
  6880  	sb := RunServer(ob)
  6881  	defer sb.Shutdown()
  6882  
  6883  	oa := testGatewayOptionsFromToWithServers(t, "A", "B", sb)
  6884  	sa := RunServer(oa)
  6885  	defer sa.Shutdown()
  6886  
  6887  	waitForInboundGateways(t, sa, 1, 2*time.Second)
  6888  	waitForOutboundGateways(t, sa, 1, 2*time.Second)
  6889  	waitForInboundGateways(t, sb, 1, 2*time.Second)
  6890  	waitForOutboundGateways(t, sb, 1, 2*time.Second)
  6891  
  6892  	c := sa.getOutboundGatewayConnection("B")
  6893  	c.mu.Lock()
  6894  	c.out.wdl = time.Nanosecond
  6895  	c.mu.Unlock()
  6896  
  6897  	<-time.After(250 * time.Millisecond)
  6898  	got := sa.NumSlowConsumersGateways()
  6899  	expected := uint64(1)
  6900  	if got != 1 {
  6901  		t.Errorf("got: %d, expected: %d", got, expected)
  6902  	}
  6903  	got = sb.NumSlowConsumersGateways()
  6904  	expected = 0
  6905  	if got != expected {
  6906  		t.Errorf("got: %d, expected: %d", got, expected)
  6907  	}
  6908  }