From 4df0543661d9852e675d8478d3ecde78ba4d2792 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Mon, 21 Mar 2022 14:32:16 +0100 Subject: [PATCH] Manager: Implementation of Shaman OAPI interface This hooks up the OpenAPI Shaman endpoints to a Shaman interface. This interface doesn't have any implementation yet. --- internal/manager/api_impl/api_impl.go | 24 +- .../api_impl/mocks/api_impl_mock.gen.go | 84 ++- internal/manager/api_impl/shaman.go | 116 ++++ internal/worker/mocks/client.gen.go | 120 ++++ pkg/api/openapi_client.gen.go | 565 ++++++++++++++++++ pkg/api/openapi_server.gen.go | 124 ++++ pkg/api/openapi_spec.gen.go | 139 +++-- pkg/api/openapi_types.gen.go | 46 ++ 8 files changed, 1156 insertions(+), 62 deletions(-) create mode 100644 internal/manager/api_impl/shaman.go diff --git a/internal/manager/api_impl/api_impl.go b/internal/manager/api_impl/api_impl.go index 1108ac39..4dd226b6 100644 --- a/internal/manager/api_impl/api_impl.go +++ b/internal/manager/api_impl/api_impl.go @@ -6,6 +6,7 @@ package api_impl import ( "context" "fmt" + "io" "net/http" "git.blender.org/flamenco/internal/appinfo" @@ -23,12 +24,13 @@ type Flamenco struct { logStorage LogStorage config ConfigService stateMachine TaskStateMachine + shaman Shaman } var _ api.ServerInterface = (*Flamenco)(nil) // Generate mock implementations of these interfaces. -//go:generate go run github.com/golang/mock/mockgen -destination mocks/api_impl_mock.gen.go -package mocks git.blender.org/flamenco/internal/manager/api_impl PersistenceService,JobCompiler,LogStorage,ConfigService,TaskStateMachine +//go:generate go run github.com/golang/mock/mockgen -destination mocks/api_impl_mock.gen.go -package mocks git.blender.org/flamenco/internal/manager/api_impl PersistenceService,JobCompiler,LogStorage,ConfigService,TaskStateMachine,Shaman type PersistenceService interface { StoreAuthoredJob(ctx context.Context, authoredJob job_compilers.AuthoredJob) error @@ -77,6 +79,26 @@ type ConfigService interface { VariableReplacer } +type Shaman interface { + // Checkout creates a directory, and symlinks the required files into it. The + // files must all have been uploaded to Shaman before calling this. + Checkout(ctx context.Context, checkoutID string, checkout api.ShamanCheckout) error + + // Requirements checks a Shaman Requirements file, and returns the subset + // containing the unknown files. + Requirements(ctx context.Context, requirements api.ShamanRequirements) (api.ShamanRequirements, error) + + // Check the status of a file on the Shaman server. + // TODO: instead of an integer, return a constant that indicates the actual + // status (stored, currently being uploaded, unknown). + FileStoreCheck(ctx context.Context, checksum string, filesize int64) (int, error) + + // Store a new file on the Shaman server. Note that the Shaman server can + // return early when another client finishes uploading the exact same file, to + // prevent double uploads. + FileStore(ctx context.Context, file io.ReadCloser, checksum string, filesize int64, canDefer bool, originalFilename string) error +} + // NewFlamenco creates a new Flamenco service. func NewFlamenco( jc JobCompiler, diff --git a/internal/manager/api_impl/mocks/api_impl_mock.gen.go b/internal/manager/api_impl/mocks/api_impl_mock.gen.go index b186fc3f..db40c763 100644 --- a/internal/manager/api_impl/mocks/api_impl_mock.gen.go +++ b/internal/manager/api_impl/mocks/api_impl_mock.gen.go @@ -1,11 +1,12 @@ // Code generated by MockGen. DO NOT EDIT. -// Source: git.blender.org/flamenco/internal/manager/api_impl (interfaces: PersistenceService,JobCompiler,LogStorage,ConfigService,TaskStateMachine) +// Source: git.blender.org/flamenco/internal/manager/api_impl (interfaces: PersistenceService,JobCompiler,LogStorage,ConfigService,TaskStateMachine,Shaman) // Package mocks is a generated GoMock package. package mocks import ( context "context" + io "io" reflect "reflect" config "git.blender.org/flamenco/internal/manager/config" @@ -386,3 +387,84 @@ func (mr *MockTaskStateMachineMockRecorder) TaskStatusChange(arg0, arg1, arg2 in mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TaskStatusChange", reflect.TypeOf((*MockTaskStateMachine)(nil).TaskStatusChange), arg0, arg1, arg2) } + +// MockShaman is a mock of Shaman interface. +type MockShaman struct { + ctrl *gomock.Controller + recorder *MockShamanMockRecorder +} + +// MockShamanMockRecorder is the mock recorder for MockShaman. +type MockShamanMockRecorder struct { + mock *MockShaman +} + +// NewMockShaman creates a new mock instance. +func NewMockShaman(ctrl *gomock.Controller) *MockShaman { + mock := &MockShaman{ctrl: ctrl} + mock.recorder = &MockShamanMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockShaman) EXPECT() *MockShamanMockRecorder { + return m.recorder +} + +// Checkout mocks base method. +func (m *MockShaman) Checkout(arg0 context.Context, arg1 string, arg2 api.ShamanCheckout) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Checkout", arg0, arg1, arg2) + ret0, _ := ret[0].(error) + return ret0 +} + +// Checkout indicates an expected call of Checkout. +func (mr *MockShamanMockRecorder) Checkout(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Checkout", reflect.TypeOf((*MockShaman)(nil).Checkout), arg0, arg1, arg2) +} + +// FileStore mocks base method. +func (m *MockShaman) FileStore(arg0 context.Context, arg1 io.ReadCloser, arg2 string, arg3 int64, arg4 bool, arg5 string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "FileStore", arg0, arg1, arg2, arg3, arg4, arg5) + ret0, _ := ret[0].(error) + return ret0 +} + +// FileStore indicates an expected call of FileStore. +func (mr *MockShamanMockRecorder) FileStore(arg0, arg1, arg2, arg3, arg4, arg5 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FileStore", reflect.TypeOf((*MockShaman)(nil).FileStore), arg0, arg1, arg2, arg3, arg4, arg5) +} + +// FileStoreCheck mocks base method. +func (m *MockShaman) FileStoreCheck(arg0 context.Context, arg1 string, arg2 int64) (int, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "FileStoreCheck", arg0, arg1, arg2) + ret0, _ := ret[0].(int) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// FileStoreCheck indicates an expected call of FileStoreCheck. +func (mr *MockShamanMockRecorder) FileStoreCheck(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FileStoreCheck", reflect.TypeOf((*MockShaman)(nil).FileStoreCheck), arg0, arg1, arg2) +} + +// Requirements mocks base method. +func (m *MockShaman) Requirements(arg0 context.Context, arg1 api.ShamanRequirements) (api.ShamanRequirements, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Requirements", arg0, arg1) + ret0, _ := ret[0].(api.ShamanRequirements) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Requirements indicates an expected call of Requirements. +func (mr *MockShamanMockRecorder) Requirements(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Requirements", reflect.TypeOf((*MockShaman)(nil).Requirements), arg0, arg1) +} diff --git a/internal/manager/api_impl/shaman.go b/internal/manager/api_impl/shaman.go new file mode 100644 index 00000000..94898172 --- /dev/null +++ b/internal/manager/api_impl/shaman.go @@ -0,0 +1,116 @@ +package api_impl + +// SPDX-License-Identifier: GPL-3.0-or-later + +import ( + "net/http" + + "github.com/labstack/echo/v4" + + "git.blender.org/flamenco/pkg/api" +) + +// Create a directory, and symlink the required files into it. The files must all have been uploaded to Shaman before calling this endpoint. +// (POST /shaman/checkout/create/{checkoutID}) +func (f *Flamenco) ShamanCheckout(e echo.Context, checkoutID string) error { + logger := requestLogger(e).With(). + Str("checkoutID", checkoutID). + Logger() + + var reqBody api.ShamanCheckoutJSONBody + err := e.Bind(&reqBody) + if err != nil { + logger.Warn().Err(err).Msg("bad request received") + return sendAPIError(e, http.StatusBadRequest, "invalid format") + } + + err = f.shaman.Checkout(e.Request().Context(), checkoutID, api.ShamanCheckout(reqBody)) + if err != nil { + // TODO: return 409 when checkout already exists. + logger.Warn().Err(err).Msg("Shaman: creating checkout") + return sendAPIError(e, http.StatusInternalServerError, "unexpected error: %v", err) + } + + return e.String(http.StatusNoContent, "") +} + +// Checks a Shaman Requirements file, and reports which files are unknown. +// (POST /shaman/checkout/requirements) +func (f *Flamenco) ShamanCheckoutRequirements(e echo.Context) error { + logger := requestLogger(e) + + var reqBody api.ShamanCheckoutRequirementsJSONBody + err := e.Bind(&reqBody) + if err != nil { + logger.Warn().Err(err).Msg("bad request received") + return sendAPIError(e, http.StatusBadRequest, "invalid format") + } + + unknownFiles, err := f.shaman.Requirements(e.Request().Context(), api.ShamanRequirements(reqBody)) + if err != nil { + logger.Warn().Err(err).Msg("Shaman: checking checkout requirements file") + return sendAPIError(e, http.StatusInternalServerError, "unexpected error: %v", err) + } + + return e.JSON(http.StatusOK, unknownFiles) +} + +// Check the status of a file on the Shaman server. +// (OPTIONS /shaman/files/{checksum}/{filesize}) +func (f *Flamenco) ShamanFileStoreCheck(e echo.Context, checksum string, filesize int) error { + logger := requestLogger(e).With(). + Str("checksum", checksum).Int("filesize", filesize). + Logger() + + status, err := f.shaman.FileStoreCheck(e.Request().Context(), checksum, int64(filesize)) + if err != nil { + logger.Warn().Err(err).Msg("Shaman: checking stored file") + return sendAPIError(e, http.StatusInternalServerError, "unexpected error: %v", err) + } + + // TODO: actually switch over the actual statuses, see the TODO in the Shaman interface. + switch status { + case 0: // known + return e.String(http.StatusOK, "") + case 1: // being uploaded + return e.String(420 /* Enhance Your Calm */, "") + case 2: // unknown + return e.String(http.StatusNotFound, "") + } + + return sendAPIError(e, http.StatusInternalServerError, "unexpected file status") +} + +// Store a new file on the Shaman server. Note that the Shaman server can +// forcibly close the HTTP connection when another client finishes uploading the +// exact same file, to prevent double uploads. +// (POST /shaman/files/{checksum}/{filesize}) +func (f *Flamenco) ShamanFileStore(e echo.Context, checksum string, filesize int, params api.ShamanFileStoreParams) error { + var ( + origFilename string + canDefer bool + ) + + logCtx := requestLogger(e).With(). + Str("checksum", checksum).Int("filesize", filesize) + if params.XShamanCanDeferUpload != nil { + canDefer = *params.XShamanCanDeferUpload + logCtx = logCtx.Bool("canDefer", canDefer) + } + if params.XShamanOriginalFilename != nil { + origFilename = *params.XShamanOriginalFilename + logCtx = logCtx.Str("originalFilename", origFilename) + } + logger := logCtx.Logger() + + err := f.shaman.FileStore(e.Request().Context(), e.Request().Body, + checksum, int64(filesize), + canDefer, origFilename, + ) + if err != nil { + logger.Warn().Err(err).Msg("Shaman: checking stored file") + return sendAPIError(e, http.StatusInternalServerError, "unexpected error: %v", err) + } + + return nil +} diff --git a/internal/worker/mocks/client.gen.go b/internal/worker/mocks/client.gen.go index 93d052c7..4c311c5a 100644 --- a/internal/worker/mocks/client.gen.go +++ b/internal/worker/mocks/client.gen.go @@ -156,6 +156,126 @@ func (mr *MockFlamencoClientMockRecorder) ScheduleTaskWithResponse(arg0 interfac return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ScheduleTaskWithResponse", reflect.TypeOf((*MockFlamencoClient)(nil).ScheduleTaskWithResponse), varargs...) } +// ShamanCheckoutRequirementsWithBodyWithResponse mocks base method. +func (m *MockFlamencoClient) ShamanCheckoutRequirementsWithBodyWithResponse(arg0 context.Context, arg1 string, arg2 io.Reader, arg3 ...api.RequestEditorFn) (*api.ShamanCheckoutRequirementsResponse, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1, arg2} + for _, a := range arg3 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "ShamanCheckoutRequirementsWithBodyWithResponse", varargs...) + ret0, _ := ret[0].(*api.ShamanCheckoutRequirementsResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ShamanCheckoutRequirementsWithBodyWithResponse indicates an expected call of ShamanCheckoutRequirementsWithBodyWithResponse. +func (mr *MockFlamencoClientMockRecorder) ShamanCheckoutRequirementsWithBodyWithResponse(arg0, arg1, arg2 interface{}, arg3 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1, arg2}, arg3...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ShamanCheckoutRequirementsWithBodyWithResponse", reflect.TypeOf((*MockFlamencoClient)(nil).ShamanCheckoutRequirementsWithBodyWithResponse), varargs...) +} + +// ShamanCheckoutRequirementsWithResponse mocks base method. +func (m *MockFlamencoClient) ShamanCheckoutRequirementsWithResponse(arg0 context.Context, arg1 api.ShamanCheckoutRequirementsJSONRequestBody, arg2 ...api.RequestEditorFn) (*api.ShamanCheckoutRequirementsResponse, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "ShamanCheckoutRequirementsWithResponse", varargs...) + ret0, _ := ret[0].(*api.ShamanCheckoutRequirementsResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ShamanCheckoutRequirementsWithResponse indicates an expected call of ShamanCheckoutRequirementsWithResponse. +func (mr *MockFlamencoClientMockRecorder) ShamanCheckoutRequirementsWithResponse(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ShamanCheckoutRequirementsWithResponse", reflect.TypeOf((*MockFlamencoClient)(nil).ShamanCheckoutRequirementsWithResponse), varargs...) +} + +// ShamanCheckoutWithBodyWithResponse mocks base method. +func (m *MockFlamencoClient) ShamanCheckoutWithBodyWithResponse(arg0 context.Context, arg1, arg2 string, arg3 io.Reader, arg4 ...api.RequestEditorFn) (*api.ShamanCheckoutResponse, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1, arg2, arg3} + for _, a := range arg4 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "ShamanCheckoutWithBodyWithResponse", varargs...) + ret0, _ := ret[0].(*api.ShamanCheckoutResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ShamanCheckoutWithBodyWithResponse indicates an expected call of ShamanCheckoutWithBodyWithResponse. +func (mr *MockFlamencoClientMockRecorder) ShamanCheckoutWithBodyWithResponse(arg0, arg1, arg2, arg3 interface{}, arg4 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1, arg2, arg3}, arg4...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ShamanCheckoutWithBodyWithResponse", reflect.TypeOf((*MockFlamencoClient)(nil).ShamanCheckoutWithBodyWithResponse), varargs...) +} + +// ShamanCheckoutWithResponse mocks base method. +func (m *MockFlamencoClient) ShamanCheckoutWithResponse(arg0 context.Context, arg1 string, arg2 api.ShamanCheckoutJSONRequestBody, arg3 ...api.RequestEditorFn) (*api.ShamanCheckoutResponse, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1, arg2} + for _, a := range arg3 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "ShamanCheckoutWithResponse", varargs...) + ret0, _ := ret[0].(*api.ShamanCheckoutResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ShamanCheckoutWithResponse indicates an expected call of ShamanCheckoutWithResponse. +func (mr *MockFlamencoClientMockRecorder) ShamanCheckoutWithResponse(arg0, arg1, arg2 interface{}, arg3 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1, arg2}, arg3...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ShamanCheckoutWithResponse", reflect.TypeOf((*MockFlamencoClient)(nil).ShamanCheckoutWithResponse), varargs...) +} + +// ShamanFileStoreCheckWithResponse mocks base method. +func (m *MockFlamencoClient) ShamanFileStoreCheckWithResponse(arg0 context.Context, arg1 string, arg2 int, arg3 ...api.RequestEditorFn) (*api.ShamanFileStoreCheckResponse, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1, arg2} + for _, a := range arg3 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "ShamanFileStoreCheckWithResponse", varargs...) + ret0, _ := ret[0].(*api.ShamanFileStoreCheckResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ShamanFileStoreCheckWithResponse indicates an expected call of ShamanFileStoreCheckWithResponse. +func (mr *MockFlamencoClientMockRecorder) ShamanFileStoreCheckWithResponse(arg0, arg1, arg2 interface{}, arg3 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1, arg2}, arg3...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ShamanFileStoreCheckWithResponse", reflect.TypeOf((*MockFlamencoClient)(nil).ShamanFileStoreCheckWithResponse), varargs...) +} + +// ShamanFileStoreWithBodyWithResponse mocks base method. +func (m *MockFlamencoClient) ShamanFileStoreWithBodyWithResponse(arg0 context.Context, arg1 string, arg2 int, arg3 *api.ShamanFileStoreParams, arg4 string, arg5 io.Reader, arg6 ...api.RequestEditorFn) (*api.ShamanFileStoreResponse, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1, arg2, arg3, arg4, arg5} + for _, a := range arg6 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "ShamanFileStoreWithBodyWithResponse", varargs...) + ret0, _ := ret[0].(*api.ShamanFileStoreResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ShamanFileStoreWithBodyWithResponse indicates an expected call of ShamanFileStoreWithBodyWithResponse. +func (mr *MockFlamencoClientMockRecorder) ShamanFileStoreWithBodyWithResponse(arg0, arg1, arg2, arg3, arg4, arg5 interface{}, arg6 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1, arg2, arg3, arg4, arg5}, arg6...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ShamanFileStoreWithBodyWithResponse", reflect.TypeOf((*MockFlamencoClient)(nil).ShamanFileStoreWithBodyWithResponse), varargs...) +} + // SignOffWithResponse mocks base method. func (m *MockFlamencoClient) SignOffWithResponse(arg0 context.Context, arg1 ...api.RequestEditorFn) (*api.SignOffResponse, error) { m.ctrl.T.Helper() diff --git a/pkg/api/openapi_client.gen.go b/pkg/api/openapi_client.gen.go index 2a70a2a2..6bf2ced7 100644 --- a/pkg/api/openapi_client.gen.go +++ b/pkg/api/openapi_client.gen.go @@ -132,6 +132,22 @@ type ClientInterface interface { TaskUpdateWithBody(ctx context.Context, taskId string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) TaskUpdate(ctx context.Context, taskId string, body TaskUpdateJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) + + // ShamanCheckout request with any body + ShamanCheckoutWithBody(ctx context.Context, checkoutID string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) + + ShamanCheckout(ctx context.Context, checkoutID string, body ShamanCheckoutJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) + + // ShamanCheckoutRequirements request with any body + ShamanCheckoutRequirementsWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) + + ShamanCheckoutRequirements(ctx context.Context, body ShamanCheckoutRequirementsJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) + + // ShamanFileStoreCheck request + ShamanFileStoreCheck(ctx context.Context, checksum string, filesize int, reqEditors ...RequestEditorFn) (*http.Response, error) + + // ShamanFileStore request with any body + ShamanFileStoreWithBody(ctx context.Context, checksum string, filesize int, params *ShamanFileStoreParams, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) } func (c *Client) SubmitJobWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { @@ -326,6 +342,78 @@ func (c *Client) TaskUpdate(ctx context.Context, taskId string, body TaskUpdateJ return c.Client.Do(req) } +func (c *Client) ShamanCheckoutWithBody(ctx context.Context, checkoutID string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewShamanCheckoutRequestWithBody(c.Server, checkoutID, contentType, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) ShamanCheckout(ctx context.Context, checkoutID string, body ShamanCheckoutJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewShamanCheckoutRequest(c.Server, checkoutID, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) ShamanCheckoutRequirementsWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewShamanCheckoutRequirementsRequestWithBody(c.Server, contentType, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) ShamanCheckoutRequirements(ctx context.Context, body ShamanCheckoutRequirementsJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewShamanCheckoutRequirementsRequest(c.Server, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) ShamanFileStoreCheck(ctx context.Context, checksum string, filesize int, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewShamanFileStoreCheckRequest(c.Server, checksum, filesize) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) ShamanFileStoreWithBody(ctx context.Context, checksum string, filesize int, params *ShamanFileStoreParams, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewShamanFileStoreRequestWithBody(c.Server, checksum, filesize, params, contentType, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + // NewSubmitJobRequest calls the generic SubmitJob builder with application/json body func NewSubmitJobRequest(server string, body SubmitJobJSONRequestBody) (*http.Request, error) { var bodyReader io.Reader @@ -702,6 +790,199 @@ func NewTaskUpdateRequestWithBody(server string, taskId string, contentType stri return req, nil } +// NewShamanCheckoutRequest calls the generic ShamanCheckout builder with application/json body +func NewShamanCheckoutRequest(server string, checkoutID string, body ShamanCheckoutJSONRequestBody) (*http.Request, error) { + var bodyReader io.Reader + buf, err := json.Marshal(body) + if err != nil { + return nil, err + } + bodyReader = bytes.NewReader(buf) + return NewShamanCheckoutRequestWithBody(server, checkoutID, "application/json", bodyReader) +} + +// NewShamanCheckoutRequestWithBody generates requests for ShamanCheckout with any type of body +func NewShamanCheckoutRequestWithBody(server string, checkoutID string, contentType string, body io.Reader) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "checkoutID", runtime.ParamLocationPath, checkoutID) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/shaman/checkout/create/%s", pathParam0) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("POST", queryURL.String(), body) + if err != nil { + return nil, err + } + + req.Header.Add("Content-Type", contentType) + + return req, nil +} + +// NewShamanCheckoutRequirementsRequest calls the generic ShamanCheckoutRequirements builder with application/json body +func NewShamanCheckoutRequirementsRequest(server string, body ShamanCheckoutRequirementsJSONRequestBody) (*http.Request, error) { + var bodyReader io.Reader + buf, err := json.Marshal(body) + if err != nil { + return nil, err + } + bodyReader = bytes.NewReader(buf) + return NewShamanCheckoutRequirementsRequestWithBody(server, "application/json", bodyReader) +} + +// NewShamanCheckoutRequirementsRequestWithBody generates requests for ShamanCheckoutRequirements with any type of body +func NewShamanCheckoutRequirementsRequestWithBody(server string, contentType string, body io.Reader) (*http.Request, error) { + var err error + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/shaman/checkout/requirements") + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("POST", queryURL.String(), body) + if err != nil { + return nil, err + } + + req.Header.Add("Content-Type", contentType) + + return req, nil +} + +// NewShamanFileStoreCheckRequest generates requests for ShamanFileStoreCheck +func NewShamanFileStoreCheckRequest(server string, checksum string, filesize int) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "checksum", runtime.ParamLocationPath, checksum) + if err != nil { + return nil, err + } + + var pathParam1 string + + pathParam1, err = runtime.StyleParamWithLocation("simple", false, "filesize", runtime.ParamLocationPath, filesize) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/shaman/files/%s/%s", pathParam0, pathParam1) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("OPTIONS", queryURL.String(), nil) + if err != nil { + return nil, err + } + + return req, nil +} + +// NewShamanFileStoreRequestWithBody generates requests for ShamanFileStore with any type of body +func NewShamanFileStoreRequestWithBody(server string, checksum string, filesize int, params *ShamanFileStoreParams, contentType string, body io.Reader) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "checksum", runtime.ParamLocationPath, checksum) + if err != nil { + return nil, err + } + + var pathParam1 string + + pathParam1, err = runtime.StyleParamWithLocation("simple", false, "filesize", runtime.ParamLocationPath, filesize) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/shaman/files/%s/%s", pathParam0, pathParam1) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("POST", queryURL.String(), body) + if err != nil { + return nil, err + } + + req.Header.Add("Content-Type", contentType) + + if params.XShamanCanDeferUpload != nil { + var headerParam0 string + + headerParam0, err = runtime.StyleParamWithLocation("simple", false, "X-Shaman-Can-Defer-Upload", runtime.ParamLocationHeader, *params.XShamanCanDeferUpload) + if err != nil { + return nil, err + } + + req.Header.Set("X-Shaman-Can-Defer-Upload", headerParam0) + } + + if params.XShamanOriginalFilename != nil { + var headerParam1 string + + headerParam1, err = runtime.StyleParamWithLocation("simple", false, "X-Shaman-Original-Filename", runtime.ParamLocationHeader, *params.XShamanOriginalFilename) + if err != nil { + return nil, err + } + + req.Header.Set("X-Shaman-Original-Filename", headerParam1) + } + + return req, nil +} + func (c *Client) applyEditors(ctx context.Context, req *http.Request, additionalEditors []RequestEditorFn) error { for _, r := range c.RequestEditors { if err := r(ctx, req); err != nil { @@ -787,6 +1068,22 @@ type ClientWithResponsesInterface interface { TaskUpdateWithBodyWithResponse(ctx context.Context, taskId string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*TaskUpdateResponse, error) TaskUpdateWithResponse(ctx context.Context, taskId string, body TaskUpdateJSONRequestBody, reqEditors ...RequestEditorFn) (*TaskUpdateResponse, error) + + // ShamanCheckout request with any body + ShamanCheckoutWithBodyWithResponse(ctx context.Context, checkoutID string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*ShamanCheckoutResponse, error) + + ShamanCheckoutWithResponse(ctx context.Context, checkoutID string, body ShamanCheckoutJSONRequestBody, reqEditors ...RequestEditorFn) (*ShamanCheckoutResponse, error) + + // ShamanCheckoutRequirements request with any body + ShamanCheckoutRequirementsWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*ShamanCheckoutRequirementsResponse, error) + + ShamanCheckoutRequirementsWithResponse(ctx context.Context, body ShamanCheckoutRequirementsJSONRequestBody, reqEditors ...RequestEditorFn) (*ShamanCheckoutRequirementsResponse, error) + + // ShamanFileStoreCheck request + ShamanFileStoreCheckWithResponse(ctx context.Context, checksum string, filesize int, reqEditors ...RequestEditorFn) (*ShamanFileStoreCheckResponse, error) + + // ShamanFileStore request with any body + ShamanFileStoreWithBodyWithResponse(ctx context.Context, checksum string, filesize int, params *ShamanFileStoreParams, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*ShamanFileStoreResponse, error) } type SubmitJobResponse struct { @@ -1037,6 +1334,97 @@ func (r TaskUpdateResponse) StatusCode() int { return 0 } +type ShamanCheckoutResponse struct { + Body []byte + HTTPResponse *http.Response + JSON409 *Error + JSONDefault *Error +} + +// Status returns HTTPResponse.Status +func (r ShamanCheckoutResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r ShamanCheckoutResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type ShamanCheckoutRequirementsResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *ShamanRequirements + JSONDefault *Error +} + +// Status returns HTTPResponse.Status +func (r ShamanCheckoutRequirementsResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r ShamanCheckoutRequirementsResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type ShamanFileStoreCheckResponse struct { + Body []byte + HTTPResponse *http.Response + JSONDefault *Error +} + +// Status returns HTTPResponse.Status +func (r ShamanFileStoreCheckResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r ShamanFileStoreCheckResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type ShamanFileStoreResponse struct { + Body []byte + HTTPResponse *http.Response + JSON409 *Error + JSONDefault *Error +} + +// Status returns HTTPResponse.Status +func (r ShamanFileStoreResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r ShamanFileStoreResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + // SubmitJobWithBodyWithResponse request with arbitrary body returning *SubmitJobResponse func (c *ClientWithResponses) SubmitJobWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*SubmitJobResponse, error) { rsp, err := c.SubmitJobWithBody(ctx, contentType, body, reqEditors...) @@ -1176,6 +1564,58 @@ func (c *ClientWithResponses) TaskUpdateWithResponse(ctx context.Context, taskId return ParseTaskUpdateResponse(rsp) } +// ShamanCheckoutWithBodyWithResponse request with arbitrary body returning *ShamanCheckoutResponse +func (c *ClientWithResponses) ShamanCheckoutWithBodyWithResponse(ctx context.Context, checkoutID string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*ShamanCheckoutResponse, error) { + rsp, err := c.ShamanCheckoutWithBody(ctx, checkoutID, contentType, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseShamanCheckoutResponse(rsp) +} + +func (c *ClientWithResponses) ShamanCheckoutWithResponse(ctx context.Context, checkoutID string, body ShamanCheckoutJSONRequestBody, reqEditors ...RequestEditorFn) (*ShamanCheckoutResponse, error) { + rsp, err := c.ShamanCheckout(ctx, checkoutID, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseShamanCheckoutResponse(rsp) +} + +// ShamanCheckoutRequirementsWithBodyWithResponse request with arbitrary body returning *ShamanCheckoutRequirementsResponse +func (c *ClientWithResponses) ShamanCheckoutRequirementsWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*ShamanCheckoutRequirementsResponse, error) { + rsp, err := c.ShamanCheckoutRequirementsWithBody(ctx, contentType, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseShamanCheckoutRequirementsResponse(rsp) +} + +func (c *ClientWithResponses) ShamanCheckoutRequirementsWithResponse(ctx context.Context, body ShamanCheckoutRequirementsJSONRequestBody, reqEditors ...RequestEditorFn) (*ShamanCheckoutRequirementsResponse, error) { + rsp, err := c.ShamanCheckoutRequirements(ctx, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseShamanCheckoutRequirementsResponse(rsp) +} + +// ShamanFileStoreCheckWithResponse request returning *ShamanFileStoreCheckResponse +func (c *ClientWithResponses) ShamanFileStoreCheckWithResponse(ctx context.Context, checksum string, filesize int, reqEditors ...RequestEditorFn) (*ShamanFileStoreCheckResponse, error) { + rsp, err := c.ShamanFileStoreCheck(ctx, checksum, filesize, reqEditors...) + if err != nil { + return nil, err + } + return ParseShamanFileStoreCheckResponse(rsp) +} + +// ShamanFileStoreWithBodyWithResponse request with arbitrary body returning *ShamanFileStoreResponse +func (c *ClientWithResponses) ShamanFileStoreWithBodyWithResponse(ctx context.Context, checksum string, filesize int, params *ShamanFileStoreParams, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*ShamanFileStoreResponse, error) { + rsp, err := c.ShamanFileStoreWithBody(ctx, checksum, filesize, params, contentType, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseShamanFileStoreResponse(rsp) +} + // ParseSubmitJobResponse parses an HTTP response from a SubmitJobWithResponse call func ParseSubmitJobResponse(rsp *http.Response) (*SubmitJobResponse, error) { bodyBytes, err := ioutil.ReadAll(rsp.Body) @@ -1503,3 +1943,128 @@ func ParseTaskUpdateResponse(rsp *http.Response) (*TaskUpdateResponse, error) { return response, nil } + +// ParseShamanCheckoutResponse parses an HTTP response from a ShamanCheckoutWithResponse call +func ParseShamanCheckoutResponse(rsp *http.Response) (*ShamanCheckoutResponse, error) { + bodyBytes, err := ioutil.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &ShamanCheckoutResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 409: + var dest Error + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON409 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && true: + var dest Error + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSONDefault = &dest + + } + + return response, nil +} + +// ParseShamanCheckoutRequirementsResponse parses an HTTP response from a ShamanCheckoutRequirementsWithResponse call +func ParseShamanCheckoutRequirementsResponse(rsp *http.Response) (*ShamanCheckoutRequirementsResponse, error) { + bodyBytes, err := ioutil.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &ShamanCheckoutRequirementsResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest ShamanRequirements + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && true: + var dest Error + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSONDefault = &dest + + } + + return response, nil +} + +// ParseShamanFileStoreCheckResponse parses an HTTP response from a ShamanFileStoreCheckWithResponse call +func ParseShamanFileStoreCheckResponse(rsp *http.Response) (*ShamanFileStoreCheckResponse, error) { + bodyBytes, err := ioutil.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &ShamanFileStoreCheckResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && true: + var dest Error + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSONDefault = &dest + + } + + return response, nil +} + +// ParseShamanFileStoreResponse parses an HTTP response from a ShamanFileStoreWithResponse call +func ParseShamanFileStoreResponse(rsp *http.Response) (*ShamanFileStoreResponse, error) { + bodyBytes, err := ioutil.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &ShamanFileStoreResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 409: + var dest Error + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON409 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && true: + var dest Error + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSONDefault = &dest + + } + + return response, nil +} diff --git a/pkg/api/openapi_server.gen.go b/pkg/api/openapi_server.gen.go index bbd8e5fc..d42a4c96 100644 --- a/pkg/api/openapi_server.gen.go +++ b/pkg/api/openapi_server.gen.go @@ -46,6 +46,18 @@ type ServerInterface interface { // Update the task, typically to indicate progress, completion, or failure. // (POST /api/worker/task/{task_id}) TaskUpdate(ctx echo.Context, taskId string) error + // Create a directory, and symlink the required files into it. The files must all have been uploaded to Shaman before calling this endpoint. + // (POST /shaman/checkout/create/{checkoutID}) + ShamanCheckout(ctx echo.Context, checkoutID string) error + // Checks a Shaman Requirements file, and reports which files are unknown. + // (POST /shaman/checkout/requirements) + ShamanCheckoutRequirements(ctx echo.Context) error + // Check the status of a file on the Shaman server. + // (OPTIONS /shaman/files/{checksum}/{filesize}) + ShamanFileStoreCheck(ctx echo.Context, checksum string, filesize int) error + // Store a new file on the Shaman server. Note that the Shaman server can forcibly close the HTTP connection when another client finishes uploading the exact same file, to prevent double uploads. + // (POST /shaman/files/{checksum}/{filesize}) + ShamanFileStore(ctx echo.Context, checksum string, filesize int, params ShamanFileStoreParams) error } // ServerInterfaceWrapper converts echo contexts to parameters. @@ -178,6 +190,114 @@ func (w *ServerInterfaceWrapper) TaskUpdate(ctx echo.Context) error { return err } +// ShamanCheckout converts echo context to params. +func (w *ServerInterfaceWrapper) ShamanCheckout(ctx echo.Context) error { + var err error + // ------------- Path parameter "checkoutID" ------------- + var checkoutID string + + err = runtime.BindStyledParameterWithLocation("simple", false, "checkoutID", runtime.ParamLocationPath, ctx.Param("checkoutID"), &checkoutID) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter checkoutID: %s", err)) + } + + // Invoke the callback with all the unmarshalled arguments + err = w.Handler.ShamanCheckout(ctx, checkoutID) + return err +} + +// ShamanCheckoutRequirements converts echo context to params. +func (w *ServerInterfaceWrapper) ShamanCheckoutRequirements(ctx echo.Context) error { + var err error + + // Invoke the callback with all the unmarshalled arguments + err = w.Handler.ShamanCheckoutRequirements(ctx) + return err +} + +// ShamanFileStoreCheck converts echo context to params. +func (w *ServerInterfaceWrapper) ShamanFileStoreCheck(ctx echo.Context) error { + var err error + // ------------- Path parameter "checksum" ------------- + var checksum string + + err = runtime.BindStyledParameterWithLocation("simple", false, "checksum", runtime.ParamLocationPath, ctx.Param("checksum"), &checksum) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter checksum: %s", err)) + } + + // ------------- Path parameter "filesize" ------------- + var filesize int + + err = runtime.BindStyledParameterWithLocation("simple", false, "filesize", runtime.ParamLocationPath, ctx.Param("filesize"), &filesize) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter filesize: %s", err)) + } + + // Invoke the callback with all the unmarshalled arguments + err = w.Handler.ShamanFileStoreCheck(ctx, checksum, filesize) + return err +} + +// ShamanFileStore converts echo context to params. +func (w *ServerInterfaceWrapper) ShamanFileStore(ctx echo.Context) error { + var err error + // ------------- Path parameter "checksum" ------------- + var checksum string + + err = runtime.BindStyledParameterWithLocation("simple", false, "checksum", runtime.ParamLocationPath, ctx.Param("checksum"), &checksum) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter checksum: %s", err)) + } + + // ------------- Path parameter "filesize" ------------- + var filesize int + + err = runtime.BindStyledParameterWithLocation("simple", false, "filesize", runtime.ParamLocationPath, ctx.Param("filesize"), &filesize) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter filesize: %s", err)) + } + + // Parameter object where we will unmarshal all parameters from the context + var params ShamanFileStoreParams + + headers := ctx.Request().Header + // ------------- Optional header parameter "X-Shaman-Can-Defer-Upload" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("X-Shaman-Can-Defer-Upload")]; found { + var XShamanCanDeferUpload bool + n := len(valueList) + if n != 1 { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Expected one value for X-Shaman-Can-Defer-Upload, got %d", n)) + } + + err = runtime.BindStyledParameterWithLocation("simple", false, "X-Shaman-Can-Defer-Upload", runtime.ParamLocationHeader, valueList[0], &XShamanCanDeferUpload) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter X-Shaman-Can-Defer-Upload: %s", err)) + } + + params.XShamanCanDeferUpload = &XShamanCanDeferUpload + } + // ------------- Optional header parameter "X-Shaman-Original-Filename" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("X-Shaman-Original-Filename")]; found { + var XShamanOriginalFilename string + n := len(valueList) + if n != 1 { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Expected one value for X-Shaman-Original-Filename, got %d", n)) + } + + err = runtime.BindStyledParameterWithLocation("simple", false, "X-Shaman-Original-Filename", runtime.ParamLocationHeader, valueList[0], &XShamanOriginalFilename) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter X-Shaman-Original-Filename: %s", err)) + } + + params.XShamanOriginalFilename = &XShamanOriginalFilename + } + + // Invoke the callback with all the unmarshalled arguments + err = w.Handler.ShamanFileStore(ctx, checksum, filesize, params) + return err +} + // This is a simple interface which specifies echo.Route addition functions which // are present on both echo.Echo and echo.Group, since we want to allow using // either of them for path registration @@ -217,5 +337,9 @@ func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL router.POST(baseURL+"/api/worker/state-changed", wrapper.WorkerStateChanged) router.POST(baseURL+"/api/worker/task", wrapper.ScheduleTask) router.POST(baseURL+"/api/worker/task/:task_id", wrapper.TaskUpdate) + router.POST(baseURL+"/shaman/checkout/create/:checkoutID", wrapper.ShamanCheckout) + router.POST(baseURL+"/shaman/checkout/requirements", wrapper.ShamanCheckoutRequirements) + router.OPTIONS(baseURL+"/shaman/files/:checksum/:filesize", wrapper.ShamanFileStoreCheck) + router.POST(baseURL+"/shaman/files/:checksum/:filesize", wrapper.ShamanFileStore) } diff --git a/pkg/api/openapi_spec.gen.go b/pkg/api/openapi_spec.gen.go index aac60025..2682fbdf 100644 --- a/pkg/api/openapi_spec.gen.go +++ b/pkg/api/openapi_spec.gen.go @@ -18,66 +18,85 @@ import ( // Base64 encoded, gzipped, json marshaled Swagger object var swaggerSpec = []string{ - "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", - "+BN0ZoqB6J3hvW2vTq/+PwAA///UdlNGQjgAAA==", + "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", } // GetSwagger returns the content of the embedded swagger specification file diff --git a/pkg/api/openapi_types.gen.go b/pkg/api/openapi_types.gen.go index 1527a982..d4581124 100644 --- a/pkg/api/openapi_types.gen.go +++ b/pkg/api/openapi_types.gen.go @@ -233,6 +233,31 @@ type SecurityError struct { Message string `json:"message"` } +// Set of files with their SHA256 checksum, size in bytes, and desired location in the checkout directory. +type ShamanCheckout struct { + Req []struct { + // SHA256 checksum of the file + C string `json:"c"` + + // File checkout path + P string `json:"p"` + + // File size in bytes + S int `json:"s"` + } `json:"req"` +} + +// Set of files with their SHA256 checksum and size in bytes. +type ShamanRequirements struct { + Req []struct { + // SHA256 checksum of the file + C string `json:"c"` + + // File size in bytes + S int `json:"s"` + } `json:"req"` +} + // Job definition submitted to Flamenco. type SubmittedJob struct { // Arbitrary metadata strings. More complex structures can be modeled by using `a.b.c` notation for the key. @@ -299,6 +324,21 @@ type WorkerStateChangedJSONBody WorkerStateChanged // TaskUpdateJSONBody defines parameters for TaskUpdate. type TaskUpdateJSONBody TaskUpdate +// ShamanCheckoutJSONBody defines parameters for ShamanCheckout. +type ShamanCheckoutJSONBody ShamanCheckout + +// ShamanCheckoutRequirementsJSONBody defines parameters for ShamanCheckoutRequirements. +type ShamanCheckoutRequirementsJSONBody ShamanRequirements + +// ShamanFileStoreParams defines parameters for ShamanFileStore. +type ShamanFileStoreParams struct { + // The client indicates that it can defer uploading this file. The "208" response will not only be returned when the file is already fully known to the Shaman server, but also when someone else is currently uploading this file. + XShamanCanDeferUpload *bool `json:"X-Shaman-Can-Defer-Upload,omitempty"` + + // The original filename. If sent along with the request, it will be included in the server logs, which can aid in debugging. + XShamanOriginalFilename *string `json:"X-Shaman-Original-Filename,omitempty"` +} + // SubmitJobJSONRequestBody defines body for SubmitJob for application/json ContentType. type SubmitJobJSONRequestBody SubmitJobJSONBody @@ -314,6 +354,12 @@ type WorkerStateChangedJSONRequestBody WorkerStateChangedJSONBody // TaskUpdateJSONRequestBody defines body for TaskUpdate for application/json ContentType. type TaskUpdateJSONRequestBody TaskUpdateJSONBody +// ShamanCheckoutJSONRequestBody defines body for ShamanCheckout for application/json ContentType. +type ShamanCheckoutJSONRequestBody ShamanCheckoutJSONBody + +// ShamanCheckoutRequirementsJSONRequestBody defines body for ShamanCheckoutRequirements for application/json ContentType. +type ShamanCheckoutRequirementsJSONRequestBody ShamanCheckoutRequirementsJSONBody + // Getter for additional properties for JobMetadata. Returns the specified // element and whether it was found func (a JobMetadata) Get(fieldName string) (value string, found bool) {