From e8c32fd1299c483fdf427207cf9f88606e0bab16 Mon Sep 17 00:00:00 2001 From: Geoffrey Ragot Date: Sat, 12 Oct 2024 22:01:25 +0200 Subject: [PATCH] feat: refine technical urls --- cmd/serve.go | 78 +++++-- docs/api/README.md | 8 +- internal/README.md | 4 +- internal/api/module.go | 2 - internal/api/router.go | 6 +- .../controllers_accounts_add_metadata_test.go | 2 +- .../api/v2/controllers_accounts_count_test.go | 2 +- ...ntrollers_accounts_delete_metadata_test.go | 2 +- .../api/v2/controllers_accounts_list_test.go | 2 +- .../api/v2/controllers_accounts_read_test.go | 2 +- internal/api/v2/controllers_balances_test.go | 2 +- internal/api/v2/controllers_bulk_test.go | 2 +- internal/api/v2/controllers_config.go | 22 -- internal/api/v2/controllers_config_test.go | 33 --- .../api/v2/controllers_ledgers_create_test.go | 2 +- ...ontrollers_ledgers_delete_metadata_test.go | 2 +- .../api/v2/controllers_ledgers_info_test.go | 2 +- .../api/v2/controllers_ledgers_list_test.go | 2 +- .../api/v2/controllers_ledgers_read_test.go | 2 +- ...ontrollers_ledgers_update_metadata_test.go | 2 +- .../api/v2/controllers_logs_export_test.go | 2 +- .../api/v2/controllers_logs_import_test.go | 2 +- internal/api/v2/controllers_logs_list_test.go | 2 +- internal/api/v2/controllers_stats_test.go | 2 +- ...trollers_transactions_add_metadata_test.go | 2 +- .../v2/controllers_transactions_count_test.go | 2 +- .../controllers_transactions_create_test.go | 2 +- ...llers_transactions_delete_metadata_test.go | 2 +- .../v2/controllers_transactions_list_test.go | 2 +- .../v2/controllers_transactions_read_test.go | 2 +- .../controllers_transactions_revert_test.go | 2 +- internal/api/v2/controllers_volumes_test.go | 2 +- internal/api/v2/routes.go | 3 - internal/ledger.go | 10 + openapi.yaml | 4 +- openapi/v2.yaml | 4 +- pkg/client/.speakeasy/gen.lock | 32 +-- pkg/client/.speakeasy/gen.yaml | 2 +- pkg/client/README.md | 41 ++-- pkg/client/USAGE.md | 4 +- pkg/client/docs/sdks/ledger/README.md | 52 +++++ pkg/client/docs/sdks/v2/README.md | 52 ----- pkg/client/formance.go | 4 +- pkg/client/ledger.go | 206 ++++++++++++++++++ pkg/client/v2.go | 191 ---------------- pkg/testserver/api.go | 2 +- test/e2e/lifecycle_test.go | 2 +- 47 files changed, 410 insertions(+), 402 deletions(-) delete mode 100644 internal/api/v2/controllers_config.go delete mode 100644 internal/api/v2/controllers_config_test.go diff --git a/cmd/serve.go b/cmd/serve.go index f66cea077..5052b32a0 100644 --- a/cmd/serve.go +++ b/cmd/serve.go @@ -1,6 +1,8 @@ package cmd import ( + apilib "github.com/formancehq/go-libs/api" + "github.com/formancehq/go-libs/health" "github.com/formancehq/go-libs/httpserver" "github.com/formancehq/go-libs/otlp" "github.com/formancehq/ledger/internal/storage/driver" @@ -74,28 +76,30 @@ func NewServeCommand() *cobra.Command { Version: Version, Debug: service.IsDebug(cmd), }), + fx.Decorate(func( + params struct { + fx.In + + Handler chi.Router + HealthController *health.HealthController + + MeterProvider *metric.MeterProvider `optional:"true"` + Exporter *otlpmetrics.InMemoryExporter `optional:"true"` + }, + ) chi.Router { + return assembleFinalRouter( + otelMetricsExporter == "memory", + enablePProf, + params.MeterProvider, + params.Exporter, + params.HealthController, + params.Handler, + ) + }), fx.Invoke(func(lc fx.Lifecycle, h chi.Router) { lc.Append(httpserver.NewHook(h, httpserver.WithAddress(serveConfiguration.bind))) }), } - if otelMetricsExporter == "memory" || enablePProf { - options = append(options, fx.Decorate(func( - h chi.Router, - meterProvider *metric.MeterProvider, - exporter *otlpmetrics.InMemoryExporter, - ) chi.Router { - wrappedRouter := chi.NewRouter() - if otelMetricsExporter == "memory" { - wrappedRouter.Handle("/_metrics", otlpmetrics.NewInMemoryExporterHandler(meterProvider, exporter)) - } - if enablePProf { - wrappedRouter.Handle("/debug/pprof/*", http.HandlerFunc(pprof.Index)) - } - wrappedRouter.Mount("/", h) - - return wrappedRouter - })) - } return service.New(cmd.OutOrStdout(), options...).Run(cmd) }, @@ -135,3 +139,41 @@ func discoverServeConfiguration(cmd *cobra.Command) serveConfiguration { return ret } + +func assembleFinalRouter( + exportMetrics, exportPProf bool, + meterProvider *metric.MeterProvider, + exporter *otlpmetrics.InMemoryExporter, + healthController *health.HealthController, + handler http.Handler, +) *chi.Mux { + wrappedRouter := chi.NewRouter() + wrappedRouter.Route("/_/", func(r chi.Router) { + if exportMetrics { + r.Handle("/metrics", otlpmetrics.NewInMemoryExporterHandler( + meterProvider, + exporter, + )) + } + if exportPProf { + r.Handle("/debug/pprof/*", http.StripPrefix( + "/_", + http.HandlerFunc(pprof.Index), + )) + } + r.Handle("/healthcheck", http.HandlerFunc(healthController.Check)) + r.Get("/info", func(w http.ResponseWriter, r *http.Request) { + apilib.RawOk(w, struct { + Server string `json:"server"` + Version string `json:"version"` + }{ + Server: "ledger", + Version: Version, + }) + }) + }) + wrappedRouter.Get("/_healthcheck", healthController.Check) + wrappedRouter.Mount("/", handler) + + return wrappedRouter +} diff --git a/docs/api/README.md b/docs/api/README.md index e74cd8e4a..3b7274369 100644 --- a/docs/api/README.md +++ b/docs/api/README.md @@ -19,7 +19,7 @@ Base URLs: |Scope|Scope Description| |---|---| -

ledger.v2

+

ledger

## Show server information @@ -28,13 +28,13 @@ Base URLs: > Code samples ```http -GET http://localhost:8080/v2/_info HTTP/1.1 +GET http://localhost:8080/_/info HTTP/1.1 Host: localhost:8080 Accept: application/json ``` -`GET /v2/_info` +`GET /_/info` > Example responses @@ -60,6 +60,8 @@ To perform this operation, you must be authenticated by means of one of the foll Authorization ( Scopes: ledger:read ) +

ledger.v2

