From 50fabe261d6e8ddb1a313444ec226aedb02ebf08 Mon Sep 17 00:00:00 2001 From: Derek Collison Date: Wed, 21 Apr 2021 15:31:46 -0700 Subject: [PATCH] Check for overlapping subjects on stream update. Signed-off-by: Derek Collison --- server/jetstream_cluster.go | 16 ++++++++++++++ server/jetstream_cluster_test.go | 37 ++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/server/jetstream_cluster.go b/server/jetstream_cluster.go index 7fa3a5c1..92b79347 100644 --- a/server/jetstream_cluster.go +++ b/server/jetstream_cluster.go @@ -3466,6 +3466,22 @@ func (s *Server) jsClusteredStreamUpdateRequest(ci *ClientInfo, acc *Account, su return } + // Check for subject collisions here. + for _, sa := range cc.streams[acc.Name] { + if sa == osa { + continue + } + for _, subj := range sa.Config.Subjects { + for _, tsubj := range newCfg.Subjects { + if SubjectsCollide(tsubj, subj) { + resp.Error = jsError(fmt.Errorf("subjects overlap with an existing stream")) + s.sendAPIErrResponse(ci, acc, subject, reply, string(rmsg), s.jsonResponse(&resp)) + return + } + } + } + } + sa := &streamAssignment{Group: osa.Group, Config: newCfg, Subject: subject, Reply: reply, Client: ci} cc.meta.Propose(encodeUpdateStreamAssignment(sa)) } diff --git a/server/jetstream_cluster_test.go b/server/jetstream_cluster_test.go index 364fa9ac..1524ee23 100644 --- a/server/jetstream_cluster_test.go +++ b/server/jetstream_cluster_test.go @@ -5880,6 +5880,43 @@ func TestJetStreamClusterCreateConcurrentDurableConsumers(t *testing.T) { } } +// https://github.com/nats-io/nats-server/issues/2144 +func TestJetStreamClusterUpdateStreamToExisting(t *testing.T) { + c := createJetStreamClusterExplicit(t, "MSL", 3) + defer c.shutdown() + + // Client for API requests. + nc, js := jsClientConnect(t, c.randomServer()) + defer nc.Close() + + _, err := js.AddStream(&nats.StreamConfig{ + Name: "ORDERS1", + Replicas: 3, + Subjects: []string{"foo"}, + }) + if err != nil { + t.Fatalf("Unexpected error: %v", err) + } + + _, err = js.AddStream(&nats.StreamConfig{ + Name: "ORDERS2", + Replicas: 3, + Subjects: []string{"bar"}, + }) + if err != nil { + t.Fatalf("Unexpected error: %v", err) + } + + _, err = js.UpdateStream(&nats.StreamConfig{ + Name: "ORDERS2", + Replicas: 3, + Subjects: []string{"foo"}, + }) + if err == nil { + t.Fatalf("Expected an error but got none") + } +} + // Support functions // Used to setup superclusters for tests.