Skip to content

Commit

Permalink
[PLATFORM-564] feat: Implement endpoints commands (#135)
Browse files Browse the repository at this point in the history
* chore: Separate deprecated logic

* test: Logs command

* feat(connectors): Add remove connector cmd

* feat(connectors): Quote connector names

* test: update connector command

* refactor: Connect using builder

* feat(endpoints): Add create endpoint cmd

* feat(endpoints): Add describe endpoint

* feat: Add list endpoints

* feat: Add remove endpoints

* fix: rebase

* chore: Rename endpoints strucs
  • Loading branch information
raulb authored Apr 30, 2021
1 parent 6071574 commit 0ca0a61
Show file tree
Hide file tree
Showing 14 changed files with 939 additions and 4 deletions.
98 changes: 98 additions & 0 deletions cmd/meroxa/root/endpoints/create.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
/*
Copyright © 2021 Meroxa Inc
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package endpoints

import (
"context"

"github.com/meroxa/meroxa-go"

"github.com/meroxa/cli/cmd/meroxa/builder"
"github.com/meroxa/cli/log"
)

type createEndpointClient interface {
CreateEndpoint(ctx context.Context, name, protocol, stream string) error
}

type Create struct {
client createEndpointClient
logger log.Logger

args struct {
Name string
}

flags struct {
Protocol string `long:"protocol" short:"p" usage:"protocol, value can be http or grpc" required:"true"`
Stream string `long:"stream" short:"s" usage:"stream name" required:"true"`
}
}

func (c *Create) Usage() string {
return "create [NAME] [flags]"
}

func (c *Create) Docs() builder.Docs {
return builder.Docs{
Short: "Create an endpoint",
Long: "Use create endpoint to expose an endpoint to a connector stream",
Example: "meroxa endpoints create my-endpoint --protocol http --stream my-stream",
}
}

func (c *Create) Execute(ctx context.Context) error {
c.logger.Info(ctx, "Creating endpoint...")

err := c.client.CreateEndpoint(ctx, c.args.Name, c.flags.Protocol, c.flags.Stream)

if err != nil {
return err
}

c.logger.Info(ctx, "Endpoint successfully created!")

return nil
}

func (c *Create) Client(client *meroxa.Client) {
c.client = client
}

func (c *Create) Logger(logger log.Logger) {
c.logger = logger
}

func (c *Create) Flags() []builder.Flag {
return builder.BuildFlags(&c.flags)
}

func (c *Create) ParseArgs(args []string) error {
if len(args) > 0 {
c.args.Name = args[0]
}
return nil
}

var (
_ builder.CommandWithDocs = (*Create)(nil)
_ builder.CommandWithArgs = (*Create)(nil)
_ builder.CommandWithFlags = (*Create)(nil)
_ builder.CommandWithClient = (*Create)(nil)
_ builder.CommandWithLogger = (*Create)(nil)
_ builder.CommandWithExecute = (*Create)(nil)
)
127 changes: 127 additions & 0 deletions cmd/meroxa/root/endpoints/create_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
/*
Copyright © 2021 Meroxa Inc
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package endpoints

import (
"context"
"testing"

"github.com/golang/mock/gomock"
"github.com/meroxa/cli/log"
mock "github.com/meroxa/cli/mock-cmd"

"github.com/meroxa/cli/cmd/meroxa/builder"
"github.com/meroxa/cli/utils"
)

func TestCreateEndpointArgs(t *testing.T) {
tests := []struct {
args []string
err error
name string
}{
{args: nil, err: nil, name: ""},
{args: []string{"endpoint-name"}, err: nil, name: "endpoint-name"},
}

for _, tt := range tests {
cc := &Create{}
err := cc.ParseArgs(tt.args)

if tt.err != err {
t.Fatalf("expected \"%s\" got \"%s\"", tt.err, err)
}

if tt.name != cc.args.Name {
t.Fatalf("expected \"%s\" got \"%s\"", tt.name, cc.args.Name)
}
}
}

func TestCreateEndpointFlags(t *testing.T) {
expectedFlags := []struct {
name string
required bool
shorthand string
hidden bool
}{
{name: "protocol", required: true, shorthand: "p", hidden: false},
{name: "stream", required: true, shorthand: "s", hidden: false},
}

c := builder.BuildCobraCommand(&Create{})

for _, f := range expectedFlags {
cf := c.Flags().Lookup(f.name)
if cf == nil {
t.Fatalf("expected flag \"%s\" to be present", f.name)
}

if f.shorthand != cf.Shorthand {
t.Fatalf("expected shorthand \"%s\" got \"%s\" for flag \"%s\"", f.shorthand, cf.Shorthand, f.name)
}

if f.required && !utils.IsFlagRequired(cf) {
t.Fatalf("expected flag \"%s\" to be required", f.name)
}

if cf.Hidden != f.hidden {
if cf.Hidden {
t.Fatalf("expected flag \"%s\" not to be hidden", f.name)
} else {
t.Fatalf("expected flag \"%s\" to be hidden", f.name)
}
}
}
}

func TestCreateEndpointExecution(t *testing.T) {
ctx := context.Background()
ctrl := gomock.NewController(t)
client := mock.NewMockCreateEndpointClient(ctrl)
logger := log.NewTestLogger()

client.
EXPECT().
CreateEndpoint(
ctx,
"",
"",
"",
).
Return(nil)

ce := &Create{
client: client,
logger: logger,
}

err := ce.Execute(ctx)

if err != nil {
t.Fatalf("not expected error, got \"%s\"", err.Error())
}

gotLeveledOutput := logger.LeveledOutput()
wantLeveledOutput := `Creating endpoint...
Endpoint successfully created!
`

if gotLeveledOutput != wantLeveledOutput {
t.Fatalf("expected output:\n%s\ngot:\n%s", wantLeveledOutput, gotLeveledOutput)
}
}
87 changes: 87 additions & 0 deletions cmd/meroxa/root/endpoints/describe.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/*
Copyright © 2021 Meroxa Inc
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package endpoints

import (
"context"
"errors"

"github.com/meroxa/cli/cmd/meroxa/builder"
"github.com/meroxa/cli/log"
"github.com/meroxa/cli/utils"
"github.com/meroxa/meroxa-go"
)

var (
_ builder.CommandWithDocs = (*Describe)(nil)
_ builder.CommandWithArgs = (*Describe)(nil)
_ builder.CommandWithClient = (*Describe)(nil)
_ builder.CommandWithLogger = (*Describe)(nil)
_ builder.CommandWithExecute = (*Describe)(nil)
)

type describeEndpointClient interface {
GetEndpoint(ctx context.Context, name string) (*meroxa.Endpoint, error)
}

type Describe struct {
client describeEndpointClient
logger log.Logger

args struct {
Name string
}
}

func (d *Describe) Usage() string {
return "describe [NAME]"
}

func (d *Describe) Docs() builder.Docs {
return builder.Docs{
Short: "Describe endpoint",
}
}

func (d *Describe) Execute(ctx context.Context) error {
endpoint, err := d.client.GetEndpoint(ctx, d.args.Name)
if err != nil {
return err
}

d.logger.Info(ctx, utils.EndpointsTable([]meroxa.Endpoint{*endpoint}))
d.logger.JSON(ctx, endpoint)

return nil
}

func (d *Describe) Client(client *meroxa.Client) {
d.client = client
}

func (d *Describe) Logger(logger log.Logger) {
d.logger = logger
}

func (d *Describe) ParseArgs(args []string) error {
if len(args) < 1 {
return errors.New("requires endpoint name")
}

d.args.Name = args[0]
return nil
}
Loading

0 comments on commit 0ca0a61

Please sign in to comment.