+ ## List ledgers diff --git a/internal/README.md b/internal/README.md index 9fa2e6b82..e71f34dc7 100644 --- a/internal/README.md +++ b/internal/README.md @@ -53,7 +53,7 @@ import "github.com/formancehq/ledger/internal" - [func LogTypeFromString\(logType string\) LogType](<#LogTypeFromString>) - [func \(lt LogType\) MarshalJSON\(\) \(\[\]byte, error\)](<#LogType.MarshalJSON>) - [func \(lt \*LogType\) Scan\(src interface\{\}\) error](<#LogType.Scan>) - - [func \(l LogType\) String\(\) string](<#LogType.String>) + - [func \(lt LogType\) String\(\) string](<#LogType.String>) - [func \(lt \*LogType\) UnmarshalJSON\(data \[\]byte\) error](<#LogType.UnmarshalJSON>) - [func \(lt LogType\) Value\(\) \(driver.Value, error\)](<#LogType.Value>) - [type Memento](<#Memento>) @@ -654,7 +654,7 @@ func (lt *LogType) Scan(src interface{}) error ### func \(LogType\) String ```go -func (l LogType) String() string +func (lt LogType) String() string ``` diff --git a/internal/api/module.go b/internal/api/module.go index 265a9fd45..58590c1ab 100644 --- a/internal/api/module.go +++ b/internal/api/module.go @@ -21,14 +21,12 @@ func Module(cfg Config) fx.Option { return fx.Options( fx.Provide(func( backend system.Controller, - healthController *health.HealthController, authenticator auth.Authenticator, logger logging.Logger, tracer trace.TracerProvider, ) chi.Router { return NewRouter( backend, - healthController, authenticator, logger, "develop", diff --git a/internal/api/router.go b/internal/api/router.go index ee4f44ca7..c5dab98da 100644 --- a/internal/api/router.go +++ b/internal/api/router.go @@ -12,7 +12,6 @@ import ( "github.com/go-chi/cors" "github.com/formancehq/go-libs/auth" - "github.com/formancehq/go-libs/health" "github.com/formancehq/ledger/internal/api/common" v1 "github.com/formancehq/ledger/internal/api/v1" v2 "github.com/formancehq/ledger/internal/api/v2" @@ -22,7 +21,6 @@ import ( // todo: refine textual errors func NewRouter( systemController system.Controller, - healthController *health.HealthController, authenticator auth.Authenticator, logger logging.Logger, version string, @@ -54,12 +52,10 @@ func NewRouter( }).Handler, common.LogID(), ) - mux.Get("/_healthcheck", healthController.Check) v2Router := v2.NewRouter( systemController, authenticator, - version, debug, v2.WithTracer(routerOptions.tracer), ) @@ -92,4 +88,4 @@ func WithTracer(tracer trace.Tracer) RouterOption { var defaultRouterOptions = []RouterOption{ WithTracer(nooptracer.Tracer{}), -} \ No newline at end of file +} diff --git a/internal/api/v2/controllers_accounts_add_metadata_test.go b/internal/api/v2/controllers_accounts_add_metadata_test.go index c1676de23..eb8c805c5 100644 --- a/internal/api/v2/controllers_accounts_add_metadata_test.go +++ b/internal/api/v2/controllers_accounts_add_metadata_test.go @@ -69,7 +69,7 @@ func TestAccountsAddMetadata(t *testing.T) { Return(nil) } - router := NewRouter(systemController, auth.NewNoAuth(), "develop", testing.Verbose()) + router := NewRouter(systemController, auth.NewNoAuth(), testing.Verbose()) req := httptest.NewRequest(http.MethodPost, "/", api.Buffer(t, testCase.body)) // httptest.NewRequest check for invalid urls while we want to test invalid urls diff --git a/internal/api/v2/controllers_accounts_count_test.go b/internal/api/v2/controllers_accounts_count_test.go index d4fd216ec..b7f1d8beb 100644 --- a/internal/api/v2/controllers_accounts_count_test.go +++ b/internal/api/v2/controllers_accounts_count_test.go @@ -173,7 +173,7 @@ func TestAccountsCount(t *testing.T) { Return(10, testCase.returnErr) } - router := NewRouter(systemController, auth.NewNoAuth(), "develop", testing.Verbose()) + router := NewRouter(systemController, auth.NewNoAuth(), testing.Verbose()) req := httptest.NewRequest(http.MethodHead, "/xxx/accounts?pit="+before.Format(time.RFC3339Nano), bytes.NewBufferString(testCase.body)) rec := httptest.NewRecorder() diff --git a/internal/api/v2/controllers_accounts_delete_metadata_test.go b/internal/api/v2/controllers_accounts_delete_metadata_test.go index e216fcdcc..65228a96e 100644 --- a/internal/api/v2/controllers_accounts_delete_metadata_test.go +++ b/internal/api/v2/controllers_accounts_delete_metadata_test.go @@ -69,7 +69,7 @@ func TestAccountsDeleteMetadata(t *testing.T) { Return(tc.returnErr) } - router := NewRouter(systemController, auth.NewNoAuth(), "develop", testing.Verbose()) + router := NewRouter(systemController, auth.NewNoAuth(), testing.Verbose()) req := httptest.NewRequest(http.MethodDelete, "/", nil) req.URL.Path = "/ledger0/accounts/" + tc.account + "/metadata/foo" diff --git a/internal/api/v2/controllers_accounts_list_test.go b/internal/api/v2/controllers_accounts_list_test.go index ed2a45ee3..55293edba 100644 --- a/internal/api/v2/controllers_accounts_list_test.go +++ b/internal/api/v2/controllers_accounts_list_test.go @@ -201,7 +201,7 @@ func TestAccountsList(t *testing.T) { Return(&expectedCursor, tc.returnErr) } - router := NewRouter(systemController, auth.NewNoAuth(), "develop", testing.Verbose()) + router := NewRouter(systemController, auth.NewNoAuth(), testing.Verbose()) req := httptest.NewRequest(http.MethodGet, "/xxx/accounts?pit="+before.Format(time.RFC3339Nano), bytes.NewBufferString(tc.body)) rec := httptest.NewRecorder() diff --git a/internal/api/v2/controllers_accounts_read_test.go b/internal/api/v2/controllers_accounts_read_test.go index 7fa970508..459e65431 100644 --- a/internal/api/v2/controllers_accounts_read_test.go +++ b/internal/api/v2/controllers_accounts_read_test.go @@ -79,7 +79,7 @@ func TestAccountsRead(t *testing.T) { Return(&ledger.Account{}, tc.returnErr) } - router := NewRouter(systemController, auth.NewNoAuth(), "develop", testing.Verbose()) + router := NewRouter(systemController, auth.NewNoAuth(), testing.Verbose()) req := httptest.NewRequest(http.MethodGet, "/", bytes.NewBufferString(tc.body)) req.URL.Path = "/xxx/accounts/" + tc.account diff --git a/internal/api/v2/controllers_balances_test.go b/internal/api/v2/controllers_balances_test.go index 534055f15..56d2ad29c 100644 --- a/internal/api/v2/controllers_balances_test.go +++ b/internal/api/v2/controllers_balances_test.go @@ -98,7 +98,7 @@ func TestBalancesAggregates(t *testing.T) { GetAggregatedBalances(gomock.Any(), testCase.expectQuery). Return(expectedBalances, nil) - router := NewRouter(systemController, auth.NewNoAuth(), "develop", testing.Verbose()) + router := NewRouter(systemController, auth.NewNoAuth(), testing.Verbose()) req := httptest.NewRequest(http.MethodGet, "/xxx/aggregate/balances?pit="+now.Format(time.RFC3339Nano), bytes.NewBufferString(testCase.body)) rec := httptest.NewRecorder() diff --git a/internal/api/v2/controllers_bulk_test.go b/internal/api/v2/controllers_bulk_test.go index 3d1f469ab..57df29dbd 100644 --- a/internal/api/v2/controllers_bulk_test.go +++ b/internal/api/v2/controllers_bulk_test.go @@ -356,7 +356,7 @@ func TestBulk(t *testing.T) { systemController, ledgerController := newTestingSystemController(t, true) testCase.expectations(ledgerController) - router := NewRouter(systemController, auth.NewNoAuth(), "develop", testing.Verbose()) + router := NewRouter(systemController, auth.NewNoAuth(), testing.Verbose()) req := httptest.NewRequest(http.MethodPost, "/xxx/_bulk", bytes.NewBufferString(testCase.body)) rec := httptest.NewRecorder() diff --git a/internal/api/v2/controllers_config.go b/internal/api/v2/controllers_config.go deleted file mode 100644 index ad0942096..000000000 --- a/internal/api/v2/controllers_config.go +++ /dev/null @@ -1,22 +0,0 @@ -package v2 - -import ( - _ "embed" - "net/http" - - "github.com/formancehq/go-libs/api" -) - -type ConfigInfo struct { - Server string `json:"server"` - Version string `json:"version"` -} - -func getInfo(version string) func(w http.ResponseWriter, r *http.Request) { - return func(w http.ResponseWriter, r *http.Request) { - api.RawOk(w, ConfigInfo{ - Server: "ledger", - Version: version, - }) - } -} diff --git a/internal/api/v2/controllers_config_test.go b/internal/api/v2/controllers_config_test.go deleted file mode 100644 index 4f3cdf3ac..000000000 --- a/internal/api/v2/controllers_config_test.go +++ /dev/null @@ -1,33 +0,0 @@ -package v2 - -import ( - "encoding/json" - "net/http" - "net/http/httptest" - "testing" - - "github.com/formancehq/go-libs/auth" - "github.com/stretchr/testify/require" -) - -func TestGetInfo(t *testing.T) { - t.Parallel() - - systemController, _ := newTestingSystemController(t, false) - router := NewRouter(systemController, auth.NewNoAuth(), "develop", testing.Verbose()) - - req := httptest.NewRequest(http.MethodGet, "/_info", nil) - rec := httptest.NewRecorder() - - router.ServeHTTP(rec, req) - - require.Equal(t, http.StatusOK, rec.Code) - - info := ConfigInfo{} - require.NoError(t, json.NewDecoder(rec.Body).Decode(&info)) - - require.EqualValues(t, ConfigInfo{ - Server: "ledger", - Version: "develop", - }, info) -} diff --git a/internal/api/v2/controllers_ledgers_create_test.go b/internal/api/v2/controllers_ledgers_create_test.go index 48d685590..a6f90f331 100644 --- a/internal/api/v2/controllers_ledgers_create_test.go +++ b/internal/api/v2/controllers_ledgers_create_test.go @@ -91,7 +91,7 @@ func TestLedgersCreate(t *testing.T) { t.Parallel() systemController, _ := newTestingSystemController(t, false) - router := NewRouter(systemController, auth.NewNoAuth(), "develop", testing.Verbose()) + router := NewRouter(systemController, auth.NewNoAuth(), testing.Verbose()) name := uuid.NewString() diff --git a/internal/api/v2/controllers_ledgers_delete_metadata_test.go b/internal/api/v2/controllers_ledgers_delete_metadata_test.go index 4fe7fe784..347e3add9 100644 --- a/internal/api/v2/controllers_ledgers_delete_metadata_test.go +++ b/internal/api/v2/controllers_ledgers_delete_metadata_test.go @@ -53,7 +53,7 @@ func TestLedgersDeleteMetadata(t *testing.T) { Return(tc.returnErr) } - router := NewRouter(systemController, auth.NewNoAuth(), "develop", testing.Verbose()) + router := NewRouter(systemController, auth.NewNoAuth(), testing.Verbose()) req := httptest.NewRequest(http.MethodDelete, "/"+name+"/metadata/foo", nil) req = req.WithContext(ctx) diff --git a/internal/api/v2/controllers_ledgers_info_test.go b/internal/api/v2/controllers_ledgers_info_test.go index 16af2b5bd..cd650ad2f 100644 --- a/internal/api/v2/controllers_ledgers_info_test.go +++ b/internal/api/v2/controllers_ledgers_info_test.go @@ -18,7 +18,7 @@ func TestLedgersInfo(t *testing.T) { t.Parallel() systemController, ledgerController := newTestingSystemController(t, false) - router := NewRouter(systemController, auth.NewNoAuth(), "develop", testing.Verbose()) + router := NewRouter(systemController, auth.NewNoAuth(), testing.Verbose()) migrationInfo := []migrations.Info{ { diff --git a/internal/api/v2/controllers_ledgers_list_test.go b/internal/api/v2/controllers_ledgers_list_test.go index ed78614d0..c4b26e65e 100644 --- a/internal/api/v2/controllers_ledgers_list_test.go +++ b/internal/api/v2/controllers_ledgers_list_test.go @@ -93,7 +93,7 @@ func TestListLedgers(t *testing.T) { }, tc.returnErr) } - router := NewRouter(systemController, auth.NewNoAuth(), "develop", testing.Verbose()) + router := NewRouter(systemController, auth.NewNoAuth(), testing.Verbose()) req := httptest.NewRequest(http.MethodGet, "/", nil) req = req.WithContext(ctx) diff --git a/internal/api/v2/controllers_ledgers_read_test.go b/internal/api/v2/controllers_ledgers_read_test.go index f43d36fec..3d3cf2fe3 100644 --- a/internal/api/v2/controllers_ledgers_read_test.go +++ b/internal/api/v2/controllers_ledgers_read_test.go @@ -21,7 +21,7 @@ func TestLedgersRead(t *testing.T) { t.Parallel() systemController, _ := newTestingSystemController(t, false) - router := NewRouter(systemController, auth.NewNoAuth(), "develop", testing.Verbose()) + router := NewRouter(systemController, auth.NewNoAuth(), testing.Verbose()) name := uuid.NewString() now := time.Now() diff --git a/internal/api/v2/controllers_ledgers_update_metadata_test.go b/internal/api/v2/controllers_ledgers_update_metadata_test.go index 17e403fd7..63542d71c 100644 --- a/internal/api/v2/controllers_ledgers_update_metadata_test.go +++ b/internal/api/v2/controllers_ledgers_update_metadata_test.go @@ -25,7 +25,7 @@ func TestLedgersUpdateMetadata(t *testing.T) { UpdateLedgerMetadata(gomock.Any(), name, metadata). Return(nil) - router := NewRouter(systemController, auth.NewNoAuth(), "develop", testing.Verbose()) + router := NewRouter(systemController, auth.NewNoAuth(), testing.Verbose()) req := httptest.NewRequest(http.MethodPut, "/"+name+"/metadata", api.Buffer(t, metadata)) req = req.WithContext(ctx) diff --git a/internal/api/v2/controllers_logs_export_test.go b/internal/api/v2/controllers_logs_export_test.go index d86eec5e7..c640c2f6b 100644 --- a/internal/api/v2/controllers_logs_export_test.go +++ b/internal/api/v2/controllers_logs_export_test.go @@ -61,7 +61,7 @@ func TestLogsExport(t *testing.T) { return nil }) - router := NewRouter(systemController, auth.NewNoAuth(), "develop", testing.Verbose()) + router := NewRouter(systemController, auth.NewNoAuth(), testing.Verbose()) req := httptest.NewRequest(http.MethodPost, "/xxx/logs/export", nil) rec := httptest.NewRecorder() diff --git a/internal/api/v2/controllers_logs_import_test.go b/internal/api/v2/controllers_logs_import_test.go index a614a14f7..82570d4c8 100644 --- a/internal/api/v2/controllers_logs_import_test.go +++ b/internal/api/v2/controllers_logs_import_test.go @@ -72,7 +72,7 @@ func TestLogsImport(t *testing.T) { } }) - router := NewRouter(systemController, auth.NewNoAuth(), "develop", testing.Verbose()) + router := NewRouter(systemController, auth.NewNoAuth(), testing.Verbose()) buf := bytes.NewBuffer(nil) require.NoError(t, json.NewEncoder(buf).Encode(log)) diff --git a/internal/api/v2/controllers_logs_list_test.go b/internal/api/v2/controllers_logs_list_test.go index 3270251a3..6f78a078f 100644 --- a/internal/api/v2/controllers_logs_list_test.go +++ b/internal/api/v2/controllers_logs_list_test.go @@ -127,7 +127,7 @@ func TestGetLogs(t *testing.T) { Return(&expectedCursor, testCase.returnErr) } - router := NewRouter(systemController, auth.NewNoAuth(), "develop", testing.Verbose()) + router := NewRouter(systemController, auth.NewNoAuth(), testing.Verbose()) req := httptest.NewRequest(http.MethodGet, "/xxx/logs", bytes.NewBufferString(testCase.body)) rec := httptest.NewRecorder() diff --git a/internal/api/v2/controllers_stats_test.go b/internal/api/v2/controllers_stats_test.go index 1bcc62a43..22603966e 100644 --- a/internal/api/v2/controllers_stats_test.go +++ b/internal/api/v2/controllers_stats_test.go @@ -16,7 +16,7 @@ func TestStats(t *testing.T) { t.Parallel() systemController, ledgerController := newTestingSystemController(t, true) - router := NewRouter(systemController, auth.NewNoAuth(), "develop", testing.Verbose()) + router := NewRouter(systemController, auth.NewNoAuth(), testing.Verbose()) expectedStats := ledgercontroller.Stats{ Transactions: 10, diff --git a/internal/api/v2/controllers_transactions_add_metadata_test.go b/internal/api/v2/controllers_transactions_add_metadata_test.go index aebee20c8..08d99844f 100644 --- a/internal/api/v2/controllers_transactions_add_metadata_test.go +++ b/internal/api/v2/controllers_transactions_add_metadata_test.go @@ -97,7 +97,7 @@ func TestTransactionsAddMetadata(t *testing.T) { Return(testCase.returnErr) } - router := NewRouter(systemController, auth.NewNoAuth(), "develop", testing.Verbose()) + router := NewRouter(systemController, auth.NewNoAuth(), testing.Verbose()) req := httptest.NewRequest(http.MethodPost, fmt.Sprintf("/xxx/transactions/%v/metadata", testCase.id), api.Buffer(t, testCase.body)) rec := httptest.NewRecorder() diff --git a/internal/api/v2/controllers_transactions_count_test.go b/internal/api/v2/controllers_transactions_count_test.go index ef9e81528..b8cb75fca 100644 --- a/internal/api/v2/controllers_transactions_count_test.go +++ b/internal/api/v2/controllers_transactions_count_test.go @@ -173,7 +173,7 @@ func TestTransactionsCount(t *testing.T) { Return(10, tc.returnErr) } - router := NewRouter(systemController, auth.NewNoAuth(), "develop", testing.Verbose()) + router := NewRouter(systemController, auth.NewNoAuth(), testing.Verbose()) req := httptest.NewRequest(http.MethodHead, "/xxx/transactions?pit="+before.Format(time.RFC3339Nano), bytes.NewBufferString(tc.body)) rec := httptest.NewRecorder() diff --git a/internal/api/v2/controllers_transactions_create_test.go b/internal/api/v2/controllers_transactions_create_test.go index 8e6069aef..46365bcaf 100644 --- a/internal/api/v2/controllers_transactions_create_test.go +++ b/internal/api/v2/controllers_transactions_create_test.go @@ -414,7 +414,7 @@ func TestTransactionCreate(t *testing.T) { } } - router := NewRouter(systemController, auth.NewNoAuth(), "develop", testing.Verbose()) + router := NewRouter(systemController, auth.NewNoAuth(), testing.Verbose()) req := httptest.NewRequest(http.MethodPost, "/xxx/transactions", api.Buffer(t, testCase.payload)) rec := httptest.NewRecorder() diff --git a/internal/api/v2/controllers_transactions_delete_metadata_test.go b/internal/api/v2/controllers_transactions_delete_metadata_test.go index ebbc2c861..d18478959 100644 --- a/internal/api/v2/controllers_transactions_delete_metadata_test.go +++ b/internal/api/v2/controllers_transactions_delete_metadata_test.go @@ -66,7 +66,7 @@ func TestTransactionsDeleteMetadata(t *testing.T) { Return(tc.returnErr) } - router := NewRouter(systemController, auth.NewNoAuth(), "develop", testing.Verbose()) + router := NewRouter(systemController, auth.NewNoAuth(), testing.Verbose()) req := httptest.NewRequest(http.MethodDelete, "/ledger0/transactions/1/metadata/foo", nil) req = req.WithContext(ctx) diff --git a/internal/api/v2/controllers_transactions_list_test.go b/internal/api/v2/controllers_transactions_list_test.go index 66eb5a4b5..94c8b1475 100644 --- a/internal/api/v2/controllers_transactions_list_test.go +++ b/internal/api/v2/controllers_transactions_list_test.go @@ -200,7 +200,7 @@ func TestTransactionsList(t *testing.T) { Return(&expectedCursor, nil) } - router := NewRouter(systemController, auth.NewNoAuth(), "develop", testing.Verbose()) + router := NewRouter(systemController, auth.NewNoAuth(), testing.Verbose()) req := httptest.NewRequest(http.MethodGet, "/xxx/transactions", bytes.NewBufferString(testCase.body)) rec := httptest.NewRecorder() diff --git a/internal/api/v2/controllers_transactions_read_test.go b/internal/api/v2/controllers_transactions_read_test.go index 7e47f8376..9fb629d22 100644 --- a/internal/api/v2/controllers_transactions_read_test.go +++ b/internal/api/v2/controllers_transactions_read_test.go @@ -32,7 +32,7 @@ func TestTransactionsRead(t *testing.T) { GetTransaction(gomock.Any(), query). Return(&tx, nil) - router := NewRouter(systemController, auth.NewNoAuth(), "develop", testing.Verbose()) + router := NewRouter(systemController, auth.NewNoAuth(), testing.Verbose()) req := httptest.NewRequest(http.MethodGet, "/xxx/transactions/0?pit="+now.Format(time.RFC3339Nano), nil) rec := httptest.NewRecorder() diff --git a/internal/api/v2/controllers_transactions_revert_test.go b/internal/api/v2/controllers_transactions_revert_test.go index 8ac81fc99..348d88612 100644 --- a/internal/api/v2/controllers_transactions_revert_test.go +++ b/internal/api/v2/controllers_transactions_revert_test.go @@ -79,7 +79,7 @@ func TestTransactionsRevert(t *testing.T) { RevertTransaction: tc.returnTx, }, tc.returnErr) - router := NewRouter(systemController, auth.NewNoAuth(), "develop", testing.Verbose()) + router := NewRouter(systemController, auth.NewNoAuth(), testing.Verbose()) req := httptest.NewRequest(http.MethodPost, "/xxx/transactions/0/revert", nil) if tc.queryParams != nil { diff --git a/internal/api/v2/controllers_volumes_test.go b/internal/api/v2/controllers_volumes_test.go index ccd0bd875..0c4eb7f58 100644 --- a/internal/api/v2/controllers_volumes_test.go +++ b/internal/api/v2/controllers_volumes_test.go @@ -145,7 +145,7 @@ func TestGetVolumes(t *testing.T) { Return(&expectedCursor, nil) } - router := NewRouter(systemController, auth.NewNoAuth(), "develop", testing.Verbose()) + router := NewRouter(systemController, auth.NewNoAuth(), testing.Verbose()) req := httptest.NewRequest(http.MethodGet, "/xxx/volumes?endTime="+before.Format(time.RFC3339Nano), bytes.NewBufferString(testCase.body)) rec := httptest.NewRecorder() diff --git a/internal/api/v2/routes.go b/internal/api/v2/routes.go index 934cff74d..fb63c15e3 100644 --- a/internal/api/v2/routes.go +++ b/internal/api/v2/routes.go @@ -22,7 +22,6 @@ import ( func NewRouter( systemController system.Controller, authenticator auth.Authenticator, - version string, debug bool, opts ...RouterOption, ) chi.Router { @@ -33,8 +32,6 @@ func NewRouter( router := chi.NewMux() - router.Get("/_info", getInfo(version)) - router.Group(func(router chi.Router) { router.Use(middleware.RequestLogger(api.NewLogFormatter())) router.Use(auth.Middleware(authenticator)) diff --git a/internal/ledger.go b/internal/ledger.go index 6863ae24c..ec448deb9 100644 --- a/internal/ledger.go +++ b/internal/ledger.go @@ -43,6 +43,9 @@ func New(name string, configuration Configuration) (*Ledger, error) { if !ledgerNameFormat.MatchString(name) { return nil, newErrInvalidLedgerName(name, fmt.Errorf("name must match format '%s'", ledgerNameFormat.String())) } + if slices.Contains(reservedLedgerName, name) { + return nil, newErrInvalidLedgerName(name, fmt.Errorf("name '%s' is reserved", name)) + } if !bucketNameFormat.MatchString(configuration.Bucket) { return nil, newErrInvalidBucketName(configuration.Bucket, fmt.Errorf("name must match format '%s'", bucketNameFormat.String())) } @@ -120,6 +123,13 @@ var ( ledgerNameFormat = regexp.MustCompile("^[0-9a-zA-Z_-]{1,63}$") bucketNameFormat = regexp.MustCompile("^[0-9a-zA-Z_-]{1,63}$") + + reservedLedgerName = []string{ + // Used for debug in urls... + "_", + "_info", + "_healthcheck", + } ) func validateFeatureWithValue(feature, value string) error { diff --git a/openapi.yaml b/openapi.yaml index 44b14252f..8a81e00f9 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -1179,10 +1179,10 @@ paths: security: - Authorization: - ledger:read - /v2/_info: + /_/info: get: tags: - - ledger.v2 + - ledger summary: Show server information operationId: v2GetInfo x-speakeasy-name-override: GetInfo diff --git a/openapi/v2.yaml b/openapi/v2.yaml index 15afce7ca..5ece0eaf0 100644 --- a/openapi/v2.yaml +++ b/openapi/v2.yaml @@ -6,10 +6,10 @@ info: servers: - url: http://localhost:8080/ paths: - /v2/_info: + /_/info: get: tags: - - ledger.v2 + - ledger summary: Show server information operationId: v2GetInfo x-speakeasy-name-override: GetInfo diff --git a/pkg/client/.speakeasy/gen.lock b/pkg/client/.speakeasy/gen.lock index 31fe3c481..f0032de95 100644 --- a/pkg/client/.speakeasy/gen.lock +++ b/pkg/client/.speakeasy/gen.lock @@ -1,12 +1,12 @@ lockVersion: 2.0.0 id: a9ac79e1-e429-4ee3-96c4-ec973f19bec3 management: - docChecksum: 46b920c97720c2cf24009a8029141b0e + docChecksum: 0558cb1f36313c824f51744f6f8c355d docVersion: v1 speakeasyVersion: 1.351.0 generationVersion: 2.384.1 - releaseVersion: 0.4.10 - configChecksum: 80adc8750c319f7d5486bd5211882798 + releaseVersion: 0.4.13 + configChecksum: a8fb416ba04bb07465d883f3e4ed1f7a features: go: additionalDependencies: 0.1.0 @@ -54,6 +54,7 @@ generatedFiles: - internal/utils/retries.go - internal/utils/security.go - internal/utils/utils.go + - /models/operations/v2getinfo.go - /models/operations/getinfo.go - /models/operations/getledgerinfo.go - /models/operations/countaccounts.go @@ -74,7 +75,6 @@ generatedFiles: - /models/operations/getbalances.go - /models/operations/getbalancesaggregated.go - /models/operations/listlogs.go - - /models/operations/v2getinfo.go - /models/operations/v2listledgers.go - /models/operations/v2getledger.go - /models/operations/v2createledger.go @@ -100,11 +100,15 @@ generatedFiles: - /models/operations/v2listlogs.go - /models/operations/v2importlogs.go - /models/operations/v2exportlogs.go + - /models/sdkerrors/v2errorresponse.go + - /models/sdkerrors/errorresponse.go + - /models/components/v2errorsenum.go + - /models/components/v2configinforesponse.go + - /models/components/httpmetadata.go - /models/components/configinforesponse.go - /models/components/configinfo.go - /models/components/config.go - /models/components/ledgerstorage.go - - /models/components/httpmetadata.go - /models/components/errorsenum.go - /models/components/ledgerinforesponse.go - /models/components/ledgerinfo.go @@ -133,8 +137,6 @@ generatedFiles: - /models/components/aggregatebalancesresponse.go - /models/components/logscursorresponse.go - /models/components/log.go - - /models/components/v2errorsenum.go - - /models/components/v2configinforesponse.go - /models/components/v2ledgerlistresponse.go - /models/components/v2ledger.go - /models/components/v2getledgerresponse.go @@ -170,8 +172,7 @@ generatedFiles: - /models/components/v2logscursorresponse.go - /models/components/v2log.go - /models/components/security.go - - /models/sdkerrors/errorresponse.go - - /models/sdkerrors/v2errorresponse.go + - docs/models/operations/v2getinforesponse.md - docs/models/operations/getinforesponse.md - docs/models/operations/getledgerinforequest.md - docs/models/operations/getledgerinforesponse.md @@ -212,7 +213,6 @@ generatedFiles: - docs/models/operations/getbalancesaggregatedresponse.md - docs/models/operations/listlogsrequest.md - docs/models/operations/listlogsresponse.md - - docs/models/operations/v2getinforesponse.md - docs/models/operations/v2listledgersrequest.md - docs/models/operations/v2listledgersresponse.md - docs/models/operations/v2getledgerrequest.md @@ -264,11 +264,15 @@ generatedFiles: - docs/models/operations/v2importlogsresponse.md - docs/models/operations/v2exportlogsrequest.md - docs/models/operations/v2exportlogsresponse.md + - docs/models/sdkerrors/v2errorresponse.md + - docs/models/sdkerrors/errorresponse.md + - docs/models/components/v2errorsenum.md + - docs/models/components/v2configinforesponse.md + - docs/models/components/httpmetadata.md - docs/models/components/configinforesponse.md - docs/models/components/configinfo.md - docs/models/components/config.md - docs/models/components/ledgerstorage.md - - docs/models/components/httpmetadata.md - docs/models/components/errorsenum.md - docs/models/components/ledgerinforesponse.md - docs/models/components/storage.md @@ -306,8 +310,6 @@ generatedFiles: - docs/models/components/logscursorresponse.md - docs/models/components/type.md - docs/models/components/log.md - - docs/models/components/v2errorsenum.md - - docs/models/components/v2configinforesponse.md - docs/models/components/v2ledgerlistresponsecursor.md - docs/models/components/v2ledgerlistresponse.md - docs/models/components/v2ledger.md @@ -360,11 +362,9 @@ generatedFiles: - docs/models/components/v2logtype.md - docs/models/components/v2log.md - docs/models/components/security.md - - docs/models/sdkerrors/errorresponse.md - - docs/models/sdkerrors/v2errorresponse.md - docs/sdks/formance/README.md - - docs/sdks/ledger/README.md - docs/models/operations/option.md + - docs/sdks/ledger/README.md - docs/sdks/v1/README.md - docs/sdks/v2/README.md - USAGE.md diff --git a/pkg/client/.speakeasy/gen.yaml b/pkg/client/.speakeasy/gen.yaml index df23cf750..c0092992c 100644 --- a/pkg/client/.speakeasy/gen.yaml +++ b/pkg/client/.speakeasy/gen.yaml @@ -15,7 +15,7 @@ generation: auth: oAuth2ClientCredentialsEnabled: true go: - version: 0.4.10 + version: 0.4.13 additionalDependencies: {} allowUnknownFieldsInWeakUnions: false clientServerStatusCodesAsErrors: true diff --git a/pkg/client/README.md b/pkg/client/README.md index e1fb468a5..3049357ff 100644 --- a/pkg/client/README.md +++ b/pkg/client/README.md @@ -69,11 +69,11 @@ func main() { ) ctx := context.Background() - res, err := s.Ledger.V1.GetInfo(ctx) + res, err := s.Ledger.GetInfo(ctx) if err != nil { log.Fatal(err) } - if res.ConfigInfoResponse != nil { + if res.V2ConfigInfoResponse != nil { // handle response } } @@ -84,6 +84,10 @@ func main() { ## Available Resources and Operations +### [Ledger](docs/sdks/ledger/README.md) + +* [GetInfo](docs/sdks/ledger/README.md#getinfo) - Show server information + ### [Ledger.V1](docs/sdks/v1/README.md) * [GetInfo](docs/sdks/v1/README.md#getinfo) - Show server information @@ -109,7 +113,6 @@ func main() { ### [Ledger.V2](docs/sdks/v2/README.md) -* [GetInfo](docs/sdks/v2/README.md#getinfo) - Show server information * [ListLedgers](docs/sdks/v2/README.md#listledgers) - List ledgers * [GetLedger](docs/sdks/v2/README.md#getledger) - Get a ledger * [CreateLedger](docs/sdks/v2/README.md#createledger) - Create a ledger @@ -164,7 +167,7 @@ func main() { ) ctx := context.Background() - res, err := s.Ledger.V1.GetInfo(ctx, operations.WithRetries( + res, err := s.Ledger.GetInfo(ctx, operations.WithRetries( retry.Config{ Strategy: "backoff", Backoff: &retry.BackoffStrategy{ @@ -178,7 +181,7 @@ func main() { if err != nil { log.Fatal(err) } - if res.ConfigInfoResponse != nil { + if res.V2ConfigInfoResponse != nil { // handle response } } @@ -217,11 +220,11 @@ func main() { ) ctx := context.Background() - res, err := s.Ledger.V1.GetInfo(ctx) + res, err := s.Ledger.GetInfo(ctx) if err != nil { log.Fatal(err) } - if res.ConfigInfoResponse != nil { + if res.V2ConfigInfoResponse != nil { // handle response } } @@ -234,10 +237,10 @@ func main() { Handling errors in this SDK should largely match your expectations. All operations return a response object or an error, they will never return both. When specified by the OpenAPI spec document, the SDK will return the appropriate subclass. -| Error Object | Status Code | Content Type | -| ----------------------- | ----------------------- | ----------------------- | -| sdkerrors.ErrorResponse | default | application/json | -| sdkerrors.SDKError | 4xx-5xx | */* | +| Error Object | Status Code | Content Type | +| ------------------------- | ------------------------- | ------------------------- | +| sdkerrors.V2ErrorResponse | default | application/json | +| sdkerrors.SDKError | 4xx-5xx | */* | ### Example @@ -262,10 +265,10 @@ func main() { ) ctx := context.Background() - res, err := s.Ledger.V1.GetInfo(ctx) + res, err := s.Ledger.GetInfo(ctx) if err != nil { - var e *sdkerrors.ErrorResponse + var e *sdkerrors.V2ErrorResponse if errors.As(err, &e) { // handle error log.Fatal(e.Error()) @@ -315,11 +318,11 @@ func main() { ) ctx := context.Background() - res, err := s.Ledger.V1.GetInfo(ctx) + res, err := s.Ledger.GetInfo(ctx) if err != nil { log.Fatal(err) } - if res.ConfigInfoResponse != nil { + if res.V2ConfigInfoResponse != nil { // handle response } } @@ -350,11 +353,11 @@ func main() { ) ctx := context.Background() - res, err := s.Ledger.V1.GetInfo(ctx) + res, err := s.Ledger.GetInfo(ctx) if err != nil { log.Fatal(err) } - if res.ConfigInfoResponse != nil { + if res.V2ConfigInfoResponse != nil { // handle response } } @@ -429,11 +432,11 @@ func main() { ) ctx := context.Background() - res, err := s.Ledger.V1.GetInfo(ctx) + res, err := s.Ledger.GetInfo(ctx) if err != nil { log.Fatal(err) } - if res.ConfigInfoResponse != nil { + if res.V2ConfigInfoResponse != nil { // handle response } } diff --git a/pkg/client/USAGE.md b/pkg/client/USAGE.md index 4dad1a404..01cb3093b 100644 --- a/pkg/client/USAGE.md +++ b/pkg/client/USAGE.md @@ -18,11 +18,11 @@ func main() { ) ctx := context.Background() - res, err := s.Ledger.V1.GetInfo(ctx) + res, err := s.Ledger.GetInfo(ctx) if err != nil { log.Fatal(err) } - if res.ConfigInfoResponse != nil { + if res.V2ConfigInfoResponse != nil { // handle response } } diff --git a/pkg/client/docs/sdks/ledger/README.md b/pkg/client/docs/sdks/ledger/README.md index 9609c10c1..a6280ff7e 100644 --- a/pkg/client/docs/sdks/ledger/README.md +++ b/pkg/client/docs/sdks/ledger/README.md @@ -3,3 +3,55 @@ ### Available Operations +* [GetInfo](#getinfo) - Show server information + +## GetInfo + +Show server information + +### Example Usage + +```go +package main + +import( + "github.com/formancehq/stack/ledger/client/models/components" + "github.com/formancehq/stack/ledger/client" + "context" + "log" +) + +func main() { + s := client.New( + client.WithSecurity(components.Security{ + ClientID: "", + ClientSecret: "", + }), + ) + + ctx := context.Background() + res, err := s.Ledger.GetInfo(ctx) + if err != nil { + log.Fatal(err) + } + if res.V2ConfigInfoResponse != nil { + // handle response + } +} +``` + +### Parameters + +| Parameter | Type | Required | Description | +| -------------------------------------------------------- | -------------------------------------------------------- | -------------------------------------------------------- | -------------------------------------------------------- | +| `ctx` | [context.Context](https://pkg.go.dev/context#Context) | :heavy_check_mark: | The context to use for the request. | +| `opts` | [][operations.Option](../../models/operations/option.md) | :heavy_minus_sign: | The options for this request. | + + +### Response + +**[*operations.V2GetInfoResponse](../../models/operations/v2getinforesponse.md), error** +| Error Object | Status Code | Content Type | +| ------------------------- | ------------------------- | ------------------------- | +| sdkerrors.V2ErrorResponse | default | application/json | +| sdkerrors.SDKError | 4xx-5xx | */* | diff --git a/pkg/client/docs/sdks/v2/README.md b/pkg/client/docs/sdks/v2/README.md index 7bb4025c4..391a50b8b 100644 --- a/pkg/client/docs/sdks/v2/README.md +++ b/pkg/client/docs/sdks/v2/README.md @@ -3,7 +3,6 @@ ### Available Operations -* [GetInfo](#getinfo) - Show server information * [ListLedgers](#listledgers) - List ledgers * [GetLedger](#getledger) - Get a ledger * [CreateLedger](#createledger) - Create a ledger @@ -30,57 +29,6 @@ * [ImportLogs](#importlogs) * [ExportLogs](#exportlogs) - Export logs -## GetInfo - -Show server information - -### Example Usage - -```go -package main - -import( - "github.com/formancehq/stack/ledger/client/models/components" - "github.com/formancehq/stack/ledger/client" - "context" - "log" -) - -func main() { - s := client.New( - client.WithSecurity(components.Security{ - ClientID: "", - ClientSecret: "", - }), - ) - - ctx := context.Background() - res, err := s.Ledger.V2.GetInfo(ctx) - if err != nil { - log.Fatal(err) - } - if res.V2ConfigInfoResponse != nil { - // handle response - } -} -``` - -### Parameters - -| Parameter | Type | Required | Description | -| -------------------------------------------------------- | -------------------------------------------------------- | -------------------------------------------------------- | -------------------------------------------------------- | -| `ctx` | [context.Context](https://pkg.go.dev/context#Context) | :heavy_check_mark: | The context to use for the request. | -| `opts` | [][operations.Option](../../models/operations/option.md) | :heavy_minus_sign: | The options for this request. | - - -### Response - -**[*operations.V2GetInfoResponse](../../models/operations/v2getinforesponse.md), error** -| Error Object | Status Code | Content Type | -| ------------------------- | ------------------------- | ------------------------- | -| sdkerrors.V2ErrorResponse | default | application/json | -| sdkerrors.SDKError | 4xx-5xx | */* | - ## ListLedgers List ledgers diff --git a/pkg/client/formance.go b/pkg/client/formance.go index a5acc0edc..ee2996eb1 100644 --- a/pkg/client/formance.go +++ b/pkg/client/formance.go @@ -143,9 +143,9 @@ func New(opts ...SDKOption) *Formance { sdkConfiguration: sdkConfiguration{ Language: "go", OpenAPIDocVersion: "v1", - SDKVersion: "0.4.10", + SDKVersion: "0.4.13", GenVersion: "2.384.1", - UserAgent: "speakeasy-sdk/go 0.4.10 2.384.1 v1 github.com/formancehq/stack/ledger/client", + UserAgent: "speakeasy-sdk/go 0.4.13 2.384.1 v1 github.com/formancehq/stack/ledger/client", Hooks: hooks.New(), }, } diff --git a/pkg/client/ledger.go b/pkg/client/ledger.go index 25fcac408..5b04266a7 100644 --- a/pkg/client/ledger.go +++ b/pkg/client/ledger.go @@ -2,6 +2,21 @@ package client +import ( + "bytes" + "context" + "fmt" + "github.com/cenkalti/backoff/v4" + "github.com/formancehq/stack/ledger/client/internal/hooks" + "github.com/formancehq/stack/ledger/client/internal/utils" + "github.com/formancehq/stack/ledger/client/models/components" + "github.com/formancehq/stack/ledger/client/models/operations" + "github.com/formancehq/stack/ledger/client/models/sdkerrors" + "io" + "net/http" + "net/url" +) + type Ledger struct { V1 *V1 V2 *V2 @@ -16,3 +31,194 @@ func newLedger(sdkConfig sdkConfiguration) *Ledger { V2: newV2(sdkConfig), } } + +// GetInfo - Show server information +func (s *Ledger) GetInfo(ctx context.Context, opts ...operations.Option) (*operations.V2GetInfoResponse, error) { + hookCtx := hooks.HookContext{ + Context: ctx, + OperationID: "v2GetInfo", + OAuth2Scopes: []string{"ledger:read", "ledger:read"}, + SecuritySource: s.sdkConfiguration.Security, + } + + o := operations.Options{} + supportedOptions := []string{ + operations.SupportedOptionRetries, + operations.SupportedOptionTimeout, + } + + for _, opt := range opts { + if err := opt(&o, supportedOptions...); err != nil { + return nil, fmt.Errorf("error applying option: %w", err) + } + } + + baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) + opURL, err := url.JoinPath(baseURL, "/_/info") + if err != nil { + return nil, fmt.Errorf("error generating URL: %w", err) + } + + timeout := o.Timeout + if timeout == nil { + timeout = s.sdkConfiguration.Timeout + } + + if timeout != nil { + var cancel context.CancelFunc + ctx, cancel = context.WithTimeout(ctx, *timeout) + defer cancel() + } + + req, err := http.NewRequestWithContext(ctx, "GET", opURL, nil) + if err != nil { + return nil, fmt.Errorf("error creating request: %w", err) + } + req.Header.Set("Accept", "application/json") + req.Header.Set("User-Agent", s.sdkConfiguration.UserAgent) + + if err := utils.PopulateSecurity(ctx, req, s.sdkConfiguration.Security); err != nil { + return nil, err + } + + globalRetryConfig := s.sdkConfiguration.RetryConfig + retryConfig := o.Retries + if retryConfig == nil { + if globalRetryConfig != nil { + retryConfig = globalRetryConfig + } + } + + var httpRes *http.Response + if retryConfig != nil { + httpRes, err = utils.Retry(ctx, utils.Retries{ + Config: retryConfig, + StatusCodes: []string{ + "429", + "500", + "502", + "503", + "504", + }, + }, func() (*http.Response, error) { + if req.Body != nil { + copyBody, err := req.GetBody() + if err != nil { + return nil, err + } + req.Body = copyBody + } + + req, err = s.sdkConfiguration.Hooks.BeforeRequest(hooks.BeforeRequestContext{HookContext: hookCtx}, req) + if err != nil { + return nil, backoff.Permanent(err) + } + + httpRes, err := s.sdkConfiguration.Client.Do(req) + if err != nil || httpRes == nil { + if err != nil { + err = fmt.Errorf("error sending request: %w", err) + } else { + err = fmt.Errorf("error sending request: no response") + } + + _, err = s.sdkConfiguration.Hooks.AfterError(hooks.AfterErrorContext{HookContext: hookCtx}, nil, err) + } + return httpRes, err + }) + + if err != nil { + return nil, err + } else { + httpRes, err = s.sdkConfiguration.Hooks.AfterSuccess(hooks.AfterSuccessContext{HookContext: hookCtx}, httpRes) + if err != nil { + return nil, err + } + } + } else { + req, err = s.sdkConfiguration.Hooks.BeforeRequest(hooks.BeforeRequestContext{HookContext: hookCtx}, req) + if err != nil { + return nil, err + } + + httpRes, err = s.sdkConfiguration.Client.Do(req) + if err != nil || httpRes == nil { + if err != nil { + err = fmt.Errorf("error sending request: %w", err) + } else { + err = fmt.Errorf("error sending request: no response") + } + + _, err = s.sdkConfiguration.Hooks.AfterError(hooks.AfterErrorContext{HookContext: hookCtx}, nil, err) + return nil, err + } else if utils.MatchStatusCodes([]string{"default"}, httpRes.StatusCode) { + _httpRes, err := s.sdkConfiguration.Hooks.AfterError(hooks.AfterErrorContext{HookContext: hookCtx}, httpRes, nil) + if err != nil { + return nil, err + } else if _httpRes != nil { + httpRes = _httpRes + } + } else { + httpRes, err = s.sdkConfiguration.Hooks.AfterSuccess(hooks.AfterSuccessContext{HookContext: hookCtx}, httpRes) + if err != nil { + return nil, err + } + } + } + + res := &operations.V2GetInfoResponse{ + HTTPMeta: components.HTTPMetadata{ + Request: req, + Response: httpRes, + }, + } + + rawBody, err := io.ReadAll(httpRes.Body) + if err != nil { + return nil, fmt.Errorf("error reading response body: %w", err) + } + httpRes.Body.Close() + httpRes.Body = io.NopCloser(bytes.NewBuffer(rawBody)) + + switch { + case httpRes.StatusCode == 200: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out components.V2ConfigInfoResponse + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + res.V2ConfigInfoResponse = &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode >= 500 && httpRes.StatusCode < 600: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.V2ErrorResponse + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + res.V2ErrorResponse = &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + default: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + var out sdkerrors.V2ErrorResponse + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + } + + return res, nil + +} diff --git a/pkg/client/v2.go b/pkg/client/v2.go index cfe6a3f81..58a581b02 100644 --- a/pkg/client/v2.go +++ b/pkg/client/v2.go @@ -27,197 +27,6 @@ func newV2(sdkConfig sdkConfiguration) *V2 { } } -// GetInfo - Show server information -func (s *V2) GetInfo(ctx context.Context, opts ...operations.Option) (*operations.V2GetInfoResponse, error) { - hookCtx := hooks.HookContext{ - Context: ctx, - OperationID: "v2GetInfo", - OAuth2Scopes: []string{"ledger:read", "ledger:read"}, - SecuritySource: s.sdkConfiguration.Security, - } - - o := operations.Options{} - supportedOptions := []string{ - operations.SupportedOptionRetries, - operations.SupportedOptionTimeout, - } - - for _, opt := range opts { - if err := opt(&o, supportedOptions...); err != nil { - return nil, fmt.Errorf("error applying option: %w", err) - } - } - - baseURL := utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) - opURL, err := url.JoinPath(baseURL, "/v2/_info") - if err != nil { - return nil, fmt.Errorf("error generating URL: %w", err) - } - - timeout := o.Timeout - if timeout == nil { - timeout = s.sdkConfiguration.Timeout - } - - if timeout != nil { - var cancel context.CancelFunc - ctx, cancel = context.WithTimeout(ctx, *timeout) - defer cancel() - } - - req, err := http.NewRequestWithContext(ctx, "GET", opURL, nil) - if err != nil { - return nil, fmt.Errorf("error creating request: %w", err) - } - req.Header.Set("Accept", "application/json") - req.Header.Set("User-Agent", s.sdkConfiguration.UserAgent) - - if err := utils.PopulateSecurity(ctx, req, s.sdkConfiguration.Security); err != nil { - return nil, err - } - - globalRetryConfig := s.sdkConfiguration.RetryConfig - retryConfig := o.Retries - if retryConfig == nil { - if globalRetryConfig != nil { - retryConfig = globalRetryConfig - } - } - - var httpRes *http.Response - if retryConfig != nil { - httpRes, err = utils.Retry(ctx, utils.Retries{ - Config: retryConfig, - StatusCodes: []string{ - "429", - "500", - "502", - "503", - "504", - }, - }, func() (*http.Response, error) { - if req.Body != nil { - copyBody, err := req.GetBody() - if err != nil { - return nil, err - } - req.Body = copyBody - } - - req, err = s.sdkConfiguration.Hooks.BeforeRequest(hooks.BeforeRequestContext{HookContext: hookCtx}, req) - if err != nil { - return nil, backoff.Permanent(err) - } - - httpRes, err := s.sdkConfiguration.Client.Do(req) - if err != nil || httpRes == nil { - if err != nil { - err = fmt.Errorf("error sending request: %w", err) - } else { - err = fmt.Errorf("error sending request: no response") - } - - _, err = s.sdkConfiguration.Hooks.AfterError(hooks.AfterErrorContext{HookContext: hookCtx}, nil, err) - } - return httpRes, err - }) - - if err != nil { - return nil, err - } else { - httpRes, err = s.sdkConfiguration.Hooks.AfterSuccess(hooks.AfterSuccessContext{HookContext: hookCtx}, httpRes) - if err != nil { - return nil, err - } - } - } else { - req, err = s.sdkConfiguration.Hooks.BeforeRequest(hooks.BeforeRequestContext{HookContext: hookCtx}, req) - if err != nil { - return nil, err - } - - httpRes, err = s.sdkConfiguration.Client.Do(req) - if err != nil || httpRes == nil { - if err != nil { - err = fmt.Errorf("error sending request: %w", err) - } else { - err = fmt.Errorf("error sending request: no response") - } - - _, err = s.sdkConfiguration.Hooks.AfterError(hooks.AfterErrorContext{HookContext: hookCtx}, nil, err) - return nil, err - } else if utils.MatchStatusCodes([]string{"default"}, httpRes.StatusCode) { - _httpRes, err := s.sdkConfiguration.Hooks.AfterError(hooks.AfterErrorContext{HookContext: hookCtx}, httpRes, nil) - if err != nil { - return nil, err - } else if _httpRes != nil { - httpRes = _httpRes - } - } else { - httpRes, err = s.sdkConfiguration.Hooks.AfterSuccess(hooks.AfterSuccessContext{HookContext: hookCtx}, httpRes) - if err != nil { - return nil, err - } - } - } - - res := &operations.V2GetInfoResponse{ - HTTPMeta: components.HTTPMetadata{ - Request: req, - Response: httpRes, - }, - } - - rawBody, err := io.ReadAll(httpRes.Body) - if err != nil { - return nil, fmt.Errorf("error reading response body: %w", err) - } - httpRes.Body.Close() - httpRes.Body = io.NopCloser(bytes.NewBuffer(rawBody)) - - switch { - case httpRes.StatusCode == 200: - switch { - case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): - var out components.V2ConfigInfoResponse - if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { - return nil, err - } - - res.V2ConfigInfoResponse = &out - default: - return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) - } - case httpRes.StatusCode >= 500 && httpRes.StatusCode < 600: - switch { - case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): - var out sdkerrors.V2ErrorResponse - if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { - return nil, err - } - - res.V2ErrorResponse = &out - default: - return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) - } - default: - switch { - case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): - var out sdkerrors.V2ErrorResponse - if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { - return nil, err - } - - return nil, &out - default: - return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) - } - } - - return res, nil - -} - // ListLedgers - List ledgers func (s *V2) ListLedgers(ctx context.Context, request operations.V2ListLedgersRequest, opts ...operations.Option) (*operations.V2ListLedgersResponse, error) { hookCtx := hooks.HookContext{ diff --git a/pkg/testserver/api.go b/pkg/testserver/api.go index dee6ac61f..49c7de6a9 100644 --- a/pkg/testserver/api.go +++ b/pkg/testserver/api.go @@ -27,7 +27,7 @@ func GetLedger(ctx context.Context, srv *Server, request operations.V2GetLedgerR } func GetInfo(ctx context.Context, srv *Server) (*operations.V2GetInfoResponse, error) { - return srv.Client().Ledger.V2.GetInfo(ctx) + return srv.Client().Ledger.GetInfo(ctx) } func CreateTransaction(ctx context.Context, srv *Server, request operations.V2CreateTransactionRequest) (*components.V2Transaction, error) { diff --git a/test/e2e/lifecycle_test.go b/test/e2e/lifecycle_test.go index 1081979c1..d9461f998 100644 --- a/test/e2e/lifecycle_test.go +++ b/test/e2e/lifecycle_test.go @@ -41,7 +41,7 @@ var _ = Context("Ledger application lifecycle tests", func() { When("starting the service", func() { It("should be ok", func() { - info, err := testServer.GetValue().Client().Ledger.V2.GetInfo(ctx) + info, err := testServer.GetValue().Client().Ledger.GetInfo(ctx) Expect(err).NotTo(HaveOccurred()) Expect(info.V2ConfigInfoResponse.Version).To(Equal("develop")) })