From dae5af798bde1ab81613ab76f8305e4fb93372d8 Mon Sep 17 00:00:00 2001 From: ko_oler <kooler89@gmail.com> Date: Fri, 22 Sep 2023 14:12:02 +0300 Subject: [PATCH] =?UTF-8?q?=D0=BF=D1=80=D0=B0=D0=B2=D0=BA=D0=B8=20=D0=BF?= =?UTF-8?q?=D0=BE=20=D0=9F=D0=A0:=20-=20=D0=BF=D0=B5=D1=80=D0=B5=D0=B8?= =?UTF-8?q?=D0=BC=D0=B5=D0=BD=D0=BE=D0=B2=D0=B0=D0=BD=20=D1=82=D0=B8=D0=BF?= =?UTF-8?q?=20=D1=81=20parsedActionURL=20->=20ActionURL=20-=20=D0=B2=D1=8B?= =?UTF-8?q?=D0=BD=D0=B5=D1=81=D0=B5=D0=BD=20=D0=B2=20=D0=BE=D1=82=D0=B4?= =?UTF-8?q?=D0=B5=D0=BB=D1=8C=D0=BD=D1=8B=D0=B9=20=D1=84=D0=B0=D0=B9=D0=BB?= =?UTF-8?q?,=20=D0=BF=D0=B5=D1=80=D0=B5=D0=B8=D0=BC=D0=B5=D0=BD=D0=BE?= =?UTF-8?q?=D0=B2=D0=B0=D0=BD=D1=8B=20=D0=BC=D0=B5=D1=82=D0=BE=D0=B4=D1=8B?= =?UTF-8?q?,=20=D0=B8=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5=D0=BD=20=D0=BA=D0=BE?= =?UTF-8?q?=D0=BD=D1=81=D1=82=D1=80=D1=83=D0=BA=D1=82=D0=BE=D1=80=20-=20?= =?UTF-8?q?=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D1=8B=20=D1=82?= =?UTF-8?q?=D0=B5=D1=81=D1=82=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pkg/extension/action_url.go | 70 ++++++++++++++++++++++++ pkg/extension/action_url_test.go | 87 ++++++++++++++++++++++++++++++ pkg/extension/extension.go | 47 ---------------- pkg/extension/server.go | 13 +++-- pkg/extension/server_test.go | 81 ++++++++++++++++++++++++++++ pkg/extension/service/extension.go | 12 +++-- 6 files changed, 254 insertions(+), 56 deletions(-) create mode 100644 pkg/extension/action_url.go create mode 100644 pkg/extension/action_url_test.go diff --git a/pkg/extension/action_url.go b/pkg/extension/action_url.go new file mode 100644 index 00000000..72d35371 --- /dev/null +++ b/pkg/extension/action_url.go @@ -0,0 +1,70 @@ +package extension + +import ( + "net/url" + "strings" + + "git.perx.ru/perxis/perxis-go/pkg/errors" +) + +// ActionURL структура для хранения данных о переданном действии +type ActionURL struct { + actionURL string + actionID string + extensionID string + scheme string + url *url.URL +} + +// NewActionURL возвращает пустую структуру ActionURL, если передано пустое действие +// при передаче в функцию действия - заполняет структуру +func NewActionURL(action string) (*ActionURL, error) { + if action != "" { + parsedURL, err := parseActionURL(action) + if err != nil { + return nil, err + } + return parsedURL, nil + } + return &ActionURL{}, nil +} + +// ID возвращает сохраненный в ActionURL id действия +func (p *ActionURL) ID() string { + return p.actionID +} + +// ExtensionID возвращает сохраненный в ActionURL id расширения +func (p *ActionURL) ExtensionID() string { + return p.extensionID +} + +// Scheme возвращает сохраненную в ActionURL схему +func (p *ActionURL) Scheme() string { + return p.scheme +} + +// parseActionURL функция для заполнения структуры ActionURL из переданного действия +func parseActionURL(action string) (*ActionURL, error) { + 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.extensionID = 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 new file mode 100644 index 00000000..7c5ef5e4 --- /dev/null +++ b/pkg/extension/action_url_test.go @@ -0,0 +1,87 @@ +package extension + +import ( + "fmt" + "net/url" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestNewActionURL(t *testing.T) { + u1, _ := url.Parse("build-site") + u2, _ := url.Parse("grpc:///perxisweb/build-site") + u3, _ := url.Parse("ui:///space/env/coll") + u4, _ := url.Parse("https://perx.ru") + tests := []struct { + name string + action string + want *ActionURL + wantErr assert.ErrorAssertionFunc + }{ + { + "Without action", + "", + &ActionURL{}, + assert.NoError, + }, + { + "Without deprecated action call", + "build-site", + &ActionURL{ + actionURL: "build-site", + url: u1, + }, + assert.NoError, + }, + { + name: "With grpc action", + action: "grpc:///perxisweb/build-site", + want: &ActionURL{ + actionURL: "grpc:///perxisweb/build-site", + actionID: "build-site", + extensionID: "perxisweb", + scheme: "grpc", + url: u2, + }, + wantErr: assert.NoError, + }, + { + name: "With ui action", + action: "ui:///space/env/coll", + want: &ActionURL{ + actionURL: "ui:///space/env/coll", + actionID: "", + extensionID: "", + scheme: "ui", + url: u3, + }, + wantErr: assert.NoError, + }, + { + name: "With http action", + action: "https://perx.ru", + want: &ActionURL{ + actionURL: "https://perx.ru", + scheme: "https", + url: u4, + }, + 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) { + 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/extension.go b/pkg/extension/extension.go index 174ac51c..fb8044c7 100644 --- a/pkg/extension/extension.go +++ b/pkg/extension/extension.go @@ -3,8 +3,6 @@ package extension import ( "context" "fmt" - "net/url" - "strings" "git.perx.ru/perxis/perxis-go/pkg/content" "git.perx.ru/perxis/perxis-go/pkg/errors" @@ -107,48 +105,3 @@ func ExtensionFromError(err error) string { ext, _ := v.(string) return ext } - -type ParsedActionURL struct { - actionID string - extensionID string - scheme string -} - -func (p *ParsedActionURL) New() *ParsedActionURL { - return &ParsedActionURL{} -} - -func (p *ParsedActionURL) GetActionID() string { - return p.actionID -} - -func (p *ParsedActionURL) GetExtensionID() string { - return p.extensionID -} - -func (p *ParsedActionURL) GetScheme() string { - return p.scheme -} - -func ParseActionURL(action string) (*ParsedActionURL, error) { - - u, err := url.Parse(action) - if err != nil { - return nil, err - } - parsed := &ParsedActionURL{} - parsed.scheme = u.Scheme - if parsed.GetScheme() == "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.extensionID = splitPath[0] - parsed.actionID = splitPath[1] - } - return parsed, nil -} diff --git a/pkg/extension/server.go b/pkg/extension/server.go index be4b6f0a..bdeac58c 100644 --- a/pkg/extension/server.go +++ b/pkg/extension/server.go @@ -80,13 +80,16 @@ func (srv *Server) Update(ctx context.Context, request *UpdateRequest) (*UpdateR } func (srv *Server) Action(ctx context.Context, in *pb.ActionRequest) (*pb.ActionResponse, error) { - - parsed, err := ParseActionURL(in.Action) - if err != nil { - return nil, err + extensionID := in.Extension + if extensionID == "" { + actionURL, err := NewActionURL(in.Action) + if err != nil { + return nil, err + } + extensionID = actionURL.extensionID } - svc, ok := srv.services[parsed.GetExtensionID()] + svc, ok := srv.services[extensionID] if !ok { return nil, ErrUnknownExtension } diff --git a/pkg/extension/server_test.go b/pkg/extension/server_test.go index 5400c8c4..9e8b8f4c 100644 --- a/pkg/extension/server_test.go +++ b/pkg/extension/server_test.go @@ -2,11 +2,13 @@ package extension import ( "context" + "fmt" "reflect" "strings" "testing" "git.perx.ru/perxis/perxis-go/pkg/errors" + "github.com/stretchr/testify/assert" ) func TestGetResults(t *testing.T) { @@ -102,3 +104,82 @@ func (t testServerExtension) Uninstall(ctx context.Context, in *UninstallRequest func (t testServerExtension) Action(ctx context.Context, in *ActionRequest) (*ActionResponse, error) { return &ActionResponse{}, t.err } + +func TestServer_Action(t *testing.T) { + getDummyExtension := func(name string, wantErr ...bool) Extension { + ext := &testServerExtension{name: name} + + if len(wantErr) > 0 { + ext.err = errors.WithDetail(errors.New("some err"), "Ошибка") + } + + return ext + } + + var tests = []struct { + name string + services map[string]Extension + in *ActionRequest + want *ActionResponse + wantErr assert.ErrorAssertionFunc + }{ + { + name: "OK (grpc)", + services: map[string]Extension{"test-extension": getDummyExtension("test-extension")}, + in: &ActionRequest{ + Action: "grpc:///test-extension/test-action", + SpaceId: "sp", + EnvId: "env", + }, + want: &ActionResponse{State: ResponseDone}, + wantErr: assert.NoError, + }, + { + name: "OK (deprecated call)", + services: map[string]Extension{"test-extension": getDummyExtension("test-extension")}, + in: &ActionRequest{ + Action: "test-action", + SpaceId: "sp", + EnvId: "env", + Extension: "test-extension", + }, + want: &ActionResponse{State: ResponseDone}, + wantErr: assert.NoError, + }, + { + name: "Error (unknown extension)", + services: map[string]Extension{"test-extension": getDummyExtension("test-extension")}, + in: &ActionRequest{ + Action: "grpc:///test-extension-2/test-action", + SpaceId: "sp", + EnvId: "env", + }, + want: nil, + wantErr: assert.Error, + }, + { + name: "Error (deprecated call, no extension)", + services: map[string]Extension{"test-extension": getDummyExtension("test-extension")}, + in: &ActionRequest{ + Action: "test-action", + SpaceId: "sp", + EnvId: "env", + }, + want: nil, + wantErr: assert.Error, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + + srv := &Server{ + services: tt.services, + } + got, err := srv.Action(context.Background(), tt.in) + if !tt.wantErr(t, err, fmt.Sprintf("Action(%v)", tt.in)) { + return + } + assert.Equalf(t, tt.want, got, "Action(%v)", tt.in) + }) + } +} diff --git a/pkg/extension/service/extension.go b/pkg/extension/service/extension.go index e0b4e2ab..f57f8253 100644 --- a/pkg/extension/service/extension.go +++ b/pkg/extension/service/extension.go @@ -155,11 +155,15 @@ func (s *Extension) Uninstall(ctx context.Context, in *extension.UninstallReques } func (s *Extension) Action(ctx context.Context, in *extension.ActionRequest) (*extension.ActionResponse, error) { - parsed, err := extension.ParseActionURL(in.Action) - if err != nil { - return nil, err + extensionID := in.Extension + if extensionID == "" { + actionURL, err := extension.NewActionURL(in.Action) + if err != nil { + return nil, err + } + extensionID = actionURL.ExtensionID() } - ok, err := extension.CheckInstalled(ctx, s.Content, in.SpaceId, in.EnvId, parsed.GetExtensionID()) + ok, err := extension.CheckInstalled(ctx, s.Content, in.SpaceId, in.EnvId, extensionID) if err != nil { return nil, errors.Wrap(err, "check extension installed") } -- GitLab