Skip to content

Commit

Permalink
fix: GET /connectors returns 404 not found (#50)
Browse files Browse the repository at this point in the history
  • Loading branch information
Antoine Gelloz authored Nov 23, 2022
1 parent a68bb1b commit cf71535
Show file tree
Hide file tree
Showing 16 changed files with 103 additions and 93 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
.DS_Store
.idea
vendor
.cloud/ressources/.terraform
Expand Down
1 change: 1 addition & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ linters:
- funlen # Disabled by design
- misspell # Disabled by design
- ireturn # Disabled by design
- wsl # Disabled by design
- gocritic # TODO: FIX. Seems to have issues with generics
- gocognit # TODO: FIX
- goerr113 # TODO: FIX
Expand Down
18 changes: 0 additions & 18 deletions internal/app/api/connector.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (

"github.com/formancehq/payments/internal/pkg/integration"
"github.com/formancehq/payments/internal/pkg/payments"

"github.com/gorilla/mux"
"github.com/numary/go-libs/sharedapi"
"github.com/numary/go-libs/sharedlogging"
Expand Down Expand Up @@ -85,23 +84,6 @@ func readTask[Config payments.ConnectorConfigObject,
}
}

func findAll[Config payments.ConnectorConfigObject,
Descriptor payments.TaskDescriptor](connectorManager *integration.ConnectorManager[Config, Descriptor],
) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
res, err := connectorManager.FindAll(context.Background())
if err != nil {
handleError(w, r, err)

return
}

if err = json.NewEncoder(w).Encode(res); err != nil {
panic(err)
}
}
}

