-
Notifications
You must be signed in to change notification settings - Fork 68
Add partitioned topic command CURD #35
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
76a8fcc
5c0e462
e3ba23b
f2f4ea2
c1e54db
a18f62a
f70a8ec
44b32f5
d4b5230
113cc41
4e271e7
9a5f6be
35224c5
3b03dc6
b213f04
dbb887f
8c707c6
513b9fd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| package args | ||
|
|
||
| import ( | ||
| "github.com/pkg/errors" | ||
| ) | ||
|
|
||
| func CheckTopicNameTwoArgs(args []string) error { | ||
| if len(args) != 2 { | ||
| return errors.New("need to specified the topic name and the partitions") | ||
| } | ||
|
|
||
| return nil | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,75 @@ | ||
| package crud | ||
|
|
||
| import ( | ||
| "github.com/pkg/errors" | ||
| "github.com/streamnative/pulsarctl/pkg/cmdutils" | ||
| . "github.com/streamnative/pulsarctl/pkg/ctl/topic/args" | ||
| . "github.com/streamnative/pulsarctl/pkg/ctl/topic/errors" | ||
| "github.com/streamnative/pulsarctl/pkg/pulsar" | ||
| "strconv" | ||
| ) | ||
|
|
||
| func CreateTopicCmd(vc *cmdutils.VerbCmd) { | ||
| var desc pulsar.LongDescription | ||
| desc.CommandUsedFor = "This command is used for creating topic." | ||
| desc.CommandPermission = "This command requires namespace admin permissions." | ||
|
|
||
| var examples []pulsar.Example | ||
| createNonPartitions := pulsar.Example{ | ||
| Desc: "Create a non-partitioned topic <topic-name>", | ||
| Command: "pulsarctl topics create <topic-name> 0", | ||
| } | ||
| examples = append(examples, createNonPartitions) | ||
|
|
||
| create := pulsar.Example{ | ||
| Desc: "Create a partitioned topic <topic-name> with <partitions-num> partitions", | ||
| Command: "pulsarctl topics create <topic-name> <partition-num>", | ||
| } | ||
| examples = append(examples, create) | ||
| desc.CommandExamples = examples | ||
|
|
||
| var out []pulsar.Output | ||
| successOut := pulsar.Output{ | ||
| Desc: "normal output", | ||
| Out: "Create topic <topic-name> with <partition-num> partitions successfully", | ||
| } | ||
| out = append(out, successOut, ArgsError, TopicAlreadyExistError) | ||
| out = append(out, TopicNameErrors...) | ||
| out = append(out, NamespaceErrors...) | ||
| desc.CommandOutput = out | ||
|
|
||
| vc.SetDescription( | ||
| "create", | ||
| "Create a topic with n partitions", | ||
| desc.ToString(), | ||
| "c") | ||
|
|
||
| vc.SetRunFuncWithMultiNameArgs(func() error { | ||
| return doCreateTopic(vc) | ||
| }, CheckTopicNameTwoArgs) | ||
| } | ||
|
|
||
| func doCreateTopic(vc *cmdutils.VerbCmd) error { | ||
| // for testing | ||
| if vc.NameError != nil { | ||
| return vc.NameError | ||
| } | ||
|
|
||
| topic, err := pulsar.GetTopicName(vc.NameArgs[0]) | ||
| if err != nil { | ||
| return err | ||
| } | ||
|
|
||
| partitions, err := strconv.Atoi(vc.NameArgs[1]) | ||
|
zymap marked this conversation as resolved.
|
||
| if err != nil || partitions < 0 { | ||
| return errors.Errorf("invalid partition number '%s'", vc.NameArgs[1]) | ||
| } | ||
|
|
||
| admin := cmdutils.NewPulsarClient() | ||
| err = admin.Topics().Create(*topic, partitions) | ||
| if err == nil { | ||
| vc.Command.Printf("Create topic %s with %d partitions successfully\n", topic.String(), partitions) | ||
| } | ||
|
|
||
| return err | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,68 @@ | ||
| package crud | ||
|
|
||
| import ( | ||
| . "github.com/streamnative/pulsarctl/pkg/ctl/topic/test" | ||
| "github.com/stretchr/testify/assert" | ||
| "testing" | ||
| ) | ||
|
|
||
| func TestCreateTopicCmd(t *testing.T) { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. add a test case for creating a non-partitioned topic
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Already added |
||
| args := []string{"create", "test-create-topic", "2"} | ||
| _, execErr, argsErr, err := TestTopicCommands(CreateTopicCmd, args) | ||
| assert.Nil(t, execErr) | ||
| assert.Nil(t, argsErr) | ||
| assert.Nil(t, err) | ||
| } | ||
|
|
||
| func TestCreateNonPersistentTopic(t *testing.T) { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. add a test case for creating a non-partitioned topic |
||
| args := []string{"create", "non-persistent://public/default/test-create-topic", "2"} | ||
| _, execErr, argsErr, err := TestTopicCommands(CreateTopicCmd, args) | ||
| assert.Nil(t, execErr) | ||
| assert.Nil(t, argsErr) | ||
| assert.Nil(t, err) | ||
| } | ||
|
|
||
| func TestCreateTopicAlreadExists(t *testing.T) { | ||
| args := []string{"create", "test-duplicate-topic", "2"} | ||
| _, _, _, err := TestTopicCommands(CreateTopicCmd, args) | ||
| assert.Nil(t, err) | ||
|
|
||
| _, execErr, _, _ := TestTopicCommands(CreateTopicCmd, args) | ||
| assert.NotNil(t, execErr) | ||
| assert.Equal(t, "code: 409 reason: Partitioned topic already exists", execErr.Error()) | ||
| } | ||
|
|
||
| func TestCreateTopicArgsError(t *testing.T) { | ||
| args := []string{"create", "topic"} | ||
| _, _, nameErr, _ := TestTopicCommands(CreateTopicCmd, args) | ||
| assert.NotNil(t, nameErr) | ||
| assert.Equal(t, "need to specified the topic name and the partitions", nameErr.Error()) | ||
| } | ||
|
|
||
| func TestCreateTopicWithInvalidPartitions(t *testing.T) { | ||
| args := []string{"create", "topic", "a"} | ||
| _, execErr, _, _ := TestTopicCommands(CreateTopicCmd, args) | ||
| assert.NotNil(t, execErr) | ||
| assert.Equal(t, "invalid partition number 'a'", execErr.Error()) | ||
|
|
||
| args = []string{"create", "topic", "--", "-1"} | ||
| _, execErr, _, _ = TestTopicCommands(CreateTopicCmd, args) | ||
| assert.NotNil(t, execErr) | ||
| assert.Equal(t, "invalid partition number '-1'", execErr.Error()) | ||
| } | ||
|
|
||
| func TestCreateNonPartitionedTopic(t *testing.T) { | ||
| args := []string{"create", "test-create-non-partitioned-topic", "0"} | ||
| _, execErr, argsErr, err := TestTopicCommands(CreateTopicCmd, args) | ||
| assert.Nil(t, execErr) | ||
| assert.Nil(t, argsErr) | ||
| assert.Nil(t, err) | ||
| } | ||
|
|
||
| func TestCreateNonPersistentNonPartitionedTopic(t *testing.T) { | ||
| args := []string{"create", "non-persistent://public/default/test-create-non-partitioned-topic", "0"} | ||
| _, execErr, argsErr, err := TestTopicCommands(CreateTopicCmd, args) | ||
| assert.Nil(t, execErr) | ||
| assert.Nil(t, argsErr) | ||
| assert.Nil(t, err) | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,91 @@ | ||
| package crud | ||
|
|
||
| import ( | ||
| "github.com/spf13/pflag" | ||
| "github.com/streamnative/pulsarctl/pkg/cmdutils" | ||
| . "github.com/streamnative/pulsarctl/pkg/ctl/topic/errors" | ||
| "github.com/streamnative/pulsarctl/pkg/pulsar" | ||
| ) | ||
|
|
||
| func DeleteTopicCmd(vc *cmdutils.VerbCmd) { | ||
| var desc pulsar.LongDescription | ||
| desc.CommandUsedFor = "This command is used for deleting an existing topic." | ||
| desc.CommandPermission = "This command requires namespace admin permissions." | ||
|
|
||
| var examples []pulsar.Example | ||
| deleteTopic := pulsar.Example{ | ||
| Desc: "Delete a partitioned topic <topic-name>", | ||
| Command: "pulsarctl topics delete <topic-name>", | ||
| } | ||
|
|
||
| deleteNonPartitionedTopic := pulsar.Example{ | ||
| Desc: "Delete a non-partitioned topic <topic-name>", | ||
| Command: "pulsarctl topics delete --non-partitioned <topic-name>", | ||
| } | ||
|
|
||
| desc.CommandExamples = append(examples, deleteTopic, deleteNonPartitionedTopic) | ||
| var out []pulsar.Output | ||
| successOut := pulsar.Output{ | ||
| Desc: "normal output", | ||
| Out: "Delete topic <topic-name> successfully", | ||
| } | ||
|
|
||
| partitionedTopicNotExistError := pulsar.Output{ | ||
| Desc: "the partitioned topic does not exist", | ||
| Out: "[✖] code: 404 reason: Partitioned topic does not exist", | ||
| } | ||
|
|
||
| nonPartitionedTopicNotExistError := pulsar.Output{ | ||
| Desc: "the non-partitioned topic does not exist", | ||
| Out: "[✖] code: 404 reason: Topic not found", | ||
| } | ||
| out = append(out, successOut, ArgError, | ||
| partitionedTopicNotExistError, nonPartitionedTopicNotExistError) | ||
| out = append(out, TopicNameErrors...) | ||
| out = append(out, NamespaceErrors...) | ||
| desc.CommandOutput = out | ||
|
|
||
| vc.SetDescription( | ||
| "delete", | ||
| "Delete a topic", | ||
| desc.ToString(), | ||
| "d") | ||
|
|
||
| var force bool | ||
| var deleteSchema bool | ||
| var nonPartitioned bool | ||
|
|
||
| vc.FlagSetGroup.InFlagSet("Delete Topic", func(set *pflag.FlagSet) { | ||
| set.BoolVarP(&nonPartitioned, "non-partitioned", "n", false, | ||
| "Delete a non-partitioned topic") | ||
| set.BoolVarP(&force, "force", "f", false, | ||
| "Close all producer/consumer/replicator and delete topic forcefully") | ||
| set.BoolVarP(&deleteSchema, "delete-schema", "d", false, | ||
| "Delete schema while deleting topic") | ||
| }) | ||
|
|
||
| vc.SetRunFuncWithNameArg(func() error { | ||
| return doDeleteTopic(vc, force, deleteSchema, nonPartitioned) | ||
| }) | ||
| } | ||
|
|
||
| // TODO add delete schema | ||
| func doDeleteTopic(vc *cmdutils.VerbCmd, force, deleteSchema, nonPartitioned bool) error { | ||
| // for testing | ||
| if vc.NameError != nil { | ||
| return vc.NameError | ||
| } | ||
|
|
||
| topic, err := pulsar.GetTopicName(vc.NameArg) | ||
| if err != nil { | ||
| return err | ||
| } | ||
|
|
||
| admin := cmdutils.NewPulsarClient() | ||
| err = admin.Topics().Delete(*topic, force, nonPartitioned) | ||
| if err == nil { | ||
| vc.Command.Printf("Delete topic %s successfully\n", topic.String()) | ||
| } | ||
|
|
||
| return err | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
where do you check the length of NameArgs?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I add a new method
RunFuncWitNameAgs, this method will check the length of NameArgs.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
okay.
RunFuncWithNameArgsis too ambiguous. Please check the name to be precise about what it is doing.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Update the name as
SetRunFuncWithMultiNameArgsThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is only checking two args. Please be more specific.
SetRunFuncWithTwoNameArgsUh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SetRunWithNameArgs(cmd func, checkArgs func)the args length check decide by the
checkArgsmethod. In topic command, there are two args needed so it only checks two args. But in other commands it maybe needs more args.Or if need more args we mark them as required?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
okay. then the checkArgs needs to be changed to
checkTwoArgs?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok.