Skip to content

Commit

Permalink
APPS-1378 Make dto pkg compatible for external use (#279)
Browse files Browse the repository at this point in the history
* extract aerospike namespace validator

* extract aerospike to top level

* move read cluster

* move aerospiek back into service

* check nil config

* check nil request
  • Loading branch information
korotkov-aerospike authored Dec 5, 2024
1 parent 8eaff63 commit ebbb018
Show file tree
Hide file tree
Showing 18 changed files with 124 additions and 92 deletions.
5 changes: 3 additions & 2 deletions cmd/backup/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"github.com/aerospike/aerospike-backup-service/v2/internal/util"
"github.com/aerospike/aerospike-backup-service/v2/pkg/model"
"github.com/aerospike/aerospike-backup-service/v2/pkg/service"
"github.com/aerospike/aerospike-backup-service/v2/pkg/service/aerospike"
"github.com/reugn/go-quartz/logger"
"github.com/spf13/cobra"
)
Expand Down Expand Up @@ -64,8 +65,8 @@ func run() int {

func startService(configFile string, remote bool) error {
ctx := systemCtx()
clientManager := service.NewClientManager(&service.DefaultClientFactory{}, 10*time.Second)
nsValidator := service.NewNamespaceValidator(clientManager)
clientManager := aerospike.NewClientManager(&aerospike.DefaultClientFactory{}, 10*time.Second)
nsValidator := aerospike.NewNamespaceValidator(clientManager)

config, configurationManager, err := configuration.Load(ctx, configFile, remote, nsValidator)
if err != nil {
Expand Down
8 changes: 4 additions & 4 deletions internal/server/configuration/configuration_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (

"github.com/aerospike/aerospike-backup-service/v2/pkg/dto"
"github.com/aerospike/aerospike-backup-service/v2/pkg/model"
"github.com/aerospike/aerospike-backup-service/v2/pkg/service"
"github.com/aerospike/aerospike-backup-service/v2/pkg/service/aerospike"
"gopkg.in/yaml.v3"
)

Expand All @@ -26,7 +26,7 @@ func Load(
ctx context.Context,
configFile string,
remote bool,
nsValidator service.NamespaceValidator,
nsValidator aerospike.NamespaceValidator,
) (*model.Config, Manager, error) {
slog.Info("Read service configuration from",
slog.String("file", configFile),
Expand All @@ -45,7 +45,7 @@ func Load(
return config, manager, nil
}

func readConfig(reader io.Reader, nsValidator service.NamespaceValidator) (*model.Config, error) {
func readConfig(reader io.Reader, nsValidator aerospike.NamespaceValidator) (*model.Config, error) {
configBytes, err := io.ReadAll(reader)
if err != nil {
return nil, fmt.Errorf("failed to read configuration content: %w", err)
Expand Down Expand Up @@ -75,7 +75,7 @@ func writeConfig(writer io.Writer, config *model.Config) error {
return err
}

func newConfigManager(configFile string, remote bool, nsValidator service.NamespaceValidator) (Manager, error) {
func newConfigManager(configFile string, remote bool, nsValidator aerospike.NamespaceValidator) (Manager, error) {
if remote {
storage, err := readStorage(configFile)
if err != nil {
Expand Down
6 changes: 3 additions & 3 deletions internal/server/configuration/configuration_manager_http.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,20 @@ import (
"net/http"

"github.com/aerospike/aerospike-backup-service/v2/pkg/model"
"github.com/aerospike/aerospike-backup-service/v2/pkg/service"
"github.com/aerospike/aerospike-backup-service/v2/pkg/service/aerospike"
)

// httpConfigurationManager implements the Manager interface,
// performing I/O operations via the HTTP(S) protocol.
type httpConfigurationManager struct {
configURL string
nsValidator service.NamespaceValidator
nsValidator aerospike.NamespaceValidator
}

var _ Manager = (*httpConfigurationManager)(nil)

// newHTTPConfigurationManager returns a new httpConfigurationManager.
func newHTTPConfigurationManager(uri string, nsValidator service.NamespaceValidator) Manager {
func newHTTPConfigurationManager(uri string, nsValidator aerospike.NamespaceValidator) Manager {
return &httpConfigurationManager{
configURL: uri,
nsValidator: nsValidator,
Expand Down
6 changes: 3 additions & 3 deletions internal/server/configuration/configuration_manager_local.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,21 @@ import (
"sync"

"github.com/aerospike/aerospike-backup-service/v2/pkg/model"
"github.com/aerospike/aerospike-backup-service/v2/pkg/service"
"github.com/aerospike/aerospike-backup-service/v2/pkg/service/aerospike"
)

// fileConfigurationManager implements the Manager interface,
// performing I/O operations on local storage.
type fileConfigurationManager struct {
sync.Mutex
FilePath string
nsValidator service.NamespaceValidator
nsValidator aerospike.NamespaceValidator
}

var _ Manager = (*fileConfigurationManager)(nil)

// newFileConfigurationManager returns a new fileConfigurationManager.
func newFileConfigurationManager(path string, nsValidator service.NamespaceValidator) Manager {
func newFileConfigurationManager(path string, nsValidator aerospike.NamespaceValidator) Manager {
return &fileConfigurationManager{
FilePath: path,
nsValidator: nsValidator,
Expand Down
6 changes: 3 additions & 3 deletions internal/server/configuration/storage_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,19 @@ import (
"fmt"

"github.com/aerospike/aerospike-backup-service/v2/pkg/model"
"github.com/aerospike/aerospike-backup-service/v2/pkg/service"
"github.com/aerospike/aerospike-backup-service/v2/pkg/service/aerospike"
"github.com/aerospike/aerospike-backup-service/v2/pkg/service/storage"
)

// storageManager implements Manager interface.
// it stores service configuration in provided Storage (Local, s3 aws etc.)
type storageManager struct {
storage model.Storage
nsValidator service.NamespaceValidator
nsValidator aerospike.NamespaceValidator
}

// newStorageManager returns new instance of storageManager
func newStorageManager(configStorage model.Storage, nsValidator service.NamespaceValidator) Manager {
func newStorageManager(configStorage model.Storage, nsValidator aerospike.NamespaceValidator) Manager {
return &storageManager{
storage: configStorage,
nsValidator: nsValidator,
Expand Down
5 changes: 3 additions & 2 deletions internal/server/handlers/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"github.com/aerospike/aerospike-backup-service/v2/internal/server/configuration"
"github.com/aerospike/aerospike-backup-service/v2/pkg/model"
"github.com/aerospike/aerospike-backup-service/v2/pkg/service"
"github.com/aerospike/aerospike-backup-service/v2/pkg/service/aerospike"
"github.com/reugn/go-quartz/quartz"
)

Expand All @@ -20,7 +21,7 @@ type Service struct {
handlerHolder service.BackupHandlerHolder
configurationManager configuration.Manager
logger *slog.Logger
nsValidator service.NamespaceValidator
nsValidator aerospike.NamespaceValidator
}

func NewService(
Expand All @@ -32,7 +33,7 @@ func NewService(
handlerHolder service.BackupHandlerHolder,
configurationManager configuration.Manager,
logger *slog.Logger,
nsValidator service.NamespaceValidator,
nsValidator aerospike.NamespaceValidator,
) *Service {
return &Service{
config: config,
Expand Down
4 changes: 2 additions & 2 deletions pkg/dto/backup_routine.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
"io"

"github.com/aerospike/aerospike-backup-service/v2/pkg/model"
"github.com/aerospike/aerospike-backup-service/v2/pkg/service"
"github.com/aerospike/aerospike-backup-service/v2/pkg/service/aerospike"
"github.com/aws/smithy-go/ptr"
"github.com/reugn/go-quartz/quartz"
)
Expand Down Expand Up @@ -83,7 +83,7 @@ func (r *BackupRoutine) Validate() error {

func (r *BackupRoutine) ToModel(
config *model.Config,
nsValidator service.NamespaceValidator,
nsValidator aerospike.NamespaceValidator,
) (*model.BackupRoutine, error) {
policy, found := config.BackupPolicies[r.BackupPolicy]
if !found {
Expand Down
4 changes: 2 additions & 2 deletions pkg/dto/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
"io"

"github.com/aerospike/aerospike-backup-service/v2/pkg/model"
"github.com/aerospike/aerospike-backup-service/v2/pkg/service"
"github.com/aerospike/aerospike-backup-service/v2/pkg/service/aerospike"
)

// Config represents the service configuration file.
Expand Down Expand Up @@ -139,7 +139,7 @@ func NewConfigWithDefaultValues() *Config {
}
}

func (c *Config) ToModel(nsValidator service.NamespaceValidator) (*model.Config, error) {
func (c *Config) ToModel(nsValidator aerospike.NamespaceValidator) (*model.Config, error) {
if err := c.validate(); err != nil {
return nil, fmt.Errorf("configuration validation failed: %w", err)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package service
package aerospike

import (
"errors"
Expand All @@ -20,13 +20,13 @@ type ClientManager interface {
Close(*backup.Client)
}

// AerospikeClientFactory defines an interface for creating and checking clients.
type AerospikeClientFactory interface {
// ClientFactory defines an interface for creating and checking clients.
type ClientFactory interface {
NewClientWithPolicyAndHost(policy *as.ClientPolicy, hosts ...*as.Host) (backup.AerospikeClient, error)
IsClusterHealthy(client backup.AerospikeClient) bool
}

// DefaultClientFactory is the default implementation of AerospikeClientFactory.
// DefaultClientFactory is the default implementation of ClientFactory.
type DefaultClientFactory struct{}

// NewClientWithPolicyAndHost creates a new Aerospike client with the given policy and hosts.
Expand Down Expand Up @@ -61,7 +61,7 @@ func (f *DefaultClientFactory) IsClusterHealthy(client backup.AerospikeClient) b
type ClientManagerImpl struct {
mu sync.RWMutex
clients map[*model.AerospikeCluster]*clientInfo
clientFactory AerospikeClientFactory
clientFactory ClientFactory
closeDelay time.Duration
}

Expand All @@ -72,7 +72,7 @@ type clientInfo struct {
}

// NewClientManager creates a new ClientManagerImpl.
func NewClientManager(aerospikeClientFactory AerospikeClientFactory, closeDelay time.Duration) *ClientManagerImpl {
func NewClientManager(aerospikeClientFactory ClientFactory, closeDelay time.Duration) *ClientManagerImpl {
return &ClientManagerImpl{
clients: make(map[*model.AerospikeCluster]*clientInfo),
clientFactory: aerospikeClientFactory,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package service
package aerospike

import (
"errors"
Expand All @@ -14,7 +14,7 @@ import (
"github.com/stretchr/testify/require"
)

// MockClientFactory is a mock implementation of the AerospikeClientFactory interface.
// MockClientFactory is a mock implementation of the ClientFactory interface.
type MockClientFactory struct {
ShouldFail bool
IsClusterDisconnected bool
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,15 @@
package service
package aerospike

import (
"errors"
"fmt"
"log/slog"
"strings"

_ "github.com/aerospike/aerospike-backup-service/v2/modules/schema" // it's required to load configuration schemas in init method
"github.com/aerospike/aerospike-backup-service/v2/pkg/model"
"github.com/aerospike/aerospike-backup-service/v2/pkg/util"
as "github.com/aerospike/aerospike-client-go/v7"
"github.com/aerospike/aerospike-management-lib/asconfig"
"github.com/aerospike/aerospike-management-lib/info"
"github.com/aerospike/backup-go"
"github.com/go-logr/logr"
)

const namespaceInfo = "namespaces"
Expand Down Expand Up @@ -103,48 +99,9 @@ func getAllNamespacesOfCluster(client backup.AerospikeClient) ([]string, error)
return strings.Split(namespaces, ";"), nil
}

func getClusterConfiguration(client backup.AerospikeClient) []asconfig.DotConf {
activeHosts := getActiveHosts(client)

var outputs = make([]asconfig.DotConf, 0, len(activeHosts))
policy := client.Cluster().ClientPolicy()
for _, host := range activeHosts {
asInfo := info.NewAsInfo(logr.Logger{}, host, &policy)

conf, err := asconfig.GenerateConf(logr.Discard(), asInfo, true)
if err != nil {
slog.Error("Error reading configuration",
slog.Any("host", host), slog.Any("err", err))
continue
}
asconf, _ := asconfig.NewMapAsConfig(logr.Discard(), conf.Conf)
configAsString, err := util.TryAndRecover(asconf.ToConfFile)
if err != nil {
slog.Error("Error serialising configuration",
slog.Any("host", host), slog.Any("err", err))
continue
}

outputs = append(outputs, configAsString)
}

return outputs
}

func getActiveHosts(client backup.AerospikeClient) []*as.Host {
var activeHosts []*as.Host
for _, node := range client.GetNodes() {
if node.IsActive() {
activeHosts = append(activeHosts, node.GetHost())
}
}

return activeHosts
}

// resolveBackupNamespaces returns the list of namespaces to back up.
// ResolveNamespaces returns the list of namespaces to back up.
// If `namespaces` is empty, it fetches all namespaces from the cluster via the provided client.
func resolveNamespaces(namespaces []string, client backup.AerospikeClient) ([]string, error) {
func ResolveNamespaces(namespaces []string, client backup.AerospikeClient) ([]string, error) {
if len(namespaces) == 0 {
return getAllNamespacesOfCluster(client)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//go:build !ci

package service
package aerospike

import (
"testing"
Expand Down
7 changes: 4 additions & 3 deletions pkg/service/backup_routine_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"time"

"github.com/aerospike/aerospike-backup-service/v2/pkg/model"
"github.com/aerospike/aerospike-backup-service/v2/pkg/service/aerospike"
"github.com/aerospike/aerospike-backup-service/v2/pkg/service/storage"
"github.com/aerospike/aerospike-backup-service/v2/pkg/util"
"github.com/aerospike/backup-go"
Expand All @@ -27,7 +28,7 @@ type BackupRoutineHandler struct {
secretAgent *model.SecretAgent
lastRun lastBackupRun
retry executor
clientManager ClientManager
clientManager aerospike.ClientManager
logger *slog.Logger
clusterConfigWriter ClusterConfigWriter

Expand Down Expand Up @@ -79,7 +80,7 @@ type BackupHandlerHolder map[string]*BackupRoutineHandler
// newBackupRoutineHandler returns a new BackupRoutineHandler instance.
func newBackupRoutineHandler(
config *model.Config,
clientManager ClientManager,
clientManager aerospike.ClientManager,
backupService Backup,
routineName string,
backupBackend backupMetadataManager,
Expand Down Expand Up @@ -174,7 +175,7 @@ func (h *BackupRoutineHandler) prepareCluster(retry executor) (*backup.Client, [
if err != nil {
return fmt.Errorf("cannot get backup client: %w", err)
}
namespaces, err = resolveNamespaces(h.namespaces, client.AerospikeClient())
namespaces, err = aerospike.ResolveNamespaces(h.namespaces, client.AerospikeClient())
if err != nil {
return fmt.Errorf("cannot retrieve namespaces from source cluster: %w", err)
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/service/cluster_config_writer.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ func (w *DefaultClusterConfigWriter) Write(
client backup.AerospikeClient,
timestamp time.Time,
) {
infos := getClusterConfiguration(client)
infos := scanClusterConfiguration(client, w.logger)
if len(infos) == 0 {
w.logger.Warn("Could not read aerospike configuration")
return
Expand Down
Loading

0 comments on commit ebbb018

Please sign in to comment.