Skip to content

Commit

Permalink
Merge pull request #67 from muzzammilshahid/config-code-reuseable
Browse files Browse the repository at this point in the history
Refactor: make config file loading and validation code reusable
  • Loading branch information
muzzammilshahid authored Jan 9, 2025
2 parents f8768e4 + 261872e commit d6e1cc6
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 59 deletions.
59 changes: 3 additions & 56 deletions cmd/xconn/main.go
Original file line number Diff line number Diff line change
@@ -1,22 +1,16 @@
package main

import (
"bytes"
_ "embed" // nolint:gci
"fmt"
"io"
"log"
"os"
"os/signal"
"path/filepath"
"time"

"github.com/alecthomas/kingpin/v2"
"golang.org/x/exp/slices"
"gopkg.in/yaml.v3"

"github.com/xconnio/xconn-go"
"github.com/xconnio/xconn-go/internal"
"github.com/xconnio/xconn-go/util"
)

var (
Expand Down Expand Up @@ -79,56 +73,9 @@ func Run(args []string) error {
}

case c.start.FullCommand():
data, err := os.ReadFile(configFile)
closers, err := util.StartServerFromConfigFile(configFile)
if err != nil {
return fmt.Errorf("unable to read config file: %w", err)
}

var decoder = yaml.NewDecoder(bytes.NewBuffer(data))
decoder.KnownFields(true)

var config Config
if err := decoder.Decode(&config); err != nil {
return fmt.Errorf("unable to decode config file: %w", err)
}

if err := config.Validate(); err != nil {
return fmt.Errorf("invalid config: %w", err)
}

router := xconn.NewRouter()
defer router.Close()

for _, realm := range config.Realms {
router.AddRealm(realm.Name)
}

authenticator := NewAuthenticator(config.Authenticators)

closers := make([]io.Closer, 0)
for _, transport := range config.Transports {
var throttle *internal.Throttle
if transport.RateLimit.Rate > 0 && transport.RateLimit.Interval > 0 {
strategy := internal.Burst
if transport.RateLimit.Strategy == LeakyBucketStrategy {
strategy = internal.LeakyBucket
}
throttle = internal.NewThrottle(transport.RateLimit.Rate,
time.Duration(transport.RateLimit.Interval)*time.Second, strategy)
}
server := xconn.NewServer(router, authenticator, &xconn.ServerConfig{Throttle: throttle})
if slices.Contains(transport.Serializers, "protobuf") {
if err := server.RegisterSpec(xconn.ProtobufSerializerSpec); err != nil {
return err
}
}

closer, err := server.Start(transport.Host, transport.Port)
if err != nil {
return err
}

closers = append(closers, closer)
return err
}

// Close server if SIGINT (CTRL-c) received.
Expand Down
2 changes: 1 addition & 1 deletion cmd/xconn/authenticator.go → util/authenticator.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package main
package util

import (
"fmt"
Expand Down
2 changes: 1 addition & 1 deletion cmd/xconn/config.go → util/config.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package main
package util

import (
"encoding/hex"
Expand Down
2 changes: 1 addition & 1 deletion cmd/xconn/types.go → util/types.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package main
package util

type Realm struct {
Name string `yaml:"name"`
Expand Down
71 changes: 71 additions & 0 deletions util/util.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package util

import (
"bytes"
"fmt"
"io"
"os"
"time"

"golang.org/x/exp/slices"
"gopkg.in/yaml.v3"

"github.com/xconnio/xconn-go"
"github.com/xconnio/xconn-go/internal"
)

func StartServerFromConfigFile(configFile string) ([]io.Closer, error) {
data, err := os.ReadFile(configFile)
if err != nil {
return nil, fmt.Errorf("unable to read config file: %w", err)
}

var decoder = yaml.NewDecoder(bytes.NewBuffer(data))
decoder.KnownFields(true)

var config Config
if err := decoder.Decode(&config); err != nil {
return nil, fmt.Errorf("unable to decode config file: %w", err)
}

if err := config.Validate(); err != nil {
return nil, fmt.Errorf("invalid config: %w", err)
}

router := xconn.NewRouter()
defer router.Close()

for _, realm := range config.Realms {
router.AddRealm(realm.Name)
}

authenticator := NewAuthenticator(config.Authenticators)

closers := make([]io.Closer, 0)
for _, transport := range config.Transports {
var throttle *internal.Throttle
if transport.RateLimit.Rate > 0 && transport.RateLimit.Interval > 0 {
strategy := internal.Burst
if transport.RateLimit.Strategy == LeakyBucketStrategy {
strategy = internal.LeakyBucket
}
throttle = internal.NewThrottle(transport.RateLimit.Rate,
time.Duration(transport.RateLimit.Interval)*time.Second, strategy)
}
server := xconn.NewServer(router, authenticator, &xconn.ServerConfig{Throttle: throttle})
if slices.Contains(transport.Serializers, "protobuf") {
if err := server.RegisterSpec(xconn.ProtobufSerializerSpec); err != nil {
return nil, err
}
}

closer, err := server.Start(transport.Host, transport.Port)
if err != nil {
return nil, err
}

closers = append(closers, closer)
}

return closers, nil
}

0 comments on commit d6e1cc6

Please sign in to comment.