From dbf7636e157d5e6a474f86bc86f46ecd02e3ec6f Mon Sep 17 00:00:00 2001 From: Tomasz Pietrek Date: Wed, 14 Sep 2022 15:29:53 +0200 Subject: [PATCH] Add error if Consumer Durable and Name are not equal This error will happen only if both Name and Durable are specified. Signed-off-by: Tomasz Pietrek --- server/consumer.go | 6 ++++ server/errors.json | 10 +++++++ server/jetstream_errors_generated.go | 14 +++++++++ server/jetstream_test.go | 43 ++++++++++++++++++++++++++++ 4 files changed, 73 insertions(+) diff --git a/server/consumer.go b/server/consumer.go index e8c64cd2..483e8d29 100644 --- a/server/consumer.go +++ b/server/consumer.go @@ -525,6 +525,12 @@ func checkConsumerCfg( return NewJSConsumerWithFlowControlNeedsHeartbeatsError() } + if config.Durable != _EMPTY_ && config.Name != _EMPTY_ { + if config.Name != config.Durable { + return NewJSConsumerCreateDurableAndNameMismatchError() + } + } + return nil } diff --git a/server/errors.json b/server/errors.json index e9cdc17d..2df7d6bf 100644 --- a/server/errors.json +++ b/server/errors.json @@ -1298,5 +1298,15 @@ "help": "", "url": "", "deprecates": "" + }, + { + "constant": "JSConsumerCreateDurableAndNameMismatch", + "code": 400, + "error_code": 10132, + "description": "Consumer Durable and Name have to be equal if both are provided", + "comment": "", + "help": "", + "url": "", + "deprecates": "" } ] \ No newline at end of file diff --git a/server/jetstream_errors_generated.go b/server/jetstream_errors_generated.go index b6067308..86fa5bf5 100644 --- a/server/jetstream_errors_generated.go +++ b/server/jetstream_errors_generated.go @@ -50,6 +50,9 @@ const ( // JSConsumerConfigRequiredErr consumer config required JSConsumerConfigRequiredErr ErrorIdentifier = 10078 + // JSConsumerCreateDurableAndNameMismatch Consumer Durable and Name have to be equal if both are provided + JSConsumerCreateDurableAndNameMismatch ErrorIdentifier = 10132 + // JSConsumerCreateErrF General consumer creation failure string ({err}) JSConsumerCreateErrF ErrorIdentifier = 10012 @@ -413,6 +416,7 @@ var ( JSClusterUnSupportFeatureErr: {Code: 503, ErrCode: 10036, Description: "not currently supported in clustered mode"}, JSConsumerBadDurableNameErr: {Code: 400, ErrCode: 10103, Description: "durable name can not contain '.', '*', '>'"}, JSConsumerConfigRequiredErr: {Code: 400, ErrCode: 10078, Description: "consumer config required"}, + JSConsumerCreateDurableAndNameMismatch: {Code: 400, ErrCode: 10132, Description: "Consumer Durable and Name have to be equal if both are provided"}, JSConsumerCreateErrF: {Code: 500, ErrCode: 10012, Description: "{err}"}, JSConsumerCreateFilterSubjectMismatchErr: {Code: 400, ErrCode: 10131, Description: "Consumer create request did not match filtered subject from create subject"}, JSConsumerDeliverCycleErr: {Code: 400, ErrCode: 10081, Description: "consumer deliver subject forms a cycle"}, @@ -709,6 +713,16 @@ func NewJSConsumerConfigRequiredError(opts ...ErrorOption) *ApiError { return ApiErrors[JSConsumerConfigRequiredErr] } +// NewJSConsumerCreateDurableAndNameMismatchError creates a new JSConsumerCreateDurableAndNameMismatch error: "Consumer Durable and Name have to be equal if both are provided" +func NewJSConsumerCreateDurableAndNameMismatchError(opts ...ErrorOption) *ApiError { + eopts := parseOpts(opts) + if ae, ok := eopts.err.(*ApiError); ok { + return ae + } + + return ApiErrors[JSConsumerCreateDurableAndNameMismatch] +} + // NewJSConsumerCreateError creates a new JSConsumerCreateErrF error: "{err}" func NewJSConsumerCreateError(err error, opts ...ErrorOption) *ApiError { eopts := parseOpts(opts) diff --git a/server/jetstream_test.go b/server/jetstream_test.go index 50ed090d..e0fe0af6 100644 --- a/server/jetstream_test.go +++ b/server/jetstream_test.go @@ -416,6 +416,49 @@ func TestJetStreamConsumerAndStreamDescriptions(t *testing.T) { t.Fatalf("Expected an error but got none") } } +func TestJetStreamConsumerWithNameAndDurable(t *testing.T) { + s := RunBasicJetStreamServer() + if config := s.JetStreamConfig(); config != nil { + defer removeDir(t, config.StoreDir) + } + defer s.Shutdown() + + descr := "foo asset" + name := "name" + durable := "durable" + acc := s.GlobalAccount() + + // Check stream's first. + mset, err := acc.addStream(&StreamConfig{Name: "foo", Description: descr}) + if err != nil { + t.Fatalf("Unexpected error adding stream: %v", err) + } + if cfg := mset.config(); cfg.Description != descr { + t.Fatalf("Expected a description of %q, got %q", descr, cfg.Description) + } + + // it's ok to specify both durable and name, but they have to be the same. + _, err = mset.addConsumer(&ConsumerConfig{ + DeliverSubject: "to", + Durable: "consumer", + Name: "consumer", + AckPolicy: AckNone}) + if err != nil { + t.Fatalf("Unexpected error adding consumer: %v", err) + } + + // if they're not the same, expect error + _, err = mset.addConsumer(&ConsumerConfig{ + DeliverSubject: "to", + Durable: durable, + Name: name, + AckPolicy: AckNone}) + + if !strings.Contains(err.Error(), "Consumer Durable and Name have to be equal") { + t.Fatalf("Wrong error while adding consumer with not matching Name and Durable: %v", err) + } + +} func TestJetStreamPubAck(t *testing.T) { s := RunBasicJetStreamServer()