Skip to content

Commit

Permalink
Adding client lib to be used in go
Browse files Browse the repository at this point in the history
  • Loading branch information
Andre Hahn committed Jun 13, 2018
1 parent e3a7d76 commit 41f83fc
Show file tree
Hide file tree
Showing 7 changed files with 613 additions and 1 deletion.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,4 @@ khan-perf.dump
/dev/default.yaml
*.coverprofile
dev/khan-linux-x86_64
*.swp
8 changes: 7 additions & 1 deletion Gopkg.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 14 additions & 0 deletions lib/interface.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package lib

import "context"

// KhanInterface defines the interface for the khan client
type KhanInterface interface {
CreatePlayer(context.Context, string, string, interface{}) (string, error)
UpdatePlayer(context.Context, string, string, interface{}) error
RetrievePlayer(context.Context, string) (*Player, error)
CreateClan(context.Context, *ClanPayload) (string, error)
UpdateClan(context.Context, *ClanPayload) error
RetrieveClanSummary(context.Context, string) (*ClanSummary, error)
RetrieveClansSummary(context.Context, []string) ([]*ClanSummary, error)
}
229 changes: 229 additions & 0 deletions lib/lib.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,229 @@
package lib

import (
"bytes"
"context"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"strings"
"sync"

"github.com/spf13/viper"
)

// Khan is a struct that represents a khan API application
type Khan struct {
httpClient *http.Client
Config *viper.Viper
url string
user string
pass string
gameID string
}

var (
client *http.Client
once sync.Once
)

func getHTTPClient() *http.Client {
once.Do(func() {
client = &http.Client{}
})
return client
}

// NewKhan returns a new khan API application
func NewKhan(config *viper.Viper) KhanInterface {
k := &Khan{
httpClient: getHTTPClient(),
Config: config,
url: config.GetString("khan.url"),
user: config.GetString("khan.user"),
pass: config.GetString("khan.pass"),
gameID: config.GetString("khan.gameid"),
}
return k
}

func (k *Khan) sendTo(ctx context.Context, method, url string, payload interface{}) ([]byte, error) {
payloadJSON, err := json.Marshal(payload)
if err != nil {
return nil, err
}

var req *http.Request

if payload != nil {
req, err = http.NewRequest(method, url, bytes.NewBuffer(payloadJSON))
if err != nil {
return nil, err
}
} else {
req, err = http.NewRequest(method, url, nil)
if err != nil {
return nil, err
}
}
req.Header.Set("Content-Type", "application/json")
req.SetBasicAuth(k.user, k.pass)
if ctx == nil {
ctx = context.Background()
}
req = req.WithContext(ctx)

resp, err := k.httpClient.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()

body, respErr := ioutil.ReadAll(resp.Body)
if respErr != nil {
return nil, respErr
}

if resp.StatusCode > 399 {
return nil, newRequestError(resp.StatusCode, string(body))
}

return body, nil
}

func (k *Khan) buildURL(pathname string) string {
return fmt.Sprintf("%s/games/%s/%s", k.url, k.gameID, pathname)
}

func (k *Khan) buildCreatePlayerURL() string {
pathname := "players"
return k.buildURL(pathname)
}

func (k *Khan) buildUpdatePlayerURL(playerID string) string {
pathname := fmt.Sprintf("players/%s", playerID)
return k.buildURL(pathname)
}

func (k *Khan) buildRetrievePlayerURL(playerID string) string {
pathname := fmt.Sprintf("players/%s", playerID)
return k.buildURL(pathname)
}

func (k *Khan) buildCreateClanURL() string {
pathname := "clans"
return k.buildURL(pathname)
}

func (k *Khan) buildUpdateClanURL(clanID string) string {
pathname := fmt.Sprintf("clans/%s", clanID)
return k.buildURL(pathname)
}

func (k *Khan) buildRetrieveClanSummaryURL(clanID string) string {
pathname := fmt.Sprintf("clans/%s/summary", clanID)
return k.buildURL(pathname)
}

func (k *Khan) buildRetrieveClansSummaryURL(clanIDs []string) string {
pathname := fmt.Sprintf("clans-summary?clanPublicIds=%s", strings.Join(clanIDs, ","))
return k.buildURL(pathname)
}

// CreatePlayer calls Khan to create a new player
func (k *Khan) CreatePlayer(ctx context.Context, publicID, name string, metadata interface{}) (string, error) {
route := k.buildCreatePlayerURL()
playerPayload := &Player{
PublicID: publicID,
Name: name,
Metadata: metadata,
}
body, err := k.sendTo(ctx, "POST", route, playerPayload)

if err != nil {
return "", err
}

var player Player
err = json.Unmarshal(body, &player)

return player.PublicID, err
}

// UpdatePlayer calls khan to update the player
func (k *Khan) UpdatePlayer(ctx context.Context, publicID, name string, metadata interface{}) error {
route := k.buildUpdatePlayerURL(publicID)
playerPayload := &Player{
Name: name,
Metadata: metadata,
}
_, err := k.sendTo(ctx, "PUT", route, playerPayload)
return err
}

// RetrievePlayer calls the retrieve player route from khan
func (k *Khan) RetrievePlayer(ctx context.Context, publicID string) (*Player, error) {
route := k.buildRetrievePlayerURL(publicID)
body, err := k.sendTo(ctx, "GET", route, nil)

if err != nil {
return nil, err
}

var player Player
err = json.Unmarshal(body, &player)
return &player, err
}

// CreateClan calls the create clan route from khan
func (k *Khan) CreateClan(ctx context.Context, clan *ClanPayload) (string, error) {
route := k.buildCreateClanURL()
body, err := k.sendTo(ctx, "POST", route, clan)

if err != nil {
return "", err
}

var player Player
err = json.Unmarshal(body, &player)
return player.PublicID, err
}

// UpdateClan calls the update clan route from khan
func (k *Khan) UpdateClan(ctx context.Context, clan *ClanPayload) error {
route := k.buildUpdateClanURL(clan.PublicID)
_, err := k.sendTo(ctx, "PUT", route, clan)
return err
}

// RetrieveClanSummary calls the route to retrieve clan summary from khan
func (k *Khan) RetrieveClanSummary(ctx context.Context, clanID string) (*ClanSummary, error) {
route := k.buildRetrieveClanSummaryURL(clanID)
body, err := k.sendTo(ctx, "GET", route, nil)

if err != nil {
return nil, err
}

var clanSummary ClanSummary
err = json.Unmarshal(body, &clanSummary)
return &clanSummary, err
}

// RetrieveClansSummary calls the route to retrieve clans summary from khan
func (k *Khan) RetrieveClansSummary(ctx context.Context, clanIDs []string) ([]*ClanSummary, error) {
route := k.buildRetrieveClansSummaryURL(clanIDs)
body, err := k.sendTo(ctx, "GET", route, nil)

if err != nil {
return nil, err
}

var clansSummary ClansSummary
err = json.Unmarshal(body, &clansSummary)
if err != nil {
return nil, err
}
return clansSummary.Clans, nil
}
13 changes: 13 additions & 0 deletions lib/lib_suite_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package lib_test

import (
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"

"testing"
)

func TestLib(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "Lib Suite")
}
Loading

0 comments on commit 41f83fc

Please sign in to comment.