func uninstall[Config payments.ConnectorConfigObject,
Descriptor payments.TaskDescriptor](connectorManager *integration.ConnectorManager[Config, Descriptor],
) http.HandlerFunc {
Expand Down
2 changes: 0 additions & 2 deletions internal/app/api/connectormodule.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,6 @@ func connectorRouter[Config payments.ConnectorConfigObject, Descriptor payments.
) *mux.Router {
r := mux.NewRouter()

r.Path("/").Methods(http.MethodGet).Handler(findAll(manager))

r.Path("/" + name).Methods(http.MethodPost).Handler(install(manager))

r.Path("/" + name + "/reset").Methods(http.MethodPost).Handler(reset(manager))
Expand Down
26 changes: 25 additions & 1 deletion internal/app/api/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,23 @@ package api

import (
"context"
"encoding/json"
"net/http"
"runtime/debug"
"strings"
"time"

"github.com/formancehq/payments/internal/pkg/connectors/bankingcircle"
"github.com/formancehq/payments/internal/pkg/connectors/currencycloud"

"github.com/formancehq/payments/internal/pkg/connectors/dummypay"
"github.com/formancehq/payments/internal/pkg/connectors/modulr"
"github.com/formancehq/payments/internal/pkg/connectors/stripe"
"github.com/formancehq/payments/internal/pkg/connectors/wise"
"github.com/formancehq/payments/internal/pkg/integration"
"github.com/formancehq/payments/internal/pkg/payments"
"github.com/gorilla/mux"
"github.com/numary/go-libs/oauth2/oauth2introspect"
"github.com/numary/go-libs/sharedapi"
"github.com/numary/go-libs/sharedauth"
sharedotlp "github.com/numary/go-libs/sharedotlp/pkg"
"github.com/rs/cors"
Expand Down Expand Up @@ -93,6 +96,7 @@ func httpRouter(db *mongo.Database, client *mongo.Client, handlers []connectorHa
authGroup.Use(sharedauth.Middleware(methods...))
}

authGroup.HandleFunc("/connectors", readConnectorsHandler(db))
connectorGroup := authGroup.PathPrefix("/connectors").Subrouter()

for _, h := range handlers {
Expand Down Expand Up @@ -158,3 +162,23 @@ func sharedAuthMethods() []sharedauth.Method {

return methods
}

func readConnectorsHandler(db *mongo.Database) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
connectorStore := integration.NewMongoDBConnectorStore(db)
res, err := connectorStore.FindAll(r.Context())
if err != nil {
handleError(w, r, err)

return
}

err = json.NewEncoder(w).Encode(
sharedapi.BaseResponse[[]payments.ConnectorBaseInfo]{
Data: &res,
})
if err != nil {
panic(err)
}
}
}
52 changes: 6 additions & 46 deletions internal/pkg/connectors/dummypay/config.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package dummypay

import (
"encoding/json"
"fmt"
"time"

"github.com/formancehq/payments/internal/pkg/connectors"
)

// Config is the configuration for the dummy payment connector.
Expand All @@ -12,10 +12,10 @@ type Config struct {
Directory string `json:"directory" yaml:"directory" bson:"directory"`

// FilePollingPeriod is the period between file polling.
FilePollingPeriod Duration `json:"filePollingPeriod" yaml:"filePollingPeriod" bson:"filePollingPeriod"`
FilePollingPeriod connectors.Duration `json:"filePollingPeriod" yaml:"filePollingPeriod" bson:"filePollingPeriod"`

// FileGenerationPeriod is the period between file generation
FileGenerationPeriod Duration `json:"fileGenerationPeriod" yaml:"fileGenerationPeriod" bson:"fileGenerationPeriod"`
FileGenerationPeriod connectors.Duration `json:"fileGenerationPeriod" yaml:"fileGenerationPeriod" bson:"fileGenerationPeriod"`
}

// String returns a string representation of the configuration.
Expand All @@ -32,56 +32,16 @@ func (cfg Config) Validate() error {
}

// check if file polling period is set properly
if cfg.FilePollingPeriod <= 0 {
if cfg.FilePollingPeriod.Duration <= 0 {
return fmt.Errorf("filePollingPeriod must be greater than 0: %w",
ErrFilePollingPeriodInvalid)
}

// check if file generation period is set properly
if cfg.FileGenerationPeriod <= 0 {
if cfg.FileGenerationPeriod.Duration <= 0 {
return fmt.Errorf("fileGenerationPeriod must be greater than 0: %w",
ErrFileGenerationPeriodInvalid)
}

return nil
}

type Duration time.Duration

func (d *Duration) String() string {
return time.Duration(*d).String()
}

func (d *Duration) Duration() time.Duration {
return time.Duration(*d)
}

func (d *Duration) MarshalJSON() ([]byte, error) {
return json.Marshal(time.Duration(*d).String())
}

func (d *Duration) UnmarshalJSON(b []byte) error {
var durationValue interface{}

if err := json.Unmarshal(b, &durationValue); err != nil {
return err
}

switch value := durationValue.(type) {
case float64:
*d = Duration(time.Duration(value))

return nil
case string:
tmp, err := time.ParseDuration(value)
if err != nil {
return err
}

*d = Duration(tmp)

return nil
default:
return ErrDurationInvalid
}
}
13 changes: 7 additions & 6 deletions internal/pkg/connectors/dummypay/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"testing"
"time"

"github.com/formancehq/payments/internal/pkg/connectors"
"github.com/stretchr/testify/assert"
)

Expand All @@ -14,8 +15,8 @@ func TestConfigString(t *testing.T) {

config := Config{
Directory: "test",
FilePollingPeriod: Duration(time.Second),
FileGenerationPeriod: Duration(time.Minute),
FilePollingPeriod: connectors.Duration{Duration: time.Second},
FileGenerationPeriod: connectors.Duration{Duration: time.Minute},
}

assert.Equal(t, "directory: test, filePollingPeriod: 1s, fileGenerationPeriod: 1m0s", config.String())
Expand Down Expand Up @@ -43,15 +44,15 @@ func TestConfigValidate(t *testing.T) {
config.Directory = userHomeDir

// fail on invalid file polling period
config.FilePollingPeriod = -1
config.FilePollingPeriod.Duration = -1
assert.ErrorIs(t, config.Validate(), ErrFilePollingPeriodInvalid)

// fail on invalid file generation period
config.FilePollingPeriod = 1
config.FileGenerationPeriod = -1
config.FilePollingPeriod.Duration = 1
config.FileGenerationPeriod.Duration = -1
assert.ErrorIs(t, config.Validate(), ErrFileGenerationPeriodInvalid)

// success
config.FileGenerationPeriod = 1
config.FileGenerationPeriod.Duration = 1
assert.NoError(t, config.Validate())
}
10 changes: 5 additions & 5 deletions internal/pkg/connectors/dummypay/loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ package dummypay
import (
"time"

"github.com/formancehq/payments/internal/pkg/connectors"
"github.com/formancehq/payments/internal/pkg/integration"

"github.com/numary/go-libs/sharedlogging"
)

Expand All @@ -30,12 +30,12 @@ const (

// ApplyDefaults applies default values to the configuration.
func (l *Loader) ApplyDefaults(cfg Config) Config {
if cfg.FileGenerationPeriod == 0 {
cfg.FileGenerationPeriod = Duration(defaultFileGenerationPeriod)
if cfg.FileGenerationPeriod.Duration == 0 {
cfg.FileGenerationPeriod = connectors.Duration{Duration: defaultFileGenerationPeriod}
}

if cfg.FilePollingPeriod == 0 {
cfg.FilePollingPeriod = Duration(defaultFilePollingPeriod)
if cfg.FilePollingPeriod.Duration == 0 {
cfg.FilePollingPeriod = connectors.Duration{Duration: defaultFilePollingPeriod}
}

return cfg
Expand Down
5 changes: 3 additions & 2 deletions internal/pkg/connectors/dummypay/loader_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"testing"
"time"

"github.com/formancehq/payments/internal/pkg/connectors"
"github.com/numary/go-libs/sharedlogging"
"github.com/stretchr/testify/assert"
)
Expand All @@ -21,8 +22,8 @@ func TestLoader(t *testing.T) {
assert.Equal(t, connectorName, loader.Name())
assert.Equal(t, 10, loader.AllowTasks())
assert.Equal(t, Config{
FilePollingPeriod: Duration(10 * time.Second),
FileGenerationPeriod: Duration(5 * time.Second),
FilePollingPeriod: connectors.Duration{Duration: 10 * time.Second},
FileGenerationPeriod: connectors.Duration{Duration: 5 * time.Second},
}, loader.ApplyDefaults(config))

assert.EqualValues(t, newConnector(logger, config, newFS()), loader.Load(logger, config))
Expand Down
9 changes: 8 additions & 1 deletion internal/pkg/connectors/dummypay/task_generate_file.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"encoding/json"
"fmt"
"math/rand"
"os"
"time"

"github.com/formancehq/payments/internal/pkg/payments"
Expand Down Expand Up @@ -32,7 +33,7 @@ func taskGenerateFiles(config Config, fs fs) task.Task {
select {
case <-ctx.Done():
return nil
case <-time.After(config.FileGenerationPeriod.Duration()):
case <-time.After(config.FileGenerationPeriod.Duration):
err := generateFile(config, fs)
if err != nil {
return err
Expand All @@ -43,6 +44,12 @@ func taskGenerateFiles(config Config, fs fs) task.Task {
}

func generateFile(config Config, fs fs) error {
err := fs.Mkdir(config.Directory, 0o777) //nolint:gomnd
if err != nil && !os.IsExist(err) {
return fmt.Errorf(
"failed to create dummypay config directory '%s': %w", config.Directory, err)
}

key := fmt.Sprintf("%s-%d", generatedFilePrefix, time.Now().UnixNano())
fileKey := fmt.Sprintf("%s/%s.json", config.Directory, key)

Expand Down
3 changes: 1 addition & 2 deletions internal/pkg/connectors/dummypay/task_read_files.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"time"

"github.com/formancehq/payments/internal/pkg/task"

"github.com/numary/go-libs/sharedlogging"
"github.com/spf13/afero"
)
Expand All @@ -32,7 +31,7 @@ func taskReadFiles(config Config, fs fs) task.Task {
select {
case <-ctx.Done():
return nil
case <-time.After(config.FilePollingPeriod.Duration()):
case <-time.After(config.FilePollingPeriod.Duration):
files, err := parseFilesToIngest(config, fs)
if err != nil {
return fmt.Errorf("error parsing files to ingest: %w", err)
Expand Down
36 changes: 36 additions & 0 deletions internal/pkg/connectors/duration.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package connectors

import (
"encoding/json"
"fmt"
"time"

"github.com/pkg/errors"
)

type Duration struct {
time.Duration
}

func (d *Duration) MarshalJSON() ([]byte, error) {
return json.Marshal(d.String())
}

func (d *Duration) UnmarshalJSON(b []byte) error {
var v any
if err := json.Unmarshal(b, &v); err != nil {
return errors.Wrap(err, "custom Duration UnmarshalJSON: json.Unmarshal")
}
switch value := v.(type) {
case string:
var err error
d.Duration, err = time.ParseDuration(value)
if err != nil {
return errors.Wrap(err, "custom Duration UnmarshalJSON: time.ParseDuration")
}

return nil
default:
return fmt.Errorf("custom Duration UnmarshalJSON: invalid type: value:%v, type:%T", value, value)
}
}
7 changes: 4 additions & 3 deletions internal/pkg/connectors/stripe/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@ package stripe
import (
"errors"
"fmt"
"time"

"github.com/formancehq/payments/internal/pkg/connectors"
)

type Config struct {
PollingPeriod time.Duration `json:"pollingPeriod" yaml:"pollingPeriod" bson:"pollingPeriod"`
APIKey string `json:"apiKey" yaml:"apiKey" bson:"apiKey"`
PollingPeriod connectors.Duration `json:"pollingPeriod" yaml:"pollingPeriod" bson:"pollingPeriod"`
APIKey string `json:"apiKey" yaml:"apiKey" bson:"apiKey"`
TimelineConfig `bson:",inline"`
}

Expand Down
Loading

0 comments on commit cf71535

Please sign in to comment.