diff --git a/pkg/action-url/action_url.go b/pkg/action-url/action_url.go new file mode 100644 index 0000000000000000000000000000000000000000..cb6760dfdd0349f4ca249c435504d5f4e260c7f4 --- /dev/null +++ b/pkg/action-url/action_url.go @@ -0,0 +1,82 @@ +package action_url + +import ( + "fmt" + "net/url" + "strings" + + "git.perx.ru/perxis/perxis-go/pkg/errors" +) + +// ActionURL структура для хранения данных о переданном действии. +type ActionURL struct { + id string + extension string + *url.URL +} + +// New возвращает структуру ActionURL +func New(action string) (*ActionURL, error) { + return parse(action) +} + +// ID возвращает сохраненный в ActionURL id действия +func (p *ActionURL) ID() string { + return p.id +} + +// SetID устанавливает в ActionURL id действия +func (p *ActionURL) SetID(id string) { + p.id = id +} + +// Extension возвращает сохраненный в ActionURL id расширения +func (p *ActionURL) Extension() string { + return p.extension +} + +// SetExtension устанавливает в ActionURL id расширения +func (p *ActionURL) SetExtension(ext string) { + p.extension = ext +} + +// SetURL устанавливает структуру URL +func (p *ActionURL) SetURL(u string) (err error) { + if p.URL, err = url.Parse(u); err != nil { + return err + } + return nil +} + +// Make возвращает Action URL из сохраненных данных +func (p *ActionURL) Make() string { + if p.id != "" && p.extension != "" { + return fmt.Sprintf("grpc:///%s/%s", p.extension, p.id) + } + return p.URL.String() +} + +// parse функция для заполнения структуры ActionURL из переданного действия +func parse(action string) (*ActionURL, error) { + if action == "" { + return &ActionURL{URL: nil}, nil + } + actionURL := &ActionURL{} + err := actionURL.SetURL(action) + if err != nil { + return nil, err + } + if actionURL.URL.Scheme == "grpc" { + path := actionURL.Path + if strings.HasPrefix(actionURL.Path, "/") { + path = actionURL.Path[1:] + } + splitPath := strings.Split(path, "/") + if len(splitPath) < 2 { + return nil, errors.Errorf("incorrect action URL, no action id: '%s'", action) + } + actionURL.extension = splitPath[0] + actionURL.id = splitPath[1] + } + return actionURL, nil +} diff --git a/pkg/action-url/action_url_test.go b/pkg/action-url/action_url_test.go new file mode 100644 index 0000000000000000000000000000000000000000..30b4b32be112ee13250c8be929181d49a1301768 --- /dev/null +++ b/pkg/action-url/action_url_test.go @@ -0,0 +1,126 @@ +package action_url + +import ( + "fmt" + "net/url" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestActionURL_New(t *testing.T) { + tests := []struct { + name string + action string + want *ActionURL + url string + wantErr assert.ErrorAssertionFunc + }{ + { + name: "Without action", + want: &ActionURL{}, + wantErr: assert.NoError, + }, + { + name: "Without deprecated action call", + action: "build-site", + want: &ActionURL{}, + url: "build-site", + wantErr: assert.NoError, + }, + { + name: "With grpc action", + action: "grpc:///perxisweb/build-site", + want: &ActionURL{ + id: "build-site", + extension: "perxisweb", + }, + url: "grpc:///perxisweb/build-site", + wantErr: assert.NoError, + }, + { + name: "With ui action", + action: "ui:///space/env/coll", + want: &ActionURL{ + id: "", + extension: "", + }, + url: "ui:///space/env/coll", + wantErr: assert.NoError, + }, + { + name: "With http action", + action: "https://perx.ru", + want: &ActionURL{}, + url: "https://perx.ru", + wantErr: assert.NoError, + }, + { + name: "With error in parse", + action: "grpc://user:abc{DEf1=ghi@example.com:5432/db?sslmode=require", + want: nil, + wantErr: assert.Error, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if tt.url != "" { + tt.want.URL, _ = url.Parse(tt.url) + } + got, err := New(tt.action) + if !tt.wantErr(t, err, fmt.Sprintf("New(%v)", tt.action)) { + return + } + assert.Equalf(t, tt.want, got, "New(%v)", tt.action) + }) + } +} + +func TestActionURL_Make(t *testing.T) { + tests := []struct { + name string + id string + extension string + url string + want string + }{ + { + name: "Without action and extensions id's #1", + url: "grpc:///extension-id/action-id", + want: "grpc:///extension-id/action-id", + }, + { + name: "Without action and extensions id's #2", + url: "ui:///space/env/coll", + want: "ui:///space/env/coll", + }, + { + name: "Without action and extensions id's #3", + url: "space/env/coll", + want: "space/env/coll", + }, + { + name: "Without action and extensions id's #4", + url: "https://perx.ru", + want: "https://perx.ru", + }, + { + name: "With action and extensions", + id: "action-id", + extension: "extension-id", + want: "grpc:///extension-id/action-id", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &ActionURL{ + id: tt.id, + extension: tt.extension, + } + if tt.url != "" { + p.URL, _ = url.Parse(tt.url) + } + assert.Equalf(t, tt.want, p.Make(), "MakeFromURL()") + }) + } +} diff --git a/pkg/extension/action_url.go b/pkg/extension/action_url.go deleted file mode 100644 index 5552b81a43ee237788a3ca217e9c6cbd49f7351c..0000000000000000000000000000000000000000 --- a/pkg/extension/action_url.go +++ /dev/null @@ -1,66 +0,0 @@ -package extension - -import ( - "net/url" - "strings" - - "git.perx.ru/perxis/perxis-go/pkg/errors" -) - -// ActionURL структура для хранения данных о переданном действии -type ActionURL struct { - actionURL string - actionID string - extension string - scheme string - url *url.URL -} - -// NewActionURL возвращает пустую структуру ActionURL, если передано пустое действие -// при передаче в функцию действия - заполняет структуру -func NewActionURL(action string) (*ActionURL, error) { - return parseActionURL(action) -} - -// ID возвращает сохраненный в ActionURL id действия -func (p *ActionURL) ID() string { - return p.actionID -} - -// Extension возвращает сохраненный в ActionURL id расширения -func (p *ActionURL) Extension() string { - return p.extension -} - -// Scheme возвращает сохраненную в ActionURL схему -func (p *ActionURL) Scheme() string { - return p.scheme -} - -// parseActionURL функция для заполнения структуры ActionURL из переданного действия -func parseActionURL(action string) (*ActionURL, error) { - if action == "" { - return &ActionURL{}, nil - } - u, err := url.Parse(action) - if err != nil { - return nil, err - } - parsed := &ActionURL{} - parsed.actionURL = action - parsed.url = u - parsed.scheme = u.Scheme - if parsed.Scheme() == "grpc" { - path := u.Path - if strings.HasPrefix(u.Path, "/") { - path = u.Path[1:] - } - splitPath := strings.Split(path, "/") - if len(splitPath) < 2 { - return nil, errors.Errorf("incorrect action URL, no action id: '%s'", action) - } - parsed.extension = splitPath[0] - parsed.actionID = splitPath[1] - } - return parsed, nil -} diff --git a/pkg/extension/action_url_test.go b/pkg/extension/action_url_test.go deleted file mode 100644 index e71ef1b6acf54fd629904893551e08995f2fd2d2..0000000000000000000000000000000000000000 --- a/pkg/extension/action_url_test.go +++ /dev/null @@ -1,86 +0,0 @@ -package extension - -import ( - "fmt" - "net/url" - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestNewActionURL(t *testing.T) { - tests := []struct { - name string - action string - want *ActionURL - url string - wantErr assert.ErrorAssertionFunc - }{ - { - name: "Without action", - want: &ActionURL{}, - wantErr: assert.NoError, - }, - { - name: "Without deprecated action call", - action: "build-site", - want: &ActionURL{ - actionURL: "build-site", - }, - url: "build-site", - wantErr: assert.NoError, - }, - { - name: "With grpc action", - action: "grpc:///perxisweb/build-site", - want: &ActionURL{ - actionURL: "grpc:///perxisweb/build-site", - actionID: "build-site", - extension: "perxisweb", - scheme: "grpc", - }, - url: "grpc:///perxisweb/build-site", - wantErr: assert.NoError, - }, - { - name: "With ui action", - action: "ui:///space/env/coll", - want: &ActionURL{ - actionURL: "ui:///space/env/coll", - actionID: "", - extension: "", - scheme: "ui", - }, - url: "ui:///space/env/coll", - wantErr: assert.NoError, - }, - { - name: "With http action", - action: "https://perx.ru", - want: &ActionURL{ - actionURL: "https://perx.ru", - scheme: "https", - }, - url: "https://perx.ru", - wantErr: assert.NoError, - }, - { - name: "With error in parse", - action: "grpc://user:abc{DEf1=ghi@example.com:5432/db?sslmode=require", - want: nil, - wantErr: assert.Error, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if tt.url != "" { - tt.want.url, _ = url.Parse(tt.url) - } - got, err := NewActionURL(tt.action) - if !tt.wantErr(t, err, fmt.Sprintf("NewActionURL(%v)", tt.action)) { - return - } - assert.Equalf(t, tt.want, got, "NewActionURL(%v)", tt.action) - }) - } -} diff --git a/pkg/extension/server.go b/pkg/extension/server.go index aec70ff7a71128ed312030cc3bd28541f7f969f4..522c38b9492f0beb622b76708d6eab90c32dcd38 100644 --- a/pkg/extension/server.go +++ b/pkg/extension/server.go @@ -3,6 +3,7 @@ package extension import ( "context" + "git.perx.ru/perxis/perxis-go/pkg/action-url" "git.perx.ru/perxis/perxis-go/pkg/errors" pb "git.perx.ru/perxis/perxis-go/proto/extensions" ) @@ -82,11 +83,11 @@ func (srv *Server) Update(ctx context.Context, request *UpdateRequest) (*UpdateR func (srv *Server) Action(ctx context.Context, in *pb.ActionRequest) (*pb.ActionResponse, error) { ext := in.Extension if ext == "" { - actionURL, err := NewActionURL(in.Action) + actionURL, err := action_url.New(in.Action) if err != nil { return nil, err } - ext = actionURL.extension + ext = actionURL.Extension() } svc, ok := srv.services[ext] diff --git a/pkg/extension/service/extension.go b/pkg/extension/service/extension.go index 2fd57ee7c36d681e8d9768fa36a0961a953508c3..27ca5ca363ece282b18e49158d005693a6854c69 100644 --- a/pkg/extension/service/extension.go +++ b/pkg/extension/service/extension.go @@ -4,6 +4,7 @@ import ( "context" "fmt" + "git.perx.ru/perxis/perxis-go/pkg/action-url" "git.perx.ru/perxis/perxis-go/pkg/clients" "git.perx.ru/perxis/perxis-go/pkg/content" "git.perx.ru/perxis/perxis-go/pkg/errors" @@ -157,7 +158,7 @@ func (s *Extension) Uninstall(ctx context.Context, in *extension.UninstallReques func (s *Extension) Action(ctx context.Context, in *extension.ActionRequest) (*extension.ActionResponse, error) { ext := in.Extension if ext == "" { - actionURL, err := extension.NewActionURL(in.Action) + actionURL, err := action_url.New(in.Action) if err != nil { return nil, err }