Skip to content

Commit

Permalink
Merge pull request #116 from inovex/enforce-adapter-interface
Browse files Browse the repository at this point in the history
Assert optional interfaces for adapter implementations
  • Loading branch information
MichaelEischer authored Mar 9, 2024
2 parents fe9b891 + bedbbff commit 4bb15a6
Show file tree
Hide file tree
Showing 7 changed files with 48 additions and 27 deletions.
21 changes: 0 additions & 21 deletions internal/adapter/adapter.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
package adapter

import (
"context"

"github.com/charmbracelet/log"
"github.com/inovex/CalendarSync/internal/auth"

"github.com/inovex/CalendarSync/internal/config"
)

Expand All @@ -14,25 +9,9 @@ type Type string
const (
GoogleCalendarType Type = "google"
ZepCalendarType Type = "zep"
OutlookCalendarType Type = "outlook"
OutlookHttpCalendarType Type = "outlook_http"
)

// LogSetter can be implemented by a struct to allows injection of a logger instance
type LogSetter interface {
SetLogger(logger *log.Logger)
}

// Configurable is an interface which defines how arbitrary configuration data can be passed
// to a struct which implements this interface. Clients should be configurable.
type Configurable interface {
Initialize(ctx context.Context, config map[string]interface{}) error
}

type OAuth2Adapter interface {
SetupOauth2(ctx context.Context, credentials auth.Credentials, storage auth.Storage, bindPort uint) error
}

// ConfigReader provides an interface for adapters to load their own configuration map.
// It's the adapter's responsibility to validate that the map is valid.
type ConfigReader interface {
Expand Down
6 changes: 6 additions & 0 deletions internal/adapter/google/adapter.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"strings"
"time"

"github.com/inovex/CalendarSync/internal/adapter/port"
"github.com/inovex/CalendarSync/internal/models"
"github.com/pkg/browser"

Expand Down Expand Up @@ -46,6 +47,11 @@ type CalendarAPI struct {
storage auth.Storage
}

// Assert that the expected interfaces are implemented
var _ port.Configurable = &CalendarAPI{}
var _ port.LogSetter = &CalendarAPI{}
var _ port.OAuth2Adapter = &CalendarAPI{}

func (c *CalendarAPI) SetupOauth2(ctx context.Context, credentials auth.Credentials, storage auth.Storage, bindPort uint) error {
// Google Adapter does not need the tenantId
switch {
Expand Down
6 changes: 6 additions & 0 deletions internal/adapter/outlook_http/adapter.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"github.com/pkg/browser"
"golang.org/x/oauth2"

"github.com/inovex/CalendarSync/internal/adapter/port"
"github.com/inovex/CalendarSync/internal/auth"
"github.com/inovex/CalendarSync/internal/models"
)
Expand Down Expand Up @@ -41,6 +42,11 @@ type CalendarAPI struct {
storage auth.Storage
}

// Assert that the expected interfaces are implemented
var _ port.Configurable = &CalendarAPI{}
var _ port.LogSetter = &CalendarAPI{}
var _ port.OAuth2Adapter = &CalendarAPI{}

func (c *CalendarAPI) SetupOauth2(ctx context.Context, credentials auth.Credentials, storage auth.Storage, bindPort uint) error {
// Outlook Adapter does not need the clientKey
switch {
Expand Down
24 changes: 24 additions & 0 deletions internal/adapter/port/interface.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package port

import (
"context"

"github.com/charmbracelet/log"

"github.com/inovex/CalendarSync/internal/auth"
)

// LogSetter can be implemented by a struct to allows injection of a logger instance
type LogSetter interface {
SetLogger(logger *log.Logger)
}

// Configurable is an interface which defines how arbitrary configuration data can be passed
// to a struct which implements this interface. Clients should be configurable.
type Configurable interface {
Initialize(ctx context.Context, config map[string]interface{}) error
}

type OAuth2Adapter interface {
SetupOauth2(ctx context.Context, credentials auth.Credentials, storage auth.Storage, bindPort uint) error
}
7 changes: 4 additions & 3 deletions internal/adapter/sink_adapter.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (

"github.com/inovex/CalendarSync/internal/adapter/google"
outlook "github.com/inovex/CalendarSync/internal/adapter/outlook_http"
"github.com/inovex/CalendarSync/internal/adapter/port"
"github.com/inovex/CalendarSync/internal/sync"
)

Expand Down Expand Up @@ -40,11 +41,11 @@ func NewSinkAdapterFromConfig(ctx context.Context, bindPort uint, config ConfigR
return nil, err
}

if c, ok := client.(LogSetter); ok {
if c, ok := client.(port.LogSetter); ok {
c.SetLogger(logger)
}

if c, ok := client.(OAuth2Adapter); ok {
if c, ok := client.(port.OAuth2Adapter); ok {
if err := c.SetupOauth2(ctx,
auth.Credentials{
Client: auth.Client{
Expand All @@ -64,7 +65,7 @@ func NewSinkAdapterFromConfig(ctx context.Context, bindPort uint, config ConfigR
}

// configure adapter client if possible
if c, ok := client.(Configurable); ok {
if c, ok := client.(port.Configurable); ok {
if err := c.Initialize(ctx, config.Adapter().Config); err != nil {
return nil, fmt.Errorf("unable to Initialize adapter %s: %w", config.Adapter().Type, err)
}
Expand Down
7 changes: 4 additions & 3 deletions internal/adapter/source_adapter.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"github.com/inovex/CalendarSync/internal/models"

outlook "github.com/inovex/CalendarSync/internal/adapter/outlook_http"
"github.com/inovex/CalendarSync/internal/adapter/port"

"github.com/inovex/CalendarSync/internal/adapter/google"
"github.com/inovex/CalendarSync/internal/adapter/zep"
Expand Down Expand Up @@ -44,11 +45,11 @@ func NewSourceAdapterFromConfig(ctx context.Context, bindPort uint, config Confi
return nil, err
}

if c, ok := client.(LogSetter); ok {
if c, ok := client.(port.LogSetter); ok {
c.SetLogger(logger)
}

if c, ok := client.(OAuth2Adapter); ok {
if c, ok := client.(port.OAuth2Adapter); ok {
if err := c.SetupOauth2(ctx,
auth.Credentials{
Client: auth.Client{
Expand All @@ -68,7 +69,7 @@ func NewSourceAdapterFromConfig(ctx context.Context, bindPort uint, config Confi
}

// configure adapter client if possible
if c, ok := client.(Configurable); ok {
if c, ok := client.(port.Configurable); ok {
if err := c.Initialize(ctx, config.Adapter().Config); err != nil {
return nil, fmt.Errorf("unable to initialize adapter %s: %w", config.Adapter().Type, err)
}
Expand Down
4 changes: 4 additions & 0 deletions internal/adapter/zep/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"strings"
"time"

"github.com/inovex/CalendarSync/internal/adapter/port"
"github.com/inovex/CalendarSync/internal/models"

"github.com/charmbracelet/log"
Expand Down Expand Up @@ -36,6 +37,9 @@ type CalendarAPI struct {
homeSet string
}

// Assert that the expected interfaces are implemented
var _ port.Configurable = &CalendarAPI{}

func (zep *CalendarAPI) GetCalendarID() string {
return zep.generateCalendarID()
}
Expand Down

0 comments on commit 4bb15a6

Please sign in to comment.