mirror of
https://github.com/gogrlx/nats-server.git
synced 2026-04-02 03:38:42 -07:00
Allow editing of RePublish on an existing stream
This commit is contained in:
@@ -6361,24 +6361,21 @@ func TestJetStreamClusterEncryptedDoubleSnapshotBug(t *testing.T) {
|
||||
require_NoError(t, err)
|
||||
}
|
||||
|
||||
func TestJetStreamClusterRePublishUpdateNotSupported(t *testing.T) {
|
||||
func TestJetStreamClusterRePublishUpdateSupported(t *testing.T) {
|
||||
test := func(t *testing.T, s *Server, stream string, replicas int) {
|
||||
nc := natsConnect(t, s.ClientURL())
|
||||
nc, js := jsClientConnect(t, s)
|
||||
defer nc.Close()
|
||||
|
||||
cfg := &StreamConfig{
|
||||
cfg := &nats.StreamConfig{
|
||||
Name: stream,
|
||||
Storage: MemoryStorage,
|
||||
Storage: nats.MemoryStorage,
|
||||
Replicas: replicas,
|
||||
Subjects: []string{"foo.>"},
|
||||
}
|
||||
addStream(t, nc, cfg)
|
||||
_, err := js.AddStream(cfg)
|
||||
require_NoError(t, err)
|
||||
|
||||
cfg.RePublish = &RePublish{
|
||||
Source: ">",
|
||||
Destination: "bar.>",
|
||||
}
|
||||
// We expect update to fail, do it manually:
|
||||
expectFailUpdate := func() {
|
||||
expectUpdate := func() {
|
||||
t.Helper()
|
||||
|
||||
req, err := json.Marshal(cfg)
|
||||
@@ -6391,41 +6388,77 @@ func TestJetStreamClusterRePublishUpdateNotSupported(t *testing.T) {
|
||||
if resp.Type != JSApiStreamUpdateResponseType {
|
||||
t.Fatalf("Invalid response type %s expected %s", resp.Type, JSApiStreamUpdateResponseType)
|
||||
}
|
||||
if !IsNatsErr(resp.Error, JSStreamInvalidConfigF) {
|
||||
t.Fatalf("Expected error regarding config error, got %+v", resp.Error)
|
||||
if IsNatsErr(resp.Error, JSStreamInvalidConfigF) {
|
||||
t.Fatalf("Expected no error regarding config error, got %+v", resp.Error)
|
||||
}
|
||||
}
|
||||
expectFailUpdate()
|
||||
|
||||
// Now try with a new stream with RePublish present and then try to change config
|
||||
cfg = &StreamConfig{
|
||||
Name: stream + "_2",
|
||||
Storage: MemoryStorage,
|
||||
Replicas: replicas,
|
||||
RePublish: &RePublish{
|
||||
Source: ">",
|
||||
Destination: "bar.>",
|
||||
},
|
||||
expectRepublished := func(expectedRepub bool) {
|
||||
t.Helper()
|
||||
|
||||
nc, js := jsClientConnect(t, s)
|
||||
defer nc.Close()
|
||||
|
||||
// Create a subscriber for foo.> so that we can see
|
||||
// our published message being echoed back to us.
|
||||
sf, err := nc.SubscribeSync("foo.>")
|
||||
require_NoError(t, err)
|
||||
defer sf.Unsubscribe()
|
||||
|
||||
// Create a subscriber for bar.> so that we can see
|
||||
// any potentially republished messages.
|
||||
sb, err := nc.SubscribeSync("bar.>")
|
||||
require_NoError(t, err)
|
||||
defer sf.Unsubscribe()
|
||||
|
||||
// Publish a message, it will hit the foo.> stream and
|
||||
// may potentially be republished to the bar.> stream.
|
||||
_, err = js.Publish("foo."+stream, []byte("HELLO!"))
|
||||
require_NoError(t, err)
|
||||
|
||||
// Wait for a little while so that we have enough time
|
||||
// to determine whether it's going to arrive on one or
|
||||
// both streams.
|
||||
checkSubsPending(t, sf, 1)
|
||||
if expectedRepub {
|
||||
checkSubsPending(t, sb, 1)
|
||||
} else {
|
||||
checkSubsPending(t, sb, 0)
|
||||
}
|
||||
}
|
||||
addStream(t, nc, cfg)
|
||||
cfg.RePublish.HeadersOnly = true
|
||||
expectFailUpdate()
|
||||
|
||||
// One last test with existing first, then trying to remove
|
||||
cfg.Name = stream + "_3"
|
||||
addStream(t, nc, cfg)
|
||||
// At this point there's no republish config, so we should
|
||||
// only receive our published message on foo.>.
|
||||
expectRepublished(false)
|
||||
|
||||
// Add a republish config so that everything on foo.> also
|
||||
// gets republished to bar.>.
|
||||
cfg.RePublish = &nats.RePublish{
|
||||
Source: "foo.>",
|
||||
Destination: "bar.>",
|
||||
}
|
||||
expectUpdate()
|
||||
expectRepublished(true)
|
||||
|
||||
// Now take the republish config away again, so we should go
|
||||
// back to only getting them on foo.>.
|
||||
cfg.RePublish = nil
|
||||
expectFailUpdate()
|
||||
expectUpdate()
|
||||
expectRepublished(false)
|
||||
}
|
||||
|
||||
s := RunBasicJetStreamServer(t)
|
||||
defer s.Shutdown()
|
||||
t.Run("Single", func(t *testing.T) {
|
||||
s := RunBasicJetStreamServer(t)
|
||||
defer s.Shutdown()
|
||||
|
||||
c := createJetStreamClusterExplicit(t, "JSC", 3)
|
||||
defer c.shutdown()
|
||||
test(t, s, "single", 1)
|
||||
})
|
||||
t.Run("Clustered", func(t *testing.T) {
|
||||
c := createJetStreamClusterExplicit(t, "JSC", 3)
|
||||
defer c.shutdown()
|
||||
|
||||
t.Run("Single", func(t *testing.T) { test(t, s, "single", 1) })
|
||||
t.Run("Clustered", func(t *testing.T) { test(t, c.randomServer(), "clustered", 3) })
|
||||
test(t, c.randomNonLeader(), "clustered", 3)
|
||||
})
|
||||
}
|
||||
|
||||
func TestJetStreamClusterDirectGetFromLeafnode(t *testing.T) {
|
||||
|
||||
Reference in New Issue
Block a user